Merge v236 into tizen
authorŁukasz Stelmach <l.stelmach@samsung.com>
Thu, 25 Jan 2024 12:07:22 +0000 (13:07 +0100)
committerŁukasz Stelmach <l.stelmach@samsung.com>
Mon, 12 Feb 2024 15:37:45 +0000 (16:37 +0100)
Change-Id: I912b2d8f996d147ffef5dc7337f7958dc2141300
Signed-off-by: Łukasz Stelmach <l.stelmach@samsung.com>
1946 files changed:
.github/CONTRIBUTING.md
.gitignore
.mailmap
.mkosi/mkosi.arch
.mkosi/mkosi.debian
.mkosi/mkosi.fedora
.ycm_extra_conf.py
CODING_STYLE
HACKING
NEWS
README
README.md
TODO
TRANSIENT-SETTINGS.md [new file with mode: 0644]
UIDS-GIDS.md [new file with mode: 0644]
catalog/meson.build
catalog/systemd.be.catalog.in
catalog/systemd.be@latin.catalog.in
catalog/systemd.bg.catalog.in
catalog/systemd.catalog.in
catalog/systemd.da.catalog.in
catalog/systemd.de.catalog.in
catalog/systemd.fr.catalog.in
catalog/systemd.hr.catalog.in
catalog/systemd.hu.catalog.in
catalog/systemd.it.catalog.in
catalog/systemd.ko.catalog.in
catalog/systemd.pl.catalog.in
catalog/systemd.pt_BR.catalog.in
catalog/systemd.ru.catalog.in
catalog/systemd.sr.catalog.in
catalog/systemd.zh_CN.catalog.in
catalog/systemd.zh_TW.catalog.in
coccinelle/const-strlen.cocci [new file with mode: 0644]
coccinelle/empty-to-null.cocci [new file with mode: 0644]
coccinelle/equals-null.cocci [new file with mode: 0644]
coccinelle/in_set.cocci
coccinelle/isempty.cocci [new file with mode: 0644]
coccinelle/not_in_set.cocci
coccinelle/run-coccinelle.sh [new file with mode: 0755]
docs/sysvinit/meson.build
docs/var-log/meson.build
hwdb/20-OUI.hwdb
hwdb/20-acpi-vendor.hwdb
hwdb/20-acpi-vendor.hwdb.patch
hwdb/20-pci-vendor-model.hwdb
hwdb/20-usb-vendor-model.hwdb
hwdb/60-evdev.hwdb
hwdb/60-input-id.hwdb [new file with mode: 0644]
hwdb/60-sensor.hwdb
hwdb/70-mouse.hwdb
hwdb/70-touchpad.hwdb
hwdb/acpi_id_registry.html
hwdb/ids_parser.py
hwdb/ma-large.txt
hwdb/ma-medium.txt
hwdb/ma-small.txt
hwdb/meson.build
hwdb/parse_hwdb.py
hwdb/pci.ids
hwdb/pnp_id_registry.html
hwdb/usb.ids
man/binfmt.d.xml
man/bootctl.xml
man/bootup.xml
man/busctl.xml
man/coredump.conf.xml
man/coredumpctl.xml
man/crypttab.xml
man/custom-entities.ent.in
man/custom-html.xsl
man/custom-man.xsl
man/daemon.xml
man/dnssec-trust-anchors.d.xml
man/environment.d.xml
man/file-hierarchy.xml
man/glib-event-glue.c
man/halt.xml
man/hostname.xml
man/hostnamectl.xml
man/hwdb.xml
man/journal-remote.conf.xml
man/journal-upload.conf.xml
man/journalctl.xml
man/journald.conf.xml
man/kernel-command-line.xml
man/kernel-install.xml
man/less-variables.xml
man/libsystemd-pkgconfig.xml
man/libudev.xml
man/locale.conf.xml
man/localectl.xml
man/localtime.xml
man/loginctl.xml
man/logind.conf.xml
man/machine-id.xml
man/machine-info.xml
man/machinectl.xml
man/meson.build
man/modules-load.d.xml
man/networkctl.xml
man/networkd.conf.xml
man/nss-myhostname.xml
man/nss-mymachines.xml
man/nss-resolve.xml
man/nss-systemd.xml
man/os-release.xml
man/pam_systemd.xml
man/resolved.conf.xml
man/rules/meson.build
man/runlevel.xml
man/sd-bus-errors.xml
man/sd-bus.xml
man/sd-daemon.xml
man/sd-event.xml
man/sd-id128.xml
man/sd-journal.xml
man/sd-login.xml
man/sd_booted.xml
man/sd_bus_add_match.xml
man/sd_bus_creds_get_pid.xml
man/sd_bus_creds_new_from_pid.xml
man/sd_bus_default.xml
man/sd_bus_error.xml
man/sd_bus_error_add_map.xml
man/sd_bus_get_fd.xml
man/sd_bus_message_append.xml
man/sd_bus_message_append_array.xml
man/sd_bus_message_append_basic.xml
man/sd_bus_message_append_string_memfd.xml
man/sd_bus_message_append_strv.xml
man/sd_bus_message_get_cookie.xml
man/sd_bus_message_get_monotonic_usec.xml
man/sd_bus_message_read_basic.xml
man/sd_bus_negotiate_fds.xml
man/sd_bus_new.xml
man/sd_bus_path_encode.xml
man/sd_bus_process.xml
man/sd_bus_request_name.xml
man/sd_bus_track_add_name.xml
man/sd_bus_track_new.xml
man/sd_event_add_child.xml
man/sd_event_add_defer.xml
man/sd_event_add_io.xml
man/sd_event_add_signal.xml
man/sd_event_add_time.xml
man/sd_event_exit.xml
man/sd_event_get_fd.xml
man/sd_event_new.xml
man/sd_event_now.xml
man/sd_event_run.xml
man/sd_event_set_watchdog.xml
man/sd_event_source_get_event.xml
man/sd_event_source_get_pending.xml
man/sd_event_source_set_description.xml
man/sd_event_source_set_enabled.xml
man/sd_event_source_set_prepare.xml
man/sd_event_source_set_priority.xml
man/sd_event_source_set_userdata.xml
man/sd_event_source_unref.xml
man/sd_event_wait.xml
man/sd_get_seats.xml
man/sd_id128_get_machine.xml
man/sd_id128_randomize.xml
man/sd_id128_to_string.xml
man/sd_is_fifo.xml
man/sd_journal_add_match.xml
man/sd_journal_enumerate_fields.xml
man/sd_journal_get_catalog.xml
man/sd_journal_get_cursor.xml
man/sd_journal_get_cutoff_realtime_usec.xml
man/sd_journal_get_data.xml
man/sd_journal_get_fd.xml
man/sd_journal_get_realtime_usec.xml
man/sd_journal_get_usage.xml
man/sd_journal_has_runtime_files.xml
man/sd_journal_next.xml
man/sd_journal_open.xml
man/sd_journal_print.xml
man/sd_journal_query_unique.xml
man/sd_journal_seek_head.xml
man/sd_journal_stream_fd.xml
man/sd_listen_fds.xml
man/sd_login_monitor_new.xml
man/sd_machine_get_class.xml
man/sd_notify.xml
man/sd_pid_get_owner_uid.xml [moved from man/sd_pid_get_session.xml with 85% similarity]
man/sd_seat_get_active.xml
man/sd_session_is_active.xml
man/sd_uid_get_state.xml
man/sd_watchdog_enabled.xml
man/shutdown.xml
man/standard-conf.xml
man/standard-options.xml
man/sysctl.d.xml
man/systemctl.xml
man/systemd-analyze.xml
man/systemd-ask-password-console.service.xml
man/systemd-ask-password.xml
man/systemd-backlight@.service.xml
man/systemd-binfmt.service.xml
man/systemd-cat.xml
man/systemd-cgls.xml
man/systemd-cgtop.xml
man/systemd-coredump.xml
man/systemd-cryptsetup-generator.xml
man/systemd-cryptsetup@.service.xml
man/systemd-debug-generator.xml
man/systemd-delta.xml
man/systemd-detect-virt.xml
man/systemd-environment-d-generator.xml
man/systemd-escape.xml
man/systemd-firstboot.xml
man/systemd-fsck@.service.xml
man/systemd-fstab-generator.xml
man/systemd-getty-generator.xml
man/systemd-gpt-auto-generator.xml
man/systemd-halt.service.xml
man/systemd-hibernate-resume-generator.xml
man/systemd-hibernate-resume@.service.xml
man/systemd-hostnamed.service.xml
man/systemd-hwdb.xml
man/systemd-importd.service.xml
man/systemd-inhibit.xml
man/systemd-initctl.service.xml
man/systemd-journal-gatewayd.service.xml
man/systemd-journal-remote.xml
man/systemd-journal-upload.xml
man/systemd-journald.service.xml
man/systemd-localed.service.xml
man/systemd-logind.service.xml
man/systemd-machine-id-commit.service.xml
man/systemd-machine-id-setup.xml
man/systemd-machined.service.xml
man/systemd-makefs@.service.xml [new file with mode: 0644]
man/systemd-modules-load.service.xml
man/systemd-mount.xml
man/systemd-networkd-wait-online.service.xml
man/systemd-networkd.service.xml
man/systemd-notify.xml
man/systemd-nspawn.xml
man/systemd-path.xml
man/systemd-quotacheck.service.xml
man/systemd-random-seed.service.xml
man/systemd-remount-fs.service.xml
man/systemd-resolve.xml
man/systemd-resolved.service.xml
man/systemd-rfkill.service.xml
man/systemd-run.xml
man/systemd-sleep.conf.xml
man/systemd-socket-activate.xml
man/systemd-socket-proxyd.xml
man/systemd-suspend.service.xml
man/systemd-sysctl.service.xml
man/systemd-system-update-generator.xml
man/systemd-system.conf.xml
man/systemd-sysusers.xml
man/systemd-sysv-generator.xml
man/systemd-timedated.service.xml
man/systemd-timesyncd.service.xml
man/systemd-tmpfiles.xml
man/systemd-tty-ask-password-agent.xml
man/systemd-udevd.service.xml
man/systemd-update-done.service.xml
man/systemd-update-utmp.service.xml
man/systemd-user-sessions.service.xml
man/systemd-vconsole-setup.service.xml
man/systemd-veritysetup-generator.xml
man/systemd-veritysetup@.service.xml
man/systemd-volatile-root.service.xml
man/systemd.automount.xml
man/systemd.device.xml
man/systemd.dnssd.xml [new file with mode: 0644]
man/systemd.environment-generator.xml
man/systemd.exec.xml
man/systemd.generator.xml
man/systemd.journal-fields.xml
man/systemd.kill.xml
man/systemd.link.xml
man/systemd.mount.xml
man/systemd.netdev.xml
man/systemd.network.xml
man/systemd.nspawn.xml
man/systemd.offline-updates.xml
man/systemd.path.xml
man/systemd.preset.xml
man/systemd.resource-control.xml
man/systemd.scope.xml
man/systemd.service.xml
man/systemd.slice.xml
man/systemd.socket.xml
man/systemd.special.xml
man/systemd.swap.xml
man/systemd.target.xml
man/systemd.time.xml
man/systemd.timer.xml
man/systemd.unit.xml
man/systemd.xml
man/sysusers.d.xml
man/telinit.xml
man/timedatectl.xml
man/timesyncd.conf.xml
man/tmpfiles.d.xml
man/udev.conf.xml
man/udev.xml
man/udev_device_get_syspath.xml
man/udev_device_has_tag.xml
man/udev_device_new_from_syspath.xml
man/udev_enumerate_add_match_subsystem.xml
man/udev_enumerate_new.xml
man/udev_enumerate_scan_devices.xml
man/udev_list_entry.xml
man/udev_monitor_filter_update.xml
man/udev_monitor_new_from_netlink.xml
man/udev_monitor_receive_device.xml
man/udev_new.xml
man/udevadm.xml
man/user-system-options.xml
man/vconsole.conf.xml
meson.build
meson_options.txt
mkosi.build
modprobe.d/systemd.conf
network/80-container-host0.network
network/80-container-ve.network
network/80-container-vz.network
network/99-default.link
network/meson.build
packaging/systemd.spec
po/be.po
po/be@latin.po
po/bg.po
po/ca.po
po/cs.po
po/da.po
po/de.po
po/el.po
po/es.po
po/fr.po
po/gl.po
po/hr.po
po/hu.po
po/id.po
po/it.po
po/its/polkit.its [new file with mode: 0644]
po/its/polkit.loc [new file with mode: 0644]
po/ko.po
po/meson.build
po/pl.po
po/pt_BR.po
po/ro.po
po/ru.po
po/sk.po
po/sr.po
po/sv.po
po/tr.po
po/uk.po
po/zh_CN.po
po/zh_TW.po
presets/90-systemd.preset [moved from system-preset/90-systemd.preset with 92% similarity]
presets/meson.build [new file with mode: 0644]
presets/user/90-systemd.preset [moved from units/remote-cryptsetup-pre.target with 57% similarity]
rules/50-udev-default.rules.in
rules/60-input-id.rules
rules/60-persistent-input.rules
rules/60-persistent-storage.rules
rules/99-systemd.rules.in
rules/meson.build
shell-completion/bash/bootctl
shell-completion/bash/busctl
shell-completion/bash/coredumpctl
shell-completion/bash/hostnamectl
shell-completion/bash/journalctl
shell-completion/bash/kernel-install
shell-completion/bash/localectl
shell-completion/bash/loginctl
shell-completion/bash/machinectl
shell-completion/bash/meson.build
shell-completion/bash/networkctl
shell-completion/bash/systemctl.in
shell-completion/bash/systemd-analyze
shell-completion/bash/systemd-cat
shell-completion/bash/systemd-cgls
shell-completion/bash/systemd-cgtop
shell-completion/bash/systemd-delta
shell-completion/bash/systemd-detect-virt
shell-completion/bash/systemd-nspawn
shell-completion/bash/systemd-path
shell-completion/bash/systemd-resolve
shell-completion/bash/systemd-run
shell-completion/bash/timedatectl
shell-completion/bash/udevadm
shell-completion/zsh/_bootctl
shell-completion/zsh/_busctl
shell-completion/zsh/_coredumpctl
shell-completion/zsh/_hostnamectl
shell-completion/zsh/_journalctl
shell-completion/zsh/_kernel-install
shell-completion/zsh/_localectl
shell-completion/zsh/_loginctl
shell-completion/zsh/_machinectl
shell-completion/zsh/_networkctl
shell-completion/zsh/_sd_hosts_or_user_at_host
shell-completion/zsh/_sd_machines
shell-completion/zsh/_sd_outputmodes
shell-completion/zsh/_sd_unit_files
shell-completion/zsh/_systemctl.in
shell-completion/zsh/_systemd
shell-completion/zsh/_systemd-analyze
shell-completion/zsh/_systemd-delta
shell-completion/zsh/_systemd-inhibit
shell-completion/zsh/_systemd-nspawn
shell-completion/zsh/_systemd-resolve
shell-completion/zsh/_systemd-run
shell-completion/zsh/_systemd-tmpfiles
shell-completion/zsh/_timedatectl
shell-completion/zsh/_udevadm
shell-completion/zsh/meson.build
src/ac-power/ac-power.c
src/activate/activate.c
src/analyze/analyze-verify.c
src/analyze/analyze-verify.h
src/analyze/analyze.c
src/analyze/meson.build
src/ask-password/ask-password.c
src/backlight/backlight.c
src/basic/MurmurHash2.c
src/basic/af-list.c
src/basic/af-list.h
src/basic/alloc-util.c
src/basic/alloc-util.h
src/basic/architecture.c
src/basic/architecture.h
src/basic/arphrd-list.c
src/basic/arphrd-list.h
src/basic/async.c
src/basic/async.h
src/basic/audit-util.c
src/basic/audit-util.h
src/basic/barrier.c
src/basic/barrier.h
src/basic/bitmap.c
src/basic/bitmap.h
src/basic/blkid-util.h
src/basic/bpf-program.c
src/basic/bpf-program.h
src/basic/btrfs-util.c
src/basic/btrfs-util.h
src/basic/build.h
src/basic/bus-label.c
src/basic/bus-label.h
src/basic/calendarspec.c
src/basic/calendarspec.h
src/basic/cap-list.c
src/basic/cap-list.h
src/basic/capability-util.c
src/basic/capability-util.h
src/basic/cgroup-util.c
src/basic/cgroup-util.h
src/basic/chattr-util.c
src/basic/chattr-util.h
src/basic/clock-util.c
src/basic/clock-util.h
src/basic/conf-files.c
src/basic/conf-files.h
src/basic/copy.c
src/basic/copy.h
src/basic/cpu-set-util.c
src/basic/cpu-set-util.h
src/basic/crypt-util.c [new file with mode: 0644]
src/basic/crypt-util.h [new file with mode: 0644]
src/basic/def.h
src/basic/device-nodes.c
src/basic/device-nodes.h
src/basic/dirent-util.c
src/basic/dirent-util.h
src/basic/env-util.c
src/basic/env-util.h
src/basic/errno-list.c
src/basic/errno-list.h
src/basic/escape.c
src/basic/escape.h
src/basic/ether-addr-util.c
src/basic/ether-addr-util.h
src/basic/exec-util.c
src/basic/exec-util.h
src/basic/exit-status.c
src/basic/exit-status.h
src/basic/extract-word.c
src/basic/extract-word.h
src/basic/fd-util.c
src/basic/fd-util.h
src/basic/fileio-label.c
src/basic/fileio-label.h
src/basic/fileio.c
src/basic/fileio.h
src/basic/format-util.h
src/basic/fs-util.c
src/basic/fs-util.h
src/basic/generate-gperfs.py
src/basic/glob-util.c
src/basic/glob-util.h
src/basic/hash-funcs.c
src/basic/hash-funcs.h
src/basic/hashmap.c
src/basic/hashmap.h
src/basic/hexdecoct.c
src/basic/hexdecoct.h
src/basic/hostname-util.c
src/basic/hostname-util.h
src/basic/in-addr-util.c
src/basic/in-addr-util.h
src/basic/io-util.c
src/basic/io-util.h
src/basic/journal-importer.c
src/basic/journal-importer.h
src/basic/khash.c
src/basic/khash.h
src/basic/label.c
src/basic/label.h
src/basic/list.h
src/basic/locale-util.c
src/basic/locale-util.h
src/basic/lockfile-util.c
src/basic/lockfile-util.h
src/basic/log.c
src/basic/log.h
src/basic/login-util.c
src/basic/login-util.h
src/basic/macro.h
src/basic/memfd-util.c
src/basic/memfd-util.h
src/basic/mempool.c
src/basic/mempool.h
src/basic/meson.build
src/basic/missing.h
src/basic/missing_syscall.h
src/basic/mkdir-label.c
src/basic/mkdir.c
src/basic/mkdir.h
src/basic/module-util.h [new file with mode: 0644]
src/basic/mount-util.c
src/basic/mount-util.h
src/basic/nss-util.h
src/basic/ordered-set.c
src/basic/ordered-set.h
src/basic/parse-util.c
src/basic/parse-util.h
src/basic/path-util.c
src/basic/path-util.h
src/basic/prioq.c
src/basic/prioq.h
src/basic/proc-cmdline.c
src/basic/proc-cmdline.h
src/basic/process-util.c
src/basic/process-util.h
src/basic/random-util.c
src/basic/random-util.h
src/basic/ratelimit.c
src/basic/ratelimit.h
src/basic/raw-clone.h
src/basic/refcnt.h
src/basic/replace-var.c
src/basic/replace-var.h
src/basic/rlimit-util.c
src/basic/rlimit-util.h
src/basic/rm-rf.c
src/basic/rm-rf.h
src/basic/securebits-util.c
src/basic/securebits-util.h
src/basic/selinux-util.c
src/basic/selinux-util.h
src/basic/set.c
src/basic/set.h
src/basic/sigbus.c
src/basic/sigbus.h
src/basic/signal-util.c
src/basic/signal-util.h
src/basic/siphash24.c
src/basic/smack-util.c
src/basic/smack-util.h
src/basic/socket-label.c
src/basic/socket-util.c
src/basic/socket-util.h
src/basic/sparse-endian.h
src/basic/special.h
src/basic/stat-util.c
src/basic/stat-util.h
src/basic/stdio-util.h
src/basic/strbuf.c
src/basic/strbuf.h
src/basic/string-table.c
src/basic/string-table.h
src/basic/string-util.c
src/basic/string-util.h
src/basic/strv.c
src/basic/strv.h
src/basic/strxcpyx.c
src/basic/strxcpyx.h
src/basic/syslog-util.c
src/basic/syslog-util.h
src/basic/terminal-util.c
src/basic/terminal-util.h
src/basic/time-util.c
src/basic/time-util.h
src/basic/umask-util.h
src/basic/unaligned.h
src/basic/unit-def.c [new file with mode: 0644]
src/basic/unit-def.h [new file with mode: 0644]
src/basic/unit-name.c
src/basic/unit-name.h
src/basic/user-util.c
src/basic/user-util.h
src/basic/utf8.c
src/basic/utf8.h
src/basic/util.c
src/basic/util.h
src/basic/verbs.c
src/basic/verbs.h
src/basic/virt.c
src/basic/virt.h
src/basic/web-util.c
src/basic/web-util.h
src/basic/xattr-util.c
src/basic/xattr-util.h
src/basic/xml.c
src/basic/xml.h
src/binfmt/binfmt.c
src/boot/bootctl.c
src/boot/efi/boot.c
src/boot/efi/console.c
src/boot/efi/console.h
src/boot/efi/disk.c
src/boot/efi/disk.h
src/boot/efi/graphics.c
src/boot/efi/graphics.h
src/boot/efi/linux.c
src/boot/efi/linux.h
src/boot/efi/measure.c
src/boot/efi/measure.h
src/boot/efi/meson.build
src/boot/efi/pe.c
src/boot/efi/pe.h
src/boot/efi/shim.c
src/boot/efi/shim.h
src/boot/efi/splash.c
src/boot/efi/splash.h
src/boot/efi/stub.c
src/boot/efi/util.c
src/boot/efi/util.h
src/busctl/busctl-introspect.c
src/busctl/busctl-introspect.h
src/busctl/busctl.c
src/cgls/cgls.c
src/cgroups-agent/cgroups-agent.c
src/cgtop/cgtop.c
src/core/audit-fd.c
src/core/audit-fd.h
src/core/automount.c
src/core/automount.h
src/core/bpf-firewall.c
src/core/bpf-firewall.h
src/core/cgroup.c
src/core/cgroup.h
src/core/chown-recursive.c
src/core/chown-recursive.h
src/core/dbus-automount.c
src/core/dbus-automount.h
src/core/dbus-cgroup.c
src/core/dbus-cgroup.h
src/core/dbus-device.c
src/core/dbus-device.h
src/core/dbus-execute.c
src/core/dbus-execute.h
src/core/dbus-job.c
src/core/dbus-job.h
src/core/dbus-kill.c
src/core/dbus-kill.h
src/core/dbus-manager.c
src/core/dbus-manager.h
src/core/dbus-mount.c
src/core/dbus-mount.h
src/core/dbus-path.c
src/core/dbus-path.h
src/core/dbus-scope.c
src/core/dbus-scope.h
src/core/dbus-service.c
src/core/dbus-service.h
src/core/dbus-slice.c
src/core/dbus-slice.h
src/core/dbus-socket.c
src/core/dbus-socket.h
src/core/dbus-swap.c
src/core/dbus-swap.h
src/core/dbus-target.c
src/core/dbus-target.h
src/core/dbus-timer.c
src/core/dbus-timer.h
src/core/dbus-unit.c
src/core/dbus-unit.h
src/core/dbus.c
src/core/dbus.h
src/core/device.c
src/core/device.h
src/core/dynamic-user.c
src/core/dynamic-user.h
src/core/emergency-action.c
src/core/emergency-action.h
src/core/execute.c
src/core/execute.h
src/core/hostname-setup.c
src/core/hostname-setup.h
src/core/ima-setup.c
src/core/ima-setup.h
src/core/ip-address-access.c
src/core/ip-address-access.h
src/core/job.c
src/core/job.h
src/core/kill.c
src/core/kill.h
src/core/killall.c
src/core/killall.h
src/core/kmod-setup.c
src/core/kmod-setup.h
src/core/load-dropin.c
src/core/load-dropin.h
src/core/load-fragment-gperf.gperf.m4
src/core/load-fragment.c
src/core/load-fragment.h
src/core/locale-setup.c
src/core/locale-setup.h
src/core/loopback-setup.c
src/core/loopback-setup.h
src/core/machine-id-setup.c
src/core/machine-id-setup.h
src/core/macros.systemd.in
src/core/main.c
src/core/manager.c
src/core/manager.h
src/core/meson.build
src/core/mount-setup.c
src/core/mount-setup.h
src/core/mount.c
src/core/mount.h
src/core/namespace.c
src/core/namespace.h
src/core/org.freedesktop.systemd1.conf
src/core/org.freedesktop.systemd1.policy.in.in
src/core/org.freedesktop.systemd1.service
src/core/path.c
src/core/path.h
src/core/scope.c
src/core/scope.h
src/core/selinux-access.c
src/core/selinux-access.h
src/core/selinux-setup.c
src/core/selinux-setup.h
src/core/service.c
src/core/service.h
src/core/show-status.c
src/core/show-status.h
src/core/shutdown.c
src/core/slice.c
src/core/slice.h
src/core/smack-setup.c
src/core/smack-setup.h
src/core/socket.c
src/core/socket.h
src/core/swap.c
src/core/swap.h
src/core/systemd.pc.in
src/core/target.c
src/core/target.h
src/core/timer.c
src/core/timer.h
src/core/transaction.c
src/core/transaction.h
src/core/triggers.systemd.in
src/core/umount.c
src/core/umount.h
src/core/unit-printf.c
src/core/unit-printf.h
src/core/unit.c
src/core/unit.h
src/coredump/coredump-vacuum.c
src/coredump/coredump-vacuum.h
src/coredump/coredump.c
src/coredump/coredumpctl.c
src/coredump/meson.build
src/coredump/stacktrace.c
src/coredump/stacktrace.h
src/coredump/test-coredump-vacuum.c
src/cryptsetup/cryptsetup-generator.c
src/cryptsetup/cryptsetup.c
src/debug-generator/debug-generator.c
src/delta/delta.c
src/detect-virt/detect-virt.c
src/dissect/dissect.c
src/environment-d-generator/environment-d-generator.c
src/escape/escape.c
src/firstboot/firstboot.c
src/fsck/fsck.c
src/fstab-generator/fstab-generator.c
src/getty-generator/getty-generator.c
src/gpt-auto-generator/gpt-auto-generator.c
src/hibernate-resume/hibernate-resume-generator.c
src/hibernate-resume/hibernate-resume.c
src/hostname/hostnamectl.c
src/hostname/hostnamed.c
src/hostname/meson.build
src/hostname/org.freedesktop.hostname1.conf
src/hostname/org.freedesktop.hostname1.policy.in
src/hostname/org.freedesktop.hostname1.service
src/hwdb/hwdb.c
src/import/curl-util.c
src/import/curl-util.h
src/import/export-raw.c
src/import/export-raw.h
src/import/export-tar.c
src/import/export-tar.h
src/import/export.c
src/import/import-common.c
src/import/import-common.h
src/import/import-compress.c
src/import/import-compress.h
src/import/import-raw.c
src/import/import-raw.h
src/import/import-tar.c
src/import/import-tar.h
src/import/import.c
src/import/importd.c
src/import/meson.build
src/import/org.freedesktop.import1.conf
src/import/org.freedesktop.import1.policy.in
src/import/org.freedesktop.import1.service
src/import/pull-common.c
src/import/pull-common.h
src/import/pull-job.c
src/import/pull-job.h
src/import/pull-raw.c
src/import/pull-raw.h
src/import/pull-tar.c
src/import/pull-tar.h
src/import/pull.c
src/import/qcow2-util.c
src/import/qcow2-util.h
src/import/test-qcow2.c
src/initctl/initctl.c
src/journal-remote/journal-gatewayd.c
src/journal-remote/journal-remote-parse.c
src/journal-remote/journal-remote-parse.h
src/journal-remote/journal-remote-write.c
src/journal-remote/journal-remote-write.h
src/journal-remote/journal-remote.c
src/journal-remote/journal-remote.h
src/journal-remote/journal-upload-journal.c
src/journal-remote/journal-upload.c
src/journal-remote/meson.build
src/journal-remote/microhttpd-util.c
src/journal-remote/microhttpd-util.h
src/journal/audit-type.c
src/journal/audit-type.h
src/journal/cat.c
src/journal/catalog.c
src/journal/catalog.h
src/journal/compress.c
src/journal/compress.h
src/journal/fsprg.c
src/journal/fsprg.h
src/journal/journal-authenticate.c
src/journal/journal-authenticate.h
src/journal/journal-def.h
src/journal/journal-file.c
src/journal/journal-file.h
src/journal/journal-internal.h
src/journal/journal-qrcode.c
src/journal/journal-qrcode.h
src/journal/journal-send.c
src/journal/journal-vacuum.c
src/journal/journal-vacuum.h
src/journal/journal-verify.c
src/journal/journal-verify.h
src/journal/journalctl.c
src/journal/journald-audit.c
src/journal/journald-audit.h
src/journal/journald-console.c
src/journal/journald-console.h
src/journal/journald-context.c
src/journal/journald-context.h
src/journal/journald-gperf.gperf
src/journal/journald-kmsg.c
src/journal/journald-kmsg.h
src/journal/journald-native.c
src/journal/journald-native.h
src/journal/journald-rate-limit.c
src/journal/journald-rate-limit.h
src/journal/journald-server.c
src/journal/journald-server.h
src/journal/journald-stream.c
src/journal/journald-stream.h
src/journal/journald-syslog.c
src/journal/journald-syslog.h
src/journal/journald-wall.c
src/journal/journald-wall.h
src/journal/journald.c
src/journal/meson.build
src/journal/mmap-cache.c
src/journal/mmap-cache.h
src/journal/sd-journal.c
src/journal/test-audit-type.c
src/journal/test-catalog.c
src/journal/test-compress-benchmark.c
src/journal/test-compress.c
src/journal/test-journal-enum.c
src/journal/test-journal-flush.c
src/journal/test-journal-init.c
src/journal/test-journal-interleaving.c
src/journal/test-journal-match.c
src/journal/test-journal-send.c
src/journal/test-journal-stream.c
src/journal/test-journal-syslog.c
src/journal/test-journal-verify.c
src/journal/test-journal.c
src/journal/test-mmap-cache.c
src/kernel-install/kernel-install
src/kernel-install/meson.build
src/libsystemd-network/arp-util.c
src/libsystemd-network/arp-util.h
src/libsystemd-network/dhcp-identifier.c
src/libsystemd-network/dhcp-identifier.h
src/libsystemd-network/dhcp-internal.h
src/libsystemd-network/dhcp-lease-internal.h
src/libsystemd-network/dhcp-network.c
src/libsystemd-network/dhcp-option.c
src/libsystemd-network/dhcp-packet.c
src/libsystemd-network/dhcp-protocol.h
src/libsystemd-network/dhcp-server-internal.h
src/libsystemd-network/dhcp6-internal.h
src/libsystemd-network/dhcp6-lease-internal.h
src/libsystemd-network/dhcp6-network.c
src/libsystemd-network/dhcp6-option.c
src/libsystemd-network/dhcp6-protocol.h
src/libsystemd-network/icmp6-util.c
src/libsystemd-network/icmp6-util.h
src/libsystemd-network/lldp-internal.h
src/libsystemd-network/lldp-neighbor.c
src/libsystemd-network/lldp-neighbor.h
src/libsystemd-network/lldp-network.c
src/libsystemd-network/lldp-network.h
src/libsystemd-network/meson.build
src/libsystemd-network/ndisc-internal.h
src/libsystemd-network/ndisc-router.c
src/libsystemd-network/ndisc-router.h
src/libsystemd-network/network-internal.c
src/libsystemd-network/network-internal.h
src/libsystemd-network/radv-internal.h
src/libsystemd-network/sd-dhcp-client.c
src/libsystemd-network/sd-dhcp-lease.c
src/libsystemd-network/sd-dhcp-server.c
src/libsystemd-network/sd-dhcp6-client.c
src/libsystemd-network/sd-dhcp6-lease.c
src/libsystemd-network/sd-ipv4acd.c
src/libsystemd-network/sd-ipv4ll.c
src/libsystemd-network/sd-lldp.c
src/libsystemd-network/sd-ndisc.c
src/libsystemd-network/sd-radv.c
src/libsystemd-network/test-acd.c
src/libsystemd-network/test-dhcp-client.c
src/libsystemd-network/test-dhcp-server.c
src/libsystemd-network/test-dhcp6-client.c
src/libsystemd-network/test-ipv4ll-manual.c
src/libsystemd-network/test-ipv4ll.c
src/libsystemd-network/test-lldp.c
src/libsystemd-network/test-ndisc-ra.c
src/libsystemd-network/test-ndisc-rs.c
src/libsystemd/libsystemd.pc.in
src/libsystemd/libsystemd.sym
src/libsystemd/meson.build
src/libsystemd/sd-bus/bus-bloom.c
src/libsystemd/sd-bus/bus-bloom.h
src/libsystemd/sd-bus/bus-common-errors.c
src/libsystemd/sd-bus/bus-common-errors.h
src/libsystemd/sd-bus/bus-container.c
src/libsystemd/sd-bus/bus-container.h
src/libsystemd/sd-bus/bus-control.c
src/libsystemd/sd-bus/bus-control.h
src/libsystemd/sd-bus/bus-convenience.c
src/libsystemd/sd-bus/bus-creds.c
src/libsystemd/sd-bus/bus-creds.h
src/libsystemd/sd-bus/bus-dump.c
src/libsystemd/sd-bus/bus-dump.h
src/libsystemd/sd-bus/bus-error.c
src/libsystemd/sd-bus/bus-error.h
src/libsystemd/sd-bus/bus-gvariant.c
src/libsystemd/sd-bus/bus-gvariant.h
src/libsystemd/sd-bus/bus-internal.c
src/libsystemd/sd-bus/bus-internal.h
src/libsystemd/sd-bus/bus-introspect.c
src/libsystemd/sd-bus/bus-introspect.h
src/libsystemd/sd-bus/bus-kernel.c
src/libsystemd/sd-bus/bus-kernel.h
src/libsystemd/sd-bus/bus-match.c
src/libsystemd/sd-bus/bus-match.h
src/libsystemd/sd-bus/bus-message.c
src/libsystemd/sd-bus/bus-message.h
src/libsystemd/sd-bus/bus-objects.c
src/libsystemd/sd-bus/bus-objects.h
src/libsystemd/sd-bus/bus-protocol.h
src/libsystemd/sd-bus/bus-signature.c
src/libsystemd/sd-bus/bus-signature.h
src/libsystemd/sd-bus/bus-slot.c
src/libsystemd/sd-bus/bus-slot.h
src/libsystemd/sd-bus/bus-socket.c
src/libsystemd/sd-bus/bus-socket.h
src/libsystemd/sd-bus/bus-track.c
src/libsystemd/sd-bus/bus-track.h
src/libsystemd/sd-bus/bus-type.c
src/libsystemd/sd-bus/bus-type.h
src/libsystemd/sd-bus/sd-bus.c
src/libsystemd/sd-bus/test-bus-benchmark.c
src/libsystemd/sd-bus/test-bus-chat.c
src/libsystemd/sd-bus/test-bus-cleanup.c
src/libsystemd/sd-bus/test-bus-creds.c
src/libsystemd/sd-bus/test-bus-error.c
src/libsystemd/sd-bus/test-bus-gvariant.c
src/libsystemd/sd-bus/test-bus-introspect.c
src/libsystemd/sd-bus/test-bus-marshal.c
src/libsystemd/sd-bus/test-bus-match.c
src/libsystemd/sd-bus/test-bus-objects.c
src/libsystemd/sd-bus/test-bus-server.c
src/libsystemd/sd-bus/test-bus-signature.c
src/libsystemd/sd-bus/test-bus-track.c
src/libsystemd/sd-daemon/sd-daemon.c
src/libsystemd/sd-device/device-enumerator-private.h
src/libsystemd/sd-device/device-enumerator.c
src/libsystemd/sd-device/device-internal.h
src/libsystemd/sd-device/device-private.c
src/libsystemd/sd-device/device-private.h
src/libsystemd/sd-device/device-util.h
src/libsystemd/sd-device/sd-device.c
src/libsystemd/sd-event/sd-event.c
src/libsystemd/sd-event/test-event.c
src/libsystemd/sd-hwdb/hwdb-internal.h
src/libsystemd/sd-hwdb/hwdb-util.h
src/libsystemd/sd-hwdb/sd-hwdb.c
src/libsystemd/sd-id128/id128-util.c
src/libsystemd/sd-id128/id128-util.h
src/libsystemd/sd-id128/sd-id128.c
src/libsystemd/sd-login/sd-login.c
src/libsystemd/sd-login/test-login.c
src/libsystemd/sd-netlink/local-addresses.c
src/libsystemd/sd-netlink/local-addresses.h
src/libsystemd/sd-netlink/netlink-internal.h
src/libsystemd/sd-netlink/netlink-message.c
src/libsystemd/sd-netlink/netlink-socket.c
src/libsystemd/sd-netlink/netlink-types.c
src/libsystemd/sd-netlink/netlink-types.h
src/libsystemd/sd-netlink/netlink-util.c
src/libsystemd/sd-netlink/netlink-util.h
src/libsystemd/sd-netlink/rtnl-message.c
src/libsystemd/sd-netlink/sd-netlink.c
src/libsystemd/sd-netlink/test-local-addresses.c
src/libsystemd/sd-netlink/test-netlink.c
src/libsystemd/sd-network/network-util.c
src/libsystemd/sd-network/network-util.h
src/libsystemd/sd-network/sd-network.c
src/libsystemd/sd-path/sd-path.c
src/libsystemd/sd-resolve/sd-resolve.c
src/libsystemd/sd-resolve/test-resolve.c
src/libsystemd/sd-utf8/sd-utf8.c
src/libudev/libudev-device-internal.h
src/libudev/libudev-device-private.c
src/libudev/libudev-device.c
src/libudev/libudev-enumerate.c
src/libudev/libudev-hwdb.c
src/libudev/libudev-list.c
src/libudev/libudev-monitor.c
src/libudev/libudev-private.h
src/libudev/libudev-queue.c
src/libudev/libudev-util.c
src/libudev/libudev.c
src/libudev/libudev.h
src/libudev/libudev.pc.in
src/libudev/libudev.sym
src/libudev/meson.build
src/locale/keymap-util.c
src/locale/keymap-util.h
src/locale/localectl.c
src/locale/localed.c
src/locale/meson.build
src/locale/org.freedesktop.locale1.conf
src/locale/org.freedesktop.locale1.policy.in
src/locale/org.freedesktop.locale1.service
src/locale/test-keymap-util.c
src/login/70-power-switch.rules
src/login/70-uaccess.rules
src/login/71-seat.rules.in
src/login/73-seat-late.rules.in
src/login/inhibit.c
src/login/loginctl.c
src/login/logind-acl.c
src/login/logind-acl.h
src/login/logind-action.c
src/login/logind-action.h
src/login/logind-button.c
src/login/logind-button.h
src/login/logind-core.c
src/login/logind-dbus.c
src/login/logind-device.c
src/login/logind-device.h
src/login/logind-gperf.gperf
src/login/logind-inhibit.c
src/login/logind-inhibit.h
src/login/logind-seat-dbus.c
src/login/logind-seat.c
src/login/logind-seat.h
src/login/logind-session-dbus.c
src/login/logind-session-device.c
src/login/logind-session-device.h
src/login/logind-session.c
src/login/logind-session.h
src/login/logind-user-dbus.c
src/login/logind-user.c
src/login/logind-user.h
src/login/logind-utmp.c
src/login/logind.c
src/login/logind.h
src/login/meson.build
src/login/org.freedesktop.login1.conf
src/login/org.freedesktop.login1.policy.in
src/login/org.freedesktop.login1.service
src/login/pam_systemd.c
src/login/pam_systemd.sym
src/login/sysfs-show.c
src/login/sysfs-show.h
src/login/test-inhibit.c
src/login/test-login-shared.c
src/login/test-login-tables.c
src/machine-id-setup/machine-id-setup-main.c
src/machine/image-dbus.c
src/machine/image-dbus.h
src/machine/machine-dbus.c
src/machine/machine-dbus.h
src/machine/machine.c
src/machine/machine.h
src/machine/machinectl.c
src/machine/machined-dbus.c
src/machine/machined.c
src/machine/machined.h
src/machine/meson.build
src/machine/operation.c
src/machine/operation.h
src/machine/org.freedesktop.machine1.conf
src/machine/org.freedesktop.machine1.policy.in
src/machine/org.freedesktop.machine1.service
src/machine/test-machine-tables.c
src/modules-load/modules-load.c
src/mount/mount-tool.c
src/network/meson.build
src/network/netdev/bond.c
src/network/netdev/bond.h
src/network/netdev/bridge.c
src/network/netdev/bridge.h
src/network/netdev/dummy.c
src/network/netdev/dummy.h
src/network/netdev/geneve.c
src/network/netdev/geneve.h
src/network/netdev/ipvlan.c
src/network/netdev/ipvlan.h
src/network/netdev/macvlan.c
src/network/netdev/macvlan.h
src/network/netdev/netdev-gperf.gperf
src/network/netdev/netdev.c
src/network/netdev/netdev.h
src/network/netdev/tunnel.c
src/network/netdev/tunnel.h
src/network/netdev/tuntap.c
src/network/netdev/tuntap.h
src/network/netdev/vcan.c
src/network/netdev/vcan.h
src/network/netdev/veth.c
src/network/netdev/veth.h
src/network/netdev/vlan.c
src/network/netdev/vlan.h
src/network/netdev/vrf.c
src/network/netdev/vrf.h
src/network/netdev/vxcan.c [new file with mode: 0644]
src/network/netdev/vxcan.h [new file with mode: 0644]
src/network/netdev/vxlan.c
src/network/netdev/vxlan.h
src/network/networkctl.c
src/network/networkd-address-label.c
src/network/networkd-address-label.h
src/network/networkd-address-pool.c
src/network/networkd-address-pool.h
src/network/networkd-address.c
src/network/networkd-address.h
src/network/networkd-brvlan.c
src/network/networkd-brvlan.h
src/network/networkd-conf.c
src/network/networkd-conf.h
src/network/networkd-dhcp4.c
src/network/networkd-dhcp6.c
src/network/networkd-fdb.c
src/network/networkd-fdb.h
src/network/networkd-gperf.gperf
src/network/networkd-ipv4ll.c
src/network/networkd-ipv6-proxy-ndp.c
src/network/networkd-ipv6-proxy-ndp.h
src/network/networkd-link-bus.c
src/network/networkd-link.c
src/network/networkd-link.h
src/network/networkd-lldp-tx.c
src/network/networkd-lldp-tx.h
src/network/networkd-manager-bus.c
src/network/networkd-manager.c
src/network/networkd-manager.h
src/network/networkd-ndisc.c
src/network/networkd-ndisc.h
src/network/networkd-network-bus.c
src/network/networkd-network-gperf.gperf
src/network/networkd-network.c
src/network/networkd-network.h
src/network/networkd-radv.c
src/network/networkd-radv.h
src/network/networkd-route.c
src/network/networkd-route.h
src/network/networkd-routing-policy-rule.c
src/network/networkd-routing-policy-rule.h
src/network/networkd-util.c
src/network/networkd-util.h
src/network/networkd.c
src/network/org.freedesktop.network1.service
src/network/test-network.c
src/network/test-networkd-conf.c
src/network/test-routing-policy-rule.c [new file with mode: 0644]
src/network/wait-online/link.c
src/network/wait-online/link.h
src/network/wait-online/manager.c
src/network/wait-online/manager.h
src/network/wait-online/wait-online.c
src/notify/notify.c
src/nspawn/meson.build
src/nspawn/nspawn-cgroup.c
src/nspawn/nspawn-cgroup.h
src/nspawn/nspawn-def.h [new file with mode: 0644]
src/nspawn/nspawn-expose-ports.c
src/nspawn/nspawn-expose-ports.h
src/nspawn/nspawn-gperf.gperf
src/nspawn/nspawn-mount.c
src/nspawn/nspawn-mount.h
src/nspawn/nspawn-network.c
src/nspawn/nspawn-network.h
src/nspawn/nspawn-patch-uid.c
src/nspawn/nspawn-patch-uid.h
src/nspawn/nspawn-register.c
src/nspawn/nspawn-register.h
src/nspawn/nspawn-seccomp.c
src/nspawn/nspawn-seccomp.h
src/nspawn/nspawn-settings.c
src/nspawn/nspawn-settings.h
src/nspawn/nspawn-setuid.c
src/nspawn/nspawn-setuid.h
src/nspawn/nspawn-stub-pid1.c
src/nspawn/nspawn-stub-pid1.h
src/nspawn/nspawn.c
src/nspawn/test-patch-uid.c
src/nss-myhostname/nss-myhostname.c
src/nss-myhostname/nss-myhostname.sym
src/nss-mymachines/nss-mymachines.c
src/nss-mymachines/nss-mymachines.sym
src/nss-resolve/nss-resolve.c
src/nss-resolve/nss-resolve.sym
src/nss-systemd/nss-systemd.c
src/nss-systemd/nss-systemd.sym
src/partition/growfs.c [new file with mode: 0644]
src/partition/makefs.c [new file with mode: 0644]
src/path/path.c
src/quotacheck/quotacheck.c
src/random-seed/random-seed.c
src/rc-local-generator/rc-local-generator.c
src/remount-fs/remount-fs.c
src/reply-password/reply-password.c
src/resolve/RFCs
src/resolve/dns-type.c
src/resolve/dns-type.h
src/resolve/generate-dns_type-gperf.py
src/resolve/meson.build
src/resolve/org.freedesktop.resolve1.policy.in [new file with mode: 0644]
src/resolve/org.freedesktop.resolve1.service
src/resolve/resolv.conf
src/resolve/resolve-tool.c
src/resolve/resolved-bus.c
src/resolve/resolved-bus.h
src/resolve/resolved-conf.c
src/resolve/resolved-conf.h
src/resolve/resolved-def.h
src/resolve/resolved-dns-answer.c
src/resolve/resolved-dns-answer.h
src/resolve/resolved-dns-cache.c
src/resolve/resolved-dns-cache.h
src/resolve/resolved-dns-dnssec.c
src/resolve/resolved-dns-dnssec.h
src/resolve/resolved-dns-packet.c
src/resolve/resolved-dns-packet.h
src/resolve/resolved-dns-query.c
src/resolve/resolved-dns-query.h
src/resolve/resolved-dns-question.c
src/resolve/resolved-dns-question.h
src/resolve/resolved-dns-rr.c
src/resolve/resolved-dns-rr.h
src/resolve/resolved-dns-scope.c
src/resolve/resolved-dns-scope.h
src/resolve/resolved-dns-search-domain.c
src/resolve/resolved-dns-search-domain.h
src/resolve/resolved-dns-server.c
src/resolve/resolved-dns-server.h
src/resolve/resolved-dns-stream.c
src/resolve/resolved-dns-stream.h
src/resolve/resolved-dns-stub.c
src/resolve/resolved-dns-stub.h
src/resolve/resolved-dns-synthesize.c
src/resolve/resolved-dns-synthesize.h
src/resolve/resolved-dns-transaction.c
src/resolve/resolved-dns-transaction.h
src/resolve/resolved-dns-trust-anchor.c
src/resolve/resolved-dns-trust-anchor.h
src/resolve/resolved-dns-zone.c
src/resolve/resolved-dns-zone.h
src/resolve/resolved-dnssd-bus.c [new file with mode: 0644]
src/resolve/resolved-dnssd-bus.h [new file with mode: 0644]
src/resolve/resolved-dnssd-gperf.gperf [new file with mode: 0644]
src/resolve/resolved-dnssd.c [new file with mode: 0644]
src/resolve/resolved-dnssd.h [new file with mode: 0644]
src/resolve/resolved-etc-hosts.c
src/resolve/resolved-etc-hosts.h
src/resolve/resolved-gperf.gperf
src/resolve/resolved-link-bus.c
src/resolve/resolved-link-bus.h
src/resolve/resolved-link.c
src/resolve/resolved-link.h
src/resolve/resolved-llmnr.c
src/resolve/resolved-llmnr.h
src/resolve/resolved-manager.c
src/resolve/resolved-manager.h
src/resolve/resolved-mdns.c
src/resolve/resolved-mdns.h
src/resolve/resolved-resolv-conf.c
src/resolve/resolved-resolv-conf.h
src/resolve/resolved.c
src/resolve/test-dns-packet.c
src/resolve/test-dnssec-complex.c
src/resolve/test-dnssec.c
src/resolve/test-resolve-tables.c
src/resolve/test-resolved-packet.c
src/rfkill/rfkill.c
src/run/run.c
src/shared/acl-util.c
src/shared/acl-util.h
src/shared/acpi-fpdt.c
src/shared/acpi-fpdt.h
src/shared/apparmor-util.c
src/shared/apparmor-util.h
src/shared/ask-password-api.c
src/shared/ask-password-api.h
src/shared/base-filesystem.c
src/shared/base-filesystem.h
src/shared/boot-timestamps.c
src/shared/boot-timestamps.h
src/shared/bootspec.c [new file with mode: 0644]
src/shared/bootspec.h [new file with mode: 0644]
src/shared/bus-unit-util.c
src/shared/bus-unit-util.h
src/shared/bus-util.c
src/shared/bus-util.h
src/shared/cgroup-show.c
src/shared/cgroup-show.h
src/shared/clean-ipc.c
src/shared/clean-ipc.h
src/shared/condition.c
src/shared/condition.h
src/shared/conf-parser.c
src/shared/conf-parser.h
src/shared/dev-setup.c
src/shared/dev-setup.h
src/shared/dissect-image.c
src/shared/dissect-image.h
src/shared/dns-domain.c
src/shared/dns-domain.h
src/shared/dropin.c
src/shared/dropin.h
src/shared/efivars.c
src/shared/efivars.h
src/shared/fdset.c
src/shared/fdset.h
src/shared/firewall-util.c
src/shared/firewall-util.h
src/shared/fstab-util.c
src/shared/fstab-util.h
src/shared/gcrypt-util.c
src/shared/gcrypt-util.h
src/shared/generator.c
src/shared/generator.h
src/shared/gpt.h
src/shared/ima-util.c
src/shared/ima-util.h
src/shared/import-util.c
src/shared/import-util.h
src/shared/install-printf.c
src/shared/install-printf.h
src/shared/install.c
src/shared/install.h
src/shared/journal-util.c
src/shared/journal-util.h
src/shared/linux/auto_dev-ioctl.h
src/shared/logs-show.c
src/shared/logs-show.h
src/shared/loop-util.c
src/shared/loop-util.h
src/shared/machine-image.c
src/shared/machine-image.h
src/shared/machine-pool.c
src/shared/machine-pool.h
src/shared/meson.build
src/shared/nsflags.c
src/shared/nsflags.h
src/shared/output-mode.c
src/shared/output-mode.h
src/shared/pager.c
src/shared/pager.h
src/shared/path-lookup.c
src/shared/path-lookup.h
src/shared/ptyfwd.c
src/shared/ptyfwd.h
src/shared/resolve-util.c
src/shared/resolve-util.h
src/shared/seccomp-util.c
src/shared/seccomp-util.h
src/shared/sleep-config.c
src/shared/sleep-config.h
src/shared/spawn-ask-password-agent.c
src/shared/spawn-ask-password-agent.h
src/shared/spawn-polkit-agent.c
src/shared/spawn-polkit-agent.h
src/shared/specifier.c
src/shared/specifier.h
src/shared/switch-root.c
src/shared/switch-root.h
src/shared/sysctl-util.c
src/shared/sysctl-util.h
src/shared/test-tables.h
src/shared/tests.c
src/shared/tests.h
src/shared/tomoyo-util.c [new file with mode: 0644]
src/shared/tomoyo-util.h [new file with mode: 0644]
src/shared/udev-util.c
src/shared/udev-util.h
src/shared/uid-range.c
src/shared/uid-range.h
src/shared/utmp-wtmp.c
src/shared/utmp-wtmp.h
src/shared/vlan-util.c
src/shared/vlan-util.h
src/shared/volatile-util.c
src/shared/volatile-util.h
src/shared/watchdog.c
src/shared/watchdog.h
src/sleep/sleep.c
src/socket-proxy/socket-proxyd.c
src/stdio-bridge/stdio-bridge.c
src/sulogin-shell/meson.build [deleted file]
src/sulogin-shell/sulogin-shell.c
src/sysctl/sysctl.c
src/system-update-generator/system-update-generator.c
src/systemctl/systemctl.c
src/systemd/_sd-common.h
src/systemd/meson.build
src/systemd/sd-bus-protocol.h
src/systemd/sd-bus-vtable.h
src/systemd/sd-bus.h
src/systemd/sd-daemon.h
src/systemd/sd-device.h
src/systemd/sd-dhcp-client.h
src/systemd/sd-dhcp-lease.h
src/systemd/sd-dhcp-server.h
src/systemd/sd-dhcp6-client.h
src/systemd/sd-dhcp6-lease.h
src/systemd/sd-event.h
src/systemd/sd-hwdb.h
src/systemd/sd-id128.h
src/systemd/sd-ipv4acd.h
src/systemd/sd-ipv4ll.h
src/systemd/sd-journal.h
src/systemd/sd-lldp.h
src/systemd/sd-login.h
src/systemd/sd-messages.h
src/systemd/sd-ndisc.h
src/systemd/sd-netlink.h
src/systemd/sd-network.h
src/systemd/sd-path.h
src/systemd/sd-radv.h
src/systemd/sd-resolve.h
src/systemd/sd-utf8.h
src/sysusers/sysusers.c
src/sysv-generator/sysv-generator.c
src/test/meson.build
src/test/test-acl-util.c
src/test/test-af-list.c
src/test/test-alloc-util.c
src/test/test-architecture.c
src/test/test-arphrd-list.c
src/test/test-ask-password-api.c
src/test/test-async.c
src/test/test-barrier.c
src/test/test-bitmap.c
src/test/test-boot-timestamps.c
src/test/test-bpf.c
src/test/test-btrfs.c
src/test/test-calendarspec.c
src/test/test-cap-list.c
src/test/test-capability.c
src/test/test-cgroup-mask.c
src/test/test-cgroup-util.c
src/test/test-cgroup.c
src/test/test-clock.c
src/test/test-condition.c
src/test/test-conf-files.c
src/test/test-conf-parser.c
src/test/test-copy.c
src/test/test-cpu-set-util.c
src/test/test-daemon.c
src/test/test-date.c
src/test/test-device-nodes.c
src/test/test-dissect-image.c
src/test/test-dlopen.c
src/test/test-dns-domain.c
src/test/test-ellipsize.c
src/test/test-engine.c
src/test/test-env-util.c
src/test/test-escape.c
src/test/test-exec-util.c
src/test/test-execute.c
src/test/test-extract-word.c
src/test/test-fd-util.c
src/test/test-fdset.c
src/test/test-fileio.c
src/test/test-firewall-util.c
src/test/test-fs-util.c
src/test/test-fstab-util.c
src/test/test-glob-util.c
src/test/test-hash.c
src/test/test-hashmap-plain.c
src/test/test-hashmap.c
src/test/test-helper.c
src/test/test-helper.h
src/test/test-hexdecoct.c
src/test/test-hostname-util.c
src/test/test-hostname.c
src/test/test-id128.c
src/test/test-in-addr-util.c
src/test/test-install-root.c
src/test/test-install.c
src/test/test-io-util.c
src/test/test-ipcrm.c
src/test/test-job-type.c
src/test/test-journal-importer.c
src/test/test-libudev.c
src/test/test-list.c
src/test/test-locale-util.c
src/test/test-log.c
src/test/test-loopback.c
src/test/test-mount-util.c
src/test/test-namespace.c
src/test/test-netlink-manual.c
src/test/test-ns.c
src/test/test-nss.c
src/test/test-parse-util.c
src/test/test-path-lookup.c
src/test/test-path-util.c
src/test/test-path.c
src/test/test-prioq.c
src/test/test-proc-cmdline.c
src/test/test-process-util.c
src/test/test-random-util.c
src/test/test-ratelimit.c
src/test/test-replace-var.c
src/test/test-rlimit-util.c
src/test/test-sched-prio.c
src/test/test-seccomp.c
src/test/test-selinux.c
src/test/test-set.c
src/test/test-sigbus.c
src/test/test-signal-util.c
src/test/test-siphash24.c
src/test/test-sizeof.c
src/test/test-sleep.c
src/test/test-socket-util.c
src/test/test-specifier.c [new file with mode: 0644]
src/test/test-stat-util.c
src/test/test-strbuf.c
src/test/test-string-util.c
src/test/test-strip-tab-ansi.c
src/test/test-strv.c
src/test/test-strxcpyx.c
src/test/test-systemd-tmpfiles.py [new file with mode: 0755]
src/test/test-tables.c
src/test/test-terminal-util.c
src/test/test-time-util.c [moved from src/test/test-time.c with 96% similarity]
src/test/test-tmpfiles.c
src/test/test-udev.c
src/test/test-uid-range.c
src/test/test-unaligned.c
src/test/test-unit-file.c
src/test/test-unit-name.c
src/test/test-user-util.c
src/test/test-utf8.c
src/test/test-util.c
src/test/test-verbs.c
src/test/test-watchdog.c
src/test/test-web-util.c
src/test/test-xattr-util.c
src/test/test-xml.c
src/timedate/meson.build
src/timedate/org.freedesktop.timedate1.conf
src/timedate/org.freedesktop.timedate1.policy.in
src/timedate/org.freedesktop.timedate1.service
src/timedate/timedatectl.c
src/timedate/timedated.c
src/timesync/meson.build
src/timesync/test-timesync.c
src/timesync/timesyncd-conf.c
src/timesync/timesyncd-conf.h
src/timesync/timesyncd-gperf.gperf
src/timesync/timesyncd-manager.c
src/timesync/timesyncd-manager.h
src/timesync/timesyncd-server.c
src/timesync/timesyncd-server.h
src/timesync/timesyncd.c
src/timesync/timesyncd.conf.in
src/tmpfiles/tmpfiles.c
src/tty-ask-password-agent/tty-ask-password-agent.c
src/udev/ata_id/ata_id.c
src/udev/cdrom_id/cdrom_id.c
src/udev/collect/collect.c
src/udev/generate-keyboard-keys-gperf.sh
src/udev/meson.build
src/udev/mtd_probe/mtd_probe.c
src/udev/mtd_probe/mtd_probe.h
src/udev/mtd_probe/probe_smartmedia.c
src/udev/net/ethtool-util.c
src/udev/net/ethtool-util.h
src/udev/net/link-config-gperf.gperf
src/udev/net/link-config.c
src/udev/net/link-config.h
src/udev/scsi_id/scsi.h
src/udev/scsi_id/scsi_id.c
src/udev/scsi_id/scsi_id.h
src/udev/scsi_id/scsi_serial.c
src/udev/udev-builtin-blkid.c
src/udev/udev-builtin-btrfs.c
src/udev/udev-builtin-hwdb.c
src/udev/udev-builtin-input_id.c
src/udev/udev-builtin-keyboard.c
src/udev/udev-builtin-kmod.c
src/udev/udev-builtin-net_id.c
src/udev/udev-builtin-net_setup_link.c
src/udev/udev-builtin-path_id.c
src/udev/udev-builtin-uaccess.c
src/udev/udev-builtin-usb_id.c
src/udev/udev-builtin.c
src/udev/udev-ctrl.c
src/udev/udev-event.c
src/udev/udev-node.c
src/udev/udev-rules.c
src/udev/udev-watch.c
src/udev/udev.h
src/udev/udevadm-control.c
src/udev/udevadm-hwdb.c
src/udev/udevadm-info.c
src/udev/udevadm-monitor.c
src/udev/udevadm-settle.c
src/udev/udevadm-test-builtin.c
src/udev/udevadm-test.c
src/udev/udevadm-trigger.c
src/udev/udevadm-util.c
src/udev/udevadm-util.h
src/udev/udevadm.c
src/udev/udevd.c
src/udev/v4l_id/v4l_id.c
src/update-done/update-done.c
src/update-utmp/update-utmp.c
src/user-sessions/user-sessions.c
src/vconsole/90-vconsole.rules.in
src/vconsole/meson.build
src/vconsole/vconsole-setup.c
src/veritysetup/veritysetup-generator.c
src/veritysetup/veritysetup.c
src/volatile-root/volatile-root.c
sysctl.d/50-default.conf
sysctl.d/meson.build
sysusers.d/basic.conf.in
sysusers.d/meson.build
sysusers.d/systemd-remote.conf.m4
sysusers.d/systemd.conf.m4
test/Makefile.guess [deleted file]
test/TEST-01-BASIC/Makefile
test/TEST-02-CRYPTSETUP/test.sh
test/TEST-04-JOURNAL/test-journal.sh
test/TEST-10-ISSUE-2467/test.sh
test/TEST-13-NSPAWN-SMOKE/Makefile
test/TEST-13-NSPAWN-SMOKE/test.sh
test/TEST-14-MACHINE-ID/test.sh
test/TEST-16-EXTEND-TIMEOUT/Makefile [new symlink]
test/TEST-16-EXTEND-TIMEOUT/assess.sh [new file with mode: 0755]
test/TEST-16-EXTEND-TIMEOUT/extend_timeout_test_service.sh [new file with mode: 0755]
test/TEST-16-EXTEND-TIMEOUT/test.sh [new file with mode: 0755]
test/TEST-16-EXTEND-TIMEOUT/testsuite-fail-runtime.service [new file with mode: 0644]
test/TEST-16-EXTEND-TIMEOUT/testsuite-fail-start.service [new file with mode: 0644]
test/TEST-16-EXTEND-TIMEOUT/testsuite-fail-stop.service [new file with mode: 0644]
test/TEST-16-EXTEND-TIMEOUT/testsuite-success-all.service [new file with mode: 0644]
test/TEST-16-EXTEND-TIMEOUT/testsuite-success-runtime.service [new file with mode: 0644]
test/TEST-16-EXTEND-TIMEOUT/testsuite-success-start.service [new file with mode: 0644]
test/TEST-16-EXTEND-TIMEOUT/testsuite-success-stop.service [new file with mode: 0644]
test/TEST-16-EXTEND-TIMEOUT/testsuite.service [new file with mode: 0644]
test/TEST-17-UDEV-WANTS/Makefile [new file with mode: 0644]
test/TEST-17-UDEV-WANTS/test.sh [new file with mode: 0755]
test/TEST-17-UDEV-WANTS/testsuite.sh [new file with mode: 0755]
test/TEST-18-FAILUREACTION/Makefile [new file with mode: 0644]
test/TEST-18-FAILUREACTION/test.sh [new file with mode: 0755]
test/TEST-18-FAILUREACTION/testsuite.sh [new file with mode: 0755]
test/TEST-19-DELEGATE/Makefile [new file with mode: 0644]
test/TEST-19-DELEGATE/test.sh [new file with mode: 0755]
test/TEST-19-DELEGATE/testsuite.sh [new file with mode: 0755]
test/create-sys-script.py
test/hwdb-test.sh
test/meson.build
test/networkd-test.py
test/rule-syntax-check.py
test/run-integration-tests.sh [new file with mode: 0755]
test/sys-script.py
test/sysv-generator-test.py
test/test-exec-deserialization.py
test/test-execute/exec-bindpaths.service [new file with mode: 0644]
test/test-execute/exec-cpuaffinity1.service [new file with mode: 0644]
test/test-execute/exec-cpuaffinity2.service [new file with mode: 0644]
test/test-execute/exec-cpuaffinity3.service [new file with mode: 0644]
test/test-execute/exec-dynamicuser-statedir-migrate-step1.service [new file with mode: 0644]
test/test-execute/exec-dynamicuser-statedir-migrate-step2.service [new file with mode: 0644]
test/test-execute/exec-dynamicuser-statedir.service [moved from test/test-execute/exec-dynamicuser-state-dir.service with 51% similarity]
test/test-execute/exec-group-nogroup.service [new file with mode: 0644]
test/test-execute/exec-readonlypaths-simple.service [moved from test/test-execute/exec-read-only-path-succeed.service with 51% similarity]
test/test-execute/exec-readonlypaths-with-bindpaths.service [new file with mode: 0644]
test/test-execute/exec-restrictnamespaces-mnt-blacklist.service [moved from test/test-execute/exec-restrict-namespaces-mnt-blacklist.service with 100% similarity]
test/test-execute/exec-restrictnamespaces-mnt.service [moved from test/test-execute/exec-restrict-namespaces-mnt.service with 100% similarity]
test/test-execute/exec-restrictnamespaces-no.service [moved from test/test-execute/exec-restrict-namespaces-no.service with 100% similarity]
test/test-execute/exec-restrictnamespaces-yes.service [moved from test/test-execute/exec-restrict-namespaces-yes.service with 100% similarity]
test/test-execute/exec-specifier-interpolation.service [moved from test/test-execute/exec-spec-interpolation.service with 100% similarity]
test/test-execute/exec-specifier.service [new file with mode: 0644]
test/test-execute/exec-specifier@.service [new file with mode: 0644]
test/test-execute/exec-standardinput-data.service [new file with mode: 0644]
test/test-execute/exec-standardinput-file.service [new file with mode: 0644]
test/test-execute/exec-systemcallerrornumber-name.service [moved from test/test-execute/exec-systemcallerrornumber.service with 56% similarity]
test/test-execute/exec-systemcallerrornumber-number.service [new file with mode: 0644]
test/test-execute/exec-systemcallfilter-failing.service
test/test-execute/exec-systemcallfilter-failing2.service
test/test-execute/exec-systemcallfilter-not-failing.service
test/test-execute/exec-systemcallfilter-not-failing2.service
test/test-execute/exec-systemcallfilter-system-user-nfsnobody.service
test/test-execute/exec-systemcallfilter-system-user.service
test/test-execute/exec-systemcallfilter-with-errno-name.service [new file with mode: 0644]
test/test-execute/exec-systemcallfilter-with-errno-number.service [new file with mode: 0644]
test/test-execute/exec-unsetenvironment.service [moved from test/test-execute/exec-unset-environment.service with 100% similarity]
test/test-functions
tmpfiles.d/meson.build
tools/catalog-report.py
tools/find-build-dir.sh [new file with mode: 0755]
tools/gdb-sd_dump_hashmaps.py
tools/make-directive-index.py
tools/make-man-index.py
tools/make-man-rules.py
tools/meson-check-help.sh
tools/meson-hwdb-update.sh
tools/xml_helper.py
units/basic.target
units/busnames.target
units/console-getty.service.m4.in
units/container-getty@.service.m4.in
units/cryptsetup-pre.target
units/cryptsetup.target
units/debug-shell.service.in
units/dev-hugepages.mount
units/dev-mqueue.mount
units/emergency.service.in
units/emergency.target
units/exit.target
units/final.target
units/getty-pre.target
units/getty.target
units/getty@.service.m4
units/graphical.target
units/halt-local.service.in
units/halt.target
units/hibernate.target
units/hybrid-sleep.target
units/initrd-cleanup.service.in
units/initrd-fs.target
units/initrd-parse-etc.service.in
units/initrd-root-device.target
units/initrd-root-fs.target
units/initrd-switch-root.service.in
units/initrd-switch-root.target
units/initrd-udevadm-cleanup-db.service.in
units/initrd.target
units/kexec.target
units/kmod-static-nodes.service.in
units/ldconfig.service
units/local-fs-pre.target
units/local-fs.target
units/machine.slice
units/machines.target
units/meson.build
units/multi-user.target
units/network-online.target
units/network-pre.target
units/network.target
units/nss-lookup.target
units/nss-user-lookup.target
units/paths.target
units/poweroff.target
units/printer.target
units/proc-sys-fs-binfmt_misc.automount
units/proc-sys-fs-binfmt_misc.mount
units/quotaon.service.in
units/rc-local.service.in
units/reboot.target
units/remote-cryptsetup.target
units/remote-fs-pre.target
units/remote-fs.target
units/rescue.service.in
units/rescue.target
units/rpcbind.target
units/serial-getty@.service.m4
units/shutdown.target
units/sigpwr.target
units/sleep.target
units/slices.target
units/smartcard.target
units/sockets.target
units/sound.target
units/suspend.target
units/swap.target
units/sys-fs-fuse-connections.mount
units/sys-kernel-config.mount
units/sys-kernel-debug.mount
units/sysinit.target
units/syslog.socket
units/system-update-cleanup.service.in
units/system-update.target
units/system.slice
units/systemd-ask-password-console.path
units/systemd-ask-password-console.service.in
units/systemd-ask-password-wall.path
units/systemd-ask-password-wall.service.in
units/systemd-backlight@.service.in
units/systemd-binfmt.service.in
units/systemd-coredump.socket
units/systemd-coredump@.service.in
units/systemd-exit.service.in
units/systemd-firstboot.service.in
units/systemd-fsck-root.service.in
units/systemd-fsck@.service.in
units/systemd-halt.service.in
units/systemd-hibernate-resume@.service.in
units/systemd-hibernate.service.in
units/systemd-hostnamed.service.in
units/systemd-hwdb-update.service.in
units/systemd-hybrid-sleep.service.in
units/systemd-importd.service.in
units/systemd-initctl.service.in
units/systemd-initctl.socket
units/systemd-journal-catalog-update.service.in
units/systemd-journal-flush.service.in
units/systemd-journal-gatewayd.service.in
units/systemd-journal-gatewayd.socket
units/systemd-journal-remote.service.in
units/systemd-journal-remote.socket
units/systemd-journal-upload.service.in
units/systemd-journald-audit.socket
units/systemd-journald-dev-log.socket
units/systemd-journald.service.in
units/systemd-journald.socket
units/systemd-kexec.service.in
units/systemd-localed.service.in
units/systemd-logind.service.in
units/systemd-machine-id-commit.service.in
units/systemd-machined.service.in
units/systemd-modules-load.service.in
units/systemd-networkd-wait-online.service.in
units/systemd-networkd.service.in
units/systemd-networkd.socket
units/systemd-nspawn@.service.in
units/systemd-poweroff.service.in
units/systemd-quotacheck.service.in
units/systemd-random-seed.service.in
units/systemd-reboot.service.in
units/systemd-remount-fs.service.in
units/systemd-resolved.service.in
units/systemd-rfkill.service.in
units/systemd-rfkill.socket
units/systemd-suspend.service.in
units/systemd-sysctl.service.in
units/systemd-sysusers.service.in
units/systemd-timedated.service.in
units/systemd-timesyncd.service.in
units/systemd-tmpfiles-clean.service.in
units/systemd-tmpfiles-clean.timer
units/systemd-tmpfiles-setup-dev.service.in
units/systemd-tmpfiles-setup.service.in
units/systemd-udev-settle.service.in
units/systemd-udev-trigger.service.in
units/systemd-udevd-control.socket
units/systemd-udevd-kernel.socket
units/systemd-udevd.service.in
units/systemd-update-done.service.in
units/systemd-update-utmp-runlevel.service.in
units/systemd-update-utmp.service.in
units/systemd-user-sessions.service.in
units/systemd-vconsole-setup.service.in
units/systemd-volatile-root.service.in
units/time-sync.target
units/timers.target
units/tmp.mount.m4
units/umount.target
units/user.slice
units/user/basic.target
units/user/default.target
units/user/exit.target
units/user/graphical-session-pre.target
units/user/graphical-session.target
units/user/meson.build
units/user/systemd-exit.service.in
units/user/systemd-tmpfiles-clean.service.in [new file with mode: 0644]
units/user/systemd-tmpfiles-clean.timer [new file with mode: 0644]
units/user/systemd-tmpfiles-setup.service.in [new file with mode: 0644]
units/user@.service.in
units/var-lib-machines.mount

index ba43f29..6f19744 100644 (file)
@@ -28,7 +28,7 @@ If you discover a security vulnerability, we'd appreciate a non-public disclosur
 * Please make sure to test your change before submitting the PR. See [HACKING](https://raw.githubusercontent.com/systemd/systemd/master/HACKING) for details how to do this.
 * Make sure to run the test suite locally, before posting your PR. We use a CI system, meaning we don't even look at your PR, if the build and tests don't pass.
 * If you need to update the code in an existing PR, force-push into the same branch, overriding old commits with new versions.
-* After you have pushed a new version, add a comment about the new version (no notification is sent just for the commits, so it's easy to miss the update without an explicit comment). If you are a member of the systemd project on github, remove the `reviewed/needs-rework` label.
+* After you have pushed a new version, add a comment about the new version (no notification is sent just for the commits, so it's easy to miss the update without an explicit comment). If you are a member of the systemd project on GitHub, remove the `reviewed/needs-rework` label.
 
 ## Final Words
 
index 2ecf163..2afcf9c 100644 (file)
@@ -23,6 +23,7 @@ cscope.out
 /GSYMS
 /GTAGS
 /TAGS
+/ID
 /build*
 /coverage/
 /image.raw
@@ -30,5 +31,6 @@ cscope.out
 /image.raw.cache-pre-inst
 /install-tree
 /mkosi.builddir/
+/mkosi.output/
 /tags
 __pycache__/
index 5f021b6..55bd44b 100644 (file)
--- a/.mailmap
+++ b/.mailmap
@@ -132,3 +132,13 @@ Dmitriy Geels <dmitriy.geels@gmail.com>
 Beniamino Galvani <bgalvani@redhat.com> <bengal@users.noreply.github.com>
 Justin Capella <justincapella@gmail.com> <b1tninja@users.noreply.github.com>
 Daniel Șerbănescu <dasj19@users.noreply.github.com>
+Stanislav Angelovič <angelovic.s@gmail.com>
+Torsten Hilbrich <torsten.hilbrich@gmx.net>
+Tinu Weber <takeya@bluewin.ch>
+Gwendal Grignou <gwendal@chromium.org>
+José Bollo <jose.bollo@iot.bzh> <jobol@nonadev.net>
+Patryk Kocielnik <longer44@gmail.com>
+Lukáš Říha <cedel@centrum.cz>
+Alan Robertson <aroberts@zen.iomart.com> <alanjrobertson@gmail.com>
+Martin Steuer <martinsteuer@gmx.de>
+Matthias-Christian Ott <ott@mirix.org> <ott@users.noreply.github.com>
index c2487c9..a823a95 100644 (file)
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
 # This file is part of systemd.
 #
 # Copyright 2016 Zeal Jagannatha
index 1a3b517..a93eb7b 100644 (file)
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
 # This file is part of systemd.
 #
 # Copyright 2016 Daniel Rusek
index 4cfdcb0..4d7168c 100644 (file)
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
 # This file is part of systemd.
 #
 # Copyright 2016 Lennart Poettering
@@ -74,3 +76,6 @@ BuildPackages=
 
 Packages=
         libidn2
+
+BuildDirectory=mkosi.builddir
+Cache=mkosi.cache
index 4edd3c8..f297dee 100644 (file)
-import itertools
+#!/usr/bin/env python
+
+# SPDX-License-Identifier: Unlicense
+#
+# Based on the template file provided by the 'YCM-Generator' project authored by
+# Reuben D'Netto.
+# Jiahui Xie has re-reformatted and expanded the original script in accordance
+# to the requirements of the PEP 8 style guide and 'systemd' project,
+# respectively.
+#
+# The original license is preserved as it is.
+#
+#
+# This is free and unencumbered software released into the public domain.
+#
+# Anyone is free to copy, modify, publish, use, compile, sell, or
+# distribute this software, either in source code form or as a compiled
+# binary, for any purpose, commercial or non-commercial, and by any
+# means.
+#
+# In jurisdictions that recognize copyright laws, the author or authors
+# of this software dedicate any and all copyright interest in the
+# software to the public domain. We make this dedication for the benefit
+# of the public at large and to the detriment of our heirs and
+# successors. We intend this dedication to be an overt act of
+# relinquishment in perpetuity of all present and future rights to this
+# software under copyright law.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#
+# For more information, please refer to <http://unlicense.org/>
+
+"""
+YouCompleteMe configuration file tailored to support the 'meson' build system
+used by the 'systemd' project.
+"""
+
+import glob
 import os
-import subprocess
+import ycm_core
 
-def GetFlagsFromMakefile(varname):
-  return subprocess.check_output([
-      "make", "-s", "print-%s" % varname]).decode().split()
 
-
-def Flatten(lists):
-  return list(itertools.chain.from_iterable(lists))
+SOURCE_EXTENSIONS = (".C", ".cpp", ".cxx", ".cc", ".c", ".m", ".mm")
+HEADER_EXTENSIONS = (".H", ".h", ".hxx", ".hpp", ".hh")
 
 
 def DirectoryOfThisScript():
-  return os.path.dirname(os.path.abspath(__file__))
+    """
+    Return the absolute path of the parent directory containing this
+    script.
+    """
+    return os.path.dirname(os.path.abspath(__file__))
+
+
+def GuessBuildDirectory():
+    """
+    Guess the build directory using the following heuristics:
+
+    1. Returns the current directory of this script plus 'build'
+    subdirectory in absolute path if this subdirectory exists.
+
+    2. Otherwise, probes whether there exists any directory
+    containing '.ninja_log' file two levels above the current directory;
+    returns this single directory only if there is one candidate.
+    """
+    result = os.path.join(DirectoryOfThisScript(), "build")
+
+    if os.path.exists(result):
+        return result
+
+    result = glob.glob(os.path.join(DirectoryOfThisScript(),
+                                    "..", "..", "*", ".ninja_log"))
+
+    if not result:
+        return ""
+
+    if 1 != len(result):
+        return ""
+
+    return os.path.split(result[0])[0]
+
+
+def TraverseByDepth(root, include_extensions):
+    """
+    Return a set of child directories of the 'root' containing file
+    extensions specified in 'include_extensions'.
+
+    NOTE:
+        1. The 'root' directory itself is excluded from the result set.
+        2. No subdirectories would be excluded if 'include_extensions' is left
+           to 'None'.
+        3. Each entry in 'include_extensions' must begin with string '.'.
+    """
+    is_root = True
+    result = set()
+    # Perform a depth first top down traverse of the given directory tree.
+    for root_dir, subdirs, file_list in os.walk(root):
+        if not is_root:
+            # print("Relative Root: ", root_dir)
+            # print(subdirs)
+            if include_extensions:
+                get_ext = os.path.splitext
+                subdir_extensions = {
+                    get_ext(f)[-1] for f in file_list if get_ext(f)[-1]
+                }
+                if subdir_extensions & include_extensions:
+                    result.add(root_dir)
+            else:
+                result.add(root_dir)
+        else:
+            is_root = False
+
+    return result
+
+
+_project_src_dir = os.path.join(DirectoryOfThisScript(), "src")
+_include_dirs_set = TraverseByDepth(_project_src_dir, frozenset({".h"}))
+flags = [
+    "-x",
+    "c"
+    # The following flags are partially redundant due to the existence of
+    # 'compile_commands.json'.
+    #    '-Wall',
+    #    '-Wextra',
+    #    '-Wfloat-equal',
+    #    '-Wpointer-arith',
+    #    '-Wshadow',
+    #    '-std=gnu99',
+]
+
+for include_dir in _include_dirs_set:
+    flags.append("-I" + include_dir)
+
+# Set this to the absolute path to the folder (NOT the file!) containing the
+# compile_commands.json file to use that instead of 'flags'. See here for
+# more details: http://clang.llvm.org/docs/JSONCompilationDatabase.html
+#
+# You can get CMake to generate this file for you by adding:
+#   set( CMAKE_EXPORT_COMPILE_COMMANDS 1 )
+# to your CMakeLists.txt file.
+#
+# Most projects will NOT need to set this to anything; you can just change the
+# 'flags' list of compilation flags. Notice that YCM itself uses that approach.
+compilation_database_folder = GuessBuildDirectory()
+
+if os.path.exists(compilation_database_folder):
+    database = ycm_core.CompilationDatabase(compilation_database_folder)
+else:
+    database = None
 
 
 def MakeRelativePathsInFlagsAbsolute(flags, working_directory):
-  if not working_directory:
-    return flags
-  new_flags = []
-  make_next_absolute = False
-  path_flags = [ '-isystem', '-I', '-iquote', '--sysroot=' ]
-  for flag in flags:
-    new_flag = flag
-
-    if make_next_absolute:
-      make_next_absolute = False
-      if not flag.startswith('/'):
-        new_flag = os.path.join(working_directory, flag)
-
-    for path_flag in path_flags:
-      if flag == path_flag:
-        make_next_absolute = True
-        break
-
-      if flag.startswith(path_flag):
-        path = flag[ len(path_flag): ]
-        new_flag = path_flag + os.path.join(working_directory, path)
-        break
-
-    if new_flag:
-      new_flags.append(new_flag)
-  return new_flags
-
-
-def FlagsForFile(filename):
-  relative_to = DirectoryOfThisScript()
-
-  return {
-    'flags': MakeRelativePathsInFlagsAbsolute(flags, relative_to),
-    'do_cache': True
-  }
-
-flags = Flatten(map(GetFlagsFromMakefile, [
-  'AM_CPPFLAGS',
-  'CPPFLAGS',
-  'AM_CFLAGS',
-  'CFLAGS',
-]))
-
-# these flags cause crashes in libclang, so remove them
-flags.remove('-Wlogical-op')
-flags.remove('-Wsuggest-attribute=noreturn')
-flags.remove('-Wdate-time')
-
-# vim: set et ts=2 sw=2:
+    """
+    Iterate through 'flags' and replace the relative paths prefixed by
+    '-isystem', '-I', '-iquote', '--sysroot=' with absolute paths
+    start with 'working_directory'.
+    """
+    if not working_directory:
+        return list(flags)
+    new_flags = []
+    make_next_absolute = False
+    path_flags = ["-isystem", "-I", "-iquote", "--sysroot="]
+    for flag in flags:
+        new_flag = flag
+
+        if make_next_absolute:
+            make_next_absolute = False
+            if not flag.startswith("/"):
+                new_flag = os.path.join(working_directory, flag)
+
+        for path_flag in path_flags:
+            if flag == path_flag:
+                make_next_absolute = True
+                break
+
+            if flag.startswith(path_flag):
+                path = flag[len(path_flag):]
+                new_flag = path_flag + os.path.join(working_directory, path)
+                break
+
+        if new_flag:
+            new_flags.append(new_flag)
+    return new_flags
+
+
+def IsHeaderFile(filename):
+    """
+    Check whether 'filename' is considered as a header file.
+    """
+    extension = os.path.splitext(filename)[1]
+    return extension in HEADER_EXTENSIONS
+
+
+def GetCompilationInfoForFile(filename):
+    """
+    Helper function to look up compilation info of 'filename' in the 'database'.
+    """
+    # The compilation_commands.json file generated by CMake does not have
+    # entries for header files. So we do our best by asking the db for flags for
+    # a corresponding source file, if any. If one exists, the flags for that
+    # file should be good enough.
+    if not database:
+        return None
+
+    if IsHeaderFile(filename):
+        basename = os.path.splitext(filename)[0]
+        for extension in SOURCE_EXTENSIONS:
+            replacement_file = basename + extension
+            if os.path.exists(replacement_file):
+                compilation_info = \
+                    database.GetCompilationInfoForFile(replacement_file)
+                if compilation_info.compiler_flags_:
+                    return compilation_info
+        return None
+    return database.GetCompilationInfoForFile(filename)
+
+
+def FlagsForFile(filename, **kwargs):
+    """
+    Callback function to be invoked by YouCompleteMe in order to get the
+    information necessary to compile 'filename'.
+
+    It returns a dictionary with a single element 'flags'. This element is a
+    list of compiler flags to pass to libclang for the file 'filename'.
+    """
+    if database:
+        # Bear in mind that compilation_info.compiler_flags_ does NOT return a
+        # python list, but a "list-like" StringVec object
+        compilation_info = GetCompilationInfoForFile(filename)
+        if not compilation_info:
+            return None
+
+        final_flags = MakeRelativePathsInFlagsAbsolute(
+            compilation_info.compiler_flags_,
+            compilation_info.compiler_working_dir_)
+
+    else:
+        relative_to = DirectoryOfThisScript()
+        final_flags = MakeRelativePathsInFlagsAbsolute(flags, relative_to)
+
+    return {
+        "flags": final_flags,
+        "do_cache": True
+    }
index ed61ea9..4119cfe 100644 (file)
 - We never use the POSIX version of basename() (which glibc defines it in
   libgen.h), only the GNU version (which glibc defines in string.h).
   The only reason to include libgen.h is because dirname()
-  is needed. Everytime you need that please immediately undefine
+  is needed. Every time you need that please immediately undefine
   basename(), and add a comment about it, so that no code ever ends up
   using the POSIX version!
 
   proper event, instead of doing time-based poll loops.
 
 - To determine the length of a constant string "foo", don't bother
-  with sizeof("foo")-1, please use strlen("foo") directly. gcc knows
-  strlen() anyway and turns it into a constant expression if possible.
+  with sizeof("foo")-1, please use STRLEN() instead.
 
 - If you want to concatenate two or more strings, consider using
   strjoin() rather than asprintf(), as the latter is a lot
   global variables. Why are global variables bad? They usually hinder
   generic reusability of code (since they break in threaded programs,
   and usually would require locking there), and as the code using them
-  has side-effects make programs intransparent. That said, there are
+  has side-effects make programs non-transparent. That said, there are
   many cases where they explicitly make a lot of sense, and are OK to
   use. For example, the log level and target in log.c is stored in a
   global variable, and that's OK and probably expected by most. Also
 
 - When exposing public C APIs, be careful what function parameters you make
   "const". For example, a parameter taking a context object should probably not
-  be "const", even if you are writing an other-wise read-only accessor function
+  be "const", even if you are writing an otherwise read-only accessor function
   for it. The reason is that making it "const" fixates the contract that your
   call won't alter the object ever, as part of the API. However, that's often
   quite a promise, given that this even prohibits object-internal caching or
 
 - Make sure to enforce limits on every user controllable resource. If the user
   can allocate resources in your code, your code must enforce some form of
-  limits after which it will refuse operation. It's fine if it is hardcoded (at
+  limits after which it will refuse operation. It's fine if it is hard-coded (at
   least initially), but it needs to be there. This is particularly important
   for objects that unprivileged users may allocate, but also matters for
   everything else any user may allocated.
 
 - htonl()/ntohl() and htons()/ntohs() are weird. Please use htobe32() and
   htobe16() instead, it's much more descriptive, and actually says what really
-  is happening, after all htonl() and htons() don't operation on longs and
+  is happening, after all htonl() and htons() don't operate on longs and
   shorts as their name would suggest, but on uint32_t and uint16_t. Also,
   "network byte order" is just a weird name for "big endian", hence we might
   want to call it "big endian" right-away.
   that interrupted system calls are automatically restarted, and we minimize
   hassles with handling EINTR (in particular as EINTR handling is pretty broken
   on Linux).
+
+- When applying C-style unescaping as well as specifier expansion on the same
+  string, always apply the C-style unescaping fist, followed by the specifier
+  expansion. When doing the reverse, make sure to escape '%' in specifier-style
+  first (i.e. '%' → '%%'), and then do C-style escaping where necessary.
diff --git a/HACKING b/HACKING
index d9d2043..6267c58 100644 (file)
--- a/HACKING
+++ b/HACKING
@@ -11,6 +11,15 @@ CODING_STYLE for details. Also have a look at our Contribution Guidelines:
 
         https://github.com/systemd/systemd/blob/master/.github/CONTRIBUTING.md
 
+When adding new functionality, tests should be added. For shared functionality
+(in src/basic and src/shared) unit tests should be sufficient. The general
+policy is to keep tests in matching files underneath src/test,
+e.g. src/test/test-path-util.c contains tests for any functions in
+src/basic/path-util.c. If adding a new source file, consider adding a matching
+test executable. For features at a higher level, tests in src/test/ are very
+strongly recommended. If that is no possible, integration tests in test/ are
+encouraged.
+
 Please always test your work before submitting a PR. For many of the components
 of systemd testing is straight-forward as you can simply compile systemd and
 run the relevant tool from the build directory.
diff --git a/NEWS b/NEWS
index d4d45c2..1def982 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,7 +1,259 @@
 systemd System and Service Manager
 
+CHANGES WITH 236:
+
+        * The modprobe.d/ drop-in for the bonding.ko kernel module introduced
+          in v235 has been extended to also set the dummy.ko module option
+          numdummies=0, preventing the kernel from automatically creating
+          dummy0. All dummy interfaces must now be explicitly created.
+
+        * Unknown '%' specifiers in configuration files are now rejected. This
+          applies to units and tmpfiles.d configuration. Any percent characters
+          that are followed by a letter or digit that are not supposed to be
+          interpreted as the beginning of a specifier should be escaped by
+          doubling ("%%").  (So "size=5%" is still accepted, as well as
+          "size=5%,foo=bar", but not "LABEL=x%y%z" since %y and %z are not
+          valid specifiers today.)
+
+        * systemd-resolved now maintains a new dynamic
+          /run/systemd/resolve/stub-resolv.conf compatibility file. It is
+          recommended to make /etc/resolv.conf a symlink to it. This file
+          points at the systemd-resolved stub DNS 127.0.0.53 resolver and
+          includes dynamically acquired search domains, achieving more correct
+          DNS resolution by software that bypasses local DNS APIs such as NSS.
+
+        * The "uaccess" udev tag has been dropped from /dev/kvm and
+          /dev/dri/renderD*.  These devices now have the 0666 permissions by
+          default (but this may be changed at build-time). /dev/dri/renderD*
+          will now be owned by the "render" group along with /dev/kfd.
+
+        * "DynamicUser=yes" has been enabled for systemd-timesyncd.service,
+          systemd-journal-gatewayd.service and
+          systemd-journal-upload.service. This means "nss-systemd" must be
+          enabled in /etc/nsswitch.conf to ensure the UIDs assigned to these
+          services are resolved properly.
+
+        * In /etc/fstab two new mount options are now understood:
+          x-systemd.makefs and x-systemd.growfs. The former has the effect that
+          the configured file system is formatted before it is mounted, the
+          latter that the file system is resized to the full block device size
+          after it is mounted (i.e. if the file system is smaller than the
+          partition it resides on, it's grown). This is similar to the fsck
+          logic in /etc/fstab, and pulls in systemd-makefs@.service and
+          systemd-growfs@.service as necessary, similar to
+          systemd-fsck@.service. Resizing is currently only supported on ext4
+          and btrfs.
+
+        * In systemd-networkd, the IPv6 RA logic now optionally may announce
+          DNS server and domain information.
+
+        * Support for the LUKS2 on-disk format for encrypted partitions has
+          been added. This requires libcryptsetup2 during compilation and
+          runtime.
+
+        * The systemd --user instance will now signal "readiness" when its
+          basic.target unit has been reached, instead of when the run queue ran
+          empty for the first time.
+
+        * Tmpfiles.d with user configuration are now also supported.
+          systemd-tmpfiles gained a new --user switch, and snippets placed in
+          ~/.config/user-tmpfiles.d/ and corresponding directories will be
+          executed by systemd-tmpfiles --user running in the new
+          systemd-tmpfiles-setup.service and systemd-tmpfiles-clean.service
+          running in the user session.
+
+        * Unit files and tmpfiles.d snippets learnt three new % specifiers:
+          %S resolves to the top-level state directory (/var/lib for the system
+          instance, $XDG_CONFIG_HOME for the user instance), %C resolves to the
+          top-level cache directory (/var/cache for the system instance,
+          $XDG_CACHE_HOME for the user instance), %L resolves to the top-level
+          logs directory (/var/log for the system instance,
+          $XDG_CONFIG_HOME/log/ for the user instance). This matches the
+          existing %t specifier, that resolves to the top-level runtime
+          directory (/run for the system instance, and $XDG_RUNTIME_DIR for the
+          user instance).
+
+        * journalctl learnt a new parameter --output-fields= for limiting the
+          set of journal fields to output in verbose and JSON output modes.
+
+        * systemd-timesyncd's configuration file gained a new option
+          RootDistanceMaxSec= for setting the maximum root distance of servers
+          it'll use, as well as the new options PollIntervalMinSec= and
+          PollIntervalMaxSec= to tweak the minimum and maximum poll interval.
+
+        * bootctl gained a new command "list" for listing all available boot
+          menu items on systems that follow the boot loader specification.
+
+        * systemctl gained a new --dry-run switch that shows what would be done
+          instead of doing it, and is currently supported by the shutdown and
+          sleep verbs.
+
+        * ConditionSecurity= can now detect the TOMOYO security module.
+
+        * Unit file [Install] sections are now also respected in unit drop-in
+          files. This is intended to be used by drop-ins under /usr/lib/.
+
+        * systemd-firstboot may now also set the initial keyboard mapping.
+
+        * Udev "changed" events for devices which are exposed as systemd
+          .device units are now propagated to units specified in
+          ReloadPropagatedFrom= as reload requests.
+
+        * If a udev device has a SYSTEMD_WANTS= property containing a systemd
+          unit template name (i.e. a name in the form of 'foobar@.service',
+          without the instance component between the '@' and - the '.'), then
+          the escaped sysfs path of the device is automatically used as the
+          instance.
+
+        * SystemCallFilter= in unit files has been extended so that an "errno"
+          can be specified individually for each system call. Example:
+          SystemCallFilter=~uname:EILSEQ.
+
+        * The cgroup delegation logic has been substantially updated. Delegate=
+          now optionally takes a list of controllers (instead of a boolean, as
+          before), which lists the controllers to delegate at least.
+
+        * The networkd DHCPv6 client now implements the FQDN option (RFC 4704).
+
+        * A new LogLevelMax= setting configures the maximum log level any
+          process of the service may log at (i.e. anything with a lesser
+          priority than what is specified is automatically dropped). A new
+          LogExtraFields= setting allows configuration of additional journal
+          fields to attach to all log records generated by any of the unit's
+          processes.
+
+        * New StandardInputData= and StandardInputText= settings along with the
+          new option StandardInput=data may be used to configure textual or
+          binary data that shall be passed to the executed service process via
+          standard input, encoded in-line in the unit file.
+
+        * StandardInput=, StandardOutput= and StandardError= may now be used to
+          connect stdin/stdout/stderr of executed processes directly with a
+          file or AF_UNIX socket in the file system, using the new "file:" option.
+
+        * A new unit file option CollectMode= has been added, that allows
+          tweaking the garbage collection logic for units. It may be used to
+          tell systemd to garbage collect units that have failed automatically
+          (normally it only GCs units that exited successfully). systemd-run
+          and systemd-mount expose this new functionality with a new -G option.
+
+        * "machinectl bind" may now be used to bind mount non-directories
+          (i.e. regularfiles, devices, fifos, sockets).
+
+        * systemd-analyze gained a new verb "calendar" for validating and
+          testing calendar time specifications to use for OnCalendar= in timer
+          units. Besides validating the expression it will calculate the next
+          time the specified expression would elapse.
+
+        * In addition to the pre-existing FailureAction= unit file setting
+          there's now SuccessAction=, for configuring a shutdown action to
+          execute when a unit completes successfully. This is useful in
+          particular inside containers that shall terminate after some workload
+          has been completed. Also, both options are now supported for all unit
+          types, not just services.
+
+        * networkds's IP rule support gained two new options
+          IncomingInterface= and OutgoingInterface= for configuring the incoming
+          and outgoing interfaces of configured rules. systemd-networkd also
+          gained support for "vxcan" network devices.
+
+        * networkd gained a new setting RequiredForOnline=, taking a
+          boolean. If set, systemd-wait-online will take it into consideration
+          when determining that the system is up, otherwise it will ignore the
+          interface for this purpose.
+
+        * The sd_notify() protocol gained support for a new operation: with
+          FDSTOREREMOVE=1 file descriptors may be removed from the per-service
+          store again, ahead of POLLHUP or POLLERR when they are removed
+          anyway.
+
+        * A new document UIDS-GIDS.md has been added to the source tree, that
+          documents the UID/GID range and assignment assumptions and
+          requirements of systemd.
+
+        * The watchdog device PID 1 will ping may now be configured through the
+          WatchdogDevice= configuration file setting, or by setting the
+          systemd.watchdog_service= kernel commandline option.
+
+        * systemd-resolved's gained support for registering DNS-SD services on
+          the local network using MulticastDNS. Services may either be
+          registered by dropping in a .dnssd file in /etc/systemd/dnssd/ (or
+          the same dir below /run, /usr/lib), or through its D-Bus API.
+
+        * The sd_notify() protocol can now with EXTEND_TIMEOUT_USEC=microsecond
+          extend the effective start, runtime, and stop time. The service must
+          continue to send EXTEND_TIMEOUT_USEC within the period specified to
+          prevent the service manager from making the service as timedout.
+
+        * systemd-resolved's DNSSEC support gained support for RFC 8080
+          (Ed25519 keys and signatures).
+
+        * The systemd-resolve command line tool gained a new set of options
+          --set-dns=, --set-domain=, --set-llmnr=, --set-mdns=, --set-dnssec=,
+          --set-nta= and --revert to configure per-interface DNS configuration
+          dynamically during runtime. It's useful for pushing DNS information
+          into systemd-resolved from DNS hook scripts that various interface
+          managing software supports (such as pppd).
+
+        * systemd-nspawn gained a new --network-namespace-path= command line
+          option, which may be used to make a container join an existing
+          network namespace, by specifying a path to a "netns" file.
+
+        Contributions from: Alan Jenkins, Alan Robertson, Alessandro Ghedini,
+        Andrew Jeddeloh, Antonio Rojas, Ari, asavah, bleep_blop, Carsten
+        Strotmann, Christian Brauner, Christian Hesse, Clinton Roy, Collin
+        Eggert, Cong Wang, Daniel Black, Daniel Lockyer, Daniel Rusek, Dimitri
+        John Ledkov, Dmitry Rozhkov, Dongsu Park, Edward A. James, Evgeny
+        Vereshchagin, Florian Klink, Franck Bui, Gwendal Grignou, Hans de
+        Goede, Harald Hoyer, Hristo Venev, Iago López Galeiras, Ikey Doherty,
+        Jakub Wilk, Jérémy Rosen, Jiahui Xie, John Lin, José Bollo, Josef
+        Andersson, juga0, Krzysztof Nowicki, Kyle Walker, Lars Karlitski, Lars
+        Kellogg-Stedman, Lauri Tirkkonen, Lennart Poettering, Lubomir Rintel,
+        Luca Bruno, Lucas Werkmeister, Lukáš Nykrýn, Lukáš Říha, Lukasz
+        Rubaszewski, Maciej S. Szmigiero, Mantas Mikulėnas, Marcus Folkesson,
+        Martin Steuer, Mathieu Trudel-Lapierre, Matija Skala,
+        Matthias-Christian Ott, Max Resch, Michael Biebl, Michael Vogt, Michal
+        Koutný, Michal Sekletar, Mike Gilbert, Muhammet Kara, Neil Brown, Olaf
+        Hering, Ondrej Kozina, Patrik Flykt, Patryk Kocielnik, Peter Hutterer,
+        Piotr Drąg, Razvan Cojocaru, Robin McCorkell, Roland Hieber, Saran
+        Tunyasuvunakool, Sergey Ptashnick, Shawn Landden, Shuang Liu, Simon
+        Arlott, Simon Peeters, Stanislav Angelovič, Stefan Agner, Susant
+        Sahani, Sylvain Plantefève, Thomas Blume, Thomas Haller, Tiago Salem
+        Herrmann, Tinu Weber, Tom Stellard, Topi Miettinen, Torsten Hilbrich,
+        Vito Caputo, Vladislav Vishnyakov, WaLyong Cho, Yu Watanabe, Zbigniew
+        Jędrzejewski-Szmek, Zeal Jagannatha
+
+        — Berlin, 2017-12-14
+
 CHANGES WITH 235:
 
+        * INCOMPATIBILITY: systemd-logind.service and other long-running
+          services now run inside an IPv4/IPv6 sandbox, prohibiting them any IP
+          communication with the outside. This generally improves security of
+          the system, and is in almost all cases a safe and good choice, as
+          these services do not and should not provide any network-facing
+          functionality. However, systemd-logind uses the glibc NSS API to
+          query the user database. This creates problems on systems where NSS
+          is set up to directly consult network services for user database
+          lookups. In particular, this creates incompatibilities with the
+          "nss-nis" module, which attempts to directly contact the NIS/YP
+          network servers it is configured for, and will now consistently
+          fail. In such cases, it is possible to turn off IP sandboxing for
+          systemd-logind.service (set IPAddressDeny= in its [Service] section
+          to the empty string, via a .d/ unit file drop-in). Downstream
+          distributions might want to update their nss-nis packaging to include
+          such a drop-in snippet, accordingly, to hide this incompatibility
+          from the user. Another option is to make use of glibc's nscd service
+          to proxy such network requests through a privilege-separated, minimal
+          local caching daemon, or to switch to more modern technologies such
+          sssd, whose NSS hook-ups generally do not involve direct network
+          access. In general, we think it's definitely time to question the
+          implementation choices of nss-nis, i.e. whether it's a good idea
+          today to embed a network-facing loadable module into all local
+          processes that need to query the user database, including the most
+          trivial and benign ones, such as "ls". For more details about
+          IPAddressDeny= see below.
+
         * A new modprobe.d drop-in is now shipped by default that sets the
           bonding module option max_bonds=0. This overrides the kernel default,
           to avoid conflicts and ambiguity as to whether or not bond0 should be
diff --git a/README b/README
index e36a1f9..b245564 100644 (file)
--- a/README
+++ b/README
@@ -94,6 +94,10 @@ REQUIREMENTS:
         Required for CPUQuota= in resource control unit settings
           CONFIG_CFS_BANDWIDTH
 
+        Required for IPAddressDeny= and IPAddressAllow= in resource control
+        unit settings
+          CONFIG_CGROUP_BPF
+
         For UEFI systems:
           CONFIG_EFIVAR_FS
           CONFIG_EFI_PARTITION
@@ -149,6 +153,7 @@ REQUIREMENTS:
         libpython (optional)
         libidn2 or libidn (optional)
         elfutils >= 158 (optional)
+        polkit (optional)
         pkg-config
         gperf
         docbook-xsl (optional, required for documentation)
@@ -192,6 +197,16 @@ REQUIREMENTS:
         under all circumstances. In fact, systemd-hostnamed will warn
         if nss-myhostname is not installed.
 
+        nss-systemd must be enabled on systemd systems, as that's required for
+        DynamicUser= to work. Note that we ship services out-of-the-box that
+        make use of DynamicUser= now, hence enabling nss-systemd is not
+        optional.
+
+        Note that the build prefix for systemd must be /usr. -Dsplit-usr=false
+        (which is the default and does not need to be specified) is the
+        recommended setting, and -Dsplit-usr=true should be used on systems
+        which have /usr on a separate partition.
+
         Additional packages are necessary to run some tests:
         - busybox            (used by test/TEST-13-NSPAWN-SMOKE)
         - nc                 (used by test/TEST-12-ISSUE-3171)
@@ -206,7 +221,7 @@ USERS AND GROUPS:
         even in the very early boot stages, where no other databases
         and network are available:
 
-        audio, cdrom, dialout, disk, input, kmem, lp, tape, tty, video
+        audio, cdrom, dialout, disk, input, kmem, kvm, lp, render, tape, tty, video
 
         During runtime, the journal daemon requires the
         "systemd-journal" system group to exist. New journal files will
@@ -272,16 +287,16 @@ SYSV INIT.D SCRIPTS:
         needs to look like, and provide an implementation at the marked places.
 
 WARNINGS:
-        systemd will warn you during boot if /usr is on a different
-        file system than /. While in systemd itself very little will
-        break if /usr is on a separate partition, many of its
-        dependencies very likely will break sooner or later in one
-        form or another. For example, udev rules tend to refer to
-        binaries in /usr, binaries that link to libraries in /usr or
-        binaries that refer to data files in /usr. Since these
-        breakages are not always directly visible, systemd will warn
-        about this, since this kind of file system setup is not really
-        supported anymore by the basic set of Linux OS components.
+        systemd will warn during early boot if /usr is not already mounted at
+        this point (that means: either located on the same file system as / or
+        already mounted in the initrd). While in systemd itself very little
+        will break if /usr is on a separate, late-mounted partition, many of
+        its dependencies very likely will break sooner or later in one form or
+        another. For example, udev rules tend to refer to binaries in /usr,
+        binaries that link to libraries in /usr or binaries that refer to data
+        files in /usr. Since these breakages are not always directly visible,
+        systemd will warn about this, since this kind of file system setup is
+        not really supported anymore by the basic set of Linux OS components.
 
         systemd requires that the /run mount point exists. systemd also
         requires that /var/run is a symlink to /run.
index c406aca..06fd691 100644 (file)
--- a/README.md
+++ b/README.md
@@ -3,7 +3,8 @@
 <a href="https://in.waw.pl/systemd-github-state/systemd-systemd-issues.svg"><img align="right" src="https://in.waw.pl/systemd-github-state/systemd-systemd-issues-small.svg" alt="Count of open issues over time"></a>
 <a href="https://in.waw.pl/systemd-github-state/systemd-systemd-pull-requests.svg"><img align="right" src="https://in.waw.pl/systemd-github-state/systemd-systemd-pull-requests-small.svg" alt="Count of open pull requests over time"></a>
 [![Build Status](https://semaphoreci.com/api/v1/projects/28a5a3ca-3c56-4078-8b5e-7ed6ef912e14/443470/shields_badge.svg)](https://semaphoreci.com/systemd/systemd)<br/>
-[![Coverity Scan Status](https://scan.coverity.com/projects/350/badge.svg)](https://scan.coverity.com/projects/350)
+[![Coverity Scan Status](https://scan.coverity.com/projects/350/badge.svg)](https://scan.coverity.com/projects/350)<br/>
+[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/1369/badge)](https://bestpractices.coreinfrastructure.org/projects/1369)
 
 ## Details
 
diff --git a/TODO b/TODO
index 4c238a2..ec8e05c 100644 (file)
--- a/TODO
+++ b/TODO
@@ -24,6 +24,84 @@ Janitorial Clean-ups:
 
 Features:
 
+* make use of ethtool veth peer info in machined, for automatically finding out
+  host-side interface pointing to the container.
+
+* add some special mode to LogsDirectory=/StateDirectory=… that allows
+  declaring these directories without necessarily pulling in deps for them, or
+  creating them when starting up. That way, we could declare that
+  systemd-journald writes to /var/log/journal, which could be useful when we
+  doing disk usage calculations and so on.
+
+* taint systemd if there are fewer than 65536 users assigned to the system.
+
+* deprecate PermissionsStartOnly= and RootDirectoryStartOnly= in favour of the ExecStart= prefix chars
+
+* add a new RuntimeDirectoryPreserve= mode that defines a similar lifecycle for
+  the runtime dir as we maintain for the fdstore: i.e. keep it around as long
+  as the unit is running or has a job queued.
+
+* hook up sd-bus' creds stuff with SO_PEERGROUPS
+
+* add async version of sd_bus_add_match and make use of that
+
+* support projid-based quota in machinectl for containers, and then drop
+  implicit btrfs loopback magic in machined
+
+* Add NetworkNamespacePath= to specify a path to a network namespace
+
+* maybe use SOURCE_DATE_EPOCH (i.e. the env var the reproducible builds folks
+  introduced) as the RTC epoch, instead of the mtime of NEWS.
+
+* add a way to lock down cgroup migration: a boolean, which when set for a unit
+  makes sure the processes in it can never migrate out of it
+
+* blog about fd store and restartable services
+
+* document Environment=SYSTEMD_LOG_LEVEL=debug drop-in in debugging document
+
+* rework ExecOutput and ExecInput enums so that EXEC_OUTPUT_NULL loses its
+  magic meaning and is no longer upgraded to something else if set explicitly.
+
+* in the long run: permit a system with /etc/machine-id linked to /dev/null, to
+  make it lose its identity, i.e. be anonymous. For this we'd have to patch
+  through the whole tree to make all code deal with the case where no machine
+  ID is available.
+
+* optionally, collect cgroup resource data, and store it in per-unit RRD files,
+  suitable for processing with rrdtool. Add bus API to access this data, and
+  possibly implement a CPULoad property based on it.
+
+* beef up pam_systemd to take unit file settings such as cgroups properties as
+  parameters
+
+* a new "systemd-analyze security" tool outputting a checklist of security
+  features a service does and does not implement
+
+* maybe hook of xfs/ext4 quotactl() with services? i.e. automatically manage
+  the quota of a the user indicated in User= via unit file settings, like the
+  other resource management concepts. Would mix nicely with DynamicUser=1. Or
+  alternatively, do this with projids, so that we can also cover services
+  running as root. Quota should probably cover all the special dirs such as
+  StateDirectory=, LogsDirectory=, CacheDirectory=, as well as RootDirectory= if it
+  is set, plus the whole disk space any image configured with RootImage=.
+
+* Introduce "exit" as an EmergencyAction value, and allow to configure a
+  per-unit success/failure exit code to configure. This would be useful for
+  running commands inside of services inside of containers, which could then
+  propagate their failure state all the way up.
+
+* In DynamicUser= mode: before selecting a UID, use disk quota APIs on relevant
+  disks to see if the UID is already in use.
+
+* add dissect_image_warn() as a wrapper around dissect_image() that prints
+  friendly log messages for the returned errors, so that we don't have to
+  duplicate that in nspawn, systemd-dissect and PID 1.
+
+* add "systemctl wait" or so, which does what "systemd-run --wait" does, but
+  for all units. It should be both a way to pin units into memory as well as a
+  wait to retrieve their exit data.
+
 * maybe set a new set of env vars for services, based on RuntimeDirectory=,
   StateDirectory=, LogsDirectory=, CacheDirectory= and ConfigurationDirectory=
   automatically. For example, there could be $RUNTIME_DIRECTORY,
@@ -33,10 +111,6 @@ Features:
   taken if multiple dirs are configured. Maybe avoid setting the env vars in
   that case?
 
-* In a similar vein, consider adding unit specifiers that resolve to the root
-  directory used for state, logs, cache and configuration
-  directory. i.e. similar to %t, but for the root of the other special dirs.
-
 * expose IO accounting data on the bus, show it in systemd-run --wait and log
   about it in the resource log message
 
@@ -48,12 +122,6 @@ Features:
 
 * replace all uses of fgets() + LINE_MAX by read_line()
 
-* set IPAddressDeny=any on all services that shouldn't do networking (possibly
-  combined with IPAddressAllow=localhost).
-
-* dissect: when we discover squashfs, don't claim we had a "writable" partition
-  in systemd-dissect
-
 * Add AddUser= setting to unit files, similar to DynamicUser=1 which however
   creates a static, persistent user rather than a dynamic, transient user. We
   can leverage code from sysusers.d for this.
@@ -63,10 +131,6 @@ Features:
 
   ReadWritePaths=:/var/lib/foobar
 
-* sort generated hwdb files alphabetically when we import them, so that git
-  diffs remain minimal (in particular: the OUI databases we import are not
-  sorted, and not stable)
-
 * maybe add call sd_journal_set_block_timeout() or so to set SO_SNDTIMEO for
   the sd-journal logging socket, and, if the timeout is set to 0, sets
   O_NONBLOCK on it. That way people can control if and when to block for
@@ -88,15 +152,6 @@ Features:
   --as-pid2 switch, and sanely proxy sd_notify() messages dropping stuff such
   as MAINPID.
 
-* change the dependency Set* objects in Unit structures to become Hashmap*, and
-  then store a bit mask who created a specific dependency: the source unit via
-  fragment configuration, the destination unit via fragment configuration, or
-  the source unit via udev rules (in case of .device units), or any combination
-  thereof. This information can then be used to flush out old udev-created
-  dependencies when the udev properties change, and eventually to implement a
-  "systemctl refresh" operation for reloading the configuration of individual
-  units without reloading the whole set.
-
 * Add ExecMonitor= setting. May be used multiple times. Forks off a process in
   the service cgroup, which is supposed to monitor the service, and when it
   exits the service is considered failed by its monitor.
@@ -115,9 +170,6 @@ Features:
 
 * maybe introduce gpt auto discovery for /var/tmp?
 
-* fix PrivateNetwork= so that we fall back gracefully on kernels lacking
-  namespacing support (similar for the other namespacing options)
-
 * maybe add gpt-partition-based user management: each user gets his own
   LUKS-encrypted GPT partition with a new GPT type. A small nss module
   enumerates users via udev partition enumeration. UIDs are assigned in a fixed
@@ -138,31 +190,20 @@ Features:
   partition, that is mounted to / and is writable, and where the actual root's
   /usr is mounted into.
 
-* machined: add apis to query /etc/machine-info data of a container
-
-* .mount and .swap units: add Format=yes|no option that formats the partition before mounting/enabling it, implicitly
-
 * gpt-auto logic: support encrypted swap, add kernel cmdline option to force it, and honour a gpt bit about it, plus maybe a configuration file
 
 * drop nss-myhostname in favour of nss-resolve?
 
-* drop internal dlopen() based nss-dns fallback in nss-resolve, and rely on the
-  external nsswitch.conf based one
-
 * add a percentage syntax for TimeoutStopSec=, e.g. TimeoutStopSec=150%, and
   then use that for the setting used in user@.service. It should be understood
   relative to the configured default value.
 
-* on cgroupsv2 add DelegateControllers=, to pick the precise cgroup controllers to delegate
-
 * in networkd, when matching device types, fix up DEVTYPE rubbish the kernel passes to us
 
 * enable LockMLOCK to take a percentage value relative to physical memory
 
 * Permit masking specific netlink APIs with RestrictAddressFamily=
 
-* nspawn: start UID allocation loop from hash of container name
-
 * nspawn: support that /proc, /sys/, /dev are pre-mounted
 
 * define gpt header bits to select volatility mode
@@ -200,8 +241,6 @@ Features:
   a user/group for a service only has to exist on the host for the right
   mapping to work.
 
-* allow attaching additional journald log fields to cgroups
-
 * add bus API for creating unit files in /etc, reusing the code for transient units
 
 * add bus API to remove unit files from /etc
@@ -239,8 +278,6 @@ Features:
   the specified range and generates sane error messages for incorrect
   specifications.
 
-* do something about "/control" subcgroups in the unified cgroup hierarchy
-
 * when we detect that there are waiting jobs but no running jobs, do something
 
 * push CPUAffinity= also into the "cpuset" cgroup controller (only after the cpuset controller got ported to the unified hierarchy)
@@ -252,8 +289,6 @@ Features:
   prefixed with /sys generally special.
   http://lists.freedesktop.org/archives/systemd-devel/2015-June/032962.html
 
-* man: document that unless you use StandardError=null the shell >/dev/stderr won't work in shell scripts in services
-
 * fstab-generator: default to tmpfs-as-root if only usr= is specified on the kernel cmdline
 
 * docs: bring http://www.freedesktop.org/wiki/Software/systemd/MyServiceCantGetRealtime up to date
@@ -281,8 +316,6 @@ Features:
 
 * Rework systemctl's GetAll property parsing to use the generic bus_map_all_properties() API
 
-* implement a per-service firewall based on net_cls
-
 * Port various tools to make use of verbs.[ch], where applicable: busctl,
   coredumpctl, hostnamectl, localectl, systemd-analyze, timedatectl
 
@@ -319,8 +352,6 @@ Features:
 
 * introduce systemd-timesync-wait.service or so to sync on an NTP fix?
 
-* systemd --user should issue sd_notify() upon reaching basic.target, not on becoming idle
-
 * consider showing the unit names during boot up in the status output, not just the unit descriptions
 
 * maybe allow timer units with an empty Units= setting, so that they
@@ -376,8 +407,6 @@ Features:
 
 * figure out a nice way how we can let the admin know what child/sibling unit causes cgroup membership for a specific unit
 
-* mount_cgroup_controllers(): symlinks need to get the label applied
-
 * For timer units: add some mechanisms so that timer units that trigger immediately on boot do not have the services
   they run added to the initial transaction and thus confuse Type=idle.
 
@@ -512,8 +541,6 @@ Features:
 
 * shutdown logging: store to EFI var, and store to USB stick?
 
-* think about window-manager-run-as-user-service problem: exit 0 → activate shutdown.target; exit != 0 → restart service
-
 * merge unit_kill_common() and unit_kill_context()
 
 * introduce ExecCondition= in services
@@ -599,7 +626,6 @@ Features:
   - journald: when we drop syslog messages because the syslog socket is
     full, make sure to write how many messages are lost as first thing
     to syslog when it works again.
-  - journald: make sure ratelimit is actually really per-service with the new cgroup changes
   - change systemd-journal-flush into a service that stays around during
     boot, and causes the journal to be moved back to /run on shutdown,
     so that we do not keep /var busy. This needs to happen synchronously,
@@ -628,19 +654,21 @@ Features:
   - add journalctl -H that talks via ssh to a remote peer and passes through
     binary logs data
   - add a version of --merge which also merges /var/log/journal/remote
-  - log accumulated resource usage after each service invocation
   - journalctl: -m should access container journals directly by enumerating
     them via machined, and also watch containers coming and going.
     Benefit: nspawn --ephemeral would start working nicely with the journal.
   - assign MESSAGE_ID to log messages about failed services
 
+* add a test if all entries in the catalog are properly formatted.
+    (Adding dashes in a catalog entry currently results in the catalog entry
+     being silently skipped. journalctl --update-catalog must warn about this,
+     and we should also have a unit test to check that all our message are OK.)
+
 * document:
   - document that deps in [Unit] sections ignore Alias= fields in
     [Install] units of other units, unless those units are disabled
   - man: clarify that time-sync.target is not only sysv compat but also useful otherwise. Same for similar targets
-  - document the exit codes when services fail before they are exec()ed
   - document that service reload may be implemented as service reexec
-  - document in wiki how to map ical recurrence events to systemd timer unit calendar specifications
   - add a man page containing packaging guidelines and recommending usage of things like Documentation=, PrivateTmp=, PrivateNetwork= and ReadOnlyDirectories=/etc /usr.
   - document systemd-journal-flush.service properly
   - documentation: recommend to connect the timer units of a service to the service via Also= in [Install]
@@ -658,7 +686,6 @@ Features:
   - add new command to systemctl: "systemctl system-reexec" which reexecs as many daemons as virtually possible
   - systemctl enable: fail if target to alias into does not exist? maybe show how many units are enabled afterwards?
   - systemctl: "Journal has been rotated since unit was started." message is misleading
-  - better error message if you run systemctl without systemd running
   - systemctl status output should include list of triggering units and their status
 
 * unit install:
@@ -698,11 +725,8 @@ Features:
     https://github.com/systemd/systemd/pull/272#issuecomment-113153176
   - should optionally support receiving WATCHDOG=1 messages from its payload
     PID 1...
-  - should send out sd_notify("WATCHDOG=1") messages
   - optionally automatically add FORWARD rules to iptables whenever nspawn is
     running, remove them when shut down.
-  - Improve error message when --bind= is used on a non-existing source
-    directory
   - maybe make copying of /etc/resolv.conf optional, and skip it if --read-only
     is used
 
@@ -789,7 +813,6 @@ Features:
 * write blog stories about:
   - hwdb: what belongs into it, lsusb
   - enabling dbus services
-  - status update
   - how to make changes to sysctl and sysfs attributes
   - remote access
   - how to pass throw-away units to systemd, or dynamically change properties of existing units
@@ -944,8 +967,6 @@ Regularly:
 
 * check for strerror(r) instead of strerror(-r)
 
-* Use PR_SET_PROCTITLE_AREA if it becomes available in the kernel
-
 * pahole
 
 * set_put(), hashmap_put() return values check. i.e. == 0 does not free()!
diff --git a/TRANSIENT-SETTINGS.md b/TRANSIENT-SETTINGS.md
new file mode 100644 (file)
index 0000000..17fe060
--- /dev/null
@@ -0,0 +1,447 @@
+# What settings are currently available for transient units?
+
+Our intention is to make all settings that are available as unit file settings
+also available for transient units, through the D-Bus API. At the moment, some
+unit types (socket, swap, path) are not supported at all via unit types, but
+most others are pretty well supported, with some notable omissions.
+
+The lists below contain all settings currently available in unit files. The
+ones currently available in transient units are prefixed with `✓`.
+
+## Generic Unit Settings
+
+Only the most important generic unit settings are available for transient units.
+
+```
+✓ Description=
+  Documentation=
+  SourcePath=
+✓ Requires=
+✓ Requisite=
+✓ Wants=
+✓ BindsTo=
+✓ Conflicts=
+✓ Before=
+✓ After=
+✓ OnFailure=
+✓ PropagatesReloadTo=
+✓ ReloadPropagatedFrom=
+✓ PartOf=
+  JoinsNamespaceOf=
+  RequiresMountsFor=
+  StopWhenUnneeded=
+  RefuseManualStart=
+  RefuseManualStop=
+  AllowIsolate=
+✓ DefaultDependencies=
+  OnFailureJobMode=
+  OnFailureIsolate=
+  IgnoreOnIsolate=
+  JobTimeoutSec=
+  JobRunningTimeoutSec=
+  JobTimeoutAction=
+  JobTimeoutRebootArgument=
+  StartLimitIntervalSec=SECONDS
+  StartLimitBurst=UNSIGNED
+  StartLimitAction=ACTION
+✓ FailureAction=
+✓ SuccessAction=
+✓ AddRef=
+  RebootArgument=STRING
+  ConditionPathExists=
+  ConditionPathExistsGlob=
+  ConditionPathIsDirectory=
+  ConditionPathIsSymbolicLink=
+  ConditionPathIsMountPoint=
+  ConditionPathIsReadWrite=
+  ConditionDirectoryNotEmpty=
+  ConditionFileNotEmpty=
+  ConditionFileIsExecutable=
+  ConditionNeedsUpdate=
+  ConditionFirstBoot=
+  ConditionKernelCommandLine=
+  ConditionArchitecture=
+  ConditionVirtualization=
+  ConditionSecurity=
+  ConditionCapability=
+  ConditionHost=
+  ConditionACPower=
+  ConditionUser=
+  ConditionGroup=
+  AssertPathExists=
+  AssertPathExistsGlob=
+  AssertPathIsDirectory=
+  AssertPathIsSymbolicLink=
+  AssertPathIsMountPoint=
+  AssertPathIsReadWrite=
+  AssertDirectoryNotEmpty=
+  AssertFileNotEmpty=
+  AssertFileIsExecutable=
+  AssertNeedsUpdate=
+  AssertFirstBoot=
+  AssertKernelCommandLine=
+  AssertArchitecture=
+  AssertVirtualization=
+  AssertSecurity=
+  AssertCapability=
+  AssertHost=
+  AssertACPower=
+  AssertUser=
+  AssertGroup=
+✓ CollectMode=
+```
+
+## Execution-Related Settings
+
+All execution-related settings are available for transient units.
+
+```
+✓ WorkingDirectory=
+✓ RootDirectory=
+✓ RootImage=
+✓ User=
+✓ Group=
+✓ SupplementaryGroups=
+✓ Nice=
+✓ OOMScoreAdjust=
+✓ IOSchedulingClass=
+✓ IOSchedulingPriority=
+✓ CPUSchedulingPolicy=
+✓ CPUSchedulingPriority=
+✓ CPUSchedulingResetOnFork=
+✓ CPUAffinity=
+✓ UMask=
+✓ Environment=
+✓ EnvironmentFile=
+✓ PassEnvironment=
+✓ UnsetEnvironment=
+✓ DynamicUser=
+✓ RemoveIPC=
+✓ StandardInput=
+✓ StandardOutput=
+✓ StandardError=
+✓ StandardInputText=
+✓ StandardInputData=
+✓ TTYPath=
+✓ TTYReset=
+✓ TTYVHangup=
+✓ TTYVTDisallocate=
+✓ SyslogIdentifier=
+✓ SyslogFacility=
+✓ SyslogLevel=
+✓ SyslogLevelPrefix=
+✓ LogLevelMax=
+✓ LogExtraFields=
+✓ SecureBits=
+✓ CapabilityBoundingSet=
+✓ AmbientCapabilities=
+✓ TimerSlackNSec=
+✓ NoNewPrivileges=
+✓ KeyringMode=
+✓ SystemCallFilter=
+✓ SystemCallArchitectures=
+✓ SystemCallErrorNumber=
+✓ MemoryDenyWriteExecute=
+✓ RestrictNamespaces=
+✓ RestrictRealtime=
+✓ RestrictAddressFamilies=
+✓ LockPersonality=
+✓ LimitCPU=
+✓ LimitFSIZE=
+✓ LimitDATA=
+✓ LimitSTACK=
+✓ LimitCORE=
+✓ LimitRSS=
+✓ LimitNOFILE=
+✓ LimitAS=
+✓ LimitNPROC=
+✓ LimitMEMLOCK=
+✓ LimitLOCKS=
+✓ LimitSIGPENDING=
+✓ LimitMSGQUEUE=
+✓ LimitNICE=
+✓ LimitRTPRIO=
+✓ LimitRTTIME=
+✓ ReadWritePaths=
+✓ ReadOnlyPaths=
+✓ InaccessiblePaths=
+✓ BindPaths=
+✓ BindReadOnlyPaths=
+✓ PrivateTmp=
+✓ PrivateDevices=
+✓ ProtectKernelTunables=
+✓ ProtectKernelModules=
+✓ ProtectControlGroups=
+✓ PrivateNetwork=
+✓ PrivateUsers=
+✓ ProtectSystem=
+✓ ProtectHome=
+✓ MountFlags=
+✓ MountAPIVFS=
+✓ Personality=
+✓ RuntimeDirectoryPreserve=
+✓ RuntimeDirectoryMode=
+✓ RuntimeDirectory=
+✓ StateDirectoryMode=
+✓ StateDirectory=
+✓ CacheDirectoryMode=
+✓ CacheDirectory=
+✓ LogsDirectoryMode=
+✓ LogsDirectory=
+✓ ConfigurationDirectoryMode=
+✓ ConfigurationDirectory=
+✓ PAMName=
+✓ IgnoreSIGPIPE=
+✓ UtmpIdentifier=
+✓ UtmpMode=
+✓ SELinuxContext=
+✓ SmackProcessLabel=
+✓ AppArmorProfile=
+✓ Slice=
+```
+
+## Resource Control Settings
+
+All cgroup/resource control settings are available for transient units
+
+```
+✓ CPUAccounting=
+✓ CPUWeight=
+✓ StartupCPUWeight=
+✓ CPUShares=
+✓ StartupCPUShares=
+✓ CPUQuota=
+✓ MemoryAccounting=
+✓ MemoryLow=
+✓ MemoryHigh=
+✓ MemoryMax=
+✓ MemorySwapMax=
+✓ MemoryLimit=
+✓ DeviceAllow=
+✓ DevicePolicy=
+✓ IOAccounting=
+✓ IOWeight=
+✓ StartupIOWeight=
+✓ IODeviceWeight=
+✓ IOReadBandwidthMax=
+✓ IOWriteBandwidthMax=
+✓ IOReadIOPSMax=
+✓ IOWriteIOPSMax=
+✓ BlockIOAccounting=
+✓ BlockIOWeight=
+✓ StartupBlockIOWeight=
+✓ BlockIODeviceWeight=
+✓ BlockIOReadBandwidth=
+✓ BlockIOWriteBandwidth=
+✓ TasksAccounting=
+✓ TasksMax=
+✓ Delegate=
+✓ IPAccounting=
+✓ IPAddressAllow=
+✓ IPAddressDeny=
+```
+
+## Process Killing Settings
+
+All process killing settings are available for transient units:
+
+```
+✓ SendSIGKILL=
+✓ SendSIGHUP=
+✓ KillMode=
+✓ KillSignal=
+```
+
+## Service Unit Settings
+
+Only the most important service settings are available for transient units.
+
+```
+  PIDFile=
+✓ ExecStartPre=
+✓ ExecStart=
+✓ ExecStartPost=
+✓ ExecReload=
+✓ ExecStop=
+✓ ExecStopPost=
+  RestartSec=
+  TimeoutStartSec=
+  TimeoutStopSec=
+  TimeoutSec=
+✓ RuntimeMaxSec=
+  WatchdogSec=
+✓ Type=
+✓ Restart=
+  PermissionsStartOnly=
+  RootDirectoryStartOnly=
+✓ RemainAfterExit=
+  GuessMainPID=
+  RestartPreventExitStatus=
+  RestartForceExitStatus=
+  SuccessExitStatus=
+✓ NonBlocking=
+  BusName=
+✓ FileDescriptorStoreMax=
+✓ NotifyAccess=
+  Sockets=
+  USBFunctionDescriptors=
+  USBFunctionStrings=
+```
+
+## Mount Unit Settings
+
+Only the most important mount unit settings are currently available to transient units:
+
+```
+✓ What=
+  Where=
+✓ Options=
+✓ Type=
+  TimeoutSec=
+  DirectoryMode=
+  SloppyOptions=
+  LazyUnmount=
+  ForceUnmount=
+```
+
+## Automount Unit Settings
+
+Only one automount unit setting is currently available to transient units:
+
+```
+  Where=
+  DirectoryMode=
+✓ TimeoutIdleSec=
+```
+
+## Timer Unit Settings
+
+Most timer unit settings are available to transient units.
+
+```
+✓ OnCalendar=
+✓ OnActiveSec=
+✓ OnBootSec=
+✓ OnStartupSec=
+✓ OnUnitActiveSec=
+✓ OnUnitInactiveSec=
+  Persistent=
+✓ WakeSystem=
+✓ RemainAfterElapse=
+✓ AccuracySec=
+✓ RandomizedDelaySec=
+  Unit=
+```
+
+## Slice Unit Settings
+
+Slice units are fully supported as transient units, but they have no settings
+of their own beyond the generic unit and resource control settings.
+
+## Scope Unit Settings
+
+Scope units are fully supported as transient units (in fact they only exist as
+such), but they have no settings of their own beyond the generic unit and
+resource control settings.
+
+## Socket Unit Settings
+
+Socket units are currently not available at all as transient units:
+
+```
+  ListenStream=
+  ListenDatagram=
+  ListenSequentialPacket=
+  ListenFIFO=
+  ListenNetlink=
+  ListenSpecial=
+  ListenMessageQueue=
+  ListenUSBFunction=
+  SocketProtocol=
+  BindIPv6Only=
+  Backlog=
+  BindToDevice=
+  ExecStartPre=
+  ExecStartPost=
+  ExecStopPre=
+  ExecStopPost=
+  TimeoutSec=
+  SocketUser=
+  SocketGroup=
+  SocketMode=
+  DirectoryMode=
+  Accept=
+  Writable=
+  MaxConnections=
+  MaxConnectionsPerSource=
+  KeepAlive=
+  KeepAliveTimeSec=
+  KeepAliveIntervalSec=
+  KeepAliveProbes=
+  DeferAcceptSec=
+  NoDelay=
+  Priority=
+  ReceiveBuffer=
+  SendBuffer=
+  IPTOS=
+  IPTTL=
+  Mark=
+  PipeSize=
+  FreeBind=
+  Transparent=
+  Broadcast=
+  PassCredentials=
+  PassSecurity=
+  TCPCongestion=
+  ReusePort=
+  MessageQueueMaxMessages=
+  MessageQueueMessageSize=
+  RemoveOnStop=
+  Symlinks=
+  FileDescriptorName=
+  Service=
+  TriggerLimitIntervalSec=
+  TriggerLimitBurst=
+  SmackLabel=
+  SmackLabelIPIn=
+  SmackLabelIPOut=
+  SELinuxContextFromNet=
+```
+
+## Swap Unit Settings
+
+Swap units are currently not available at all as transient units:
+
+```
+  What=
+  Priority=
+  Options=
+  TimeoutSec=
+```
+
+## Path Unit Settings
+
+Path units are currently not available at all as transient units:
+
+```
+  PathExists=
+  PathExistsGlob=
+  PathChanged=
+  PathModified=
+  DirectoryNotEmpty=
+  Unit=
+  MakeDirectory=
+  DirectoryMode=
+```
+
+## Install Section
+
+The `[Install]` section is currently not available at all for transient units, and it probably doesn't even make sense.
+
+```
+  Alias=
+  WantedBy=
+  RequiredBy=
+  Also=
+  DefaultInstance=
+```
diff --git a/UIDS-GIDS.md b/UIDS-GIDS.md
new file mode 100644 (file)
index 0000000..d44d93d
--- /dev/null
@@ -0,0 +1,242 @@
+# Users, Groups, UIDs and GIDs on `systemd` systems
+
+Here's a summary of the requirements `systemd` (and Linux) make on UID/GID
+assignments and their ranges.
+
+Note that while in theory UIDs and GIDs are orthogonal concepts they really
+aren't IRL. With that in mind, when we discuss UIDs below it should be assumed
+that whatever we say about UIDs applies to GIDs in mostly the same way, and all
+the special assignments and ranges for UIDs always have mostly the same
+validity for GIDs too.
+
+## Special Linux UIDs
+
+In theory, the range of the C type `uid_t` is 32bit wide on Linux,
+i.e. 0…4294967295. However, four UIDs are special on Linux:
+
+1. 0 → The `root` super-user
+
+2. 65534 → The `nobody` UID, also called the "overflow" UID or similar. It's
+   where various subsystems map unmappable users to, for example NFS or user
+   namespacing. (The latter can be changed with a sysctl during runtime, but
+   that's not supported on `systemd`. If you do change it you void your
+   warranty.) Because Fedora is a bit confused the `nobody` user is called
+   `nfsnobody` there (and they have a different `nobody` user at UID 99). I
+   hope this will be corrected eventually though. (Also, some distributions
+   call the `nobody` group `nogroup`. I wish they didn't.)
+
+3. 4294967295, aka "32bit `(uid_t) -1`" → This UID is not a valid user ID, as
+   setresuid(), chown() and friends treat -1 as a special request to not change
+   the UID of the process/file. This UID is hence not available for assignment
+   to users in the user database.
+
+4. 65535, aka "16bit `(uid_t) -1`" → Once upon a time `uid_t` used to be 16bit, and
+   programs compiled for that would hence assume that `(uid_t) -1` is 65535. This
+   UID is hence not usable either.
+
+The `nss-systemd` glibc NSS module will synthesize user database records for
+the UIDs 0 and 65534 if the system user database doesn't list them. This means
+that any system where this module is enabled works to some minimal level
+without `/etc/passwd`.
+
+## Special Distribution UID ranges
+
+Distributions generally split the available UID range in two:
+
+1. 1…999 → System users. These are users that do not map to actual "human"
+   users, but are used as security identities for system daemons, to implement
+   privilege separation and run system daemons with minimal privileges.
+
+2. 1000…65533 and 65536…4294967294 → Everything else, i.e. regular (human) users.
+
+Note that most distributions allow changing the boundary between system and
+regular users, even during runtime as user configuration. Moreover, some older
+systems placed the boundary at 499/500, or even 99/100. In `systemd`, the
+boundary is configurable only during compilation time, as this should be a
+decision for distribution builders, not for users. Moreover, we strongly
+discourage downstreams to change the boundary from the upstream default of
+999/1000.
+
+Also note that programs such as `adduser` tend to allocate from a subset of the
+available regular user range only, usually 1000..60000. And it's also usually
+user-configurable, too.
+
+Note that systemd requires that system users and groups are resolvable without
+networking available — a requirement that is not made for regular users. This
+means regular users may be stored in remote LDAP or NIS databases, but system
+users may not (except when there's a consistent local cache kept, that is
+available during earliest boot, including in the initial RAM disk).
+
+## Special `systemd` GIDs
+
+`systemd` defines no special UIDs beyond what Linux already defines (see
+above). However, it does define some special group/GID assignments, which are
+primarily used for `systemd-udevd`'s device management. The precise list of the
+currently defined groups is found in this `sysusers.d` snippet:
+[basic.conf](https://raw.githubusercontent.com/systemd/systemd/master/sysusers.d/basic.conf.in)
+
+It's strongly recommended that downstream distributions include these groups in
+their default group databases.
+
+Note that the actual GID numbers assigned to these groups do not have to be
+constant beyond a specific system. There's one exception however: the `tty`
+group must have the GID 5. That's because it must be encoded in the `devpts`
+mount parameters during earliest boot, at a time where NSS lookups are not
+possible. (Note that the actual GID can be changed during `systemd` build time,
+but downstreams are strongly advised against doing that.)
+
+## Special `systemd` UID ranges
+
+`systemd` defines a number of special UID ranges:
+
+1. 61184…65519 → UIDs for dynamic users are allocated from this range (see the
+   `DynamicUser=` documentation in
+   [`systemd.exec(5)`](https://www.freedesktop.org/software/systemd/man/systemd.exec.html)). This
+   range has been chosen so that it is below the 16bit boundary (i.e. below
+   65535), in order to provide compatibility with container environments that
+   assign a 64K range of UIDs to containers using user namespacing. This range
+   is above the 60000 boundary, so that its allocations are unlikely to be
+   affected by `adduser` allocations (see above). And we leave some room
+   upwards for other purposes. (And if you wonder why precisely these numbers:
+   if you write them in hexadecimal, they might make more sense: 0xEF00 and
+   0xFFEF). The `nss-systemd` module will synthesize user records implicitly
+   for all currently allocated dynamic users from this range. Thus, NSS-based
+   user record resolving works correctly without those users being in
+   `/etc/passwd`.
+
+2. 524288…1879048191 → UID range for `systemd-nspawn`'s automatic allocation of
+   per-container UID ranges. When the `--private-users=pick` switch is used (or
+   `-U`) then it will automatically find a so far unused 16bit subrange of this
+   range and assign it to the container. The range is picked so that the upper
+   16bit of the 32bit UIDs are constant for all users of the container, while
+   the lower 16bit directly encode the 65536 UIDs assigned to the
+   container. This mode of allocation means that the upper 16bit of any UID
+   assigned to a container are kind of a "container ID", while the lower 16bit
+   directly expose the container's own UID numbers. If you wonder why precisely
+   these numbers, consider them in hexadecimal: 0x00080000…0x6FFFFFFF. This
+   range is above the 16bit boundary. Moreover it's below the 31bit boundary,
+   as some broken code (specifically: the kernel's `devpts` file system)
+   erroneously considers UIDs signed integers, and hence can't deal with values
+   above 2^31. The `nss-mymachines` glibc NSS module will synthesize user
+   database records for all UIDs assigned to a running container from this
+   range.
+
+Note for both allocation ranges: when an UID allocation takes place NSS is
+checked for collisions first, and a different UID is picked if an entry is
+found. Thus, the user database is used as synchronization mechanism to ensure
+exclusive ownership of UIDs and UID ranges. To ensure compatibility with other
+subsystems allocating from the same ranges it is hence essential that they
+ensure that whatever they pick shows up in the user/group databases, either by
+providing an NSS module, or by adding entries directly to `/etc/passwd` and
+`/etc/group`. For performance reasons, do note that `systemd-nspawn` will only
+do an NSS check for the first UID of the range it allocates, not all 65536 of
+them. Also note that while the allocation logic is operating, the glibc
+`lckpwdf()` user database lock is taken, in order to make this logic race-free.
+
+## Figuring out the system's UID boundaries
+
+The most important boundaries of the local system may be queried with
+`pkg-config`:
+
+```
+$ pkg-config --variable=systemuidmax systemd
+999
+$ pkg-config --variable=dynamicuidmin systemd
+61184
+$ pkg-config --variable=dynamicuidmax systemd
+65519
+$ pkg-config --variable=containeruidbasemin systemd
+524288
+$ pkg-config --variable=containeruidbasemax systemd
+1878982656
+```
+
+(Note that the latter encodes the maximum UID *base* `systemd-nspawn` might
+pick — given that 64K UIDs are assigned to each container according to this
+allocation logic, the maximum UID used for this range is hence
+1878982656+65535=1879048191.)
+
+Note that systemd does not make any of these values runtime-configurable. All
+these boundaries are chosen during build time. That said, the system UID/GID
+boundary is traditionally configured in /etc/login.defs, though systemd won't
+look there during runtime.
+
+## Considerations for container managers
+
+If you hack on a container manager, and wonder how and how many UIDs best to
+assign to your containers, here are a few recommendations:
+
+1. Definitely, don't assign less than 65536 UIDs/GIDs. After all the `nobody`
+user has magic properties, and hence should be available in your container, and
+given that it's assigned the UID 65534, you should really cover the full 16bit
+range in your container. Note that systemd will — as mentioned — synthesize
+user records for the `nobody` user, and assumes its availability in various
+other parts of its codebase, too, hence assigning fewer users means you lose
+compatibility with running systemd code inside your container. And most likely
+other packages make similar restrictions.
+
+2. While it's fine to assign more than 65536 UIDs/GIDs to a container, there's
+most likely not much value in doing so, as Linux distributions won't use the
+higher ranges by default (as mentioned neither `adduser` nor `systemd`'s
+dynamic user concept allocate from above the 16bit range). Unless you actively
+care for nested containers, it's hence probably a good idea to allocate exactly
+65536 UIDs per container, and neither less nor more. A pretty side-effect is
+that by doing so, you expose the same number of UIDs per container as Linux 2.2
+supported for the whole system, back in the days.
+
+3. Consider allocating UID ranges for containers so that the first UID you
+assign has the lower 16bits all set to zero. That way, the upper 16bits become
+a container ID of some kind, while the lower 16bits directly encode the
+internal container UID. This is the way `systemd-nspawn` allocates UID ranges
+(see above). Following this allocation logic ensures best compability with
+`systemd-nspawn` and all other container managers following the scheme, as it
+is sufficient then to check NSS for the first UID you pick regarding conflicts,
+as that's what they do, too. Moreover, it makes `chown()`ing container file
+system trees nicely robust to interruptions: as the external UID encodes the
+internal UID in a fixed way, it's very easy to adjust the container's base UID
+without the need to know the original base UID: to change the container base,
+just mask away the upper 16bit, and insert the upper 16bit of the new container
+base instead. Here are the easy conversions to derive the internal UID, the
+external UID, and the container base UID from each other:
+
+    ```
+    INTERNAL_UID = EXTERNAL_UID & 0x0000FFFF
+    CONTAINER_BASE_UID = EXTERNAL_UID & 0xFFFF0000
+    EXTERNAL_UID = INTERNAL_UID | CONTAINER_BASE_UID
+    ```
+
+4. When picking a UID range for containers, make sure to check NSS first, with
+a simple `getpwuid()` call: if there's already a user record for the first UID
+you want to pick, then it's already in use: pick a different one. Wrap that
+call in a `lckpwdf()` + `ulckpwdf()` pair, to make allocation
+race-free. Provide an NSS module that makes all UIDs you end up taking show up
+in the user database, and make sure that the NSS module returns up-to-date
+information before you release the lock, so that other system components can
+safely use the NSS user database as allocation check, too. Note that if you
+follow this scheme no changes to `/etc/passwd` need to be made, thus minimizing
+the artifacts the container manager persistently leaves in the system.
+
+## Summary
+
+|               UID/GID | Purpose               | Defined By    | Listed in                     |
+|-----------------------|-----------------------|---------------|-------------------------------|
+|                     0 | `root` user           | Linux         | `/etc/passwd` + `nss-systemd` |
+|                   1…4 | System users          | Distributions | `/etc/passwd`                 |
+|                     5 | `tty` group           | `systemd`     | `/etc/passwd`                 |
+|                 6…999 | System users          | Distributions | `/etc/passwd`                 |
+|            1000…60000 | Regular users         | Distributions | `/etc/passwd` + LDAP/NIS/…    |
+|           60001…61183 | Unused                |               |                               |
+|           61184…65519 | Dynamic service users | `systemd`     | `nss-systemd`                 |
+|           65520…65533 | Unused                |               |                               |
+|                 65534 | `nobody` user         | Linux         | `/etc/passwd` + `nss-systemd` |
+|                 65535 | 16bit `(uid_t) -1`    | Linux         |                               |
+|          65536…524287 | Unused                |               |                               |
+|     524288…1879048191 | Container UID ranges  | `systemd`     | `nss-mymachines`              |
+| 1879048192…4294967294 | Unused                |               |                               |
+|            4294967295 | 32bit `(uid_t) -1`    | Linux         |                               |
+
+Note that "Unused" in the table above doesn't meant that these ranges are
+really unused. It just means that these ranges have no well-established
+pre-defined purposes between Linux, generic low-level distributions and
+`systemd`. There might very well be other packages that allocate from these
+ranges.
index 3e61e6f..69f9703 100644 (file)
@@ -1,3 +1,20 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
+# Copyright 2017 Zbigniew Jędrzejewski-Szmek
+#
+# 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.
+#
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
 in_files = '''
         systemd.bg.catalog
         systemd.be.catalog
@@ -27,3 +44,7 @@ foreach file : in_files
                 install : true,
                 install_dir : catalogdir)
 endforeach
+
+meson.add_install_script('sh', '-c',
+                         'test -n "$DESTDIR" || @0@/journalctl --update-catalog'
+                         .format(rootbindir))
index 5b1cdf2..28de086 100644 (file)
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  Copyright 2012 Lennart Poettering
index 764432c..dc5f9b7 100644 (file)
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  Copyright 2012 Lennart Poettering
index 4b6cf11..202b192 100644 (file)
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  Copyright 2012 Lennart Poettering
index 1efa021..118fe86 100644 (file)
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  Copyright 2012 Lennart Poettering
@@ -199,7 +201,7 @@ Subject: System shutdown initiated
 Defined-By: systemd
 Support: %SUPPORT_URL%
 
-Systemd shutdown has been initiated. The shutdown has now begun and
+System shutdown has been initiated. The shutdown has now begun and
 all system services are terminated and all file systems unmounted.
 
 -- 7d4958e842da4a758f6c1cdc7b36dcc5
@@ -357,3 +359,20 @@ Defined-By: systemd
 Support: %SUPPORT_URL%
 
 The unit @UNIT@ completed and consumed the indicated resources.
+
+-- 50876a9db00f4c40bde1a2ad381c3a1b
+Subject: The system is configured in a way that might cause problems
+Defined-By: systemd
+Support: %SUPPORT_URL%
+
+The following "tags" are possible:
+- "split-usr" — /usr is a separate file system and was not mounted when systemd
+  was booted
+- "cgroups-missing" — the kernel was compiled without cgroup support or access
+  to expected interface files is resticted
+- "var-run-bad" — /var/run is not a symlink to /run
+- "overflowuid-not-65534" — the kernel user ID used for "unknown" users (with
+  NFS or user namespaces) is not 65534
+- "overflowgid-not-65534" — the kernel group ID used for "unknown" users (with
+  NFS or user namespaces) is not 65534
+Current system is tagged as @TAINT@.
index a5570f4..69446fb 100644 (file)
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  Copyright 2012 Lennart Poettering
index b69a8be..8fdedaf 100644 (file)
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  Copyright 2012 Lennart Poettering
index c4b1a81..36c8714 100644 (file)
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  Copyright 2012 Lennart Poettering
@@ -329,3 +331,18 @@ Documentation: man:systemd-resolved.service(8)
 Une ancre de confiance DNSSEC a été révoquée. Une nouvelle ancre de
 confiance doit être configurée, ou le système d'exploitation a besoin
 d'être mis à jour, pour fournir une version à jour de l'ancre de confiance.
+
+-- 5eb03494b6584870a536b337290809b3
+Subject: Le redémarrage automatique d'une unité (unit) a été planifié
+Defined-By: systemd
+Support: %SUPPORT_URL%
+
+Le redémarrage automatique de l'unité (unit) @UNIT@ a été planifié, en
+raison de sa configuration avec le paramètre Restart=.
+
+-- ae8f7b866b0347b9af31fe1c80b127c0
+Subject: Ressources consommées durant l'éxécution de l'unité (unit)
+Defined-By: systemd
+Support: %SUPPORT_URL%
+
+L'unité (unit) @UNIT@ s'est arrêtée et a consommé les ressources indiquées.
index d30e955..f6e238e 100644 (file)
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  Copyright 2012 Lennart Poettering
index 23c1cd4..9f5e878 100644 (file)
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  Copyright 2012 Lennart Poettering
index 208ac2b..df1e225 100644 (file)
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  Copyright 2013 Daniele Medri
index 4e8d700..e578180 100644 (file)
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  Copyright 2012 Lennart Poettering
index 278b699..3641db2 100644 (file)
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  Copyright 2012 Lennart Poettering
index 192fd33..6a30dd3 100644 (file)
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  Copyright 2012 Lennart Poettering
index 367ed89..25ee6ac 100644 (file)
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  Copyright 2012 Lennart Poettering
@@ -377,3 +379,20 @@ Documentation: man:systemd-resolved.service(8)
 
 Открытый ключ (trust ahcnor) DNSSEC был отозван. Необходимо настроить новый
 открытый ключ, либо обновить систему, чтобы получить обновленный открытый ключ.
+
+# Subject: Automatic restarting of a unit has been scheduled
+-- 5eb03494b6584870a536b337290809b3
+Subject: Назначен автоматический перезапуск юнита
+Defined-By: systemd
+Support: %SUPPORT_URL%
+
+Назначен автоматический перезапуск юнита @UNIT@, так как для него был задан 
+параметр Restart=.
+
+# Subject: Resources consumed by unit runtime
+-- ae8f7b866b0347b9af31fe1c80b127c0
+Subject: Потребленные юнитом ресурсы
+Defined-By: systemd
+Support: %SUPPORT_URL%
+
+Юнит @UNIT@ завершен. Приводится статистика по потребленным им ресурсам.
index 674eb55..1d494ff 100644 (file)
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  Copyright 2012 Lennart Poettering
index 78a8a8c..92e3220 100644 (file)
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  Copyright 2012 Lennart Poettering
index d262b88..66db58d 100644 (file)
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  Copyright 2012 Lennart Poettering
diff --git a/coccinelle/const-strlen.cocci b/coccinelle/const-strlen.cocci
new file mode 100644 (file)
index 0000000..38bf9b1
--- /dev/null
@@ -0,0 +1,10 @@
+@@
+constant s;
+@@
+- sizeof(s)-1
++ STRLEN(s)
+@@
+constant s;
+@@
+- strlen(s)
++ STRLEN(s)
diff --git a/coccinelle/empty-to-null.cocci b/coccinelle/empty-to-null.cocci
new file mode 100644 (file)
index 0000000..fbc75b9
--- /dev/null
@@ -0,0 +1,5 @@
+@@
+expression s;
+@@
+- isempty(s) ? NULL : s
++ empty_to_null(s)
diff --git a/coccinelle/equals-null.cocci b/coccinelle/equals-null.cocci
new file mode 100644 (file)
index 0000000..957d828
--- /dev/null
@@ -0,0 +1,14 @@
+@@
+expression e;
+statement s;
+@@
+- if (e == NULL)
++ if (!e)
+s
+@@
+expression e;
+statement s;
+@@
+- if (e != NULL)
++ if (e)
+s
index f5ddd3d..12d5475 100644 (file)
@@ -1,35 +1,54 @@
 @@
 expression e;
-identifier n1, n2, n3, n4, n5, n6;
-statement s;
+constant n0, n1, n2, n3, n4, n5, n6, n7, n8, n9;
 @@
-- e == n1 || e == n2 || e == n3 || e == n4 || e == n5 || e == n6
-+ IN_SET(e, n1, n2, n3, n4, n5, n6)
+- e == n0 || e == n1 || e == n2 || e == n3 || e == n4 || e == n5 || e == n6 || e == n7 || e == n8 || e == n9
++ IN_SET(e, n0, n1, n2, n3, n4, n5, n6, n7, n8, n9)
 @@
 expression e;
-identifier n1, n2, n3, n4, n5;
-statement s;
+constant n0, n1, n2, n3, n4, n5, n6, n7, n8;
 @@
-- e == n1 || e == n2 || e == n3 || e == n4 || e == n5
-+ IN_SET(e, n1, n2, n3, n4, n5)
+- e == n0 || e == n1 || e == n2 || e == n3 || e == n4 || e == n5 || e == n6 || e == n7 || e == n8
++ IN_SET(e, n0, n1, n2, n3, n4, n5, n6, n7, n8)
 @@
 expression e;
-identifier n1, n2, n3, n4;
-statement s;
+constant n0, n1, n2, n3, n4, n5, n6, n7;
 @@
-- e == n1 || e == n2 || e == n3 || e == n4
-+ IN_SET(e, n1, n2, n3, n4)
+- e == n0 || e == n1 || e == n2 || e == n3 || e == n4 || e == n5 || e == n6 || e == n7
++ IN_SET(e, n0, n1, n2, n3, n4, n5, n6, n7)
 @@
 expression e;
-identifier n1, n2, n3;
-statement s;
+constant n0, n1, n2, n3, n4, n5, n6;
 @@
-- e == n1 || e == n2 || e == n3
-+ IN_SET(e, n1, n2, n3)
+- e == n0 || e == n1 || e == n2 || e == n3 || e == n4 || e == n5 || e == n6
++ IN_SET(e, n0, n1, n2, n3, n4, n5, n6)
 @@
 expression e;
-identifier n, p;
-statement s;
+constant n0, n1, n2, n3, n4, n5;
 @@
-- e == n || e == p
-+ IN_SET(e, n, p)
+- e == n0 || e == n1 || e == n2 || e == n3 || e == n4 || e == n5
++ IN_SET(e, n0, n1, n2, n3, n4, n5)
+@@
+expression e;
+constant n0, n1, n2, n3, n4;
+@@
+- e == n0 || e == n1 || e == n2 || e == n3 || e == n4
++ IN_SET(e, n0, n1, n2, n3, n4)
+@@
+expression e;
+constant n0, n1, n2, n3;
+@@
+- e == n0 || e == n1 || e == n2 || e == n3
++ IN_SET(e, n0, n1, n2, n3)
+@@
+expression e;
+constant n0, n1, n2;
+@@
+- e == n0 || e == n1 || e == n2
++ IN_SET(e, n0, n1, n2)
+@@
+expression e;
+constant n0, n1;
+@@
+- e == n0 || e == n1
++ IN_SET(e, n0, n1)
diff --git a/coccinelle/isempty.cocci b/coccinelle/isempty.cocci
new file mode 100644 (file)
index 0000000..1374ee4
--- /dev/null
@@ -0,0 +1,15 @@
+@@
+expression s;
+@@
+- strv_length(s) == 0
++ strv_isempty(s)
+@@
+expression s;
+@@
+- strlen(s) == 0
++ isempty(s)
+@@
+expression s;
+@@
+- strlen_ptr(s) == 0
++ isempty(s)
index e6bcf47..7cf9850 100644 (file)
 @@
 expression e;
-identifier n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14, n15, n16, n17, n18, n19, n20;
-statement s;
-@@
-- e != n0 && e != n1 && e != n2 && e != n3 && e != n4 && e != n5 && e != n6 && e != n7 && e != n8 && e != n9 && e != n10 && e != n11 && e != n12 && e != n13 && e != n14 && e != n15 && e != n16 && e != n17 && e != n18 && e != n19 && e != n20
-+ !IN_SET(e, n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14, n15, n16, n17, n18, n19, n20)
-@@
-expression e;
-identifier n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14, n15, n16, n17, n18, n19;
-statement s;
-@@
-- e != n0 && e != n1 && e != n2 && e != n3 && e != n4 && e != n5 && e != n6 && e != n7 && e != n8 && e != n9 && e != n10 && e != n11 && e != n12 && e != n13 && e != n14 && e != n15 && e != n16 && e != n17 && e != n18 && e != n19
-+ !IN_SET(e, n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14, n15, n16, n17, n18, n19)
-@@
-expression e;
-identifier n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14, n15, n16, n17, n18;
-statement s;
-@@
-- e != n0 && e != n1 && e != n2 && e != n3 && e != n4 && e != n5 && e != n6 && e != n7 && e != n8 && e != n9 && e != n10 && e != n11 && e != n12 && e != n13 && e != n14 && e != n15 && e != n16 && e != n17 && e != n18
-+ !IN_SET(e, n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14, n15, n16, n17, n18)
-@@
-expression e;
-identifier n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14, n15, n16, n17;
-statement s;
-@@
-- e != n0 && e != n1 && e != n2 && e != n3 && e != n4 && e != n5 && e != n6 && e != n7 && e != n8 && e != n9 && e != n10 && e != n11 && e != n12 && e != n13 && e != n14 && e != n15 && e != n16 && e != n17
-+ !IN_SET(e, n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14, n15, n16, n17)
-@@
-expression e;
-identifier n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14, n15, n16;
-statement s;
-@@
-- e != n0 && e != n1 && e != n2 && e != n3 && e != n4 && e != n5 && e != n6 && e != n7 && e != n8 && e != n9 && e != n10 && e != n11 && e != n12 && e != n13 && e != n14 && e != n15 && e != n16
-+ !IN_SET(e, n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14, n15, n16)
-@@
-expression e;
-identifier n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14, n15;
-statement s;
-@@
-- e != n0 && e != n1 && e != n2 && e != n3 && e != n4 && e != n5 && e != n6 && e != n7 && e != n8 && e != n9 && e != n10 && e != n11 && e != n12 && e != n13 && e != n14 && e != n15
-+ !IN_SET(e, n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14, n15)
-@@
-expression e;
-identifier n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14;
-statement s;
-@@
-- e != n0 && e != n1 && e != n2 && e != n3 && e != n4 && e != n5 && e != n6 && e != n7 && e != n8 && e != n9 && e != n10 && e != n11 && e != n12 && e != n13 && e != n14
-+ !IN_SET(e, n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14)
-@@
-expression e;
-identifier n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13;
-statement s;
-@@
-- e != n0 && e != n1 && e != n2 && e != n3 && e != n4 && e != n5 && e != n6 && e != n7 && e != n8 && e != n9 && e != n10 && e != n11 && e != n12 && e != n13
-+ !IN_SET(e, n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13)
-@@
-expression e;
-identifier n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12;
-statement s;
-@@
-- e != n0 && e != n1 && e != n2 && e != n3 && e != n4 && e != n5 && e != n6 && e != n7 && e != n8 && e != n9 && e != n10 && e != n11 && e != n12
-+ !IN_SET(e, n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12)
-@@
-expression e;
-identifier n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11;
-statement s;
-@@
-- e != n0 && e != n1 && e != n2 && e != n3 && e != n4 && e != n5 && e != n6 && e != n7 && e != n8 && e != n9 && e != n10 && e != n11
-+ !IN_SET(e, n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11)
-@@
-expression e;
-identifier n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10;
-statement s;
-@@
-- e != n0 && e != n1 && e != n2 && e != n3 && e != n4 && e != n5 && e != n6 && e != n7 && e != n8 && e != n9 && e != n10
-+ !IN_SET(e, n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10)
-@@
-expression e;
-identifier n0, n1, n2, n3, n4, n5, n6, n7, n8, n9;
-statement s;
+constant n0, n1, n2, n3, n4, n5, n6, n7, n8, n9;
 @@
 - e != n0 && e != n1 && e != n2 && e != n3 && e != n4 && e != n5 && e != n6 && e != n7 && e != n8 && e != n9
 + !IN_SET(e, n0, n1, n2, n3, n4, n5, n6, n7, n8, n9)
 @@
 expression e;
-identifier n0, n1, n2, n3, n4, n5, n6, n7, n8;
-statement s;
+constant n0, n1, n2, n3, n4, n5, n6, n7, n8;
 @@
 - e != n0 && e != n1 && e != n2 && e != n3 && e != n4 && e != n5 && e != n6 && e != n7 && e != n8
 + !IN_SET(e, n0, n1, n2, n3, n4, n5, n6, n7, n8)
 @@
 expression e;
-identifier n0, n1, n2, n3, n4, n5, n6, n7;
-statement s;
+constant n0, n1, n2, n3, n4, n5, n6, n7;
 @@
 - e != n0 && e != n1 && e != n2 && e != n3 && e != n4 && e != n5 && e != n6 && e != n7
 + !IN_SET(e, n0, n1, n2, n3, n4, n5, n6, n7)
 @@
 expression e;
-identifier n0, n1, n2, n3, n4, n5, n6;
-statement s;
+constant n0, n1, n2, n3, n4, n5, n6;
 @@
 - e != n0 && e != n1 && e != n2 && e != n3 && e != n4 && e != n5 && e != n6
 + !IN_SET(e, n0, n1, n2, n3, n4, n5, n6)
 @@
 expression e;
-identifier n0, n1, n2, n3, n4, n5;
-statement s;
+constant n0, n1, n2, n3, n4, n5;
 @@
 - e != n0 && e != n1 && e != n2 && e != n3 && e != n4 && e != n5
 + !IN_SET(e, n0, n1, n2, n3, n4, n5)
 @@
 expression e;
-identifier n1, n2, n3, n4, n5;
-statement s;
-@@
-- e != n1 && e != n2 && e != n3 && e != n4 && e != n5
-+ !IN_SET(e, n1, n2, n3, n4, n5)
-@@
-expression e;
-identifier n1, n2, n3, n4;
-statement s;
+constant n0, n1, n2, n3, n4;
 @@
-- e != n1 && e != n2 && e != n3 && e != n4
-+ !IN_SET(e, n1, n2, n3, n4)
+- e != n0 && e != n1 && e != n2 && e != n3 && e != n4
++ !IN_SET(e, n0, n1, n2, n3, n4)
 @@
 expression e;
-identifier n1, n2, n3, n4;
-statement s;
+constant n0, n1, n2, n3;
 @@
-- e != n1 && e != n2 && e != n3 && e != n4
-+ !IN_SET(e, n1, n2, n3, n4)
+- e != n0 && e != n1 && e != n2 && e != n3
++ !IN_SET(e, n0, n1, n2, n3)
 @@
 expression e;
-identifier n1, n2, n3;
-statement s;
+constant n0, n1, n2;
 @@
-- e != n1 && e != n2 && e != n3
-+ !IN_SET(e, n1, n2, n3)
+- e != n0 && e != n1 && e != n2
++ !IN_SET(e, n0, n1, n2)
 @@
 expression e;
-identifier n, p;
-statement s;
+constant n0, n1;
 @@
-- e != n && e != p
-+ !IN_SET(e, n, p)
+- e != n0 && e != n1
++ !IN_SET(e, n0, n1)
diff --git a/coccinelle/run-coccinelle.sh b/coccinelle/run-coccinelle.sh
new file mode 100755 (executable)
index 0000000..1373b53
--- /dev/null
@@ -0,0 +1,11 @@
+#!/bin/bash -e
+
+for SCRIPT in ${@-*.cocci} ; do
+        [ "$SCRIPT" = "empty-if.cocci" ] && continue
+        echo "--x-- Processing $SCRIPT --x--"
+        TMPFILE=`mktemp`
+        spatch --sp-file $SCRIPT --dir $(pwd)/.. 2> "$TMPFILE" || cat "$TMPFILE"
+        rm "$TMPFILE"
+        echo "--x-- Processed $SCRIPT --x--"
+        echo ""
+done
index 115ad39..5c1aa4c 100644 (file)
@@ -1,3 +1,20 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
+# Copyright 2017 Zbigniew Jędrzejewski-Szmek
+#
+# 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.
+#
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
 file = configure_file(
         input : 'README.in',
         output : 'README',
index 60acf49..fc14c04 100644 (file)
@@ -1,3 +1,20 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
+# Copyright 2017 Zbigniew Jędrzejewski-Szmek
+#
+# 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.
+#
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
 file = configure_file(
         input : 'README.in',
         output : 'README',
index 1eec297..20d168c 100644 (file)
@@ -1329,7 +1329,7 @@ OUI:0001B8*
  ID_OUI_FROM_DATABASE=Netsensity, Inc.
 
 OUI:0001B9*
- ID_OUI_FROM_DATABASE=SKF Condition Monitoring
+ ID_OUI_FROM_DATABASE=SKF (U.K.) Limited
 
 OUI:0001BA*
  ID_OUI_FROM_DATABASE=IC-Net, Inc.
@@ -2763,7 +2763,7 @@ OUI:000396*
  ID_OUI_FROM_DATABASE=EZ Cast Co., Ltd.
 
 OUI:000397*
- ID_OUI_FROM_DATABASE=Watchfront Limited
+ ID_OUI_FROM_DATABASE=FireBrick Limited
 
 OUI:000398*
  ID_OUI_FROM_DATABASE=WISI
@@ -6480,7 +6480,7 @@ OUI:000888*
  ID_OUI_FROM_DATABASE=OULLIM Information Technology Inc,.
 
 OUI:000889*
- ID_OUI_FROM_DATABASE=Echostar Technologies Corp
+ ID_OUI_FROM_DATABASE=Dish Technologies Corp
 
 OUI:00088A*
  ID_OUI_FROM_DATABASE=Minds@Work
@@ -14916,7 +14916,7 @@ OUI:001385*
  ID_OUI_FROM_DATABASE=Add-On Technology Co., LTD.
 
 OUI:001386*
- ID_OUI_FROM_DATABASE=ABB Inc./Totalflow
+ ID_OUI_FROM_DATABASE=ABB Inc/Totalflow
 
 OUI:001387*
  ID_OUI_FROM_DATABASE=27M Technologies AB
@@ -21906,10 +21906,10 @@ OUI:001BD7*
  ID_OUI_FROM_DATABASE=Cisco SPVTG
 
 OUI:001BD8*
- ID_OUI_FROM_DATABASE=DVTel LTD
+ ID_OUI_FROM_DATABASE=FLIR Systems Inc
 
 OUI:001BD9*
- ID_OUI_FROM_DATABASE=Edgewater Computer Systems
+ ID_OUI_FROM_DATABASE=Edgewater Wireless Systems Inc
 
 OUI:001BDA*
  ID_OUI_FROM_DATABASE=UTStarcom Inc
@@ -28686,7 +28686,7 @@ OUI:0024AE*
  ID_OUI_FROM_DATABASE=Morpho
 
 OUI:0024AF*
- ID_OUI_FROM_DATABASE=Echostar Technologies Corp
+ ID_OUI_FROM_DATABASE=Dish Technologies Corp
 
 OUI:0024B0*
  ID_OUI_FROM_DATABASE=ESAB AB
@@ -30590,6 +30590,9 @@ OUI:002D76*
 OUI:002EC7*
  ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
 
+OUI:002FD9*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
 OUI:003000*
  ID_OUI_FROM_DATABASE=ALLWELL TECHNOLOGY CORP.
 
@@ -31427,12 +31430,18 @@ OUI:003A9D*
 OUI:003AAF*
  ID_OUI_FROM_DATABASE=BlueBit Ltd.
 
+OUI:003C10*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
 OUI:003CC5*
  ID_OUI_FROM_DATABASE=WONWOO Engineering Co., Ltd
 
 OUI:003D41*
  ID_OUI_FROM_DATABASE=Hatteland Computer AS
 
+OUI:003DE8*
+ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
+
 OUI:003EE1*
  ID_OUI_FROM_DATABASE=Apple, Inc.
 
@@ -33878,6 +33887,9 @@ OUI:0070B0*
 OUI:0070B3*
  ID_OUI_FROM_DATABASE=DATA RECALL LTD.
 
+OUI:007147*
+ ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
+
 OUI:0071C2*
  ID_OUI_FROM_DATABASE=PEGATRON CORPORATION
 
@@ -36198,7 +36210,7 @@ OUI:00A0D4*
  ID_OUI_FROM_DATABASE=RADIOLAN,  INC.
 
 OUI:00A0D5*
- ID_OUI_FROM_DATABASE=SIERRA WIRELESS INC.
+ ID_OUI_FROM_DATABASE=Sierra Wireless Inc
 
 OUI:00A0D6*
  ID_OUI_FROM_DATABASE=SBE, Inc.
@@ -36551,6 +36563,9 @@ OUI:00BD3A*
 OUI:00BD82*
  ID_OUI_FROM_DATABASE=Shenzhen YOUHUA Technology Co., Ltd
 
+OUI:00BE75*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
 OUI:00BE9E*
  ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
 
@@ -36560,6 +36575,9 @@ OUI:00BF15*
 OUI:00BF61*
  ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
 
+OUI:00BF77*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
 OUI:00C000*
  ID_OUI_FROM_DATABASE=LANOPTICS, LTD.
 
@@ -37989,7 +38007,7 @@ OUI:00D0CD*
  ID_OUI_FROM_DATABASE=ATAN TECHNOLOGY INC.
 
 OUI:00D0CE*
- ID_OUI_FROM_DATABASE=ASYST ELECTRONIC
+ ID_OUI_FROM_DATABASE=iSystem Labs
 
 OUI:00D0CF*
  ID_OUI_FROM_DATABASE=MORETON BAY
@@ -39143,6 +39161,9 @@ OUI:0403D6*
 OUI:0404EA*
  ID_OUI_FROM_DATABASE=Valens Semiconductor Ltd.
 
+OUI:040973*
+ ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise
+
 OUI:040A83*
  ID_OUI_FROM_DATABASE=Alcatel-Lucent
 
@@ -39272,6 +39293,9 @@ OUI:044E06*
 OUI:044E5A*
  ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
 
+OUI:044EAF*
+ ID_OUI_FROM_DATABASE=LG Innotek
+
 OUI:044F17*
  ID_OUI_FROM_DATABASE=HUMAX Co., Ltd.
 
@@ -39425,6 +39449,9 @@ OUI:04766E*
 OUI:047863*
  ID_OUI_FROM_DATABASE=Shanghai MXCHIP Information Technology Co., Ltd.
 
+OUI:047970*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
 OUI:047D50*
  ID_OUI_FROM_DATABASE=Shenzhen Kang Ying Technology Co.Ltd.
 
@@ -39512,6 +39539,9 @@ OUI:04A3F3*
 OUI:04A82A*
  ID_OUI_FROM_DATABASE=Nokia Corporation
 
+OUI:04AC44*
+ ID_OUI_FROM_DATABASE=Holtek Semiconductor Inc.
+
 OUI:04B0E7*
  ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
 
@@ -39563,6 +39593,9 @@ OUI:04C1B9*
 OUI:04C23E*
  ID_OUI_FROM_DATABASE=HTC Corporation
 
+OUI:04C241*
+ ID_OUI_FROM_DATABASE=Nokia
+
 OUI:04C5A4*
  ID_OUI_FROM_DATABASE=Cisco Systems, Inc
 
@@ -39573,7 +39606,7 @@ OUI:04C991*
  ID_OUI_FROM_DATABASE=Phistek INC.
 
 OUI:04C9D9*
- ID_OUI_FROM_DATABASE=Echostar Technologies Corp
+ ID_OUI_FROM_DATABASE=Dish Technologies Corp
 
 OUI:04CB1D*
  ID_OUI_FROM_DATABASE=Traka plc
@@ -39584,6 +39617,9 @@ OUI:04CE14*
 OUI:04CF25*
  ID_OUI_FROM_DATABASE=MANYCOLORS, INC.
 
+OUI:04D13A*
+ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd
+
 OUI:04D3CF*
  ID_OUI_FROM_DATABASE=Apple, Inc.
 
@@ -39647,6 +39683,9 @@ OUI:04E676*
 OUI:04E9E5*
  ID_OUI_FROM_DATABASE=PJRC.COM, LLC
 
+OUI:04ECBB*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
 OUI:04EE91*
  ID_OUI_FROM_DATABASE=x-fabric GmbH
 
@@ -40187,6 +40226,9 @@ OUI:08184C*
 OUI:0819A6*
  ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
 
+OUI:081DC4*
+ ID_OUI_FROM_DATABASE=Thermo Fisher Scientific Messtechnik GmbH
+
 OUI:081DFB*
  ID_OUI_FROM_DATABASE=Shanghai Mexon Communication Technology Co.,Ltd
 
@@ -40553,6 +40595,9 @@ OUI:08E5DA*
 OUI:08E672*
  ID_OUI_FROM_DATABASE=JEBSEE ELECTRONICS CO.,LTD.
 
+OUI:08E689*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
 OUI:08E84F*
  ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
 
@@ -40667,6 +40712,9 @@ OUI:0C0400*
 OUI:0C0535*
  ID_OUI_FROM_DATABASE=Juniper Systems
 
+OUI:0C08B4*
+ ID_OUI_FROM_DATABASE=HUMAX Co., Ltd.
+
 OUI:0C1105*
  ID_OUI_FROM_DATABASE=Ringslink (Xiamen) Network Communication Technologies Co., Ltd
 
@@ -40709,6 +40757,9 @@ OUI:0C1DC2*
 OUI:0C2026*
  ID_OUI_FROM_DATABASE=noax Technologies AG
 
+OUI:0C2369*
+ ID_OUI_FROM_DATABASE=Honeywell SPS
+
 OUI:0C2576*
  ID_OUI_FROM_DATABASE=LONGCHEER TELECOMMUNICATION LIMITED
 
@@ -40754,6 +40805,9 @@ OUI:0C3E9F*
 OUI:0C413E*
  ID_OUI_FROM_DATABASE=Microsoft Corporation
 
+OUI:0C41E9*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
 OUI:0C45BA*
  ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
 
@@ -40793,6 +40847,9 @@ OUI:0C51F7*
 OUI:0C5203*
  ID_OUI_FROM_DATABASE=AGM GROUP LIMITED
 
+OUI:0C5415*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
 OUI:0C54A5*
  ID_OUI_FROM_DATABASE=PEGATRON CORPORATION
 
@@ -40835,12 +40892,18 @@ OUI:0C6127*
 OUI:0C61CF*
  ID_OUI_FROM_DATABASE=Texas Instruments
 
+OUI:0C62A6*
+ ID_OUI_FROM_DATABASE=Hui Zhou Gaoshengda Technology Co.,LTD
+
 OUI:0C63FC*
  ID_OUI_FROM_DATABASE=Nanjing Signway Technology Co., Ltd
 
 OUI:0C6803*
  ID_OUI_FROM_DATABASE=Cisco Systems, Inc
 
+OUI:0C6ABC*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
 OUI:0C6AE6*
  ID_OUI_FROM_DATABASE=Stanley Security Solutions
 
@@ -40850,6 +40913,9 @@ OUI:0C6E4F*
 OUI:0C6F9C*
  ID_OUI_FROM_DATABASE=Shaw Communications Inc.
 
+OUI:0C704A*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
 OUI:0C715D*
  ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
 
@@ -40913,6 +40979,9 @@ OUI:0C8910*
 OUI:0C8A87*
  ID_OUI_FROM_DATABASE=AgLogica Holdings, Inc
 
+OUI:0C8BD3*
+ ID_OUI_FROM_DATABASE=ITEL MOBILE LIMITED
+
 OUI:0C8BFD*
  ID_OUI_FROM_DATABASE=Intel Corporate
 
@@ -40979,6 +41048,9 @@ OUI:0CA8A7*
 OUI:0CAC05*
  ID_OUI_FROM_DATABASE=Unitend Technologies Inc.
 
+OUI:0CAE7D*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
 OUI:0CAF5A*
  ID_OUI_FROM_DATABASE=GENUS POWER INFRASTRUCTURES LIMITED
 
@@ -41036,6 +41108,9 @@ OUI:0CC66A*
 OUI:0CC6AC*
  ID_OUI_FROM_DATABASE=DAGS
 
+OUI:0CC6CC*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
 OUI:0CC731*
  ID_OUI_FROM_DATABASE=Currant, Inc.
 
@@ -41186,6 +41261,9 @@ OUI:0CF019*
 OUI:0CF0B4*
  ID_OUI_FROM_DATABASE=Globalsat International Technology Ltd
 
+OUI:0CF346*
+ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd
+
 OUI:0CF361*
  ID_OUI_FROM_DATABASE=Java Information
 
@@ -41352,7 +41430,7 @@ OUI:101C0C*
  ID_OUI_FROM_DATABASE=Apple, Inc.
 
 OUI:101D51*
- ID_OUI_FROM_DATABASE=ON-Q LLC dba ON-Q Mesh Networks
+ ID_OUI_FROM_DATABASE=8Mesh Networks
 
 OUI:101DC0*
  ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
@@ -41594,6 +41672,9 @@ OUI:109FA9*
 OUI:10A13B*
  ID_OUI_FROM_DATABASE=FUJIKURA RUBBER LTD.
 
+OUI:10A4B9*
+ ID_OUI_FROM_DATABASE=Baidu Online Network Technology (Beijing) Co., Ltd
+
 OUI:10A4BE*
  ID_OUI_FROM_DATABASE=SHENZHEN BILIAN ELECTRONIC CO.,LTD
 
@@ -41648,6 +41729,9 @@ OUI:10BF48*
 OUI:10C07C*
  ID_OUI_FROM_DATABASE=Blu-ray Disc Association
 
+OUI:10C25A*
+ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc.
+
 OUI:10C2BA*
  ID_OUI_FROM_DATABASE=UTT Co., Ltd.
 
@@ -41738,6 +41822,9 @@ OUI:10E68F*
 OUI:10E6AE*
  ID_OUI_FROM_DATABASE=Source Technologies, LLC
 
+OUI:10E7C6*
+ ID_OUI_FROM_DATABASE=Hewlett Packard
+
 OUI:10E878*
  ID_OUI_FROM_DATABASE=Nokia
 
@@ -41774,6 +41861,9 @@ OUI:10F681*
 OUI:10F96F*
  ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
 
+OUI:10F9EB*
+ ID_OUI_FROM_DATABASE=Industria Fueguina de Relojería Electrónica s.a.
+
 OUI:10F9EE*
  ID_OUI_FROM_DATABASE=Nokia Corporation
 
@@ -42008,6 +42098,9 @@ OUI:144C1A*
 OUI:144D67*
  ID_OUI_FROM_DATABASE=Zioncom Electronics (Shenzhen) Ltd.
 
+OUI:144E34*
+ ID_OUI_FROM_DATABASE=Remote Solution
+
 OUI:144FD70*
  ID_OUI_FROM_DATABASE=annapurnalabs
 
@@ -42101,6 +42194,9 @@ OUI:146A0B*
 OUI:146B72*
  ID_OUI_FROM_DATABASE=Shenzhen Fortune Ship Technology Co., Ltd.
 
+OUI:146B9C*
+ ID_OUI_FROM_DATABASE=SHENZHEN BILIAN ELECTRONIC CO.,LTD
+
 OUI:146E0A*
  ID_OUI_FROM_DATABASE=Private
 
@@ -42197,6 +42293,9 @@ OUI:14A51A*
 OUI:14A62C*
  ID_OUI_FROM_DATABASE=S.M. Dezac S.A.
 
+OUI:14A72B*
+ ID_OUI_FROM_DATABASE=currentoptronics Pvt.Ltd
+
 OUI:14A78B*
  ID_OUI_FROM_DATABASE=Zhejiang Dahua Technology Co., Ltd.
 
@@ -42383,6 +42482,9 @@ OUI:180C77*
 OUI:180CAC*
  ID_OUI_FROM_DATABASE=CANON INC.
 
+OUI:180F76*
+ ID_OUI_FROM_DATABASE=D-Link International
+
 OUI:18104E*
  ID_OUI_FROM_DATABASE=CEDINT-UPM
 
@@ -42458,6 +42560,9 @@ OUI:182D98*
 OUI:183009*
  ID_OUI_FROM_DATABASE=Woojin Industrial Systems Co., Ltd.
 
+OUI:1831BF*
+ ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
+
 OUI:1832A2*
  ID_OUI_FROM_DATABASE=LAON TECHNOLOGY CO., LTD.
 
@@ -42521,12 +42626,18 @@ OUI:1848D8*
 OUI:184A6F*
  ID_OUI_FROM_DATABASE=Alcatel-Lucent Shanghai Bell Co., Ltd
 
+OUI:184C08*
+ ID_OUI_FROM_DATABASE=Rockwell Automation
+
 OUI:184E94*
  ID_OUI_FROM_DATABASE=MESSOA TECHNOLOGIES INC.
 
 OUI:184F32*
  ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
 
+OUI:18502A*
+ ID_OUI_FROM_DATABASE=SOARNEX
+
 OUI:185207*
  ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO., LTD
 
@@ -42686,6 +42797,9 @@ OUI:18922C*
 OUI:1893D7*
  ID_OUI_FROM_DATABASE=Texas Instruments
 
+OUI:1894C6*
+ ID_OUI_FROM_DATABASE=ShenZhen Chenyee Technology Co., Ltd.
+
 OUI:1897FF*
  ID_OUI_FROM_DATABASE=TechFaith Wireless Technology Limited
 
@@ -42746,6 +42860,9 @@ OUI:189C5D*
 OUI:189EFC*
  ID_OUI_FROM_DATABASE=Apple, Inc.
 
+OUI:18A28A*
+ ID_OUI_FROM_DATABASE=Essel-T Co., Ltd
+
 OUI:18A3E8*
  ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
 
@@ -42956,6 +43073,9 @@ OUI:1C0FAF*
 OUI:1C0FCF*
  ID_OUI_FROM_DATABASE=Sypro Optics GmbH
 
+OUI:1C1161*
+ ID_OUI_FROM_DATABASE=Ciena Corporation
+
 OUI:1C11E1*
  ID_OUI_FROM_DATABASE=Wartsila Finland Oy
 
@@ -43514,6 +43634,9 @@ OUI:1C9E46*
 OUI:1C9ECB*
  ID_OUI_FROM_DATABASE=Beijing Nari Smartchip Microelectronics Company Limited
 
+OUI:1CA0B8*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co., Ltd.
+
 OUI:1CA0D30*
  ID_OUI_FROM_DATABASE=OOO Tekhnotronika
 
@@ -43592,6 +43715,9 @@ OUI:1CAF05*
 OUI:1CAFF7*
  ID_OUI_FROM_DATABASE=D-Link International
 
+OUI:1CB044*
+ ID_OUI_FROM_DATABASE=ASKEY COMPUTER CORP
+
 OUI:1CB094*
  ID_OUI_FROM_DATABASE=HTC Corporation
 
@@ -43844,6 +43970,9 @@ OUI:200CC8*
 OUI:200E95*
  ID_OUI_FROM_DATABASE=IEC – TC9 WG43
 
+OUI:200F70*
+ ID_OUI_FROM_DATABASE=FOXTECH
+
 OUI:20107A*
  ID_OUI_FROM_DATABASE=Gemtek Technology Co., Ltd.
 
@@ -43889,12 +44018,18 @@ OUI:202CB7*
 OUI:202D07*
  ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
 
+OUI:202D23*
+ ID_OUI_FROM_DATABASE=Collinear Networks Inc.
+
 OUI:202DF8*
  ID_OUI_FROM_DATABASE=Digital Media Cartridge Ltd.
 
 OUI:2031EB*
  ID_OUI_FROM_DATABASE=HDSN
 
+OUI:20365B*
+ ID_OUI_FROM_DATABASE=Megafone Limited
+
 OUI:203706*
  ID_OUI_FROM_DATABASE=Cisco Systems, Inc
 
@@ -44009,6 +44144,9 @@ OUI:20635F*
 OUI:206432*
  ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO MECHANICS CO., LTD.
 
+OUI:20677C*
+ ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise
+
 OUI:2067B1*
  ID_OUI_FROM_DATABASE=Pluto inc.
 
@@ -44339,6 +44477,9 @@ OUI:240995*
 OUI:240A11*
  ID_OUI_FROM_DATABASE=TCT mobile ltd
 
+OUI:240A63*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
 OUI:240A64*
  ID_OUI_FROM_DATABASE=AzureWave Technology Inc.
 
@@ -44375,6 +44516,9 @@ OUI:241148*
 OUI:2411D0*
  ID_OUI_FROM_DATABASE=Chongqing Ehs Science and Technology Development Co.,Ltd.
 
+OUI:24181D*
+ ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO-MECHANICS(THAILAND)
+
 OUI:241A8C*
  ID_OUI_FROM_DATABASE=Squarehead Technology AS
 
@@ -44408,6 +44552,9 @@ OUI:24240E*
 OUI:242642*
  ID_OUI_FROM_DATABASE=SHARP Corporation.
 
+OUI:2429FE*
+ ID_OUI_FROM_DATABASE=KYOCERA Corporation
+
 OUI:242FFA*
  ID_OUI_FROM_DATABASE=Toshiba Global Commerce Solutions
 
@@ -44585,6 +44732,9 @@ OUI:24792A*
 OUI:247C4C*
  ID_OUI_FROM_DATABASE=Herman Miller
 
+OUI:247E12*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
 OUI:247F20*
  ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
 
@@ -44744,6 +44894,9 @@ OUI:24C9A1*
 OUI:24C9DE*
  ID_OUI_FROM_DATABASE=Genoray
 
+OUI:24CACB*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
 OUI:24CBE7*
  ID_OUI_FROM_DATABASE=MYK, Inc.
 
@@ -44852,6 +45005,9 @@ OUI:24FD52*
 OUI:24FD5B*
  ID_OUI_FROM_DATABASE=SmartThings, Inc.
 
+OUI:2802D8*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
 OUI:2804E0*
  ID_OUI_FROM_DATABASE=FERMAX ELECTRONICA S.A.U.
 
@@ -44942,18 +45098,42 @@ OUI:282C021*
 OUI:282C022*
  ID_OUI_FROM_DATABASE=Shenzhen emb-star technology co. LTD
 
+OUI:282C023*
+ ID_OUI_FROM_DATABASE=Dexin Digital Technology Corp. Ltd.
+
+OUI:282C024*
+ ID_OUI_FROM_DATABASE=EFENTO T P SZYDŁOWSKI K ZARĘBA SPÓŁKA JAWNA
+
+OUI:282C025*
+ ID_OUI_FROM_DATABASE=LLC MICROTEH
+
 OUI:282C026*
  ID_OUI_FROM_DATABASE=Lookman Electroplast Industries Ltd
 
 OUI:282C027*
  ID_OUI_FROM_DATABASE=Telecom and Microelectonic Industries
 
+OUI:282C028*
+ ID_OUI_FROM_DATABASE=Shenzhen Neoway Technology Co.,Ltd.
+
 OUI:282C029*
  ID_OUI_FROM_DATABASE=Systec Intelligent Building Technology (Tianjin) Co.,Ltd.
 
+OUI:282C02A*
+ ID_OUI_FROM_DATABASE=Tokin Limited
+
+OUI:282C02B*
+ ID_OUI_FROM_DATABASE=ThirdReality, Inc
+
 OUI:282C02C*
  ID_OUI_FROM_DATABASE=Epoch International Enterprises, Inc.
 
+OUI:282C02D*
+ ID_OUI_FROM_DATABASE=SHENZHEN DOMENOR TECHNOLOGY LLC
+
+OUI:282C02E*
+ ID_OUI_FROM_DATABASE=Capintec, Inc.
+
 OUI:282CB2*
  ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
 
@@ -45038,6 +45218,9 @@ OUI:28395E*
 OUI:2839E7*
  ID_OUI_FROM_DATABASE=Preceno Technology Pte.Ltd.
 
+OUI:283B82*
+ ID_OUI_FROM_DATABASE=D-Link International
+
 OUI:283B96*
  ID_OUI_FROM_DATABASE=Cool Control LTD
 
@@ -45090,7 +45273,7 @@ OUI:2856C1*
  ID_OUI_FROM_DATABASE=Harman International
 
 OUI:285767*
- ID_OUI_FROM_DATABASE=Echostar Technologies Corp
+ ID_OUI_FROM_DATABASE=Dish Technologies Corp
 
 OUI:2857BE*
  ID_OUI_FROM_DATABASE=Hangzhou Hikvision Digital Technology Co.,Ltd.
@@ -45914,6 +46097,9 @@ OUI:2C5FF3*
 OUI:2C600C*
  ID_OUI_FROM_DATABASE=QUANTA COMPUTER INC.
 
+OUI:2C61F6*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
 OUI:2C625A*
  ID_OUI_FROM_DATABASE=Finest Security Systems Co., Ltd
 
@@ -46043,6 +46229,9 @@ OUI:2C922C*
 OUI:2C9464*
  ID_OUI_FROM_DATABASE=Cincoze Co., Ltd.
 
+OUI:2C9569*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
 OUI:2C957F*
  ID_OUI_FROM_DATABASE=zte corporation
 
@@ -46229,6 +46418,9 @@ OUI:2CD2E7*
 OUI:2CD444*
  ID_OUI_FROM_DATABASE=FUJITSU LIMITED
 
+OUI:2CD974*
+ ID_OUI_FROM_DATABASE=Hui Zhou Gaoshengda Technology Co.,LTD
+
 OUI:2CDCAD*
  ID_OUI_FROM_DATABASE=Wistron Neweb Corporation
 
@@ -46349,6 +46541,9 @@ OUI:301966*
 OUI:301A28*
  ID_OUI_FROM_DATABASE=Mako Networks Ltd
 
+OUI:301F9A*
+ ID_OUI_FROM_DATABASE=IEEE Registration Authority
+
 OUI:30215B*
  ID_OUI_FROM_DATABASE=Shenzhen Ostar Display Electronic Co.,Ltd
 
@@ -46412,6 +46607,9 @@ OUI:304487*
 OUI:3044A1*
  ID_OUI_FROM_DATABASE=Shanghai Nanchao Information Technology
 
+OUI:304511*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
 OUI:30469A*
  ID_OUI_FROM_DATABASE=NETGEAR
 
@@ -46511,6 +46709,9 @@ OUI:30786B*
 OUI:3078C2*
  ID_OUI_FROM_DATABASE=Innowireless, Co. Ltd.
 
+OUI:307BAC*
+ ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd
+
 OUI:307C30*
  ID_OUI_FROM_DATABASE=RIM
 
@@ -46605,7 +46806,7 @@ OUI:30B164*
  ID_OUI_FROM_DATABASE=Power Electronics International Inc.
 
 OUI:30B216*
- ID_OUI_FROM_DATABASE=Hytec Geraetebau GmbH
+ ID_OUI_FROM_DATABASE=ABB AG - Power Grids - Grid Automation
 
 OUI:30B3A2*
  ID_OUI_FROM_DATABASE=Shenzhen Heguang Measurement & Control Technology Co.,Ltd
@@ -46628,6 +46829,9 @@ OUI:30B62D*
 OUI:30B64F*
  ID_OUI_FROM_DATABASE=Juniper Networks
 
+OUI:30B7D4*
+ ID_OUI_FROM_DATABASE=Hitron Technologies. Inc
+
 OUI:30C01B*
  ID_OUI_FROM_DATABASE=Shenzhen Jingxun Software Telecommunication Technology Co.,Ltd
 
@@ -46745,6 +46949,9 @@ OUI:30FC68*
 OUI:30FD11*
  ID_OUI_FROM_DATABASE=MACROTECH (USA) INC.
 
+OUI:30FD38*
+ ID_OUI_FROM_DATABASE=Google, Inc.
+
 OUI:30FE31*
  ID_OUI_FROM_DATABASE=Nokia
 
@@ -46805,6 +47012,9 @@ OUI:340286*
 OUI:34029B*
  ID_OUI_FROM_DATABASE=CloudBerry Technologies Private Limited
 
+OUI:3403DE*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
 OUI:34049E0*
  ID_OUI_FROM_DATABASE=GoChip Inc.
 
@@ -47066,6 +47276,9 @@ OUI:3456FE*
 OUI:345760*
  ID_OUI_FROM_DATABASE=MitraStar Technology Corp.
 
+OUI:345A06*
+ ID_OUI_FROM_DATABASE=SHARP Corporation
+
 OUI:345B11*
  ID_OUI_FROM_DATABASE=EVI HEAT AB
 
@@ -47135,9 +47348,18 @@ OUI:3478D7*
 OUI:347A60*
  ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
 
+OUI:347C25*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
 OUI:347E39*
  ID_OUI_FROM_DATABASE=Nokia Danmark A/S
 
+OUI:347E5C*
+ ID_OUI_FROM_DATABASE=Sonos, Inc.
+
+OUI:347ECA*
+ ID_OUI_FROM_DATABASE=NEXTWILL
+
 OUI:3480B3*
  ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd
 
@@ -47411,6 +47633,9 @@ OUI:34D270*
 OUI:34D2C4*
  ID_OUI_FROM_DATABASE=RENA GmbH Print Systeme
 
+OUI:34D712*
+ ID_OUI_FROM_DATABASE=Smartisan Digital Co., Ltd
+
 OUI:34D7B4*
  ID_OUI_FROM_DATABASE=Tributary Systems, Inc.
 
@@ -47849,9 +48074,15 @@ OUI:3876CA*
 OUI:3876D1*
  ID_OUI_FROM_DATABASE=Euronda SpA
 
+OUI:387862*
+ ID_OUI_FROM_DATABASE=Sony Mobile Communications AB
+
 OUI:387B47*
  ID_OUI_FROM_DATABASE=AKELA, Inc.
 
+OUI:3880DF*
+ ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company
+
 OUI:388345*
  ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
 
@@ -48080,9 +48311,15 @@ OUI:38DBBB*
 OUI:38DE60*
  ID_OUI_FROM_DATABASE=Mohlenhoff GmbH
 
+OUI:38DEAD*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
 OUI:38E08E*
  ID_OUI_FROM_DATABASE=Mitsubishi Electric Corporation
 
+OUI:38E1AA*
+ ID_OUI_FROM_DATABASE=zte corporation
+
 OUI:38E2DD*
  ID_OUI_FROM_DATABASE=zte corporation
 
@@ -48092,6 +48329,9 @@ OUI:38E3C5*
 OUI:38E595*
  ID_OUI_FROM_DATABASE=SHENZHEN GONGJIN ELECTRONICS CO.,LT
 
+OUI:38E60A*
+ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd
+
 OUI:38E7D8*
  ID_OUI_FROM_DATABASE=HTC Corporation
 
@@ -48131,6 +48371,9 @@ OUI:38F23E*
 OUI:38F33F*
  ID_OUI_FROM_DATABASE=TATSUNO CORPORATION
 
+OUI:38F554*
+ ID_OUI_FROM_DATABASE=HISENSE ELECTRIC CO.,LTD
+
 OUI:38F557*
  ID_OUI_FROM_DATABASE=JOLATA, INC.
 
@@ -48212,6 +48455,9 @@ OUI:38FF36*
 OUI:3C02B1*
  ID_OUI_FROM_DATABASE=Creation Technologies LP
 
+OUI:3C0461*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
 OUI:3C04BF*
  ID_OUI_FROM_DATABASE=PRAVIS SYSTEMS Co.Ltd.,
 
@@ -48266,6 +48512,9 @@ OUI:3C15C2*
 OUI:3C15EA*
  ID_OUI_FROM_DATABASE=TESCOM CO., LTD.
 
+OUI:3C1710*
+ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
+
 OUI:3C189F*
  ID_OUI_FROM_DATABASE=Nokia Corporation
 
@@ -48413,6 +48662,9 @@ OUI:3C46D8*
 OUI:3C4711*
  ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
 
+OUI:3C479B*
+ ID_OUI_FROM_DATABASE=Theissen Training Systems, Inc.
+
 OUI:3C4937*
  ID_OUI_FROM_DATABASE=ASSMANN Electronic GmbH
 
@@ -48431,6 +48683,9 @@ OUI:3C4E47*
 OUI:3C5282*
  ID_OUI_FROM_DATABASE=Hewlett Packard
 
+OUI:3C574F*
+ ID_OUI_FROM_DATABASE=China Mobile Group Device Co.,Ltd.
+
 OUI:3C57BD*
  ID_OUI_FROM_DATABASE=Kessler Crane Inc.
 
@@ -48743,6 +48998,9 @@ OUI:3CD9CE*
 OUI:3CDA2A*
  ID_OUI_FROM_DATABASE=zte corporation
 
+OUI:3CDCBC*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
 OUI:3CDD89*
  ID_OUI_FROM_DATABASE=SOMO HOLDINGS & TECH. CO.,LTD.
 
@@ -48767,6 +49025,9 @@ OUI:3CE5B4*
 OUI:3CE624*
  ID_OUI_FROM_DATABASE=LG Display
 
+OUI:3CE824*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
 OUI:3CEA4F*
  ID_OUI_FROM_DATABASE=2Wire Inc
 
@@ -49169,6 +49430,9 @@ OUI:40984E*
 OUI:40987B*
  ID_OUI_FROM_DATABASE=Aisino Corporation
 
+OUI:4098AD*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
 OUI:409922*
  ID_OUI_FROM_DATABASE=AzureWave Technology Inc.
 
@@ -49310,6 +49574,9 @@ OUI:40BC73*
 OUI:40BC8B*
  ID_OUI_FROM_DATABASE=itelio GmbH
 
+OUI:40BD32*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
 OUI:40BD9E*
  ID_OUI_FROM_DATABASE=Physio-Control, Inc
 
@@ -49337,6 +49604,9 @@ OUI:40C8CB*
 OUI:40CBA8*
  ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
 
+OUI:40CBC0*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
 OUI:40CD3A*
  ID_OUI_FROM_DATABASE=Z3 Technology
 
@@ -49832,6 +50102,9 @@ OUI:449B78*
 OUI:449CB5*
  ID_OUI_FROM_DATABASE=Alcomp, Inc
 
+OUI:449EF9*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
 OUI:449F7F*
  ID_OUI_FROM_DATABASE=DataCore Software Corporation
 
@@ -50021,6 +50294,9 @@ OUI:44FB42*
 OUI:44FDA3*
  ID_OUI_FROM_DATABASE=Everysight LTD.
 
+OUI:44FFBA*
+ ID_OUI_FROM_DATABASE=zte corporation
+
 OUI:480031*
  ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
 
@@ -50063,6 +50339,9 @@ OUI:48174C*
 OUI:481842*
  ID_OUI_FROM_DATABASE=Shanghai Winaas Co. Equipment Co. Ltd.
 
+OUI:4818FA*
+ ID_OUI_FROM_DATABASE=Nocsys
+
 OUI:481A84*
  ID_OUI_FROM_DATABASE=Pointer Telocation Ltd
 
@@ -50369,6 +50648,9 @@ OUI:48BA4E*
 OUI:48BCA6*
  ID_OUI_FROM_DATABASE=​ASUNG TECHNO CO.,Ltd
 
+OUI:48BD3D*
+ ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd
+
 OUI:48BE2D*
  ID_OUI_FROM_DATABASE=Symanitron
 
@@ -50393,6 +50675,9 @@ OUI:48C58D*
 OUI:48C663*
  ID_OUI_FROM_DATABASE=GTO Access Systems LLC
 
+OUI:48C796*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
 OUI:48C862*
  ID_OUI_FROM_DATABASE=Simo Wireless,Inc.
 
@@ -50792,6 +51077,9 @@ OUI:4C7625*
 OUI:4C774F*
  ID_OUI_FROM_DATABASE=Embedded Wireless Labs
 
+OUI:4C776D*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
 OUI:4C7872*
  ID_OUI_FROM_DATABASE=Cav. Uff. Giacomo Cimberio S.p.A.
 
@@ -50817,7 +51105,7 @@ OUI:4C8120*
  ID_OUI_FROM_DATABASE=Taicang T&W Electronics
 
 OUI:4C82CF*
- ID_OUI_FROM_DATABASE=Echostar Technologies Corp
+ ID_OUI_FROM_DATABASE=Dish Technologies Corp
 
 OUI:4C83DE*
  ID_OUI_FROM_DATABASE=Cisco SPVTG
@@ -50882,6 +51170,9 @@ OUI:4CAA16*
 OUI:4CAB33*
  ID_OUI_FROM_DATABASE=KST technology
 
+OUI:4CABFC*
+ ID_OUI_FROM_DATABASE=zte corporation
+
 OUI:4CAC0A*
  ID_OUI_FROM_DATABASE=zte corporation
 
@@ -50942,6 +51233,9 @@ OUI:4CBCA5*
 OUI:4CBD8F*
  ID_OUI_FROM_DATABASE=Hangzhou Hikvision Digital Technology Co.,Ltd.
 
+OUI:4CC206*
+ ID_OUI_FROM_DATABASE=Somfy
+
 OUI:4CC452*
  ID_OUI_FROM_DATABASE=Shang Hai Tyd. Electon Technology Ltd.
 
@@ -51053,6 +51347,9 @@ OUI:4CEDDE*
 OUI:4CEEB0*
  ID_OUI_FROM_DATABASE=SHC Netzwerktechnik GmbH
 
+OUI:4CEFC0*
+ ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
+
 OUI:4CF02E*
  ID_OUI_FROM_DATABASE=Vifa Denmark A/S
 
@@ -51167,6 +51464,9 @@ OUI:500FF5*
 OUI:5011EB*
  ID_OUI_FROM_DATABASE=SilverNet Ltd
 
+OUI:501479*
+ ID_OUI_FROM_DATABASE=iRobot Corporation
+
 OUI:5014B5*
  ID_OUI_FROM_DATABASE=Richfit Information Technology Co., Ltd
 
@@ -51182,6 +51482,9 @@ OUI:501AA5*
 OUI:501AC5*
  ID_OUI_FROM_DATABASE=Microsoft
 
+OUI:501CB0*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
 OUI:501CBF*
  ID_OUI_FROM_DATABASE=Cisco Systems, Inc
 
@@ -51374,12 +51677,21 @@ OUI:50680A*
 OUI:506A03*
  ID_OUI_FROM_DATABASE=NETGEAR
 
+OUI:506B4B*
+ ID_OUI_FROM_DATABASE=Mellanox Technologies, Inc.
+
 OUI:506B8D*
  ID_OUI_FROM_DATABASE=Nutanix
 
+OUI:506CBE*
+ ID_OUI_FROM_DATABASE=InnosiliconTechnology Ltd
+
 OUI:506E92*
  ID_OUI_FROM_DATABASE=Innocent Technology Co., Ltd.
 
+OUI:506F77*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
 OUI:506F98*
  ID_OUI_FROM_DATABASE=Sehaj Synergy Technologies Private Limited
 
@@ -51461,6 +51773,9 @@ OUI:5092B9*
 OUI:50934F*
  ID_OUI_FROM_DATABASE=Gradual Tecnologia Ltda.
 
+OUI:509551*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
 OUI:509772*
  ID_OUI_FROM_DATABASE=Westinghouse Digital
 
@@ -51638,6 +51953,9 @@ OUI:50D753*
 OUI:50DA00*
  ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited
 
+OUI:50DCE7*
+ ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
+
 OUI:50DD4F*
  ID_OUI_FROM_DATABASE=Automation Components, Inc
 
@@ -51890,6 +52208,9 @@ OUI:543B30*
 OUI:543D37*
  ID_OUI_FROM_DATABASE=Ruckus Wireless
 
+OUI:543E64*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
 OUI:5440AD*
  ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
 
@@ -52130,6 +52451,9 @@ OUI:54A54B*
 OUI:54A619*
  ID_OUI_FROM_DATABASE=Alcatel-Lucent Shanghai Bell Co., Ltd
 
+OUI:54A65C*
+ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc.
+
 OUI:54A9D4*
  ID_OUI_FROM_DATABASE=Minibar Systems
 
@@ -52151,6 +52475,9 @@ OUI:54B620*
 OUI:54B753*
  ID_OUI_FROM_DATABASE=Hunan Fenghui Yinjia Science And Technology Co.,Ltd
 
+OUI:54B7E5*
+ ID_OUI_FROM_DATABASE=Rayson Technology Co., Ltd.
+
 OUI:54B802*
  ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
 
@@ -52379,6 +52706,9 @@ OUI:5820B1*
 OUI:582136*
  ID_OUI_FROM_DATABASE=KMB systems, s.r.o.
 
+OUI:5821E9*
+ ID_OUI_FROM_DATABASE=TWPI
+
 OUI:58238C*
  ID_OUI_FROM_DATABASE=Technicolor CH USA Inc.
 
@@ -52541,6 +52871,9 @@ OUI:587A4D*
 OUI:587A62*
  ID_OUI_FROM_DATABASE=Texas Instruments
 
+OUI:587A6A*
+ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+
 OUI:587BE9*
  ID_OUI_FROM_DATABASE=AirPro Technology India Pvt. Ltd
 
@@ -52646,6 +52979,9 @@ OUI:58B035*
 OUI:58B0D4*
  ID_OUI_FROM_DATABASE=ZuniData Systems Inc.
 
+OUI:58B3FC*
+ ID_OUI_FROM_DATABASE=SHENZHEN RF-LINK TECHNOLOGY CO.,LTD.
+
 OUI:58B42D*
  ID_OUI_FROM_DATABASE=YSTen Technology Co.,Ltd
 
@@ -52706,6 +53042,9 @@ OUI:58D67A*
 OUI:58D6D3*
  ID_OUI_FROM_DATABASE=Dairy Cheq Inc
 
+OUI:58D759*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
 OUI:58D9D5*
  ID_OUI_FROM_DATABASE=Tenda Technology Co.,Ltd.Dongguan branch
 
@@ -53048,6 +53387,9 @@ OUI:5C5819*
 OUI:5C5948*
  ID_OUI_FROM_DATABASE=Apple, Inc.
 
+OUI:5C5AEA*
+ ID_OUI_FROM_DATABASE=FORD
+
 OUI:5C5B35*
  ID_OUI_FROM_DATABASE=Mist Systems, Inc.
 
@@ -53642,6 +53984,9 @@ OUI:605718*
 OUI:605BB4*
  ID_OUI_FROM_DATABASE=AzureWave Technology Inc.
 
+OUI:605F8D*
+ ID_OUI_FROM_DATABASE=eero inc.
+
 OUI:60601F*
  ID_OUI_FROM_DATABASE=SZ DJI TECHNOLOGY CO.,LTD
 
@@ -53672,6 +54017,9 @@ OUI:60699B*
 OUI:606BBD*
  ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
 
+OUI:606BFF*
+ ID_OUI_FROM_DATABASE=Nintendo Co.,Ltd
+
 OUI:606C66*
  ID_OUI_FROM_DATABASE=Intel Corporate
 
@@ -53717,6 +54065,9 @@ OUI:6083B2*
 OUI:60843B*
  ID_OUI_FROM_DATABASE=Soladigm, Inc.
 
+OUI:6084BD*
+ ID_OUI_FROM_DATABASE=BUFFALO.INC
+
 OUI:608645*
  ID_OUI_FROM_DATABASE=Avery Weigh-Tronix, LLC
 
@@ -53756,6 +54107,12 @@ OUI:609217*
 OUI:609620*
  ID_OUI_FROM_DATABASE=Private
 
+OUI:6097DD*
+ ID_OUI_FROM_DATABASE=MicroSys Electronics GmbH
+
+OUI:609813*
+ ID_OUI_FROM_DATABASE=Shanghai Visking Digital Technology Co. LTD
+
 OUI:6099D1*
  ID_OUI_FROM_DATABASE=Vuzix / Lenovo
 
@@ -54053,6 +54410,9 @@ OUI:64006A*
 OUI:6400F1*
  ID_OUI_FROM_DATABASE=Cisco Systems, Inc
 
+OUI:6402CB*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
 OUI:6405BE*
  ID_OUI_FROM_DATABASE=NEW LIGHT LED
 
@@ -54113,6 +54473,9 @@ OUI:641A22*
 OUI:641C67*
  ID_OUI_FROM_DATABASE=DIGIBRAS INDUSTRIA DO BRASILS/A
 
+OUI:641CB0*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
 OUI:641E81*
  ID_OUI_FROM_DATABASE=Dowslake Microsystems
 
@@ -54338,6 +54701,9 @@ OUI:64899A*
 OUI:648D9E*
  ID_OUI_FROM_DATABASE=IVT Electronic Co.,Ltd
 
+OUI:649829*
+ ID_OUI_FROM_DATABASE=Integrated Device Technology (Malaysia) Sdn. Bhd.
+
 OUI:64995D*
  ID_OUI_FROM_DATABASE=LGE
 
@@ -54446,6 +54812,9 @@ OUI:64BC11*
 OUI:64C354*
  ID_OUI_FROM_DATABASE=Avaya Inc
 
+OUI:64C3D6*
+ ID_OUI_FROM_DATABASE=Juniper Networks
+
 OUI:64C5AA*
  ID_OUI_FROM_DATABASE=South African Broadcasting Corporation
 
@@ -54458,6 +54827,9 @@ OUI:64C6AF*
 OUI:64C944*
  ID_OUI_FROM_DATABASE=LARK Technologies, Inc
 
+OUI:64CB5D*
+ ID_OUI_FROM_DATABASE=SIA TeleSet
+
 OUI:64CBA3*
  ID_OUI_FROM_DATABASE=Pointmobile
 
@@ -54509,6 +54881,9 @@ OUI:64DB43*
 OUI:64DB81*
  ID_OUI_FROM_DATABASE=Syszone Co., Ltd.
 
+OUI:64DB8B*
+ ID_OUI_FROM_DATABASE=Hangzhou Hikvision Digital Technology Co.,Ltd.
+
 OUI:64DBA0*
  ID_OUI_FROM_DATABASE=Select Comfort
 
@@ -54770,6 +55145,9 @@ OUI:6854F5*
 OUI:6854FD*
  ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
 
+OUI:68572D*
+ ID_OUI_FROM_DATABASE=HANGZHOU AIXIANGJI TECHNOLOGY CO., LTD
+
 OUI:6858C5*
  ID_OUI_FROM_DATABASE=ZF TRW Automotive
 
@@ -54941,6 +55319,9 @@ OUI:68974B*
 OUI:6897E8*
  ID_OUI_FROM_DATABASE=Society of Motion Picture &amp; Television Engineers
 
+OUI:689861*
+ ID_OUI_FROM_DATABASE=Beacon Inc
+
 OUI:6899CD*
  ID_OUI_FROM_DATABASE=Cisco Systems, Inc
 
@@ -54989,6 +55370,9 @@ OUI:68A86D*
 OUI:68AAD2*
  ID_OUI_FROM_DATABASE=DATECS LTD.,
 
+OUI:68AB1E*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
 OUI:68AB8A*
  ID_OUI_FROM_DATABASE=RF IDeas
 
@@ -55055,6 +55439,9 @@ OUI:68D1FD*
 OUI:68D247*
  ID_OUI_FROM_DATABASE=Portalis LC
 
+OUI:68D482*
+ ID_OUI_FROM_DATABASE=SHENZHEN GONGJIN ELECTRONICS CO.,LT
+
 OUI:68D925*
  ID_OUI_FROM_DATABASE=ProSys Development Services
 
@@ -55109,6 +55496,9 @@ OUI:68EDA4*
 OUI:68EE96*
  ID_OUI_FROM_DATABASE=Cisco SPVTG
 
+OUI:68EF43*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
 OUI:68EFBD*
  ID_OUI_FROM_DATABASE=Cisco Systems, Inc
 
@@ -55139,6 +55529,9 @@ OUI:68FB95*
 OUI:68FCB3*
  ID_OUI_FROM_DATABASE=Next Level Security Systems, Inc.
 
+OUI:68FEDA*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
 OUI:6C0273*
  ID_OUI_FROM_DATABASE=Shenzhen Jin Yun Video Equipment Co., Ltd.
 
@@ -55286,12 +55679,18 @@ OUI:6C4B7F*
 OUI:6C4B90*
  ID_OUI_FROM_DATABASE=LiteON
 
+OUI:6C4D73*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
 OUI:6C4E86*
  ID_OUI_FROM_DATABASE=Third Millennium Systems Ltd.
 
 OUI:6C504D*
  ID_OUI_FROM_DATABASE=Cisco Systems, Inc
 
+OUI:6C54CD*
+ ID_OUI_FROM_DATABASE=LAMPEX ELECTRONICS LIMITED
+
 OUI:6C5697*
  ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
 
@@ -55505,6 +55904,9 @@ OUI:6CB4A7*
 OUI:6CB56B*
  ID_OUI_FROM_DATABASE=HUMAX Co., Ltd.
 
+OUI:6CB6CA*
+ ID_OUI_FROM_DATABASE=DIVUS GmbH
+
 OUI:6CB749*
  ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
 
@@ -55532,6 +55934,9 @@ OUI:6CC217*
 OUI:6CC26B*
  ID_OUI_FROM_DATABASE=Apple, Inc.
 
+OUI:6CC4D5*
+ ID_OUI_FROM_DATABASE=HMD Global Oy
+
 OUI:6CCA08*
  ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
 
@@ -55565,6 +55970,9 @@ OUI:6CE3B6*
 OUI:6CE4CE*
  ID_OUI_FROM_DATABASE=Villiger Security Solutions AG
 
+OUI:6CE4DA*
+ ID_OUI_FROM_DATABASE=NEC Platforms, Ltd.
+
 OUI:6CE873*
  ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
 
@@ -55631,6 +56039,9 @@ OUI:700258*
 OUI:700514*
  ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
 
+OUI:7006AC*
+ ID_OUI_FROM_DATABASE=Eastcompeace Technology Co., Ltd
+
 OUI:700BC0*
  ID_OUI_FROM_DATABASE=Dewav Technology Company
 
@@ -55658,6 +56069,9 @@ OUI:701404*
 OUI:7014A6*
  ID_OUI_FROM_DATABASE=Apple, Inc.
 
+OUI:70169F*
+ ID_OUI_FROM_DATABASE=EtherCAT Technology Group
+
 OUI:70188B*
  ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
 
@@ -55751,6 +56165,9 @@ OUI:7038EE*
 OUI:703A0E*
  ID_OUI_FROM_DATABASE=Aruba Networks
 
+OUI:703A73*
+ ID_OUI_FROM_DATABASE=Shenzhen Sundray Technologies Company Limited
+
 OUI:703ACB*
  ID_OUI_FROM_DATABASE=Google, Inc.
 
@@ -55820,6 +56237,9 @@ OUI:7054D2*
 OUI:7054F5*
  ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
 
+OUI:7055F8*
+ ID_OUI_FROM_DATABASE=Cerebras Systems Inc
+
 OUI:705681*
  ID_OUI_FROM_DATABASE=Apple, Inc.
 
@@ -55841,6 +56261,9 @@ OUI:705A0F*
 OUI:705A9E*
  ID_OUI_FROM_DATABASE=Technicolor CH USA Inc.
 
+OUI:705AAC*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
 OUI:705AB6*
  ID_OUI_FROM_DATABASE=COMPAL INFORMATION (KUNSHAN) CO., LTD.
 
@@ -55877,6 +56300,9 @@ OUI:70661B*
 OUI:706879*
  ID_OUI_FROM_DATABASE=Saijo Denki International Co., Ltd.
 
+OUI:70695A*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
 OUI:706BB9*
  ID_OUI_FROM_DATABASE=Cisco Systems, Inc
 
@@ -56189,6 +56615,9 @@ OUI:70B3D5030*
 OUI:70B3D5031*
  ID_OUI_FROM_DATABASE=SHENZHEN GAONA ELECTRONIC CO.LTD
 
+OUI:70B3D5032*
+ ID_OUI_FROM_DATABASE=iFreecomm Technology Co., Ltd
+
 OUI:70B3D5033*
  ID_OUI_FROM_DATABASE=Sailmon BV
 
@@ -56273,6 +56702,9 @@ OUI:70B3D5063*
 OUI:70B3D5066*
  ID_OUI_FROM_DATABASE=North Pole Engineering, Inc.
 
+OUI:70B3D5069*
+ ID_OUI_FROM_DATABASE=ONDEMAND LABORATORY Co., Ltd.
+
 OUI:70B3D506B*
  ID_OUI_FROM_DATABASE=U-Tech
 
@@ -56282,6 +56714,9 @@ OUI:70B3D506C*
 OUI:70B3D5070*
  ID_OUI_FROM_DATABASE=Lumiplan Duhamel
 
+OUI:70B3D5075*
+ ID_OUI_FROM_DATABASE=Mo-Sys Engineering Ltd
+
 OUI:70B3D5077*
  ID_OUI_FROM_DATABASE=InAccess Networks SA
 
@@ -56318,6 +56753,9 @@ OUI:70B3D5087*
 OUI:70B3D5088*
  ID_OUI_FROM_DATABASE=OptiScan Biomedical Corp.
 
+OUI:70B3D508A*
+ ID_OUI_FROM_DATABASE=MB connect line GmbH Fernwartungssysteme
+
 OUI:70B3D508D*
  ID_OUI_FROM_DATABASE=Clover Electronics Technology Co., Ltd.
 
@@ -56339,12 +56777,18 @@ OUI:70B3D5092*
 OUI:70B3D5094*
  ID_OUI_FROM_DATABASE=Circuitlink Pty Ltd
 
+OUI:70B3D5096*
+ ID_OUI_FROM_DATABASE=HAVELSAN A.Ş.
+
 OUI:70B3D5097*
  ID_OUI_FROM_DATABASE=Avant Technologies
 
 OUI:70B3D5099*
  ID_OUI_FROM_DATABASE=Schwer+Kopka GmbH
 
+OUI:70B3D509B*
+ ID_OUI_FROM_DATABASE=Jacarta Ltd
+
 OUI:70B3D509D*
  ID_OUI_FROM_DATABASE=P&S GmbH
 
@@ -56387,6 +56831,9 @@ OUI:70B3D50AB*
 OUI:70B3D50AE*
  ID_OUI_FROM_DATABASE=Norsat International Inc.
 
+OUI:70B3D50AF*
+ ID_OUI_FROM_DATABASE=KMtronic ltd
+
 OUI:70B3D50B0*
  ID_OUI_FROM_DATABASE=Raven Systems Design, Inc
 
@@ -56507,6 +56954,12 @@ OUI:70B3D50F0*
 OUI:70B3D50F1*
  ID_OUI_FROM_DATABASE=Beijing One City Science & Technology Co., LTD
 
+OUI:70B3D50F3*
+ ID_OUI_FROM_DATABASE=MonsoonRF, Inc.
+
+OUI:70B3D50F8*
+ ID_OUI_FROM_DATABASE=Special Services Group, LLC
+
 OUI:70B3D50FA*
  ID_OUI_FROM_DATABASE=InsideRF Co., Ltd.
 
@@ -56648,6 +57101,9 @@ OUI:70B3D5140*
 OUI:70B3D5142*
  ID_OUI_FROM_DATABASE=DAVE SRL
 
+OUI:70B3D5144*
+ ID_OUI_FROM_DATABASE=GS Elektromedizinsiche Geräte G. Stemple GmbH
+
 OUI:70B3D5146*
  ID_OUI_FROM_DATABASE=3City Electronics
 
@@ -56684,6 +57140,9 @@ OUI:70B3D5153*
 OUI:70B3D515C*
  ID_OUI_FROM_DATABASE=Woods Hole Oceanographic Institution
 
+OUI:70B3D515D*
+ ID_OUI_FROM_DATABASE=Vtron Pty Ltd
+
 OUI:70B3D515F*
  ID_OUI_FROM_DATABASE=SAVRONİK ELEKTRONİK
 
@@ -56852,6 +57311,9 @@ OUI:70B3D51B6*
 OUI:70B3D51B8*
  ID_OUI_FROM_DATABASE=OES Inc.
 
+OUI:70B3D51B9*
+ ID_OUI_FROM_DATABASE=RELISTE Ges.m.b.H.
+
 OUI:70B3D51BB*
  ID_OUI_FROM_DATABASE=EFENTO T P SZYDŁOWSKI K ZARĘBA SPÓŁKA JAWNA
 
@@ -56867,6 +57329,12 @@ OUI:70B3D51C7*
 OUI:70B3D51C8*
  ID_OUI_FROM_DATABASE=LDA audio video profesional S.L.
 
+OUI:70B3D51CB*
+ ID_OUI_FROM_DATABASE=MatchX GmbH
+
+OUI:70B3D51D0*
+ ID_OUI_FROM_DATABASE=Shenzhen INVT Electric Co.,Ltd
+
 OUI:70B3D51D4*
  ID_OUI_FROM_DATABASE=Brinkmann Audio GmbH
 
@@ -56936,6 +57404,9 @@ OUI:70B3D5204*
 OUI:70B3D5205*
  ID_OUI_FROM_DATABASE=Esource Srl
 
+OUI:70B3D5207*
+ ID_OUI_FROM_DATABASE=Savari Inc
+
 OUI:70B3D5208*
  ID_OUI_FROM_DATABASE=DSP DESIGN LTD
 
@@ -56972,6 +57443,9 @@ OUI:70B3D5216*
 OUI:70B3D5217*
  ID_OUI_FROM_DATABASE=Tecnint HTE SRL
 
+OUI:70B3D521B*
+ ID_OUI_FROM_DATABASE=Lab241 Co.,Ltd.
+
 OUI:70B3D521D*
  ID_OUI_FROM_DATABASE=iRF - Intelligent RF Solutions, LLC
 
@@ -56990,6 +57464,9 @@ OUI:70B3D5226*
 OUI:70B3D5227*
  ID_OUI_FROM_DATABASE=Montalvo
 
+OUI:70B3D5228*
+ ID_OUI_FROM_DATABASE=HEITEC AG
+
 OUI:70B3D5229*
  ID_OUI_FROM_DATABASE=CONTROL SYSTEMS Srl
 
@@ -57041,6 +57518,9 @@ OUI:70B3D524B*
 OUI:70B3D524D*
  ID_OUI_FROM_DATABASE=INFO CREATIVE (HK) LTD
 
+OUI:70B3D524F*
+ ID_OUI_FROM_DATABASE=ELBIT SYSTEMS BMD AND LAND EW - ELISRA LTD
+
 OUI:70B3D5250*
  ID_OUI_FROM_DATABASE=Datum Electronics Limited
 
@@ -57062,6 +57542,9 @@ OUI:70B3D525A*
 OUI:70B3D525B*
  ID_OUI_FROM_DATABASE=GID Industrial
 
+OUI:70B3D525D*
+ ID_OUI_FROM_DATABASE=Mimo Networks
+
 OUI:70B3D5260*
  ID_OUI_FROM_DATABASE=ModuSystems, Inc
 
@@ -57194,6 +57677,9 @@ OUI:70B3D52AC*
 OUI:70B3D52AD*
  ID_OUI_FROM_DATABASE=Opgal Optronic Industries
 
+OUI:70B3D52AE*
+ ID_OUI_FROM_DATABASE=Alere Technologies AS
+
 OUI:70B3D52B0*
  ID_OUI_FROM_DATABASE=Beijing Zhongyi Yue Tai Technology Co., Ltd
 
@@ -57206,6 +57692,9 @@ OUI:70B3D52B3*
 OUI:70B3D52B4*
  ID_OUI_FROM_DATABASE=Foerster-Technik GmbH
 
+OUI:70B3D52B7*
+ ID_OUI_FROM_DATABASE=Matrix Orbital Corporation
+
 OUI:70B3D52B9*
  ID_OUI_FROM_DATABASE=BELECTRIC GmbH
 
@@ -57329,6 +57818,9 @@ OUI:70B3D5300*
 OUI:70B3D5303*
  ID_OUI_FROM_DATABASE=Fuchu Giken, Inc.
 
+OUI:70B3D5304*
+ ID_OUI_FROM_DATABASE=Transas Marine Limited
+
 OUI:70B3D5305*
  ID_OUI_FROM_DATABASE=CAITRON Industrial Solutions GmbH
 
@@ -57407,6 +57899,9 @@ OUI:70B3D533C*
 OUI:70B3D533E*
  ID_OUI_FROM_DATABASE=Dynamic Connect (Suzhou) Hi-Tech Electronic Co.,Ltd.
 
+OUI:70B3D5340*
+ ID_OUI_FROM_DATABASE=Renesas Electronics
+
 OUI:70B3D5341*
  ID_OUI_FROM_DATABASE=Vtron Pty Ltd
 
@@ -57443,6 +57938,9 @@ OUI:70B3D534E*
 OUI:70B3D5350*
  ID_OUI_FROM_DATABASE=Tickster AB
 
+OUI:70B3D5351*
+ ID_OUI_FROM_DATABASE=KST technology
+
 OUI:70B3D5352*
  ID_OUI_FROM_DATABASE=Globalcom Engineering SPA
 
@@ -57485,6 +57983,9 @@ OUI:70B3D5365*
 OUI:70B3D5367*
  ID_OUI_FROM_DATABASE=Living Water
 
+OUI:70B3D5368*
+ ID_OUI_FROM_DATABASE=White Matter LLC
+
 OUI:70B3D536A*
  ID_OUI_FROM_DATABASE=Becton Dickinson
 
@@ -57605,6 +58106,9 @@ OUI:70B3D53AF*
 OUI:70B3D53B2*
  ID_OUI_FROM_DATABASE=Sicon srl
 
+OUI:70B3D53B5*
+ ID_OUI_FROM_DATABASE=Preston Industries dba PolyScience
+
 OUI:70B3D53B7*
  ID_OUI_FROM_DATABASE=Paul Scherrer Institut (PSI)
 
@@ -57746,6 +58250,9 @@ OUI:70B3D5408*
 OUI:70B3D540A*
  ID_OUI_FROM_DATABASE=Monroe Electronics, Inc.
 
+OUI:70B3D5410*
+ ID_OUI_FROM_DATABASE=Avant Technologies, Inc
+
 OUI:70B3D5412*
  ID_OUI_FROM_DATABASE=TATTILE SRL
 
@@ -57899,6 +58406,9 @@ OUI:70B3D547C*
 OUI:70B3D547F*
  ID_OUI_FROM_DATABASE=ASE GmbH
 
+OUI:70B3D5480*
+ ID_OUI_FROM_DATABASE=Emergency Lighting Products Limited
+
 OUI:70B3D5482*
  ID_OUI_FROM_DATABASE=Aeryon Labs Inc
 
@@ -57956,6 +58466,9 @@ OUI:70B3D549E*
 OUI:70B3D549F*
  ID_OUI_FROM_DATABASE=B.P.A. SRL
 
+OUI:70B3D54A0*
+ ID_OUI_FROM_DATABASE=FLUDIA
+
 OUI:70B3D54A1*
  ID_OUI_FROM_DATABASE=Herholdt Controls srl
 
@@ -58040,6 +58553,9 @@ OUI:70B3D54CF*
 OUI:70B3D54D1*
  ID_OUI_FROM_DATABASE=Contraves Advanced Devices Sdn. Bhd.
 
+OUI:70B3D54D4*
+ ID_OUI_FROM_DATABASE=Nortek Global HVAC
+
 OUI:70B3D54D5*
  ID_OUI_FROM_DATABASE=Moog Rekofa  GmbH
 
@@ -58061,6 +58577,9 @@ OUI:70B3D54DE*
 OUI:70B3D54DF*
  ID_OUI_FROM_DATABASE=Nidec Avtron Automation Corp
 
+OUI:70B3D54E1*
+ ID_OUI_FROM_DATABASE=Grupo Epelsa S.L.
+
 OUI:70B3D54E5*
  ID_OUI_FROM_DATABASE=viZaar industrial imaging AG
 
@@ -58085,6 +58604,9 @@ OUI:70B3D54F4*
 OUI:70B3D54F8*
  ID_OUI_FROM_DATABASE=Private
 
+OUI:70B3D54F9*
+ ID_OUI_FROM_DATABASE=OptoPrecision GmbH
+
 OUI:70B3D54FC*
  ID_OUI_FROM_DATABASE=Mettler Toledo
 
@@ -58148,6 +58670,9 @@ OUI:70B3D5523*
 OUI:70B3D5524*
  ID_OUI_FROM_DATABASE=Wuxi New Optical Communication Co.,Ltd.
 
+OUI:70B3D5525*
+ ID_OUI_FROM_DATABASE=Plantiga Technologies Inc
+
 OUI:70B3D5528*
  ID_OUI_FROM_DATABASE=Aplex Technology Inc.
 
@@ -58412,15 +58937,24 @@ OUI:70B3D55D6*
 OUI:70B3D55D8*
  ID_OUI_FROM_DATABASE=LYNX Technik AG
 
+OUI:70B3D55DA*
+ ID_OUI_FROM_DATABASE=Valk Welding B.V.
+
 OUI:70B3D55DB*
  ID_OUI_FROM_DATABASE=Movicom LLC
 
+OUI:70B3D55DC*
+ ID_OUI_FROM_DATABASE=FactoryLab B.V.
+
 OUI:70B3D55E0*
  ID_OUI_FROM_DATABASE=Hexagon Metrology SAS
 
 OUI:70B3D55E2*
  ID_OUI_FROM_DATABASE=Grossenbacher Systeme AG
 
+OUI:70B3D55E3*
+ ID_OUI_FROM_DATABASE=Imecon Engineering SrL
+
 OUI:70B3D55E4*
  ID_OUI_FROM_DATABASE=DSP DESIGN
 
@@ -58475,6 +59009,9 @@ OUI:70B3D55FF*
 OUI:70B3D5600*
  ID_OUI_FROM_DATABASE=Stellwerk GmbH
 
+OUI:70B3D5602*
+ ID_OUI_FROM_DATABASE=Quantum Opus, LLC
+
 OUI:70B3D5605*
  ID_OUI_FROM_DATABASE=Aplex Technology Inc.
 
@@ -58508,6 +59045,9 @@ OUI:70B3D560F*
 OUI:70B3D5610*
  ID_OUI_FROM_DATABASE=POLVISION
 
+OUI:70B3D5611*
+ ID_OUI_FROM_DATABASE=Avionica
+
 OUI:70B3D5615*
  ID_OUI_FROM_DATABASE=JSC OTZVUK
 
@@ -58545,7 +59085,7 @@ OUI:70B3D5630*
  ID_OUI_FROM_DATABASE=LGE
 
 OUI:70B3D5631*
- ID_OUI_FROM_DATABASE=SENSO2ME bvba
+ ID_OUI_FROM_DATABASE=SENSO2ME
 
 OUI:70B3D5634*
  ID_OUI_FROM_DATABASE=idaqs Co.,Ltd.
@@ -58565,9 +59105,15 @@ OUI:70B3D563B*
 OUI:70B3D563C*
  ID_OUI_FROM_DATABASE=Pivothead
 
+OUI:70B3D563D*
+ ID_OUI_FROM_DATABASE=Storbyte, Inc.
+
 OUI:70B3D563E*
  ID_OUI_FROM_DATABASE=RIKEN OPTECH CORPORATION
 
+OUI:70B3D563F*
+ ID_OUI_FROM_DATABASE=YG COMPANY CO., LTD
+
 OUI:70B3D5640*
  ID_OUI_FROM_DATABASE=Electronic Equipment Company Pvt. Ltd.
 
@@ -58643,6 +59189,9 @@ OUI:70B3D5666*
 OUI:70B3D566B*
  ID_OUI_FROM_DATABASE=Innitive B.V.
 
+OUI:70B3D5670*
+ ID_OUI_FROM_DATABASE=Particle sizing systems
+
 OUI:70B3D5671*
  ID_OUI_FROM_DATABASE=Sea Shell Corporation
 
@@ -58667,6 +59216,9 @@ OUI:70B3D567B*
 OUI:70B3D5682*
  ID_OUI_FROM_DATABASE=Rosslare Enterprises Limited
 
+OUI:70B3D5689*
+ ID_OUI_FROM_DATABASE=Prisma Telecom Testing Srl
+
 OUI:70B3D568C*
  ID_OUI_FROM_DATABASE=ND METER
 
@@ -58787,6 +59339,9 @@ OUI:70B3D56DF*
 OUI:70B3D56E0*
  ID_OUI_FROM_DATABASE=ABB SPA - DMPC
 
+OUI:70B3D56E1*
+ ID_OUI_FROM_DATABASE=Shanghai Holystar Information Technology Co.,Ltd
+
 OUI:70B3D56E4*
  ID_OUI_FROM_DATABASE=Institute of Power Engineering, Gdansk Division
 
@@ -58802,9 +59357,15 @@ OUI:70B3D56E7*
 OUI:70B3D56E8*
  ID_OUI_FROM_DATABASE=Blu Wireless Technology Ltd
 
+OUI:70B3D56E9*
+ ID_OUI_FROM_DATABASE=Krontech
+
 OUI:70B3D56EA*
  ID_OUI_FROM_DATABASE=Edgeware AB
 
+OUI:70B3D56EB*
+ ID_OUI_FROM_DATABASE=QUANTAFLOW
+
 OUI:70B3D56EC*
  ID_OUI_FROM_DATABASE=CRDE
 
@@ -58841,12 +59402,18 @@ OUI:70B3D56FD*
 OUI:70B3D56FF*
  ID_OUI_FROM_DATABASE=AKEO PLUS
 
+OUI:70B3D5700*
+ ID_OUI_FROM_DATABASE=University Of Groningen
+
 OUI:70B3D5702*
  ID_OUI_FROM_DATABASE=Sensor Highway Ltd
 
 OUI:70B3D5703*
  ID_OUI_FROM_DATABASE=StromIdee GmbH
 
+OUI:70B3D5704*
+ ID_OUI_FROM_DATABASE=Melecs EWS GmbH
+
 OUI:70B3D5705*
  ID_OUI_FROM_DATABASE=Digital Matter Pty Ltd
 
@@ -58862,6 +59429,9 @@ OUI:70B3D570F*
 OUI:70B3D5710*
  ID_OUI_FROM_DATABASE=Guardian Controls International Ltd
 
+OUI:70B3D5711*
+ ID_OUI_FROM_DATABASE=X-Laser LLC
+
 OUI:70B3D5712*
  ID_OUI_FROM_DATABASE=APG Cash Drawer, LLC
 
@@ -58952,6 +59522,9 @@ OUI:70B3D5741*
 OUI:70B3D5742*
  ID_OUI_FROM_DATABASE=YUYAMA MFG Co.,Ltd
 
+OUI:70B3D5743*
+ ID_OUI_FROM_DATABASE=EA Elektroautomatik GmbH & Co. KG
+
 OUI:70B3D5745*
  ID_OUI_FROM_DATABASE=TMSI LLC
 
@@ -58997,6 +59570,9 @@ OUI:70B3D575C*
 OUI:70B3D575D*
  ID_OUI_FROM_DATABASE=Nanjing Magewell Electronics Co., Ltd.
 
+OUI:70B3D575E*
+ ID_OUI_FROM_DATABASE=Cardinal Health
+
 OUI:70B3D5760*
  ID_OUI_FROM_DATABASE=QUALITTEQ LLC
 
@@ -59069,6 +59645,9 @@ OUI:70B3D5781*
 OUI:70B3D5782*
  ID_OUI_FROM_DATABASE=thou&tech
 
+OUI:70B3D5784*
+ ID_OUI_FROM_DATABASE=Shenzhen bayue software co. LTD
+
 OUI:70B3D5785*
  ID_OUI_FROM_DATABASE=Density Inc.
 
@@ -59114,6 +59693,9 @@ OUI:70B3D57A1*
 OUI:70B3D57A2*
  ID_OUI_FROM_DATABASE=Alpha ESS Co., Ltd.
 
+OUI:70B3D57A3*
+ ID_OUI_FROM_DATABASE=Impulse Automation
+
 OUI:70B3D57A4*
  ID_OUI_FROM_DATABASE=Potter Electric Signal Co. LLC
 
@@ -59136,7 +59718,7 @@ OUI:70B3D57AB*
  ID_OUI_FROM_DATABASE=Microgate Srl
 
 OUI:70B3D57AD*
- ID_OUI_FROM_DATABASE=Insitu Inc
+ ID_OUI_FROM_DATABASE=Insitu, Inc
 
 OUI:70B3D57AE*
  ID_OUI_FROM_DATABASE=Exi Flow Measurement Ltd
@@ -59168,6 +59750,12 @@ OUI:70B3D57B8*
 OUI:70B3D57B9*
  ID_OUI_FROM_DATABASE=QIAGEN Instruments AG
 
+OUI:70B3D57BF*
+ ID_OUI_FROM_DATABASE=Stone Three
+
+OUI:70B3D57C0*
+ ID_OUI_FROM_DATABASE=TORGOVYY DOM  TEHNOLOGIY LLC
+
 OUI:70B3D57C1*
  ID_OUI_FROM_DATABASE=Data Sciences International
 
@@ -59240,6 +59828,9 @@ OUI:70B3D57E8*
 OUI:70B3D57E9*
  ID_OUI_FROM_DATABASE=Mecsel Oy
 
+OUI:70B3D57EA*
+ ID_OUI_FROM_DATABASE=Waterkotte GmbH
+
 OUI:70B3D57EB*
  ID_OUI_FROM_DATABASE=Xerox International Partners
 
@@ -59372,6 +59963,9 @@ OUI:70B3D5833*
 OUI:70B3D5835*
  ID_OUI_FROM_DATABASE=CommBox P/L
 
+OUI:70B3D5837*
+ ID_OUI_FROM_DATABASE=HiDes, Inc.
+
 OUI:70B3D5838*
  ID_OUI_FROM_DATABASE=Tofino
 
@@ -59423,6 +60017,9 @@ OUI:70B3D5850*
 OUI:70B3D5852*
  ID_OUI_FROM_DATABASE=NetBoxSC, LLC
 
+OUI:70B3D5853*
+ ID_OUI_FROM_DATABASE=HGH SYSTEMES INFRAROUGES
+
 OUI:70B3D5854*
  ID_OUI_FROM_DATABASE=Adimec Advanced Image Systems
 
@@ -59591,6 +60188,9 @@ OUI:70B3D58C3*
 OUI:70B3D58C5*
  ID_OUI_FROM_DATABASE=HMicro Inc
 
+OUI:70B3D58C8*
+ ID_OUI_FROM_DATABASE=KRONOTECH SRL
+
 OUI:70B3D58CA*
  ID_OUI_FROM_DATABASE=Allied Data Systems
 
@@ -59603,6 +60203,9 @@ OUI:70B3D58CE*
 OUI:70B3D58CF*
  ID_OUI_FROM_DATABASE=Dainichi Denshi Co.,LTD
 
+OUI:70B3D58D0*
+ ID_OUI_FROM_DATABASE=Raft Technologies
+
 OUI:70B3D58D3*
  ID_OUI_FROM_DATABASE=PERFORMANCE CONTROLS, INC.
 
@@ -59780,6 +60383,9 @@ OUI:70B3D5945*
 OUI:70B3D5947*
  ID_OUI_FROM_DATABASE=Checkbill Co,Ltd.
 
+OUI:70B3D594A*
+ ID_OUI_FROM_DATABASE=SHENZHEN WISEWING INTERNET TECHNOLOGY CO.,LTD
+
 OUI:70B3D594D*
  ID_OUI_FROM_DATABASE=SEASON DESIGN TECHNOLOGY
 
@@ -59822,6 +60428,9 @@ OUI:70B3D595C*
 OUI:70B3D595E*
  ID_OUI_FROM_DATABASE=BLOCKSI LLC
 
+OUI:70B3D5963*
+ ID_OUI_FROM_DATABASE=Triax A/S
+
 OUI:70B3D5967*
  ID_OUI_FROM_DATABASE=TATTILE SRL
 
@@ -59855,6 +60464,9 @@ OUI:70B3D597C*
 OUI:70B3D597F*
  ID_OUI_FROM_DATABASE=BISTOS.,Co.,Ltd
 
+OUI:70B3D5981*
+ ID_OUI_FROM_DATABASE=Zamir Recognition Systems Ltd.
+
 OUI:70B3D5986*
  ID_OUI_FROM_DATABASE=Aplex Technology Inc.
 
@@ -59864,6 +60476,9 @@ OUI:70B3D5987*
 OUI:70B3D5989*
  ID_OUI_FROM_DATABASE=DCNS
 
+OUI:70B3D598B*
+ ID_OUI_FROM_DATABASE=Richard Paul Russell Ltd
+
 OUI:70B3D598C*
  ID_OUI_FROM_DATABASE=University of Wisconsin Madison - Department of High Energy Physics
 
@@ -59903,6 +60518,9 @@ OUI:70B3D599E*
 OUI:70B3D599F*
  ID_OUI_FROM_DATABASE=Confed Holding B.V.
 
+OUI:70B3D59A0*
+ ID_OUI_FROM_DATABASE=ELDES
+
 OUI:70B3D59A1*
  ID_OUI_FROM_DATABASE=ITS Industrial Turbine Services GmbH
 
@@ -60005,6 +60623,9 @@ OUI:70B3D59E0*
 OUI:70B3D59E2*
  ID_OUI_FROM_DATABASE=Ofil USA
 
+OUI:70B3D59E6*
+ ID_OUI_FROM_DATABASE=BLOCKSI LLC
+
 OUI:70B3D59E7*
  ID_OUI_FROM_DATABASE=Xiamen Maxincom Technologies Co., Ltd.
 
@@ -60077,6 +60698,9 @@ OUI:70B3D5A08*
 OUI:70B3D5A0B*
  ID_OUI_FROM_DATABASE=ambiHome GmbH
 
+OUI:70B3D5A0D*
+ ID_OUI_FROM_DATABASE=Globalcom Engineering SPA
+
 OUI:70B3D5A0E*
  ID_OUI_FROM_DATABASE=Vetaphone A/S
 
@@ -60089,6 +60713,9 @@ OUI:70B3D5A12*
 OUI:70B3D5A15*
  ID_OUI_FROM_DATABASE=Intercore GmbH
 
+OUI:70B3D5A17*
+ ID_OUI_FROM_DATABASE=Tunstall A/S
+
 OUI:70B3D5A18*
  ID_OUI_FROM_DATABASE=Embedded Systems Lukasz Panasiuk
 
@@ -60125,6 +60752,9 @@ OUI:70B3D5A27*
 OUI:70B3D5A28*
  ID_OUI_FROM_DATABASE=PEEK TRAFFIC
 
+OUI:70B3D5A29*
+ ID_OUI_FROM_DATABASE=QIAGEN Instruments AG
+
 OUI:70B3D5A2A*
  ID_OUI_FROM_DATABASE=Redwood Systems
 
@@ -60152,6 +60782,9 @@ OUI:70B3D5A35*
 OUI:70B3D5A36*
  ID_OUI_FROM_DATABASE=Beijing DamingWuzhou Science&Technology Co., Ltd.
 
+OUI:70B3D5A3A*
+ ID_OUI_FROM_DATABASE=EPSOFT Co., Ltd
+
 OUI:70B3D5A3B*
  ID_OUI_FROM_DATABASE=Grace Design/Lunatec LLC
 
@@ -60164,6 +60797,9 @@ OUI:70B3D5A3F*
 OUI:70B3D5A40*
  ID_OUI_FROM_DATABASE=STRACK LIFT AUTOMATION GmbH
 
+OUI:70B3D5A43*
+ ID_OUI_FROM_DATABASE=OLEDCOMM
+
 OUI:70B3D5A44*
  ID_OUI_FROM_DATABASE=FSR Inc
 
@@ -60266,6 +60902,9 @@ OUI:70B3D5A81*
 OUI:70B3D5A85*
  ID_OUI_FROM_DATABASE=exceet electronics GesmbH
 
+OUI:70B3D5A86*
+ ID_OUI_FROM_DATABASE=Divigraph (Pty) LTD
+
 OUI:70B3D5A88*
  ID_OUI_FROM_DATABASE=Shangdong Bosure Automation Technology Ltd
 
@@ -60371,6 +61010,9 @@ OUI:70B3D5ABE*
 OUI:70B3D5ABF*
  ID_OUI_FROM_DATABASE=AGR International
 
+OUI:70B3D5AC1*
+ ID_OUI_FROM_DATABASE=AEM Singapore Pte. Ltd.
+
 OUI:70B3D5AC3*
  ID_OUI_FROM_DATABASE=Novoptel GmbH
 
@@ -60443,6 +61085,9 @@ OUI:70B3D5AE9*
 OUI:70B3D5AEA*
  ID_OUI_FROM_DATABASE=BBR Verkehrstechnik GmbH
 
+OUI:70B3D5AEB*
+ ID_OUI_FROM_DATABASE=Association Romandix
+
 OUI:70B3D5AEE*
  ID_OUI_FROM_DATABASE=DiTEST Fahrzeugdiagnose GmbH
 
@@ -60455,6 +61100,9 @@ OUI:70B3D5AF0*
 OUI:70B3D5AF1*
  ID_OUI_FROM_DATABASE=Emka Technologies
 
+OUI:70B3D5AF2*
+ ID_OUI_FROM_DATABASE=True Networks Ltd.
+
 OUI:70B3D5AF3*
  ID_OUI_FROM_DATABASE=New Japan Radio Co., Ltd
 
@@ -60518,6 +61166,12 @@ OUI:70B3D5B15*
 OUI:70B3D5B16*
  ID_OUI_FROM_DATABASE=XI'AN SHENMING ELECTRON TECHNOLOGY CO.,LTD
 
+OUI:70B3D5B17*
+ ID_OUI_FROM_DATABASE=Intesens
+
+OUI:70B3D5B18*
+ ID_OUI_FROM_DATABASE=Abbas, a.s.
+
 OUI:70B3D5B1A*
  ID_OUI_FROM_DATABASE=Aaronia AG
 
@@ -60575,6 +61229,9 @@ OUI:70B3D5B39*
 OUI:70B3D5B3A*
  ID_OUI_FROM_DATABASE=Adigitalmedia
 
+OUI:70B3D5B3B*
+ ID_OUI_FROM_DATABASE=Insitu, Inc
+
 OUI:70B3D5B3C*
  ID_OUI_FROM_DATABASE=DORLET SAU
 
@@ -60620,6 +61277,9 @@ OUI:70B3D5B5C*
 OUI:70B3D5B62*
  ID_OUI_FROM_DATABASE=Sakura Seiki Co.,Ltd.
 
+OUI:70B3D5B64*
+ ID_OUI_FROM_DATABASE=OSUNG LST CO.,LTD.
+
 OUI:70B3D5B67*
  ID_OUI_FROM_DATABASE=RedWave Labs Ltd
 
@@ -60725,6 +61385,9 @@ OUI:70B3D5BAA*
 OUI:70B3D5BAB*
  ID_OUI_FROM_DATABASE=Axotec Technologies GmbH
 
+OUI:70B3D5BAC*
+ ID_OUI_FROM_DATABASE=AdInte, inc.
+
 OUI:70B3D5BAD*
  ID_OUI_FROM_DATABASE=Technik & Design GmbH
 
@@ -60746,6 +61409,9 @@ OUI:70B3D5BB7*
 OUI:70B3D5BB8*
  ID_OUI_FROM_DATABASE=Al Kamel Systems S.L.
 
+OUI:70B3D5BB9*
+ ID_OUI_FROM_DATABASE=KOSMEK.Ltd
+
 OUI:70B3D5BBD*
  ID_OUI_FROM_DATABASE=Providius Corp
 
@@ -60794,6 +61460,9 @@ OUI:70B3D5BE1*
 OUI:70B3D5BE3*
  ID_OUI_FROM_DATABASE=Saratov Electrounit Production Plant named after Sergo Ordzhonikidze, OJSC
 
+OUI:70B3D5BE4*
+ ID_OUI_FROM_DATABASE=Kunshan excellent Intelligent Technology Co., Ltd.
+
 OUI:70B3D5BE5*
  ID_OUI_FROM_DATABASE=Pantec Engineering AG
 
@@ -60833,6 +61502,9 @@ OUI:70B3D5BF5*
 OUI:70B3D5BF6*
  ID_OUI_FROM_DATABASE=comtac AG
 
+OUI:70B3D5BFA*
+ ID_OUI_FROM_DATABASE=NESA SRL
+
 OUI:70B3D5BFB*
  ID_OUI_FROM_DATABASE=Sensor 42
 
@@ -60914,6 +61586,9 @@ OUI:70B3D5C2C*
 OUI:70B3D5C2E*
  ID_OUI_FROM_DATABASE=Triax A/S
 
+OUI:70B3D5C2F*
+ ID_OUI_FROM_DATABASE=ATBiS Co.,Ltd
+
 OUI:70B3D5C32*
  ID_OUI_FROM_DATABASE=INFRASAFE/ ADVANTOR SYSTEMS
 
@@ -61004,6 +61679,9 @@ OUI:70B3D5C62*
 OUI:70B3D5C63*
  ID_OUI_FROM_DATABASE=Xentech Solutions Limited
 
+OUI:70B3D5C67*
+ ID_OUI_FROM_DATABASE=Collini Dienstleistungs GmbH
+
 OUI:70B3D5C68*
  ID_OUI_FROM_DATABASE=Mini Solution Co. Ltd.
 
@@ -61073,6 +61751,9 @@ OUI:70B3D5C8C*
 OUI:70B3D5C8D*
  ID_OUI_FROM_DATABASE=KST technology
 
+OUI:70B3D5C8F*
+ ID_OUI_FROM_DATABASE=TRIDENT INFOSOL PVT LTD
+
 OUI:70B3D5C91*
  ID_OUI_FROM_DATABASE=Grossenbacher Systeme AG
 
@@ -61121,6 +61802,9 @@ OUI:70B3D5CB2*
 OUI:70B3D5CB3*
  ID_OUI_FROM_DATABASE=KST technology
 
+OUI:70B3D5CB4*
+ ID_OUI_FROM_DATABASE=Planewave Instruments
+
 OUI:70B3D5CB6*
  ID_OUI_FROM_DATABASE=Kuebrich Ingeniergesellschaft mbh & Co. KG
 
@@ -61154,6 +61838,9 @@ OUI:70B3D5CC9*
 OUI:70B3D5CCA*
  ID_OUI_FROM_DATABASE=SIEMENS AS
 
+OUI:70B3D5CCB*
+ ID_OUI_FROM_DATABASE=RealD
+
 OUI:70B3D5CCC*
  ID_OUI_FROM_DATABASE=AEC s.r.l.
 
@@ -61184,6 +61871,9 @@ OUI:70B3D5CD6*
 OUI:70B3D5CD9*
  ID_OUI_FROM_DATABASE=Peter Huber Kaeltemaschinenbau GmbH
 
+OUI:70B3D5CDA*
+ ID_OUI_FROM_DATABASE=VITEC
+
 OUI:70B3D5CDE*
  ID_OUI_FROM_DATABASE=Multipure International
 
@@ -61430,6 +62120,9 @@ OUI:70B3D5D79*
 OUI:70B3D5D7A*
  ID_OUI_FROM_DATABASE=Speedifi Inc
 
+OUI:70B3D5D7B*
+ ID_OUI_FROM_DATABASE=Peter Huber Kaeltemaschinenbau AG
+
 OUI:70B3D5D7E*
  ID_OUI_FROM_DATABASE=Triax A/S
 
@@ -61514,6 +62207,9 @@ OUI:70B3D5DA4*
 OUI:70B3D5DA8*
  ID_OUI_FROM_DATABASE=Tagarno AS
 
+OUI:70B3D5DAA*
+ ID_OUI_FROM_DATABASE=AmTote Australasia
+
 OUI:70B3D5DAD*
  ID_OUI_FROM_DATABASE=GD Mission Systems
 
@@ -61532,6 +62228,9 @@ OUI:70B3D5DB5*
 OUI:70B3D5DB8*
  ID_OUI_FROM_DATABASE=SISTEM SA
 
+OUI:70B3D5DBF*
+ ID_OUI_FROM_DATABASE=Infodev Electronic Designers Intl.
+
 OUI:70B3D5DC0*
  ID_OUI_FROM_DATABASE=ATEME
 
@@ -61595,6 +62294,9 @@ OUI:70B3D5DE7*
 OUI:70B3D5DE8*
  ID_OUI_FROM_DATABASE=Nation-E Ltd.
 
+OUI:70B3D5DE9*
+ ID_OUI_FROM_DATABASE=Private
+
 OUI:70B3D5DEC*
  ID_OUI_FROM_DATABASE=Condev-Automation GmbH
 
@@ -61667,6 +62369,9 @@ OUI:70B3D5E18*
 OUI:70B3D5E1A*
  ID_OUI_FROM_DATABASE=BIZERBA LUCEO
 
+OUI:70B3D5E1B*
+ ID_OUI_FROM_DATABASE=Neuron GmbH
+
 OUI:70B3D5E1C*
  ID_OUI_FROM_DATABASE=Xcenter AS
 
@@ -61709,6 +62414,9 @@ OUI:70B3D5E36*
 OUI:70B3D5E39*
  ID_OUI_FROM_DATABASE=Thinnect, Inc,
 
+OUI:70B3D5E3A*
+ ID_OUI_FROM_DATABASE=Cyanview
+
 OUI:70B3D5E3B*
  ID_OUI_FROM_DATABASE=ComNav Technology Ltd.
 
@@ -61769,6 +62477,9 @@ OUI:70B3D5E5E*
 OUI:70B3D5E67*
  ID_OUI_FROM_DATABASE=APPLIED PROCESSING
 
+OUI:70B3D5E69*
+ ID_OUI_FROM_DATABASE=Fire4 Systems UK Ltd
+
 OUI:70B3D5E6C*
  ID_OUI_FROM_DATABASE=Fusar Technologies inc
 
@@ -61817,6 +62528,9 @@ OUI:70B3D5E82*
 OUI:70B3D5E85*
  ID_OUI_FROM_DATABASE=Explorer Inc.
 
+OUI:70B3D5E86*
+ ID_OUI_FROM_DATABASE=YUYAMA MFG Co.,Ltd
+
 OUI:70B3D5E88*
  ID_OUI_FROM_DATABASE=Breas Medical AB
 
@@ -61895,6 +62609,12 @@ OUI:70B3D5EB1*
 OUI:70B3D5EB2*
  ID_OUI_FROM_DATABASE=Shooter Detection Systems
 
+OUI:70B3D5EB3*
+ ID_OUI_FROM_DATABASE=KWS-Electronic GmbH
+
+OUI:70B3D5EB5*
+ ID_OUI_FROM_DATABASE=JUSTEK INC
+
 OUI:70B3D5EB7*
  ID_OUI_FROM_DATABASE=Skreens
 
@@ -62141,6 +62861,9 @@ OUI:70B3D5F5B*
 OUI:70B3D5F5C*
  ID_OUI_FROM_DATABASE=Nable Communications, Inc.
 
+OUI:70B3D5F5E*
+ ID_OUI_FROM_DATABASE=Selex ES Inc.
+
 OUI:70B3D5F61*
  ID_OUI_FROM_DATABASE=Power Diagnostic Service
 
@@ -62186,6 +62909,9 @@ OUI:70B3D5F78*
 OUI:70B3D5F79*
  ID_OUI_FROM_DATABASE=Firehose Labs, Inc.
 
+OUI:70B3D5F7A*
+ ID_OUI_FROM_DATABASE=SENSO2ME
+
 OUI:70B3D5F7B*
  ID_OUI_FROM_DATABASE=KST technology
 
@@ -62201,6 +62927,9 @@ OUI:70B3D5F83*
 OUI:70B3D5F85*
  ID_OUI_FROM_DATABASE=Solystic
 
+OUI:70B3D5F87*
+ ID_OUI_FROM_DATABASE=SHINWA INDUSTRIES, INC.
+
 OUI:70B3D5F8B*
  ID_OUI_FROM_DATABASE=IOOOTA Srl
 
@@ -62213,6 +62942,9 @@ OUI:70B3D5F8D*
 OUI:70B3D5F8E*
  ID_OUI_FROM_DATABASE=Isabellenhütte Heusler Gmbh &Co KG
 
+OUI:70B3D5F8F*
+ ID_OUI_FROM_DATABASE=DIMASTEC GESTAO DE PONTO E ACESSO EIRELI-ME
+
 OUI:70B3D5F92*
  ID_OUI_FROM_DATABASE=TechOne
 
@@ -62225,6 +62957,9 @@ OUI:70B3D5F95*
 OUI:70B3D5F96*
  ID_OUI_FROM_DATABASE=Ecologicsense
 
+OUI:70B3D5F98*
+ ID_OUI_FROM_DATABASE=Metrum Sweden AB
+
 OUI:70B3D5F99*
  ID_OUI_FROM_DATABASE=TEX COMPUTER SRL
 
@@ -62246,6 +62981,9 @@ OUI:70B3D5FA1*
 OUI:70B3D5FA2*
  ID_OUI_FROM_DATABASE=Sarokal Test Systems Oy
 
+OUI:70B3D5FA3*
+ ID_OUI_FROM_DATABASE=ELVA-1 MICROWAVE HANDELSBOLAG
+
 OUI:70B3D5FA4*
  ID_OUI_FROM_DATABASE=Energybox Limited
 
@@ -62354,6 +63092,9 @@ OUI:70B3D5FDF*
 OUI:70B3D5FE2*
  ID_OUI_FROM_DATABASE=Galileo Tıp Teknolojileri San. ve Tic. A.S.
 
+OUI:70B3D5FE3*
+ ID_OUI_FROM_DATABASE=CSM MACHINERY srl
+
 OUI:70B3D5FE4*
  ID_OUI_FROM_DATABASE=CARE PVT LTD
 
@@ -62429,6 +63170,9 @@ OUI:70C6AC*
 OUI:70C76F*
  ID_OUI_FROM_DATABASE=INNO S
 
+OUI:70C94E*
+ ID_OUI_FROM_DATABASE=Liteon Technology Corporation
+
 OUI:70CA4D*
  ID_OUI_FROM_DATABASE=Shenzhen lnovance Technology Co.,Ltd.
 
@@ -62438,6 +63182,9 @@ OUI:70CA9B*
 OUI:70CD60*
  ID_OUI_FROM_DATABASE=Apple, Inc.
 
+OUI:70D081*
+ ID_OUI_FROM_DATABASE=Beijing Netpower Technologies Inc.
+
 OUI:70D379*
  ID_OUI_FROM_DATABASE=Cisco Systems, Inc
 
@@ -62516,6 +63263,9 @@ OUI:70EE50*
 OUI:70EEA3*
  ID_OUI_FROM_DATABASE=Eoptolink Technology Inc. Ltd,
 
+OUI:70EF00*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
 OUI:70F087*
  ID_OUI_FROM_DATABASE=Apple, Inc.
 
@@ -62534,6 +63284,9 @@ OUI:70F1A1*
 OUI:70F1E5*
  ID_OUI_FROM_DATABASE=Xetawave LLC
 
+OUI:70F220*
+ ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc
+
 OUI:70F35A*
  ID_OUI_FROM_DATABASE=Cisco Systems, Inc
 
@@ -62882,6 +63635,12 @@ OUI:746F3D*
 OUI:746FF7*
  ID_OUI_FROM_DATABASE=Wistron Neweb Corporation
 
+OUI:7470FD*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:74721E*
+ ID_OUI_FROM_DATABASE=Edison Labs Inc.
+
 OUI:7472B0*
  ID_OUI_FROM_DATABASE=Guangzhou Shiyuan Electronics Co., Ltd.
 
@@ -63182,6 +63941,9 @@ OUI:74E14AE*
 OUI:74E14AF*
  ID_OUI_FROM_DATABASE=Private
 
+OUI:74E182*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
 OUI:74E19A*
  ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
 
@@ -63353,6 +64115,9 @@ OUI:780AC7*
 OUI:780CB8*
  ID_OUI_FROM_DATABASE=Intel Corporate
 
+OUI:780F77*
+ ID_OUI_FROM_DATABASE=HangZhou Gubei Electronics Technology Co.,Ltd
+
 OUI:781185*
  ID_OUI_FROM_DATABASE=NBS Payment Solutions Inc.
 
@@ -63398,6 +64163,9 @@ OUI:7824AF*
 OUI:782544*
  ID_OUI_FROM_DATABASE=Omnima Limited
 
+OUI:78257A*
+ ID_OUI_FROM_DATABASE=LEO Innovation Lab
+
 OUI:7825AD*
  ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
 
@@ -63500,6 +64268,9 @@ OUI:78521A*
 OUI:785262*
  ID_OUI_FROM_DATABASE=Shenzhen Hojy Software Co., Ltd.
 
+OUI:785364*
+ ID_OUI_FROM_DATABASE=SHIFT GmbH
+
 OUI:7853F2*
  ID_OUI_FROM_DATABASE=ROXTON Ltd.
 
@@ -63512,6 +64283,9 @@ OUI:785517*
 OUI:785712*
  ID_OUI_FROM_DATABASE=Mobile Integration Workgroup
 
+OUI:785860*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
 OUI:7858F3*
  ID_OUI_FROM_DATABASE=Vachen Co.,Ltd
 
@@ -63530,6 +64304,9 @@ OUI:785C28*
 OUI:785C72*
  ID_OUI_FROM_DATABASE=Hioso Technology Co., Ltd.
 
+OUI:785DC8*
+ ID_OUI_FROM_DATABASE=LG Electronics
+
 OUI:785F4C*
  ID_OUI_FROM_DATABASE=Argox Information Co., Ltd.
 
@@ -63612,7 +64389,7 @@ OUI:788C4D*
  ID_OUI_FROM_DATABASE=Indyme Solutions, LLC
 
 OUI:788C54*
- ID_OUI_FROM_DATABASE=Eltek Technologies LTD
+ ID_OUI_FROM_DATABASE=Ping Communication
 
 OUI:788DF7*
  ID_OUI_FROM_DATABASE=Hitron Technologies. Inc
@@ -64163,6 +64940,9 @@ OUI:7C2048*
 OUI:7C2064*
  ID_OUI_FROM_DATABASE=Alcatel-Lucent IPD
 
+OUI:7C2586*
+ ID_OUI_FROM_DATABASE=Juniper Networks
+
 OUI:7C2587*
  ID_OUI_FROM_DATABASE=chaowifi.com
 
@@ -64172,6 +64952,9 @@ OUI:7C2634*
 OUI:7C2664*
  ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
 
+OUI:7C2A31*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
 OUI:7C2BE1*
  ID_OUI_FROM_DATABASE=Shenzhen Ferex Electrical Co.,Ltd
 
@@ -64202,6 +64985,9 @@ OUI:7C386C*
 OUI:7C3920*
  ID_OUI_FROM_DATABASE=SSOMA SECURITY
 
+OUI:7C3953*
+ ID_OUI_FROM_DATABASE=zte corporation
+
 OUI:7C3BD5*
  ID_OUI_FROM_DATABASE=Imago Group
 
@@ -64268,6 +65054,9 @@ OUI:7C477CE*
 OUI:7C49B9*
  ID_OUI_FROM_DATABASE=Plexus Manufacturing Sdn Bhd
 
+OUI:7C49EB*
+ ID_OUI_FROM_DATABASE=XIAOMI Electronics,CO.,LTD
+
 OUI:7C4A82*
  ID_OUI_FROM_DATABASE=Portsmith LLC
 
@@ -64814,6 +65603,9 @@ OUI:7CFE4E*
 OUI:7CFE90*
  ID_OUI_FROM_DATABASE=Mellanox Technologies, Inc.
 
+OUI:7CFF4D*
+ ID_OUI_FROM_DATABASE=AVM Audiovisuelles Marketing und Computersysteme GmbH
+
 OUI:7CFF62*
  ID_OUI_FROM_DATABASE=Huizhou Super Electron Technology Co.,Ltd.
 
@@ -64913,6 +65705,9 @@ OUI:801DAA*
 OUI:801F02*
  ID_OUI_FROM_DATABASE=Edimax Technology Co. Ltd.
 
+OUI:801F12*
+ ID_OUI_FROM_DATABASE=Microchip Technology Inc.
+
 OUI:8020AF*
  ID_OUI_FROM_DATABASE=Trade FIDES, a.s.
 
@@ -64985,6 +65780,9 @@ OUI:803F5D*
 OUI:803FD6*
  ID_OUI_FROM_DATABASE=bytes at work AG
 
+OUI:804126*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
 OUI:80414E*
  ID_OUI_FROM_DATABASE=BBK EDUCATIONAL ELECTRONICS CORP.,LTD.
 
@@ -65003,6 +65801,9 @@ OUI:804971*
 OUI:804B20*
  ID_OUI_FROM_DATABASE=Ventilation Control
 
+OUI:804E70*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
 OUI:804E81*
  ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
 
@@ -65228,6 +66029,9 @@ OUI:80AAA4*
 OUI:80ACAC*
  ID_OUI_FROM_DATABASE=Juniper Networks
 
+OUI:80AD16*
+ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd
+
 OUI:80AD67*
  ID_OUI_FROM_DATABASE=Kasda Networks Inc
 
@@ -65273,6 +66077,9 @@ OUI:80BE05*
 OUI:80C16E*
  ID_OUI_FROM_DATABASE=Hewlett Packard
 
+OUI:80C548*
+ ID_OUI_FROM_DATABASE=Shenzhen Zowee Technology Co.,Ltd
+
 OUI:80C5E6*
  ID_OUI_FROM_DATABASE=Microsoft Corporation
 
@@ -65294,6 +66101,9 @@ OUI:80C755*
 OUI:80C862*
  ID_OUI_FROM_DATABASE=Openpeak, Inc
 
+OUI:80CE62*
+ ID_OUI_FROM_DATABASE=Hewlett Packard
+
 OUI:80CEB1*
  ID_OUI_FROM_DATABASE=Theissen Training Systems GmbH
 
@@ -65693,6 +66503,9 @@ OUI:847303*
 OUI:84742A*
  ID_OUI_FROM_DATABASE=zte corporation
 
+OUI:847460*
+ ID_OUI_FROM_DATABASE=zte corporation
+
 OUI:847616*
  ID_OUI_FROM_DATABASE=Addat s.r.o.
 
@@ -65930,6 +66743,9 @@ OUI:84D9C8*
 OUI:84DB2F*
  ID_OUI_FROM_DATABASE=Sierra Wireless Inc
 
+OUI:84DB9E*
+ ID_OUI_FROM_DATABASE=Aifloo AB
+
 OUI:84DBAC*
  ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
 
@@ -66083,6 +66899,9 @@ OUI:88142B*
 OUI:881544*
  ID_OUI_FROM_DATABASE=Cisco Meraki
 
+OUI:8817A3*
+ ID_OUI_FROM_DATABASE=Integrated Device Technology (Malaysia) Sdn. Bhd.
+
 OUI:8818AE*
  ID_OUI_FROM_DATABASE=Tamron Co., Ltd
 
@@ -66117,7 +66936,7 @@ OUI:8828B3*
  ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
 
 OUI:882950*
- ID_OUI_FROM_DATABASE=Dalian Netmoon Tech Develop Co.,Ltd
+ ID_OUI_FROM_DATABASE=Netmoon Technology Co., Ltd
 
 OUI:882BD7*
  ID_OUI_FROM_DATABASE=ADDÉNERGIE  TECHNOLOGIES
@@ -66155,6 +66974,9 @@ OUI:883B8B*
 OUI:883C1C*
  ID_OUI_FROM_DATABASE=MERCURY CORPORATION
 
+OUI:883D24*
+ ID_OUI_FROM_DATABASE=Google, Inc.
+
 OUI:883FD3*
  ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
 
@@ -66269,6 +67091,9 @@ OUI:885D90F*
 OUI:885DFB*
  ID_OUI_FROM_DATABASE=zte corporation
 
+OUI:885FE8*
+ ID_OUI_FROM_DATABASE=IEEE Registration Authority
+
 OUI:88615A*
  ID_OUI_FROM_DATABASE=Siano Mobile Silicon Ltd.
 
@@ -66446,6 +67271,51 @@ OUI:88A6C6*
 OUI:88A73C*
  ID_OUI_FROM_DATABASE=Ragentek Technology Group
 
+OUI:88A9A70*
+ ID_OUI_FROM_DATABASE=Shenzhenshi kechuangzhixian technology Co.LTD
+
+OUI:88A9A71*
+ ID_OUI_FROM_DATABASE=Solaredge LTD.
+
+OUI:88A9A72*
+ ID_OUI_FROM_DATABASE=Honeywell spol. s.r.o. HTS CZ o.z.
+
+OUI:88A9A73*
+ ID_OUI_FROM_DATABASE=Mikroelektronika
+
+OUI:88A9A74*
+ ID_OUI_FROM_DATABASE=Thomas & Darden, Inc
+
+OUI:88A9A75*
+ ID_OUI_FROM_DATABASE=Volterman Inc.
+
+OUI:88A9A76*
+ ID_OUI_FROM_DATABASE=Sieper Lüdenscheid GmbH & Co. KG
+
+OUI:88A9A77*
+ ID_OUI_FROM_DATABASE=kimura giken corporation
+
+OUI:88A9A78*
+ ID_OUI_FROM_DATABASE=psb intralogistics GmbH
+
+OUI:88A9A79*
+ ID_OUI_FROM_DATABASE=FlashForge Corporation
+
+OUI:88A9A7A*
+ ID_OUI_FROM_DATABASE=Zhejiang Haoteng Electronic Technology Co.,Ltd.
+
+OUI:88A9A7B*
+ ID_OUI_FROM_DATABASE=TWK-ELEKTRONIK
+
+OUI:88A9A7C*
+ ID_OUI_FROM_DATABASE=AndroVideo Inc.
+
+OUI:88A9A7D*
+ ID_OUI_FROM_DATABASE=AVLINK INDUSTRIAL CO., LTD
+
+OUI:88A9A7E*
+ ID_OUI_FROM_DATABASE=Impact Distribution
+
 OUI:88ACC1*
  ID_OUI_FROM_DATABASE=Generiton Co., Ltd.
 
@@ -66467,12 +67337,18 @@ OUI:88B168*
 OUI:88B1E1*
  ID_OUI_FROM_DATABASE=Mojo Networks, Inc.
 
+OUI:88B362*
+ ID_OUI_FROM_DATABASE=Nokia Shanghai Bell Co. Ltd.)
+
 OUI:88B4A6*
  ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company
 
 OUI:88B627*
  ID_OUI_FROM_DATABASE=Gembird Europe BV
 
+OUI:88B6EE*
+ ID_OUI_FROM_DATABASE=Dish Technologies Corp
+
 OUI:88B8D0*
  ID_OUI_FROM_DATABASE=Dongguan Koppo Electronic Co.,Ltd
 
@@ -66590,6 +67466,9 @@ OUI:88E87F*
 OUI:88E8F8*
  ID_OUI_FROM_DATABASE=YONG TAI ELECTRONIC (DONGGUAN) LTD.
 
+OUI:88E90F*
+ ID_OUI_FROM_DATABASE=innomdlelab
+
 OUI:88E917*
  ID_OUI_FROM_DATABASE=Tamaggo
 
@@ -66704,6 +67583,9 @@ OUI:8C147DD*
 OUI:8C147DE*
  ID_OUI_FROM_DATABASE=Electrical & Automation Larsen & Toubro Limited
 
+OUI:8C1645*
+ ID_OUI_FROM_DATABASE=LCFC(HeFei) Electronics Technology co., ltd
+
 OUI:8C18D9*
  ID_OUI_FROM_DATABASE=Shenzhen RF Technology Co., Ltd
 
@@ -66821,6 +67703,9 @@ OUI:8C4AEE*
 OUI:8C4B59*
  ID_OUI_FROM_DATABASE=3D Imaging & Simulations Corp
 
+OUI:8C4CAD*
+ ID_OUI_FROM_DATABASE=Evoluzn Inc.
+
 OUI:8C4CDC*
  ID_OUI_FROM_DATABASE=PLANEX COMMUNICATIONS INC.
 
@@ -66854,6 +67739,9 @@ OUI:8C57FD*
 OUI:8C5877*
  ID_OUI_FROM_DATABASE=Apple, Inc.
 
+OUI:8C5973*
+ ID_OUI_FROM_DATABASE=Zyxel Communications Corporation
+
 OUI:8C598B*
  ID_OUI_FROM_DATABASE=C Technologies AB
 
@@ -67202,12 +68090,21 @@ OUI:8CF228*
 OUI:8CF5A3*
  ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO-MECHANICS(THAILAND)
 
+OUI:8CF710*
+ ID_OUI_FROM_DATABASE=AMPAK Technology, Inc.
+
+OUI:8CF773*
+ ID_OUI_FROM_DATABASE=Nokia
+
 OUI:8CF813*
  ID_OUI_FROM_DATABASE=ORANGE POLSKA
 
 OUI:8CF945*
  ID_OUI_FROM_DATABASE=Power Automation pte Ltd
 
+OUI:8CF957*
+ ID_OUI_FROM_DATABASE=RuiXingHengFang Network (Shenzhen) Co.,Ltd
+
 OUI:8CF9C9*
  ID_OUI_FROM_DATABASE=MESADA Technology Co.,Ltd.
 
@@ -67238,6 +68135,9 @@ OUI:9002A9*
 OUI:900325*
  ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
 
+OUI:900372*
+ ID_OUI_FROM_DATABASE=Longnan Junya Digital Technology Co. Ltd.
+
 OUI:9003B7*
  ID_OUI_FROM_DATABASE=PARROT SA
 
@@ -67358,6 +68258,9 @@ OUI:903809*
 OUI:9038DF*
  ID_OUI_FROM_DATABASE=Changzhou Tiannengbo System Co. Ltd.
 
+OUI:903A72*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
 OUI:903AA0*
  ID_OUI_FROM_DATABASE=Nokia
 
@@ -67541,6 +68444,9 @@ OUI:907240*
 OUI:907282*
  ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
 
+OUI:907910*
+ ID_OUI_FROM_DATABASE=Integrated Device Technology (Malaysia) Sdn. Bhd.
+
 OUI:907990*
  ID_OUI_FROM_DATABASE=Benchmark Electronics Romania SRL
 
@@ -67562,6 +68468,9 @@ OUI:907F61*
 OUI:908260*
  ID_OUI_FROM_DATABASE=IEEE 1904.1 Working Group
 
+OUI:90834B*
+ ID_OUI_FROM_DATABASE=BEIJING YUNYI TIMES TECHNOLOGY CO,.LTD
+
 OUI:90837A*
  ID_OUI_FROM_DATABASE=General Electric Water & Process Technologies
 
@@ -67571,6 +68480,9 @@ OUI:90840D*
 OUI:90842B*
  ID_OUI_FROM_DATABASE=LEGO System A/S
 
+OUI:90848B*
+ ID_OUI_FROM_DATABASE=HDR10+ Technologies, LLC
+
 OUI:908674*
  ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO., LTD
 
@@ -67607,6 +68519,9 @@ OUI:909060*
 OUI:9092B4*
  ID_OUI_FROM_DATABASE=Diehl BGT Defence GmbH & Co. KG
 
+OUI:909497*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
 OUI:9094E4*
  ID_OUI_FROM_DATABASE=D-Link International
 
@@ -68048,6 +68963,9 @@ OUI:946124*
 OUI:946269*
  ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
 
+OUI:946372*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
 OUI:9463D1*
  ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
 
@@ -68060,6 +68978,9 @@ OUI:94659C*
 OUI:9466E7*
  ID_OUI_FROM_DATABASE=WOM Engineering
 
+OUI:946AB0*
+ ID_OUI_FROM_DATABASE=Arcadyan Corporation
+
 OUI:9470D2*
  ID_OUI_FROM_DATABASE=WINFIRM TECHNOLOGY
 
@@ -68120,6 +69041,9 @@ OUI:948BC1*
 OUI:948D50*
  ID_OUI_FROM_DATABASE=Beamex Oy Ab
 
+OUI:948DEF*
+ ID_OUI_FROM_DATABASE=Oetiker Schweiz AG
+
 OUI:948E89*
  ID_OUI_FROM_DATABASE=INDUSTRIAS UNIDAS SA DE CV
 
@@ -68198,6 +69122,9 @@ OUI:94B40F*
 OUI:94B819*
  ID_OUI_FROM_DATABASE=Nokia
 
+OUI:94B86D*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
 OUI:94B8C5*
  ID_OUI_FROM_DATABASE=RuggedCom Inc.
 
@@ -68396,6 +69323,9 @@ OUI:94FD2E*
 OUI:94FE22*
  ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
 
+OUI:94FE9D*
+ ID_OUI_FROM_DATABASE=SHENZHEN GONGJIN ELECTRONICS CO.,LT
+
 OUI:94FEF4*
  ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
 
@@ -68579,6 +69509,9 @@ OUI:984246*
 OUI:9843DA*
  ID_OUI_FROM_DATABASE=INTERTECH
 
+OUI:984562*
+ ID_OUI_FROM_DATABASE=Shanghai Baud Data Communication Co.,Ltd.
+
 OUI:98473C*
  ID_OUI_FROM_DATABASE=SHANGHAI SUNMON COMMUNICATION TECHNOGY CO.,LTD
 
@@ -68870,6 +69803,9 @@ OUI:98C5DB*
 OUI:98C845*
  ID_OUI_FROM_DATABASE=PacketAccess
 
+OUI:98CA33*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
 OUI:98CB27*
  ID_OUI_FROM_DATABASE=Galore Networks Pvt. Ltd.
 
@@ -68897,6 +69833,9 @@ OUI:98D6BB*
 OUI:98D6F7*
  ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
 
+OUI:98D863*
+ ID_OUI_FROM_DATABASE=Shanghai High-Flying Electronics Technology Co., Ltd
+
 OUI:98D88C*
  ID_OUI_FROM_DATABASE=Nortel Networks
 
@@ -69119,6 +70058,51 @@ OUI:9C3EAA*
 OUI:9C417C*
  ID_OUI_FROM_DATABASE=Hame  Technology Co.,  Limited
 
+OUI:9C431E0*
+ ID_OUI_FROM_DATABASE=Antailiye Technology Co.,Ltd
+
+OUI:9C431E1*
+ ID_OUI_FROM_DATABASE=Symfun Telecom Ltd
+
+OUI:9C431E2*
+ ID_OUI_FROM_DATABASE=HAESUNG DS
+
+OUI:9C431E3*
+ ID_OUI_FROM_DATABASE=Advanced Logic Technology (ALT) sa
+
+OUI:9C431E4*
+ ID_OUI_FROM_DATABASE=Wireless Environment, LLC
+
+OUI:9C431E5*
+ ID_OUI_FROM_DATABASE=ProMOS Technologies Inc.
+
+OUI:9C431E6*
+ ID_OUI_FROM_DATABASE=R-S-I Elektrotechnik GmbH  CO KG
+
+OUI:9C431E7*
+ ID_OUI_FROM_DATABASE=Optris GmbH
+
+OUI:9C431E8*
+ ID_OUI_FROM_DATABASE=Wunda Group plc
+
+OUI:9C431E9*
+ ID_OUI_FROM_DATABASE=CONTINENT Co. Ltd
+
+OUI:9C431EA*
+ ID_OUI_FROM_DATABASE=ST Access Control System Corp.
+
+OUI:9C431EB*
+ ID_OUI_FROM_DATABASE=JNL Technologies Inc
+
+OUI:9C431EC*
+ ID_OUI_FROM_DATABASE=SuZhou Jinruiyang Information Technology CO.,LTD
+
+OUI:9C431ED*
+ ID_OUI_FROM_DATABASE=HK ELEPHONE Communication Tech Co.,Limited
+
+OUI:9C431EE*
+ ID_OUI_FROM_DATABASE=Midas Technology DBA Phoenix Audio Technologies
+
 OUI:9C443D*
  ID_OUI_FROM_DATABASE=CHENGDU XUGUANG TECHNOLOGY CO, LTD
 
@@ -69662,6 +70646,12 @@ OUI:A036F0*
 OUI:A036FA*
  ID_OUI_FROM_DATABASE=Ettus Research LLC
 
+OUI:A038F8*
+ ID_OUI_FROM_DATABASE=OURA Health Oy
+
+OUI:A039EE*
+ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
+
 OUI:A039F7*
  ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
 
@@ -69779,6 +70769,9 @@ OUI:A055DE*
 OUI:A056B2*
  ID_OUI_FROM_DATABASE=Harman/Becker Automotive Systems GmbH
 
+OUI:A057E3*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
 OUI:A0593A*
  ID_OUI_FROM_DATABASE=V.D.S. Video Display Systems srl
 
@@ -69809,6 +70802,9 @@ OUI:A0648F*
 OUI:A06518*
  ID_OUI_FROM_DATABASE=VNPT TECHNOLOGY
 
+OUI:A06610*
+ ID_OUI_FROM_DATABASE=FUJITSU LIMITED
+
 OUI:A067BE*
  ID_OUI_FROM_DATABASE=Sicon srl
 
@@ -70421,6 +71417,9 @@ OUI:A43135*
 OUI:A433D1*
  ID_OUI_FROM_DATABASE=Fibrlink Communications Co.,Ltd.
 
+OUI:A433D7*
+ ID_OUI_FROM_DATABASE=MitraStar Technology Corp.
+
 OUI:A43412*
  ID_OUI_FROM_DATABASE=Thales Alenia Space
 
@@ -70433,6 +71432,9 @@ OUI:A434F1*
 OUI:A43831*
  ID_OUI_FROM_DATABASE=RF elements s.r.o.
 
+OUI:A438CC*
+ ID_OUI_FROM_DATABASE=Nintendo Co.,Ltd
+
 OUI:A438FC*
  ID_OUI_FROM_DATABASE=Plastic Logic
 
@@ -70493,6 +71495,9 @@ OUI:A43D78*
 OUI:A43E51*
  ID_OUI_FROM_DATABASE=ANOV FRANCE
 
+OUI:A44027*
+ ID_OUI_FROM_DATABASE=zte corporation
+
 OUI:A444D1*
  ID_OUI_FROM_DATABASE=Wingtech Group (HongKong)Limited
 
@@ -70569,7 +71574,7 @@ OUI:A44F29F*
  ID_OUI_FROM_DATABASE=Private
 
 OUI:A45055*
- ID_OUI_FROM_DATABASE=busware.de
+ ID_OUI_FROM_DATABASE=BUSWARE.DE
 
 OUI:A4516F*
  ID_OUI_FROM_DATABASE=Microsoft Mobile Oy
@@ -70907,6 +71912,9 @@ OUI:A4D1D2*
 OUI:A4D3B5*
  ID_OUI_FROM_DATABASE=GLITEL Stropkov, s.r.o.
 
+OUI:A4D4B2*
+ ID_OUI_FROM_DATABASE=Shenzhen MeiG Smart Technology Co.,Ltd
+
 OUI:A4D578*
  ID_OUI_FROM_DATABASE=Texas Instruments
 
@@ -70919,6 +71927,51 @@ OUI:A4D8CA*
 OUI:A4D9A4*
  ID_OUI_FROM_DATABASE=neXus ID Solutions AB
 
+OUI:A4DA220*
+ ID_OUI_FROM_DATABASE=General Electric Company
+
+OUI:A4DA221*
+ ID_OUI_FROM_DATABASE=T2T System
+
+OUI:A4DA222*
+ ID_OUI_FROM_DATABASE=Wyze Labs Inc
+
+OUI:A4DA223*
+ ID_OUI_FROM_DATABASE=DURATECH Enterprise,LLC
+
+OUI:A4DA224*
+ ID_OUI_FROM_DATABASE=LORIOT AG
+
+OUI:A4DA225*
+ ID_OUI_FROM_DATABASE=Original Products Pvt. Ltd.
+
+OUI:A4DA226*
+ ID_OUI_FROM_DATABASE=AURANEXT
+
+OUI:A4DA227*
+ ID_OUI_FROM_DATABASE=Hydro Electronic Devices, Inc.
+
+OUI:A4DA228*
+ ID_OUI_FROM_DATABASE=SolidPro Technology Corporation
+
+OUI:A4DA229*
+ ID_OUI_FROM_DATABASE=Malldon Technology Limited
+
+OUI:A4DA22A*
+ ID_OUI_FROM_DATABASE=Abetechs GmbH
+
+OUI:A4DA22B*
+ ID_OUI_FROM_DATABASE=Klashwerks Inc.
+
+OUI:A4DA22C*
+ ID_OUI_FROM_DATABASE=EHO.LINK
+
+OUI:A4DA22D*
+ ID_OUI_FROM_DATABASE=Shen Zhen City YaKun Electronics Co., Ltd
+
+OUI:A4DA22E*
+ ID_OUI_FROM_DATABASE=Quuppa Oy
+
 OUI:A4DA3F*
  ID_OUI_FROM_DATABASE=Bionics Corp.
 
@@ -71093,6 +72146,9 @@ OUI:A830AD*
 OUI:A8329A*
  ID_OUI_FROM_DATABASE=Digicom Futuristic Technologies Ltd.
 
+OUI:A8367A*
+ ID_OUI_FROM_DATABASE=frogblue TECHNOLOGY GmbH
+
 OUI:A83944*
  ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc
 
@@ -71117,6 +72173,9 @@ OUI:A849A5*
 OUI:A84E3F*
  ID_OUI_FROM_DATABASE=Hitron Technologies. Inc
 
+OUI:A8515B*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
 OUI:A854B2*
  ID_OUI_FROM_DATABASE=Wistron Neweb Corporation
 
@@ -71147,6 +72206,9 @@ OUI:A85EE4*
 OUI:A860B6*
  ID_OUI_FROM_DATABASE=Apple, Inc.
 
+OUI:A8610A*
+ ID_OUI_FROM_DATABASE=ARDUINO AG
+
 OUI:A861AA*
  ID_OUI_FROM_DATABASE=Cloudview Limited
 
@@ -71390,6 +72452,9 @@ OUI:A8D828*
 OUI:A8D88A*
  ID_OUI_FROM_DATABASE=Wyconn
 
+OUI:A8DA01*
+ ID_OUI_FROM_DATABASE=Shenzhen NUOLIJIA Digital Technology Co.,Ltd
+
 OUI:A8E018*
  ID_OUI_FROM_DATABASE=Nokia Corporation
 
@@ -71474,6 +72539,9 @@ OUI:AC0613*
 OUI:AC06C7*
  ID_OUI_FROM_DATABASE=ServerNet S.r.l.
 
+OUI:AC075F*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
 OUI:AC0A61*
  ID_OUI_FROM_DATABASE=Labor S.r.L.
 
@@ -71498,6 +72566,9 @@ OUI:AC162D*
 OUI:AC1702*
  ID_OUI_FROM_DATABASE=Fibar Group sp. z o.o.
 
+OUI:AC17C8*
+ ID_OUI_FROM_DATABASE=Cisco Meraki
+
 OUI:AC1826*
  ID_OUI_FROM_DATABASE=Seiko Epson Corporation
 
@@ -72092,6 +73163,9 @@ OUI:ACF7F3*
 OUI:ACF85C*
  ID_OUI_FROM_DATABASE=Private
 
+OUI:ACF970*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
 OUI:ACF97E*
  ID_OUI_FROM_DATABASE=ELESYS INC.
 
@@ -72206,6 +73280,9 @@ OUI:B025AA*
 OUI:B02628*
  ID_OUI_FROM_DATABASE=Broadcom Limited
 
+OUI:B02680*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
 OUI:B03495*
  ID_OUI_FROM_DATABASE=Apple, Inc.
 
@@ -72473,6 +73550,9 @@ OUI:B0AA36*
 OUI:B0AA77*
  ID_OUI_FROM_DATABASE=Cisco Systems, Inc
 
+OUI:B0ACD2*
+ ID_OUI_FROM_DATABASE=zte corporation
+
 OUI:B0ACFA*
  ID_OUI_FROM_DATABASE=FUJITSU LIMITED
 
@@ -72488,6 +73568,9 @@ OUI:B0B2DC*
 OUI:B0B32B*
  ID_OUI_FROM_DATABASE=Slican Sp. z o.o.
 
+OUI:B0B3AD*
+ ID_OUI_FROM_DATABASE=HUMAX Co., Ltd.
+
 OUI:B0B448*
  ID_OUI_FROM_DATABASE=Texas Instruments
 
@@ -72761,6 +73844,9 @@ OUI:B41780*
 OUI:B418D1*
  ID_OUI_FROM_DATABASE=Apple, Inc.
 
+OUI:B41C30*
+ ID_OUI_FROM_DATABASE=zte corporation
+
 OUI:B41DEF*
  ID_OUI_FROM_DATABASE=Internet Laboratories, Inc.
 
@@ -72794,6 +73880,9 @@ OUI:B42CBE*
 OUI:B42D56*
  ID_OUI_FROM_DATABASE=Extreme Networks, Inc.
 
+OUI:B42EF8*
+ ID_OUI_FROM_DATABASE=Eline Technology co.Ltd
+
 OUI:B43052*
  ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
 
@@ -72980,6 +74069,9 @@ OUI:B47C9C*
 OUI:B47F5E*
  ID_OUI_FROM_DATABASE=Foresight Manufacture (S) Pte Ltd
 
+OUI:B481BF*
+ ID_OUI_FROM_DATABASE=Meta-Networks, LLC
+
 OUI:B48255*
  ID_OUI_FROM_DATABASE=Research Products Corporation
 
@@ -73052,6 +74144,9 @@ OUI:B4A828*
 OUI:B4A82B*
  ID_OUI_FROM_DATABASE=Histar Digital Electronics Co., Ltd.
 
+OUI:B4A8B9*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
 OUI:B4A95A*
  ID_OUI_FROM_DATABASE=Avaya Inc
 
@@ -73151,6 +74246,12 @@ OUI:B4D8DE*
 OUI:B4DD15*
  ID_OUI_FROM_DATABASE=ControlThings Oy Ab
 
+OUI:B4DE31*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:B4DEDF*
+ ID_OUI_FROM_DATABASE=zte corporation
+
 OUI:B4DF3B*
  ID_OUI_FROM_DATABASE=Chromlech
 
@@ -73172,9 +74273,15 @@ OUI:B4E1EB*
 OUI:B4E62A*
  ID_OUI_FROM_DATABASE=LG Innotek
 
+OUI:B4E62D*
+ ID_OUI_FROM_DATABASE=Espressif Inc.
+
 OUI:B4E782*
  ID_OUI_FROM_DATABASE=Vivalnk
 
+OUI:B4E9A3*
+ ID_OUI_FROM_DATABASE=port GmbH
+
 OUI:B4E9B0*
  ID_OUI_FROM_DATABASE=Cisco Systems, Inc
 
@@ -73214,12 +74321,18 @@ OUI:B4F323*
 OUI:B4F61C*
  ID_OUI_FROM_DATABASE=Apple, Inc.
 
+OUI:B4F7A1*
+ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
+
 OUI:B4F81E*
  ID_OUI_FROM_DATABASE=Kinova
 
 OUI:B4FBE4*
  ID_OUI_FROM_DATABASE=Ubiquiti Networks Inc.
 
+OUI:B4FBF9*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
 OUI:B4FC75*
  ID_OUI_FROM_DATABASE=SEMA Electronics(HK) CO.,LTD
 
@@ -73499,6 +74612,9 @@ OUI:B88F14*
 OUI:B8921D*
  ID_OUI_FROM_DATABASE=BG T&A
 
+OUI:B89436*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
 OUI:B894D2*
  ID_OUI_FROM_DATABASE=Retail Innovation HTT AB
 
@@ -73727,6 +74843,9 @@ OUI:B8DB1C*
 OUI:B8DC87*
  ID_OUI_FROM_DATABASE=IAI Corporation
 
+OUI:B8DE5E*
+ ID_OUI_FROM_DATABASE=LONGCHEER TELECOMMUNICATION LIMITED
+
 OUI:B8DF6B*
  ID_OUI_FROM_DATABASE=SpotCam Co., Ltd.
 
@@ -73829,6 +74948,9 @@ OUI:BC0F2B*
 OUI:BC0F64*
  ID_OUI_FROM_DATABASE=Intel Corporate
 
+OUI:BC0FA7*
+ ID_OUI_FROM_DATABASE=Ouster
+
 OUI:BC125E*
  ID_OUI_FROM_DATABASE=Beijing  WisVideo  INC.
 
@@ -74276,6 +75398,9 @@ OUI:BCA920*
 OUI:BCA9D6*
  ID_OUI_FROM_DATABASE=Cyber-Rain, Inc.
 
+OUI:BCAB7C*
+ ID_OUI_FROM_DATABASE=TRnP KOREA Co Ltd
+
 OUI:BCAD28*
  ID_OUI_FROM_DATABASE=Hangzhou Hikvision Digital Technology Co.,Ltd.
 
@@ -74363,6 +75488,9 @@ OUI:BCD713*
 OUI:BCD940*
  ID_OUI_FROM_DATABASE=ASR Co,.Ltd.
 
+OUI:BCDDC2*
+ ID_OUI_FROM_DATABASE=Espressif Inc.
+
 OUI:BCE09D*
  ID_OUI_FROM_DATABASE=Eoslink
 
@@ -74543,12 +75671,18 @@ OUI:C03FD5*
 OUI:C041F6*
  ID_OUI_FROM_DATABASE=LG ELECTRONICS INC
 
+OUI:C042D0*
+ ID_OUI_FROM_DATABASE=Juniper Networks
+
 OUI:C04301*
  ID_OUI_FROM_DATABASE=Epec Oy
 
 OUI:C044E3*
  ID_OUI_FROM_DATABASE=Shenzhen Sinkna Electronics Co., LTD
 
+OUI:C048E6*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
 OUI:C0493D*
  ID_OUI_FROM_DATABASE=MAITRISE TECHNOLOGIQUE
 
@@ -74666,6 +75800,9 @@ OUI:C09727*
 OUI:C09879*
  ID_OUI_FROM_DATABASE=Acer Inc.
 
+OUI:C098DA*
+ ID_OUI_FROM_DATABASE=China Mobile IOT Company Limited
+
 OUI:C098E5*
  ID_OUI_FROM_DATABASE=University of Michigan
 
@@ -74720,6 +75857,9 @@ OUI:C0A53E*
 OUI:C0A5DD*
  ID_OUI_FROM_DATABASE=SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD.
 
+OUI:C0A8F0*
+ ID_OUI_FROM_DATABASE=Adamson Systems Engineering
+
 OUI:C0AA68*
  ID_OUI_FROM_DATABASE=OSASI Technos Inc.
 
@@ -74903,6 +76043,9 @@ OUI:C40006*
 OUI:C40049*
  ID_OUI_FROM_DATABASE=Kamama
 
+OUI:C400AD*
+ ID_OUI_FROM_DATABASE=Advantech Technology (CHINA) Co., Ltd.
+
 OUI:C40142*
  ID_OUI_FROM_DATABASE=MaxMedia Technology Limited
 
@@ -75005,12 +76148,18 @@ OUI:C4291D*
 OUI:C42C03*
  ID_OUI_FROM_DATABASE=Apple, Inc.
 
+OUI:C42C4F*
+ ID_OUI_FROM_DATABASE=Qingdao Hisense Mobile Communication Technology Co,Ltd
+
 OUI:C42F90*
  ID_OUI_FROM_DATABASE=Hangzhou Hikvision Digital Technology Co.,Ltd.
 
 OUI:C43018*
  ID_OUI_FROM_DATABASE=MCS Logic Inc.
 
+OUI:C43306*
+ ID_OUI_FROM_DATABASE=China Mobile Group Device Co.,Ltd.
+
 OUI:C4346B*
  ID_OUI_FROM_DATABASE=Hewlett Packard
 
@@ -75122,6 +76271,9 @@ OUI:C45DD8*
 OUI:C46044*
  ID_OUI_FROM_DATABASE=Everex Electronics Limited
 
+OUI:C4618B*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
 OUI:C4626B*
  ID_OUI_FROM_DATABASE=ZPT Vigantice
 
@@ -75134,6 +76286,9 @@ OUI:C46354*
 OUI:C46413*
  ID_OUI_FROM_DATABASE=Cisco Systems, Inc
 
+OUI:C464E3*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
 OUI:C46699*
  ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
 
@@ -75257,6 +76412,9 @@ OUI:C4824E*
 OUI:C4836F*
  ID_OUI_FROM_DATABASE=Ciena Corporation
 
+OUI:C48466*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
 OUI:C48508*
  ID_OUI_FROM_DATABASE=Intel Corporate
 
@@ -75302,6 +76460,9 @@ OUI:C49DED*
 OUI:C49E41*
  ID_OUI_FROM_DATABASE=G24 Power Limited
 
+OUI:C49F4C*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
 OUI:C49FF3*
  ID_OUI_FROM_DATABASE=Mciao Technologies, Inc.
 
@@ -75464,6 +76625,51 @@ OUI:C4FCE4*
 OUI:C4FF1F*
  ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
 
+OUI:C4FFBC0*
+ ID_OUI_FROM_DATABASE=Danego BV
+
+OUI:C4FFBC1*
+ ID_OUI_FROM_DATABASE=VISATECH C0., LTD.
+
+OUI:C4FFBC2*
+ ID_OUI_FROM_DATABASE=Mobiletron Electronics Co., Ltd
+
+OUI:C4FFBC3*
+ ID_OUI_FROM_DATABASE=SHENZHEN KALIF ELECTRONICS CO.,LTD
+
+OUI:C4FFBC4*
+ ID_OUI_FROM_DATABASE=iMageTech CO.,LTD.
+
+OUI:C4FFBC5*
+ ID_OUI_FROM_DATABASE=comtime GmbH
+
+OUI:C4FFBC6*
+ ID_OUI_FROM_DATABASE=Shenzhen C & D Electronics Co., Ltd.
+
+OUI:C4FFBC7*
+ ID_OUI_FROM_DATABASE=Critical Link
+
+OUI:C4FFBC8*
+ ID_OUI_FROM_DATABASE=ShenZhen ZYT Technology co., Ltd
+
+OUI:C4FFBC9*
+ ID_OUI_FROM_DATABASE=GSM Innovations Pty Ltd
+
+OUI:C4FFBCA*
+ ID_OUI_FROM_DATABASE=Advanced Navigation
+
+OUI:C4FFBCB*
+ ID_OUI_FROM_DATABASE=KAGA ELECTRONICS CO.,LTD.
+
+OUI:C4FFBCC*
+ ID_OUI_FROM_DATABASE=KyongBo Electric Co., Ltd.
+
+OUI:C4FFBCD*
+ ID_OUI_FROM_DATABASE=Beijing  KDF information technology co. LTD.
+
+OUI:C4FFBCE*
+ ID_OUI_FROM_DATABASE=viRaTec GmbH
+
 OUI:C80084*
  ID_OUI_FROM_DATABASE=Cisco Systems, Inc
 
@@ -75689,6 +76895,9 @@ OUI:C87324*
 OUI:C8755B*
  ID_OUI_FROM_DATABASE=Quantify Technology Pty. Ltd.
 
+OUI:C87765*
+ ID_OUI_FROM_DATABASE=Tiesse SpA
+
 OUI:C8778B*
  ID_OUI_FROM_DATABASE=Themis Computer
 
@@ -75776,6 +76985,9 @@ OUI:C88ED1E*
 OUI:C88ED1F*
  ID_OUI_FROM_DATABASE=Private
 
+OUI:C88F26*
+ ID_OUI_FROM_DATABASE=Skyworth Digital Technology(Shenzhen) Co.,Ltd
+
 OUI:C8903E*
  ID_OUI_FROM_DATABASE=Pakton Technologies
 
@@ -76031,6 +77243,9 @@ OUI:C8F9C8*
 OUI:C8F9F9*
  ID_OUI_FROM_DATABASE=Cisco Systems, Inc
 
+OUI:C8FAE1*
+ ID_OUI_FROM_DATABASE=ARQ Digital LLC
+
 OUI:C8FB26*
  ID_OUI_FROM_DATABASE=Cisco SPVTG
 
@@ -76232,6 +77447,9 @@ OUI:CC2D83*
 OUI:CC2D8C*
  ID_OUI_FROM_DATABASE=LG ELECTRONICS INC
 
+OUI:CC2DB7*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
 OUI:CC2DE0*
  ID_OUI_FROM_DATABASE=Routerboard.com
 
@@ -76268,6 +77486,9 @@ OUI:CC3ADF*
 OUI:CC3B3E*
  ID_OUI_FROM_DATABASE=Lester Electrical
 
+OUI:CC3B58*
+ ID_OUI_FROM_DATABASE=Curiouser Products Inc
+
 OUI:CC3C3F*
  ID_OUI_FROM_DATABASE=SA.S.S. Datentechnik AG
 
@@ -76439,6 +77660,9 @@ OUI:CC8CDA*
 OUI:CC8CE3*
  ID_OUI_FROM_DATABASE=Texas Instruments
 
+OUI:CC8E71*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
 OUI:CC9093*
  ID_OUI_FROM_DATABASE=Hansong Tehnologies
 
@@ -76466,6 +77690,9 @@ OUI:CC96A0*
 OUI:CC9891*
  ID_OUI_FROM_DATABASE=Cisco Systems, Inc
 
+OUI:CC9916*
+ ID_OUI_FROM_DATABASE=Integrated Device Technology (Malaysia) Sdn. Bhd.
+
 OUI:CC9E00*
  ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
 
@@ -76832,6 +78059,9 @@ OUI:D02598*
 OUI:D02788*
  ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
 
+OUI:D02B20*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
 OUI:D02C45*
  ID_OUI_FROM_DATABASE=littleBits Electronics, Inc.
 
@@ -77060,6 +78290,9 @@ OUI:D07650E*
 OUI:D07650F*
  ID_OUI_FROM_DATABASE=Private
 
+OUI:D07714*
+ ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company
+
 OUI:D07AB5*
  ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
 
@@ -77078,6 +78311,9 @@ OUI:D07E35*
 OUI:D07FC4*
  ID_OUI_FROM_DATABASE=Ou Wei Technology Co.,Ltd. of Shenzhen City
 
+OUI:D0817A*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
 OUI:D083D4*
  ID_OUI_FROM_DATABASE=Xtel Wireless ApS
 
@@ -77561,6 +78797,9 @@ OUI:D45DDF*
 OUI:D45F25*
  ID_OUI_FROM_DATABASE=Shenzhen YOUHUA Technology Co., Ltd
 
+OUI:D460E3*
+ ID_OUI_FROM_DATABASE=Sercomm Corporation.
+
 OUI:D4612E*
  ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
 
@@ -77583,7 +78822,7 @@ OUI:D464F7*
  ID_OUI_FROM_DATABASE=CHENGDU USEE DIGITAL TECHNOLOGY CO., LTD
 
 OUI:D466A8*
- ID_OUI_FROM_DATABASE=Riedo Networks GmbH
+ ID_OUI_FROM_DATABASE=Riedo Networks Ltd
 
 OUI:D46761*
  ID_OUI_FROM_DATABASE=SAHAB TECHNOLOGY
@@ -77618,6 +78857,9 @@ OUI:D46CDA*
 OUI:D46D50*
  ID_OUI_FROM_DATABASE=Cisco Systems, Inc
 
+OUI:D46D6D*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
 OUI:D46E0E*
  ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
 
@@ -77690,6 +78932,9 @@ OUI:D48F33*
 OUI:D48FAA*
  ID_OUI_FROM_DATABASE=Sogecam Industrial, S.A.
 
+OUI:D4909C*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
 OUI:D490E0*
  ID_OUI_FROM_DATABASE=Topcon Electronics GmbH & Co. KG
 
@@ -77732,6 +78977,9 @@ OUI:D49C28*
 OUI:D49C8E*
  ID_OUI_FROM_DATABASE=University of FUKUI
 
+OUI:D49CF4*
+ ID_OUI_FROM_DATABASE=Palo Alto Networks
+
 OUI:D49E6D*
  ID_OUI_FROM_DATABASE=Wuhan Zhongyuan Huadian Science & Technology Co.,
 
@@ -77741,6 +78989,9 @@ OUI:D4A02A*
 OUI:D4A148*
  ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
 
+OUI:D4A33D*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
 OUI:D4A425*
  ID_OUI_FROM_DATABASE=SMAX Technology Co., Ltd.
 
@@ -77789,6 +79040,9 @@ OUI:D4BF2D*
 OUI:D4BF7F*
  ID_OUI_FROM_DATABASE=UPVEL
 
+OUI:D4C19E*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
 OUI:D4C1C8*
  ID_OUI_FROM_DATABASE=zte corporation
 
@@ -77864,6 +79118,9 @@ OUI:D4E32C*
 OUI:D4E33F*
  ID_OUI_FROM_DATABASE=Nokia
 
+OUI:D4E6B7*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
 OUI:D4E8B2*
  ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
 
@@ -77906,6 +79163,9 @@ OUI:D4F513*
 OUI:D4F63F*
  ID_OUI_FROM_DATABASE=IEA S.R.L.
 
+OUI:D4F786*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
 OUI:D4F9A1*
  ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
 
@@ -78050,6 +79310,9 @@ OUI:D842E2*
 OUI:D843ED*
  ID_OUI_FROM_DATABASE=Suzuken
 
+OUI:D8445C*
+ ID_OUI_FROM_DATABASE=DEV Tecnologia Ind Com Man Eq LTDA
+
 OUI:D8452B*
  ID_OUI_FROM_DATABASE=Integrated Device Technology (Malaysia) Sdn. Bhd.
 
@@ -78386,6 +79649,9 @@ OUI:D8D67E*
 OUI:D8D723*
  ID_OUI_FROM_DATABASE=IDS, Inc
 
+OUI:D8D775*
+ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
+
 OUI:D8D866*
  ID_OUI_FROM_DATABASE=SHENZHEN TOZED TECHNOLOGIES CO.,LTD.
 
@@ -78707,6 +79973,9 @@ OUI:DC4D23*
 OUI:DC4EDE*
  ID_OUI_FROM_DATABASE=SHINYEI TECHNOLOGY CO., LTD.
 
+OUI:DC4EF4*
+ ID_OUI_FROM_DATABASE=Shenzhen MTN Electronics CO., Ltd
+
 OUI:DC4F22*
  ID_OUI_FROM_DATABASE=Espressif Inc.
 
@@ -78722,6 +79991,9 @@ OUI:DC5583*
 OUI:DC56E6*
  ID_OUI_FROM_DATABASE=Shenzhen Bococom Technology Co.,LTD
 
+OUI:DC56E7*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
 OUI:DC5726*
  ID_OUI_FROM_DATABASE=Power-One
 
@@ -78764,6 +80036,9 @@ OUI:DC7014*
 OUI:DC7144*
  ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO MECHANICS CO., LTD.
 
+OUI:DC729B*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
 OUI:DC74A8*
  ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
 
@@ -78812,6 +80087,9 @@ OUI:DC9FDB*
 OUI:DCA266*
  ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
 
+OUI:DCA333*
+ ID_OUI_FROM_DATABASE=Shenzhen YOUHUA Technology Co., Ltd
+
 OUI:DCA3AC*
  ID_OUI_FROM_DATABASE=RBcloudtech
 
@@ -78938,6 +80216,9 @@ OUI:DCDB70*
 OUI:DCDC07*
  ID_OUI_FROM_DATABASE=TRP Systems BV
 
+OUI:DCDD24*
+ ID_OUI_FROM_DATABASE=Energica Motor Company SpA
+
 OUI:DCDECA*
  ID_OUI_FROM_DATABASE=Akyllor
 
@@ -78950,6 +80231,51 @@ OUI:DCE1AD*
 OUI:DCE2AC*
  ID_OUI_FROM_DATABASE=Lumens Digital Optics Inc.
 
+OUI:DCE5330*
+ ID_OUI_FROM_DATABASE=FLYHT Aerospace
+
+OUI:DCE5331*
+ ID_OUI_FROM_DATABASE=Ambi Labs Limited
+
+OUI:DCE5332*
+ ID_OUI_FROM_DATABASE=Remko GmbH & Co. KG
+
+OUI:DCE5333*
+ ID_OUI_FROM_DATABASE=ShenZhen C&D Electronics CO.Ltd.
+
+OUI:DCE5334*
+ ID_OUI_FROM_DATABASE=shenzhen bangying electronics co,.ltd
+
+OUI:DCE5335*
+ ID_OUI_FROM_DATABASE=Controls Inc
+
+OUI:DCE5336*
+ ID_OUI_FROM_DATABASE=WECAN Solution Inc.
+
+OUI:DCE5337*
+ ID_OUI_FROM_DATABASE=SAN Engineering
+
+OUI:DCE5338*
+ ID_OUI_FROM_DATABASE=JB-Lighting Lichtanlagen GmbH
+
+OUI:DCE5339*
+ ID_OUI_FROM_DATABASE=Tiertime Corporation
+
+OUI:DCE533A*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:DCE533B*
+ ID_OUI_FROM_DATABASE=Tintel Hongkong Co.Ltd
+
+OUI:DCE533C*
+ ID_OUI_FROM_DATABASE=BRCK
+
+OUI:DCE533D*
+ ID_OUI_FROM_DATABASE=Suzhou ATES electronic technology co.LTD
+
+OUI:DCE533E*
+ ID_OUI_FROM_DATABASE=Giant Power Technology Biomedical Corporation
+
 OUI:DCE578*
  ID_OUI_FROM_DATABASE=Experimental Factory of Scientific Engineering and Special Design Department
 
@@ -79535,6 +80861,9 @@ OUI:E0DDC0*
 OUI:E0E5CF*
  ID_OUI_FROM_DATABASE=Texas Instruments
 
+OUI:E0E62E*
+ ID_OUI_FROM_DATABASE=TCT mobile ltd
+
 OUI:E0E631*
  ID_OUI_FROM_DATABASE=SNB TECHNOLOGIES LIMITED
 
@@ -79646,6 +80975,9 @@ OUI:E42C56*
 OUI:E42D02*
  ID_OUI_FROM_DATABASE=TCT mobile ltd
 
+OUI:E42D7B*
+ ID_OUI_FROM_DATABASE=China Mobile IOT Company Limited
+
 OUI:E42F26*
  ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
 
@@ -79991,6 +81323,9 @@ OUI:E4C1F1*
 OUI:E4C2D1*
  ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
 
+OUI:E4C483*
+ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+
 OUI:E4C62B*
  ID_OUI_FROM_DATABASE=Airware
 
@@ -80009,6 +81344,9 @@ OUI:E4C801*
 OUI:E4C806*
  ID_OUI_FROM_DATABASE=Ceiec Electric Technology Inc.
 
+OUI:E4CB59*
+ ID_OUI_FROM_DATABASE=Beijing Loveair Science and Technology Co. Ltd.
+
 OUI:E4CE02*
  ID_OUI_FROM_DATABASE=WyreStorm Technologies Ltd
 
@@ -80033,6 +81371,9 @@ OUI:E4D71D*
 OUI:E4DD79*
  ID_OUI_FROM_DATABASE=En-Vision America, Inc.
 
+OUI:E4E0A6*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
 OUI:E4E0C5*
  ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
 
@@ -80222,6 +81563,9 @@ OUI:E81863E*
 OUI:E81863F*
  ID_OUI_FROM_DATABASE=Private
 
+OUI:E81AAC*
+ ID_OUI_FROM_DATABASE=ORFEO SOUNDWORKS Inc.
+
 OUI:E81DA8*
  ID_OUI_FROM_DATABASE=Ruckus Wireless
 
@@ -80243,6 +81587,9 @@ OUI:E82AEA*
 OUI:E82E24*
  ID_OUI_FROM_DATABASE=Out of the Fog Research LLC
 
+OUI:E8330D*
+ ID_OUI_FROM_DATABASE=Xaptec GmbH
+
 OUI:E83381*
  ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
 
@@ -80444,6 +81791,9 @@ OUI:E894F6*
 OUI:E89606*
  ID_OUI_FROM_DATABASE=testo Instruments (Shenzhen) Co., Ltd.
 
+OUI:E8986D*
+ ID_OUI_FROM_DATABASE=Palo Alto Networks
+
 OUI:E8995A*
  ID_OUI_FROM_DATABASE=PiiGAB, Processinformation i Goteborg AB
 
@@ -80477,6 +81827,9 @@ OUI:E8A4C1*
 OUI:E8A7F2*
  ID_OUI_FROM_DATABASE=sTraffic
 
+OUI:E8ABF3*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
 OUI:E8ABFA*
  ID_OUI_FROM_DATABASE=Shenzhen Reecam Tech.Ltd.
 
@@ -80513,6 +81866,9 @@ OUI:E8BDD1*
 OUI:E8BE81*
  ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
 
+OUI:E8C1B8*
+ ID_OUI_FROM_DATABASE=Nanjing Bangzhong Electronic Commerce Limited
+
 OUI:E8C1D7*
  ID_OUI_FROM_DATABASE=Philips
 
@@ -80561,6 +81917,9 @@ OUI:E8DA96*
 OUI:E8DAAA*
  ID_OUI_FROM_DATABASE=VideoHome Technology Corp.
 
+OUI:E8DE00*
+ ID_OUI_FROM_DATABASE=ChongQing GuanFang Technology Co.,LTD
+
 OUI:E8DE27*
  ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
 
@@ -80570,6 +81929,9 @@ OUI:E8DE8E*
 OUI:E8DED6*
  ID_OUI_FROM_DATABASE=Intrising Networks, Inc.
 
+OUI:E8DEFB*
+ ID_OUI_FROM_DATABASE=MESOTIC SAS
+
 OUI:E8DF70*
  ID_OUI_FROM_DATABASE=AVM Audiovisuelles Marketing und Computersysteme GmbH
 
@@ -80861,6 +82223,9 @@ OUI:EC63E5*
 OUI:EC64E7*
  ID_OUI_FROM_DATABASE=MOCACARE Corporation
 
+OUI:EC65CC*
+ ID_OUI_FROM_DATABASE=Panasonic Automotive Systems Company of America
+
 OUI:EC66D1*
  ID_OUI_FROM_DATABASE=B&W Group LTD
 
@@ -80888,6 +82253,9 @@ OUI:EC7D11*
 OUI:EC7D9D*
  ID_OUI_FROM_DATABASE=MEI
 
+OUI:EC7FC6*
+ ID_OUI_FROM_DATABASE=ECCEL CORPORATION SAS
+
 OUI:EC8009*
  ID_OUI_FROM_DATABASE=NovaSparks
 
@@ -80909,6 +82277,9 @@ OUI:EC888F*
 OUI:EC8892*
  ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company
 
+OUI:EC8914*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
 OUI:EC89F5*
  ID_OUI_FROM_DATABASE=Lenovo Mobile Communication Technology Ltd.
 
@@ -80954,6 +82325,9 @@ OUI:EC9A74*
 OUI:EC9B5B*
  ID_OUI_FROM_DATABASE=Nokia Corporation
 
+OUI:EC9B8B*
+ ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise
+
 OUI:EC9BF3*
  ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO-MECHANICS(THAILAND)
 
@@ -81200,6 +82574,9 @@ OUI:F008F1*
 OUI:F00D5C*
  ID_OUI_FROM_DATABASE=JinQianMao  Technology Co.,Ltd.
 
+OUI:F00FEC*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
 OUI:F013C3*
  ID_OUI_FROM_DATABASE=SHENZHEN FENDA TECHNOLOGY CO., LTD
 
@@ -81362,6 +82739,36 @@ OUI:F03FF8*
 OUI:F0407B*
  ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
 
+OUI:F041C80*
+ ID_OUI_FROM_DATABASE=LINPA ACOUSTIC TECHNOLOGY CO.,LTD
+
+OUI:F041C82*
+ ID_OUI_FROM_DATABASE=Shenzhen Medica Technology Development Co., Ltd.
+
+OUI:F041C83*
+ ID_OUI_FROM_DATABASE=SHENZHEN WISEWING INTERNET TECHNOLOGY CO.,LTD
+
+OUI:F041C85*
+ ID_OUI_FROM_DATABASE=XI'AN MEI SHANG MEI WIRELESS TECHNOLOGY.Co., Ltd.
+
+OUI:F041C86*
+ ID_OUI_FROM_DATABASE=AED Engineering GmbH
+
+OUI:F041C87*
+ ID_OUI_FROM_DATABASE=Nanchang BlackShark Co.,Ltd.
+
+OUI:F041C89*
+ ID_OUI_FROM_DATABASE=Shenzhen  Nufilo Electronic Technology Co., Ltd.
+
+OUI:F041C8B*
+ ID_OUI_FROM_DATABASE=Powervault Ltd
+
+OUI:F041C8C*
+ ID_OUI_FROM_DATABASE=Shanghai Think-Force Electronic Technology Co. Ltd
+
+OUI:F041C8D*
+ ID_OUI_FROM_DATABASE=ATN Media Group FZ LLC
+
 OUI:F0421C*
  ID_OUI_FROM_DATABASE=Intel Corporate
 
@@ -81455,6 +82862,9 @@ OUI:F074E4*
 OUI:F0761C*
  ID_OUI_FROM_DATABASE=COMPAL INFORMATION (KUNSHAN) CO., LTD.
 
+OUI:F0766F*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
 OUI:F07765*
  ID_OUI_FROM_DATABASE=Sourcefire, Inc
 
@@ -81485,6 +82895,9 @@ OUI:F07F06*
 OUI:F07F0C*
  ID_OUI_FROM_DATABASE=Leopold Kostal GmbH &Co. KG
 
+OUI:F08173*
+ ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
+
 OUI:F081AF*
  ID_OUI_FROM_DATABASE=IRZ AUTOMATION TECHNOLOGIES LTD
 
@@ -81629,6 +83042,9 @@ OUI:F0B429*
 OUI:F0B479*
  ID_OUI_FROM_DATABASE=Apple, Inc.
 
+OUI:F0B5B7*
+ ID_OUI_FROM_DATABASE=Disruptive Technologies Research AS
+
 OUI:F0B6EB*
  ID_OUI_FROM_DATABASE=Poslab Technology Co., Ltd.
 
@@ -81662,6 +83078,9 @@ OUI:F0C850*
 OUI:F0C88C*
  ID_OUI_FROM_DATABASE=LeddarTech Inc.
 
+OUI:F0C9D1*
+ ID_OUI_FROM_DATABASE=GD Midea Air-Conditioning Equipment Co.,Ltd.
+
 OUI:F0CBA1*
  ID_OUI_FROM_DATABASE=Apple, Inc.
 
@@ -81725,6 +83144,9 @@ OUI:F0DEB9*
 OUI:F0DEF1*
  ID_OUI_FROM_DATABASE=Wistron Infocomm (Zhongshan) Corporation
 
+OUI:F0E3DC*
+ ID_OUI_FROM_DATABASE=Tecon MT, LLC
+
 OUI:F0E5C3*
  ID_OUI_FROM_DATABASE=Drägerwerk AG & Co. KG aA
 
@@ -81791,6 +83213,9 @@ OUI:F0F8F2*
 OUI:F0F9F7*
  ID_OUI_FROM_DATABASE=IES GmbH & Co. KG
 
+OUI:F0FCC8*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
 OUI:F0FDA0*
  ID_OUI_FROM_DATABASE=Acurix Networks Pty Ltd
 
@@ -82094,6 +83519,9 @@ OUI:F46E24*
 OUI:F470AB*
  ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
 
+OUI:F47190*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
 OUI:F473CA*
  ID_OUI_FROM_DATABASE=Conversion Sound Inc.
 
@@ -82121,6 +83549,9 @@ OUI:F483CD*
 OUI:F483E1*
  ID_OUI_FROM_DATABASE=Shanghai Clouder Semiconductor Co.,Ltd
 
+OUI:F4844C*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
 OUI:F485C6*
  ID_OUI_FROM_DATABASE=FDT Technologies
 
@@ -82229,6 +83660,9 @@ OUI:F4B8A7*
 OUI:F4BD7C*
  ID_OUI_FROM_DATABASE=Chengdu jinshi communication Co., LTD
 
+OUI:F4C248*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
 OUI:F4C447*
  ID_OUI_FROM_DATABASE=Coagent International Enterprise Limited
 
@@ -82286,6 +83720,9 @@ OUI:F4DC41*
 OUI:F4DC4D*
  ID_OUI_FROM_DATABASE=Beijing CCD Digital Technology Co., Ltd
 
+OUI:F4DCA5*
+ ID_OUI_FROM_DATABASE=DAWON DNS
+
 OUI:F4DCDA*
  ID_OUI_FROM_DATABASE=Zhuhai Jiahe Communication Technology Co., limited
 
@@ -82298,6 +83735,9 @@ OUI:F4DD9E*
 OUI:F4DE0C*
  ID_OUI_FROM_DATABASE=ESPOD Ltd.
 
+OUI:F4E11E*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
 OUI:F4E142*
  ID_OUI_FROM_DATABASE=Delta Elektronika BV
 
@@ -82808,6 +84248,9 @@ OUI:F88A3CD*
 OUI:F88A3CE*
  ID_OUI_FROM_DATABASE=Avateq Corp.
 
+OUI:F88B37*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
 OUI:F88C1C*
  ID_OUI_FROM_DATABASE=KAISHUN ELECTRONIC TECHNOLOGY CO., LTD. BEIJING
 
@@ -82820,6 +84263,9 @@ OUI:F88E85*
 OUI:F88FCA*
  ID_OUI_FROM_DATABASE=Google, Inc.
 
+OUI:F89066*
+ ID_OUI_FROM_DATABASE=Nain Inc.
+
 OUI:F8912A*
  ID_OUI_FROM_DATABASE=GLP German Light Products GmbH
 
@@ -82973,6 +84419,9 @@ OUI:F8C001*
 OUI:F8C091*
  ID_OUI_FROM_DATABASE=Highgates Technology
 
+OUI:F8C120*
+ ID_OUI_FROM_DATABASE=Xi'an Link-Science Technology Co.,Ltd
+
 OUI:F8C288*
  ID_OUI_FROM_DATABASE=Cisco Systems, Inc
 
@@ -83042,6 +84491,9 @@ OUI:F8DB88*
 OUI:F8DC7A*
  ID_OUI_FROM_DATABASE=Variscite LTD
 
+OUI:F8DF15*
+ ID_OUI_FROM_DATABASE=Sunitec Enterprise Co.,Ltd
+
 OUI:F8DFA8*
  ID_OUI_FROM_DATABASE=zte corporation
 
@@ -83348,6 +84800,9 @@ OUI:FC626E*
 OUI:FC62B9*
  ID_OUI_FROM_DATABASE=ALPS ELECTRIC CO.,LTD.
 
+OUI:FC643A*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
 OUI:FC64BA*
  ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd
 
@@ -83375,6 +84830,9 @@ OUI:FC75E6*
 OUI:FC790B*
  ID_OUI_FROM_DATABASE=Hitachi High Technologies America, Inc.
 
+OUI:FC7C02*
+ ID_OUI_FROM_DATABASE=Phicomm (Shanghai) Co., Ltd.
+
 OUI:FC7CE7*
  ID_OUI_FROM_DATABASE=FCI USA LLC
 
@@ -83444,6 +84902,9 @@ OUI:FCA386*
 OUI:FCA667*
  ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
 
+OUI:FCA6CD*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
 OUI:FCA841*
  ID_OUI_FROM_DATABASE=Avaya Inc
 
index 42e21db..10b427c 100644 (file)
@@ -120,6 +120,9 @@ acpi:IHSE*:
 acpi:IMPJ*:
  ID_VENDOR_FROM_DATABASE=Impinj
 
+acpi:INSY*:
+ ID_VENDOR_FROM_DATABASE=Insyde Software
+
 acpi:INTC*:
  ID_VENDOR_FROM_DATABASE=Intel Corporation
 
@@ -171,6 +174,9 @@ acpi:NVDA*:
 acpi:NVTN*:
  ID_VENDOR_FROM_DATABASE=Nuvoton Technology Corporation
 
+acpi:NXGO*:
+ ID_VENDOR_FROM_DATABASE=Nexstgo Company Limited
+
 acpi:OBDA*:
  ID_VENDOR_FROM_DATABASE=REALTEK Semiconductor Corp.
 
@@ -882,6 +888,9 @@ acpi:AVO*:
 acpi:AVR*:
  ID_VENDOR_FROM_DATABASE=AVer Information Inc.
 
+acpi:AVS*:
+ ID_VENDOR_FROM_DATABASE=Avatron Software Inc.
+
 acpi:AVT*:
  ID_VENDOR_FROM_DATABASE=Avtek (Electronics) Pty Ltd
 
@@ -963,6 +972,9 @@ acpi:BBH*:
 acpi:BBL*:
  ID_VENDOR_FROM_DATABASE=Brain Boxes Limited
 
+acpi:BBV*:
+ ID_VENDOR_FROM_DATABASE=BlueBox Video Limited
+
 acpi:BBX*:
  ID_VENDOR_FROM_DATABASE=Black Box Corporation
 
@@ -1341,6 +1353,9 @@ acpi:CHO*:
 acpi:CHP*:
  ID_VENDOR_FROM_DATABASE=CH Products
 
+acpi:CHR*:
+ ID_VENDOR_FROM_DATABASE=christmann informationstechnik + medien GmbH & Co. KG
+
 acpi:CHS*:
  ID_VENDOR_FROM_DATABASE=Agentur Chairos
 
@@ -2736,6 +2751,9 @@ acpi:GFN*:
 acpi:GGL*:
  ID_VENDOR_FROM_DATABASE=Google Inc.
 
+acpi:GGT*:
+ ID_VENDOR_FROM_DATABASE=G2TOUCH KOREA
+
 acpi:GIC*:
  ID_VENDOR_FROM_DATABASE=General Inst. Corporation
 
@@ -4371,6 +4389,9 @@ acpi:MNL*:
 acpi:MNP*:
  ID_VENDOR_FROM_DATABASE=Microcom
 
+acpi:MOC*:
+ ID_VENDOR_FROM_DATABASE=Matrix Orbital Corporation
+
 acpi:MOD*:
  ID_VENDOR_FROM_DATABASE=Modular Technology
 
@@ -4548,6 +4569,9 @@ acpi:MVM*:
 acpi:MVN*:
  ID_VENDOR_FROM_DATABASE=Meta Company
 
+acpi:MVR*:
+ ID_VENDOR_FROM_DATABASE=MediCapture, Inc.
+
 acpi:MVS*:
  ID_VENDOR_FROM_DATABASE=Microvision
 
@@ -4758,6 +4782,9 @@ acpi:NPA*:
 acpi:NPI*:
  ID_VENDOR_FROM_DATABASE=Network Peripherals Inc
 
+acpi:NRI*:
+ ID_VENDOR_FROM_DATABASE=Noritake Itron Corporation
+
 acpi:NRL*:
  ID_VENDOR_FROM_DATABASE=U.S. Naval Research Lab
 
@@ -4791,6 +4818,9 @@ acpi:NTC*:
 acpi:NTI*:
  ID_VENDOR_FROM_DATABASE=New Tech Int'l Company
 
+acpi:NTK*:
+ ID_VENDOR_FROM_DATABASE=NewTek
+
 acpi:NTL*:
  ID_VENDOR_FROM_DATABASE=National Transcomm. Ltd
 
@@ -5259,6 +5289,9 @@ acpi:PNR*:
 acpi:PNS*:
  ID_VENDOR_FROM_DATABASE=PanaScope
 
+acpi:PNT*:
+ ID_VENDOR_FROM_DATABASE=HOYA Corporation PENTAX Lifecare Division
+
 acpi:PNX*:
  ID_VENDOR_FROM_DATABASE=Phoenix Technologies, Ltd.
 
@@ -5271,6 +5304,9 @@ acpi:PON*:
 acpi:POR*:
  ID_VENDOR_FROM_DATABASE=Portalis LC
 
+acpi:POS*:
+ ID_VENDOR_FROM_DATABASE=Positivo Tecnologia S.A.
+
 acpi:POT*:
  ID_VENDOR_FROM_DATABASE=Parrot
 
@@ -5308,7 +5344,7 @@ acpi:PRD*:
  ID_VENDOR_FROM_DATABASE=Praim S.R.L.
 
 acpi:PRF*:
- ID_VENDOR_FROM_DATABASE=Digital Electronics Corporation
+ ID_VENDOR_FROM_DATABASE=Schneider Electric Japan Holdings, Ltd.
 
 acpi:PRG*:
  ID_VENDOR_FROM_DATABASE=The Phoenix Research Group Inc
@@ -6513,12 +6549,18 @@ acpi:TEK*:
 acpi:TEL*:
  ID_VENDOR_FROM_DATABASE=Promotion and Display Technology Ltd.
 
+acpi:TEN*:
+ ID_VENDOR_FROM_DATABASE=Tencent
+
 acpi:TER*:
  ID_VENDOR_FROM_DATABASE=TerraTec Electronic GmbH
 
 acpi:TET*:
  ID_VENDOR_FROM_DATABASE=TETRADYNE CO., LTD.
 
+acpi:TEV*:
+ ID_VENDOR_FROM_DATABASE=Televés, S.A.
+
 acpi:TEX*:
  ID_VENDOR_FROM_DATABASE=Texas Instruments
 
@@ -7146,9 +7188,15 @@ acpi:VQ@*:
 acpi:VRC*:
  ID_VENDOR_FROM_DATABASE=Virtual Resources Corporation
 
+acpi:VRG*:
+ ID_VENDOR_FROM_DATABASE=VRgineers, Inc.
+
 acpi:VRM*:
  ID_VENDOR_FROM_DATABASE=VRmagic Holding AG
 
+acpi:VRS*:
+ ID_VENDOR_FROM_DATABASE=VRstudios, Inc.
+
 acpi:VSC*:
  ID_VENDOR_FROM_DATABASE=ViewSonic Corporation
 
@@ -7344,6 +7392,9 @@ acpi:XAD*:
 acpi:XDM*:
  ID_VENDOR_FROM_DATABASE=XDM Ltd.
 
+acpi:XES*:
+ ID_VENDOR_FROM_DATABASE=Extreme Engineering Solutions, Inc.
+
 acpi:XFG*:
  ID_VENDOR_FROM_DATABASE=Jan Strapko - FOTO
 
index b8f877e..0d9be60 100644 (file)
@@ -1,5 +1,5 @@
---- 20-acpi-vendor.hwdb.base   2017-09-28 13:48:25.370636463 +0200
-+++ 20-acpi-vendor.hwdb        2017-09-28 13:48:25.375636571 +0200
+--- 20-acpi-vendor.hwdb.base   2017-12-14 15:57:48.154005635 +0100
++++ 20-acpi-vendor.hwdb        2017-12-14 15:57:48.160005689 +0100
 @@ -3,6 +3,8 @@
  # Data imported from:
  #     http://www.uefi.org/uefi-pnp-export
@@ -19,7 +19,7 @@
  acpi:AMDI*:
   ID_VENDOR_FROM_DATABASE=AMD
  
-@@ -244,6 +243,9 @@
+@@ -250,6 +249,9 @@
  acpi:AAA*:
   ID_VENDOR_FROM_DATABASE=Avolites Ltd
  
@@ -29,7 +29,7 @@
  acpi:AAE*:
   ID_VENDOR_FROM_DATABASE=Anatek Electronics Inc.
  
-@@ -271,6 +273,9 @@
+@@ -277,6 +279,9 @@
  acpi:ABO*:
   ID_VENDOR_FROM_DATABASE=D-Link Systems Inc
  
@@ -39,7 +39,7 @@
  acpi:ABS*:
   ID_VENDOR_FROM_DATABASE=Abaco Systems, Inc.
  
-@@ -316,7 +321,7 @@
+@@ -322,7 +327,7 @@
  acpi:ACO*:
   ID_VENDOR_FROM_DATABASE=Allion Computer Inc.
  
@@ -48,7 +48,7 @@
   ID_VENDOR_FROM_DATABASE=Aspen Tech Inc
  
  acpi:ACR*:
-@@ -586,6 +591,9 @@
+@@ -592,6 +597,9 @@
  acpi:AMT*:
   ID_VENDOR_FROM_DATABASE=AMT International Industry
  
@@ -58,7 +58,7 @@
  acpi:AMX*:
   ID_VENDOR_FROM_DATABASE=AMX LLC
  
-@@ -634,6 +642,9 @@
+@@ -640,6 +648,9 @@
  acpi:AOA*:
   ID_VENDOR_FROM_DATABASE=AOpen Inc.
  
@@ -68,7 +68,7 @@
  acpi:AOE*:
   ID_VENDOR_FROM_DATABASE=Advanced Optics Electronics, Inc.
  
-@@ -643,6 +654,9 @@
+@@ -649,6 +660,9 @@
  acpi:AOT*:
   ID_VENDOR_FROM_DATABASE=Alcatel
  
@@ -78,7 +78,7 @@
  acpi:APC*:
   ID_VENDOR_FROM_DATABASE=American Power Conversion
  
-@@ -818,7 +832,7 @@
+@@ -824,7 +838,7 @@
   ID_VENDOR_FROM_DATABASE=Alps Electric Inc
  
  acpi:AUO*:
@@ -87,7 +87,7 @@
  
  acpi:AUR*:
   ID_VENDOR_FROM_DATABASE=Aureal Semiconductor
-@@ -895,6 +909,9 @@
+@@ -904,6 +918,9 @@
  acpi:AXE*:
   ID_VENDOR_FROM_DATABASE=Axell Corporation
  
@@ -97,7 +97,7 @@
  acpi:AXI*:
   ID_VENDOR_FROM_DATABASE=American Magnetics
  
-@@ -1039,6 +1056,9 @@
+@@ -1051,6 +1068,9 @@
  acpi:BML*:
   ID_VENDOR_FROM_DATABASE=BIOMED Lab
  
  acpi:BMS*:
   ID_VENDOR_FROM_DATABASE=BIOMEDISYS
  
-@@ -1051,6 +1071,9 @@
+@@ -1063,6 +1083,9 @@
  acpi:BNO*:
   ID_VENDOR_FROM_DATABASE=Bang & Olufsen
  
  acpi:BNS*:
   ID_VENDOR_FROM_DATABASE=Boulder Nonlinear Systems
  
-@@ -1291,6 +1314,9 @@
+@@ -1303,6 +1326,9 @@
  acpi:CHA*:
   ID_VENDOR_FROM_DATABASE=Chase Research PLC
  
  acpi:CHD*:
   ID_VENDOR_FROM_DATABASE=ChangHong Electric Co.,Ltd
  
-@@ -1438,6 +1464,9 @@
+@@ -1453,6 +1479,9 @@
  acpi:COD*:
   ID_VENDOR_FROM_DATABASE=CODAN Pty. Ltd.
  
  acpi:COI*:
   ID_VENDOR_FROM_DATABASE=Codec Inc.
  
-@@ -1841,7 +1870,7 @@
+@@ -1856,7 +1885,7 @@
   ID_VENDOR_FROM_DATABASE=Dragon Information Technology
  
  acpi:DJE*:
  
  acpi:DJP*:
   ID_VENDOR_FROM_DATABASE=Maygay Machines, Ltd
-@@ -2161,6 +2190,9 @@
+@@ -2176,6 +2205,9 @@
  acpi:EIC*:
   ID_VENDOR_FROM_DATABASE=Eicon Technology Corporation
  
  acpi:EKA*:
   ID_VENDOR_FROM_DATABASE=MagTek Inc.
  
-@@ -2419,6 +2451,9 @@
+@@ -2434,6 +2466,9 @@
  acpi:FCG*:
   ID_VENDOR_FROM_DATABASE=First International Computer Ltd
  
  acpi:FCS*:
   ID_VENDOR_FROM_DATABASE=Focus Enhancements, Inc.
  
-@@ -2884,6 +2919,9 @@
+@@ -2902,6 +2937,9 @@
  acpi:HEC*:
   ID_VENDOR_FROM_DATABASE=Hisense Electric Co., Ltd.
  
  acpi:HEL*:
   ID_VENDOR_FROM_DATABASE=Hitachi Micro Systems Europe Ltd
  
-@@ -3013,6 +3051,9 @@
+@@ -3031,6 +3069,9 @@
  acpi:HSD*:
   ID_VENDOR_FROM_DATABASE=HannStar Display Corp
  
  acpi:HSM*:
   ID_VENDOR_FROM_DATABASE=AT&T Microelectronics
  
-@@ -3133,6 +3174,9 @@
+@@ -3151,6 +3192,9 @@
  acpi:ICI*:
   ID_VENDOR_FROM_DATABASE=Infotek Communication Inc
  
  acpi:ICM*:
   ID_VENDOR_FROM_DATABASE=Intracom SA
  
-@@ -3226,6 +3270,9 @@
+@@ -3244,6 +3288,9 @@
  acpi:IKE*:
   ID_VENDOR_FROM_DATABASE=Ikegami Tsushinki Co. Ltd.
  
  acpi:IKS*:
   ID_VENDOR_FROM_DATABASE=Ikos Systems Inc
  
-@@ -3268,6 +3315,9 @@
+@@ -3286,6 +3333,9 @@
  acpi:IMT*:
   ID_VENDOR_FROM_DATABASE=Inmax Technology Corporation
  
  acpi:INA*:
   ID_VENDOR_FROM_DATABASE=Inventec Corporation
  
-@@ -3769,6 +3819,9 @@
+@@ -3787,6 +3837,9 @@
  acpi:LAN*:
   ID_VENDOR_FROM_DATABASE=Sodeman Lancom Inc
  
  acpi:LAS*:
   ID_VENDOR_FROM_DATABASE=LASAT Comm. A/S
  
-@@ -3814,6 +3867,9 @@
+@@ -3832,6 +3885,9 @@
  acpi:LED*:
   ID_VENDOR_FROM_DATABASE=Long Engineering Design Inc
  
  acpi:LEG*:
   ID_VENDOR_FROM_DATABASE=Legerity, Inc
  
-@@ -3829,6 +3885,9 @@
+@@ -3847,6 +3903,9 @@
  acpi:LGC*:
   ID_VENDOR_FROM_DATABASE=Logic Ltd
  
  acpi:LGI*:
   ID_VENDOR_FROM_DATABASE=Logitech Inc
  
-@@ -3880,6 +3939,9 @@
+@@ -3898,6 +3957,9 @@
  acpi:LND*:
   ID_VENDOR_FROM_DATABASE=Land Computer Company Ltd
  
  acpi:LNK*:
   ID_VENDOR_FROM_DATABASE=Link Tech Inc
  
-@@ -3914,7 +3976,7 @@
+@@ -3932,7 +3994,7 @@
   ID_VENDOR_FROM_DATABASE=Design Technology
  
  acpi:LPL*:
  
  acpi:LSC*:
   ID_VENDOR_FROM_DATABASE=LifeSize Communications
-@@ -4084,6 +4146,9 @@
+@@ -4102,6 +4164,9 @@
  acpi:MCX*:
   ID_VENDOR_FROM_DATABASE=Millson Custom Solutions Inc.
  
  acpi:MDA*:
   ID_VENDOR_FROM_DATABASE=Media4 Inc
  
-@@ -4312,6 +4377,9 @@
+@@ -4333,6 +4398,9 @@
  acpi:MOM*:
   ID_VENDOR_FROM_DATABASE=Momentum Data Systems
  
  acpi:MOS*:
   ID_VENDOR_FROM_DATABASE=Moses Corporation
  
-@@ -4534,6 +4602,9 @@
+@@ -4558,6 +4626,9 @@
  acpi:NAL*:
   ID_VENDOR_FROM_DATABASE=Network Alchemy
  
  acpi:NAT*:
   ID_VENDOR_FROM_DATABASE=NaturalPoint Inc.
  
-@@ -5032,6 +5103,9 @@
+@@ -5062,6 +5133,9 @@
  acpi:PCX*:
   ID_VENDOR_FROM_DATABASE=PC Xperten
  
  acpi:PDM*:
   ID_VENDOR_FROM_DATABASE=Psion Dacom Plc.
  
-@@ -5095,9 +5169,6 @@
+@@ -5125,9 +5199,6 @@
  acpi:PHE*:
   ID_VENDOR_FROM_DATABASE=Philips Medical Systems Boeblingen GmbH
  
  acpi:PHL*:
   ID_VENDOR_FROM_DATABASE=Philips Consumer Electronics Company
  
-@@ -5182,9 +5253,6 @@
+@@ -5212,9 +5283,6 @@
  acpi:PNL*:
   ID_VENDOR_FROM_DATABASE=Panelview, Inc.
  
  acpi:PNR*:
   ID_VENDOR_FROM_DATABASE=Planar Systems, Inc.
  
-@@ -5314,15 +5382,9 @@
+@@ -5350,15 +5418,9 @@
  acpi:PTS*:
   ID_VENDOR_FROM_DATABASE=Plain Tree Systems Inc
  
  acpi:PVG*:
   ID_VENDOR_FROM_DATABASE=Proview Global Co., Ltd
  
-@@ -5629,9 +5691,6 @@
+@@ -5665,9 +5727,6 @@
  acpi:RTI*:
   ID_VENDOR_FROM_DATABASE=Rancho Tech Inc
  
  acpi:RTL*:
   ID_VENDOR_FROM_DATABASE=Realtek Semiconductor Company Ltd
  
-@@ -5794,9 +5853,6 @@
+@@ -5830,9 +5889,6 @@
  acpi:SEE*:
   ID_VENDOR_FROM_DATABASE=SeeColor Corporation
  
  acpi:SEI*:
   ID_VENDOR_FROM_DATABASE=Seitz & Associates Inc
  
-@@ -6247,6 +6303,9 @@
+@@ -6283,6 +6339,9 @@
  acpi:SVD*:
   ID_VENDOR_FROM_DATABASE=SVD Computer
  
  acpi:SVI*:
   ID_VENDOR_FROM_DATABASE=Sun Microsystems
  
-@@ -6328,6 +6387,9 @@
+@@ -6364,6 +6423,9 @@
  acpi:SZM*:
   ID_VENDOR_FROM_DATABASE=Shenzhen MTC Co., Ltd
  
  acpi:TAA*:
   ID_VENDOR_FROM_DATABASE=Tandberg
  
-@@ -6418,6 +6480,9 @@
+@@ -6454,6 +6516,9 @@
  acpi:TDG*:
   ID_VENDOR_FROM_DATABASE=Six15 Technologies
  
  acpi:TDM*:
   ID_VENDOR_FROM_DATABASE=Tandem Computer Europe Inc
  
-@@ -6454,6 +6519,9 @@
- acpi:TET*:
-  ID_VENDOR_FROM_DATABASE=TETRADYNE CO., LTD.
+@@ -6496,6 +6561,9 @@
+ acpi:TEV*:
+  ID_VENDOR_FROM_DATABASE=Televés, S.A.
  
 +acpi:TEX*:
 + ID_VENDOR_FROM_DATABASE=Texas Instruments
  acpi:TEZ*:
   ID_VENDOR_FROM_DATABASE=Tech Source Inc.
  
-@@ -6568,9 +6636,6 @@
+@@ -6610,9 +6678,6 @@
  acpi:TNC*:
   ID_VENDOR_FROM_DATABASE=TNC Industrial Company Ltd
  
  acpi:TNM*:
   ID_VENDOR_FROM_DATABASE=TECNIMAGEN SA
  
-@@ -6874,14 +6939,14 @@
+@@ -6916,14 +6981,14 @@
  acpi:UNC*:
   ID_VENDOR_FROM_DATABASE=Unisys Corporation
  
  
  acpi:UNI*:
   ID_VENDOR_FROM_DATABASE=Uniform Industry Corp.
-@@ -6916,6 +6981,9 @@
+@@ -6958,6 +7023,9 @@
  acpi:USA*:
   ID_VENDOR_FROM_DATABASE=Utimaco Safeware AG
  
  acpi:USD*:
   ID_VENDOR_FROM_DATABASE=U.S. Digital Corporation
  
-@@ -7144,9 +7212,6 @@
+@@ -7192,9 +7260,6 @@
  acpi:WAL*:
   ID_VENDOR_FROM_DATABASE=Wave Access
  
  acpi:WAV*:
   ID_VENDOR_FROM_DATABASE=Wavephore
  
-@@ -7265,7 +7330,7 @@
+@@ -7313,7 +7378,7 @@
   ID_VENDOR_FROM_DATABASE=Woxter Technology Co. Ltd
  
  acpi:WYS*:
  
  acpi:WYT*:
   ID_VENDOR_FROM_DATABASE=Wooyoung Image & Information Co.,Ltd.
-@@ -7279,9 +7344,6 @@
+@@ -7327,9 +7392,6 @@
  acpi:XDM*:
   ID_VENDOR_FROM_DATABASE=XDM Ltd.
  
 -acpi:XER*:
 - ID_VENDOR_FROM_DATABASE=DO NOT USE - XER
 -
- acpi:XFG*:
-  ID_VENDOR_FROM_DATABASE=Jan Strapko - FOTO
+ acpi:XES*:
+  ID_VENDOR_FROM_DATABASE=Extreme Engineering Solutions, Inc.
  
-@@ -7309,9 +7371,6 @@
+@@ -7360,9 +7422,6 @@
  acpi:XNT*:
   ID_VENDOR_FROM_DATABASE=XN Technologies, Inc.
  
  acpi:XQU*:
   ID_VENDOR_FROM_DATABASE=SHANGHAI SVA-DAV ELECTRONICS CO., LTD
  
-@@ -7378,6 +7437,9 @@
+@@ -7429,6 +7488,9 @@
  acpi:ZBX*:
   ID_VENDOR_FROM_DATABASE=Zebax Technologies
  
index c756e2e..e6ed2e3 100644 (file)
@@ -150,7 +150,7 @@ pci:v00000B0Bd00000205*
  ID_MODEL_FROM_DATABASE=R4FXO
 
 pci:v00000B0Bd00000206*
- ID_MODEL_FROM_DATABASE=RCB4FXO 4-channel FXO analog telphony card
+ ID_MODEL_FROM_DATABASE=RCB4FXO 4-channel FXO analog telephony card
 
 pci:v00000B0Bd00000305*
  ID_MODEL_FROM_DATABASE=R4T1
@@ -159,13 +159,13 @@ pci:v00000B0Bd00000405*
  ID_MODEL_FROM_DATABASE=R8FXX
 
 pci:v00000B0Bd00000406*
- ID_MODEL_FROM_DATABASE=RCB8FXX 8-channel modular analog telphony card
+ ID_MODEL_FROM_DATABASE=RCB8FXX 8-channel modular analog telephony card
 
 pci:v00000B0Bd00000505*
  ID_MODEL_FROM_DATABASE=R24FXX
 
 pci:v00000B0Bd00000506*
- ID_MODEL_FROM_DATABASE=RCB24FXS 24-Channel FXS analog telphony card
+ ID_MODEL_FROM_DATABASE=RCB24FXS 24-Channel FXS analog telephony card
 
 pci:v00000B0Bd00000605*
  ID_MODEL_FROM_DATABASE=R2T1
@@ -174,16 +174,16 @@ pci:v00000B0Bd00000705*
  ID_MODEL_FROM_DATABASE=R24FXS
 
 pci:v00000B0Bd00000706*
- ID_MODEL_FROM_DATABASE=RCB24FXO 24-Channel FXO analog telphony card
+ ID_MODEL_FROM_DATABASE=RCB24FXO 24-Channel FXO analog telephony card
 
 pci:v00000B0Bd00000905*
  ID_MODEL_FROM_DATABASE=R1T3 Single T3 Digital Telephony Card
 
 pci:v00000B0Bd00000906*
- ID_MODEL_FROM_DATABASE=RCB24FXX 24-channel modular analog telphony card
+ ID_MODEL_FROM_DATABASE=RCB24FXX 24-channel modular analog telephony card
 
 pci:v00000B0Bd00000A06*
- ID_MODEL_FROM_DATABASE=RCB672FXX 672-channel modular analog telphony card
+ ID_MODEL_FROM_DATABASE=RCB672FXX 672-channel modular analog telephony card
 
 pci:v00000E11*
  ID_VENDOR_FROM_DATABASE=Compaq Computer Corporation
@@ -662,6 +662,15 @@ pci:v00001000d00000014sv00001D49sd00000602*
 pci:v00001000d00000014sv00001D49sd00000604*
  ID_MODEL_FROM_DATABASE=MegaRAID Tri-Mode SAS3516 (ThinkSystem RAID 930-8e 4GB Flash PCIe 12Gb Adapter)
 
+pci:v00001000d00000014sv00008086sd0000352D*
+ ID_MODEL_FROM_DATABASE=MegaRAID Tri-Mode SAS3516 (Integrated RAID Module RMSP3AD160F)
+
+pci:v00001000d00000014sv00008086sd00009460*
+ ID_MODEL_FROM_DATABASE=MegaRAID Tri-Mode SAS3516 (RAID Controller RSP3TD160F)
+
+pci:v00001000d00000014sv00008086sd00009480*
+ ID_MODEL_FROM_DATABASE=MegaRAID Tri-Mode SAS3516 (RAID Controller RSP3MD088F)
+
 pci:v00001000d00000015*
  ID_MODEL_FROM_DATABASE=MegaRAID Tri-Mode SAS3416
 
@@ -689,6 +698,15 @@ pci:v00001000d00000016sv00001D49sd00000603*
 pci:v00001000d00000016sv00001D49sd00000604*
  ID_MODEL_FROM_DATABASE=MegaRAID Tri-Mode SAS3508 (ThinkSystem RAID 930-8e 4GB Flash PCIe 12Gb Adapter)
 
+pci:v00001000d00000016sv00008086sd0000352E*
+ ID_MODEL_FROM_DATABASE=MegaRAID Tri-Mode SAS3508 (Integrated RAID Module RMSP3CD080F)
+
+pci:v00001000d00000016sv00008086sd0000352F*
+ ID_MODEL_FROM_DATABASE=MegaRAID Tri-Mode SAS3508 (Integrated RAID Module RMSP3HD080E)
+
+pci:v00001000d00000016sv00008086sd00009461*
+ ID_MODEL_FROM_DATABASE=MegaRAID Tri-Mode SAS3508 (RAID Controller RSP3DD080F)
+
 pci:v00001000d00000017*
  ID_MODEL_FROM_DATABASE=MegaRAID Tri-Mode SAS3408
 
@@ -698,6 +716,15 @@ pci:v00001000d00000017sv00001D49sd00000500*
 pci:v00001000d00000017sv00001D49sd00000502*
  ID_MODEL_FROM_DATABASE=MegaRAID Tri-Mode SAS3408 (ThinkSystem RAID 530-8i Dense Adapter)
 
+pci:v00001000d00000017sv00008086sd00003528*
+ ID_MODEL_FROM_DATABASE=MegaRAID Tri-Mode SAS3408 (Integrated RAID RMSP3LD060)
+
+pci:v00001000d00000017sv00008086sd00003529*
+ ID_MODEL_FROM_DATABASE=MegaRAID Tri-Mode SAS3408 (Integrated RAID RMSP3LD060)
+
+pci:v00001000d00000017sv00008086sd00009441*
+ ID_MODEL_FROM_DATABASE=MegaRAID Tri-Mode SAS3408 (RAID Controller RSP3WD080E)
+
 pci:v00001000d0000001B*
  ID_MODEL_FROM_DATABASE=MegaRAID Tri-Mode SAS3504
 
@@ -1664,6 +1691,9 @@ pci:v00001000d00000097sv00001BD4sd00000011*
 pci:v00001000d000000AB*
  ID_MODEL_FROM_DATABASE=SAS3516 Fusion-MPT Tri-Mode RAID On Chip (ROC)
 
+pci:v00001000d000000ABsv00008086sd00003530*
+ ID_MODEL_FROM_DATABASE=SAS3516 Fusion-MPT Tri-Mode RAID On Chip (ROC) (Integrated RAID Module RMSP3JD160J)
+
 pci:v00001000d000000AC*
  ID_MODEL_FROM_DATABASE=SAS3416 Fusion-MPT Tri-Mode I/O Controller Chip (IOC)
 
@@ -1673,6 +1703,12 @@ pci:v00001000d000000ACsv00001D49sd00000201*
 pci:v00001000d000000ACsv00001D49sd00000203*
  ID_MODEL_FROM_DATABASE=SAS3416 Fusion-MPT Tri-Mode I/O Controller Chip (IOC) (ThinkSystem 430-16e SAS/SATA 12Gb HBA)
 
+pci:v00001000d000000ACsv00008086sd00003000*
+ ID_MODEL_FROM_DATABASE=SAS3416 Fusion-MPT Tri-Mode I/O Controller Chip (IOC) (RAID Controller RSP3QD160J)
+
+pci:v00001000d000000ACsv00008086sd00003020*
+ ID_MODEL_FROM_DATABASE=SAS3416 Fusion-MPT Tri-Mode I/O Controller Chip (IOC) (RAID Controller RSP3GD016J)
+
 pci:v00001000d000000AE*
  ID_MODEL_FROM_DATABASE=SAS3508 Fusion-MPT Tri-Mode RAID On Chip (ROC)
 
@@ -2120,6 +2156,9 @@ pci:v00001002d0000131C*
 pci:v00001002d0000131D*
  ID_MODEL_FROM_DATABASE=Kaveri [Radeon R6 Graphics]
 
+pci:v00001002d000015DD*
+ ID_MODEL_FROM_DATABASE=Radeon Vega 8 Mobile
+
 pci:v00001002d00001714*
  ID_MODEL_FROM_DATABASE=BeaverCreek HDMI Audio [Radeon HD 6500D and 6400G-6600G series]
 
@@ -2624,6 +2663,9 @@ pci:v00001002d00004383sv00001043sd00008410*
 pci:v00001002d00004383sv00001043sd0000841B*
  ID_MODEL_FROM_DATABASE=SBx00 Azalia (Intel HDA) (M5A88-V EVO)
 
+pci:v00001002d00004383sv0000105Bsd00000E13*
+ ID_MODEL_FROM_DATABASE=SBx00 Azalia (Intel HDA) (N15235/A74MX mainboard / AMD SB700)
+
 pci:v00001002d00004383sv00001179sd0000FF50*
  ID_MODEL_FROM_DATABASE=SBx00 Azalia (Intel HDA) (Satellite P305D-S8995E)
 
@@ -2654,6 +2696,9 @@ pci:v00001002d00004385sv00001043sd000082EF*
 pci:v00001002d00004385sv00001043sd00008389*
  ID_MODEL_FROM_DATABASE=SBx00 SMBus Controller (M4A785TD Motherboard)
 
+pci:v00001002d00004385sv0000105Bsd00000E13*
+ ID_MODEL_FROM_DATABASE=SBx00 SMBus Controller (N15235/A74MX mainboard / AMD SB700)
+
 pci:v00001002d00004385sv00001179sd0000FF50*
  ID_MODEL_FROM_DATABASE=SBx00 SMBus Controller (Satellite P305D-S8995E)
 
@@ -2807,6 +2852,9 @@ pci:v00001002d00004390sv00001043sd000082EF*
 pci:v00001002d00004390sv00001043sd00008389*
  ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 SATA Controller [IDE mode] (M4A785TD Motherboard)
 
+pci:v00001002d00004390sv0000105Bsd00000E13*
+ ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 SATA Controller [IDE mode] (N15235/A74MX mainboard / AMD SB700)
+
 pci:v00001002d00004390sv00001458sd0000B002*
  ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 SATA Controller [IDE mode] (GA-MA770-DS3rev2.0 Motherboard)
 
@@ -2825,12 +2873,18 @@ pci:v00001002d00004391sv00001043sd000082EF*
 pci:v00001002d00004391sv00001043sd00008443*
  ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 SATA Controller [AHCI mode] (M5A88-V EVO)
 
+pci:v00001002d00004391sv0000105Bsd00000E13*
+ ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 SATA Controller [AHCI mode] (N15235/A74MX mainboard / AMD SB700)
+
 pci:v00001002d00004391sv0000174Bsd00001001*
  ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 SATA Controller [AHCI mode] (PURE Fusion Mini)
 
 pci:v00001002d00004392*
  ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 SATA Controller [Non-RAID5 mode]
 
+pci:v00001002d00004392sv0000105Bsd00000E13*
+ ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 SATA Controller [Non-RAID5 mode] (N15235/A74MX mainboard / AMD SB700)
+
 pci:v00001002d00004393*
  ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 SATA Controller [RAID5 mode]
 
@@ -2855,6 +2909,9 @@ pci:v00001002d00004396sv00001043sd000082EF*
 pci:v00001002d00004396sv00001043sd00008443*
  ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 USB EHCI Controller (M5A88-V EVO)
 
+pci:v00001002d00004396sv0000105Bsd00000E13*
+ ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 USB EHCI Controller (N15235/A74MX mainboard / AMD SB700)
+
 pci:v00001002d00004396sv000015D9sd0000A811*
  ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 USB EHCI Controller (H8DGU)
 
@@ -2876,6 +2933,9 @@ pci:v00001002d00004397sv00001043sd000082EF*
 pci:v00001002d00004397sv00001043sd00008443*
  ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 USB OHCI0 Controller (M5A88-V EVO)
 
+pci:v00001002d00004397sv0000105Bsd00000E13*
+ ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 USB OHCI0 Controller (N15235/A74MX mainboard / AMD SB700)
+
 pci:v00001002d00004397sv000015D9sd0000A811*
  ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 USB OHCI0 Controller (H8DGU)
 
@@ -2891,6 +2951,9 @@ pci:v00001002d00004398sv00001019sd00002120*
 pci:v00001002d00004398sv00001043sd000082EF*
  ID_MODEL_FROM_DATABASE=SB7x0 USB OHCI1 Controller (M3A78-EH Motherboard)
 
+pci:v00001002d00004398sv0000105Bsd00000E13*
+ ID_MODEL_FROM_DATABASE=SB7x0 USB OHCI1 Controller (N15235/A74MX mainboard / AMD SB700)
+
 pci:v00001002d00004398sv000015D9sd0000A811*
  ID_MODEL_FROM_DATABASE=SB7x0 USB OHCI1 Controller (H8DGU)
 
@@ -2906,6 +2969,9 @@ pci:v00001002d00004399sv00001043sd000082EF*
 pci:v00001002d00004399sv00001043sd00008443*
  ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 USB OHCI2 Controller (M5A88-V EVO)
 
+pci:v00001002d00004399sv0000105Bsd00000E13*
+ ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 USB OHCI2 Controller (N15235/A74MX mainboard / AMD SB700)
+
 pci:v00001002d00004399sv0000174Bsd00001001*
  ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 USB OHCI2 Controller (PURE Fusion Mini)
 
@@ -2918,6 +2984,9 @@ pci:v00001002d0000439Csv00001019sd00002120*
 pci:v00001002d0000439Csv00001043sd000082EF*
  ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 IDE Controller (M3A78-EH Motherboard)
 
+pci:v00001002d0000439Csv0000105Bsd00000E13*
+ ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 IDE Controller (N15235/A74MX mainboard / AMD SB700)
+
 pci:v00001002d0000439D*
  ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 LPC host controller
 
@@ -2933,6 +3002,9 @@ pci:v00001002d0000439Dsv00001043sd000082EF*
 pci:v00001002d0000439Dsv00001043sd00008443*
  ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 LPC host controller (M5A88-V EVO)
 
+pci:v00001002d0000439Dsv0000105Bsd00000E13*
+ ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 LPC host controller (N15235/A74MX mainboard / AMD SB700)
+
 pci:v00001002d0000439Dsv0000174Bsd00001001*
  ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 LPC host controller (PURE Fusion Mini)
 
@@ -4628,6 +4700,9 @@ pci:v00001002d00006604sv000017AAsd00003643*
 pci:v00001002d00006605*
  ID_MODEL_FROM_DATABASE=Opal PRO [Radeon R7 M260]
 
+pci:v00001002d00006605sv0000103Csd00002259*
+ ID_MODEL_FROM_DATABASE=Opal PRO [Radeon R7 M260] (FirePro M4150)
+
 pci:v00001002d00006606*
  ID_MODEL_FROM_DATABASE=Mars XTX [Radeon HD 8790M]
 
@@ -4712,6 +4787,9 @@ pci:v00001002d00006631*
 pci:v00001002d00006640*
  ID_MODEL_FROM_DATABASE=Saturn XT [FirePro M6100]
 
+pci:v00001002d00006640sv0000106Bsd0000014B*
+ ID_MODEL_FROM_DATABASE=Saturn XT [FirePro M6100] (Tropo XT [Radeon R9 M380 Mac Edition])
+
 pci:v00001002d00006641*
  ID_MODEL_FROM_DATABASE=Saturn PRO [Radeon HD 8930M]
 
@@ -6915,7 +6993,10 @@ pci:v00001002d0000682A*
  ID_MODEL_FROM_DATABASE=Venus PRO
 
 pci:v00001002d0000682B*
- ID_MODEL_FROM_DATABASE=Venus LE [Radeon HD 8830M]
+ ID_MODEL_FROM_DATABASE=Venus LE / Tropo PRO-L [Radeon HD 8830M / R7 M465X]
+
+pci:v00001002d0000682Bsv00000128sd0000079C*
+ ID_MODEL_FROM_DATABASE=Venus LE / Tropo PRO-L [Radeon HD 8830M / R7 M465X] (Radeon R7 465X)
 
 pci:v00001002d0000682C*
  ID_MODEL_FROM_DATABASE=Cape Verde GL [FirePro W4100]
@@ -7316,6 +7397,9 @@ pci:v00001002d00006842*
 pci:v00001002d00006843*
  ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7670M]
 
+pci:v00001002d00006861*
+ ID_MODEL_FROM_DATABASE=Vega 10 XT [Radeon PRO WX 9100]
+
 pci:v00001002d00006863*
  ID_MODEL_FROM_DATABASE=Vega 10 XTX [Radeon Vega Frontier Edition]
 
@@ -9261,10 +9345,13 @@ pci:v00001002d00007910sv000017F2sd00005000*
  ID_MODEL_FROM_DATABASE=RS690 Host Bridge (KI690-AM2 Motherboard)
 
 pci:v00001002d00007911*
- ID_MODEL_FROM_DATABASE=RS690 Host Bridge
+ ID_MODEL_FROM_DATABASE=RS690/RS740 Host Bridge
+
+pci:v00001002d00007911sv00001002sd00007910*
+ ID_MODEL_FROM_DATABASE=RS690/RS740 Host Bridge
 
 pci:v00001002d00007912*
- ID_MODEL_FROM_DATABASE=RS690 PCI to PCI Bridge (Internal gfx)
+ ID_MODEL_FROM_DATABASE=RS690/RS740 PCI to PCI Bridge (Internal gfx)
 
 pci:v00001002d00007913*
  ID_MODEL_FROM_DATABASE=RS690 PCI to PCI Bridge (PCI Express Graphics Port 0)
@@ -9338,6 +9425,9 @@ pci:v00001002d00007942*
 pci:v00001002d0000796E*
  ID_MODEL_FROM_DATABASE=RS740 [Radeon 2100]
 
+pci:v00001002d0000796Esv0000105Bsd00000E13*
+ ID_MODEL_FROM_DATABASE=RS740 [Radeon 2100] (N15235/A74MX mainboard)
+
 pci:v00001002d00009400*
  ID_MODEL_FROM_DATABASE=R600 [Radeon HD 2900 PRO/XT]
 
@@ -9971,6 +10061,9 @@ pci:v00001002d00009850*
 pci:v00001002d00009851*
  ID_MODEL_FROM_DATABASE=Mullins [Radeon R4/R5 Graphics]
 
+pci:v00001002d00009851sv00001179sd0000F928*
+ ID_MODEL_FROM_DATABASE=Mullins [Radeon R4/R5 Graphics] (Beema [Radeon R5 Graphics])
+
 pci:v00001002d00009852*
  ID_MODEL_FROM_DATABASE=Mullins [Radeon R2 Graphics]
 
@@ -11858,6 +11951,9 @@ pci:v00001022d00001422*
 pci:v00001022d00001423*
  ID_MODEL_FROM_DATABASE=Family 15h (Models 30h-3fh) I/O Memory Management Unit
 
+pci:v00001022d00001424*
+ ID_MODEL_FROM_DATABASE=Family 15h (Models 30h-3fh) Processor Root Port
+
 pci:v00001022d00001426*
  ID_MODEL_FROM_DATABASE=Family 15h (Models 30h-3fh) Processor Root Port
 
@@ -11876,17 +11972,29 @@ pci:v00001022d00001439*
 pci:v00001022d00001450*
  ID_MODEL_FROM_DATABASE=Family 17h (Models 00h-0fh) Root Complex
 
+pci:v00001022d00001451*
+ ID_MODEL_FROM_DATABASE=Family 17h (Models 00h-0fh) I/O Memory Management Unit
+
 pci:v00001022d00001452*
  ID_MODEL_FROM_DATABASE=Family 17h (Models 00h-0fh) PCIe Dummy Host Bridge
 
+pci:v00001022d00001453*
+ ID_MODEL_FROM_DATABASE=Family 17h (Models 00h-0fh) PCIe GPP Bridge
+
 pci:v00001022d00001454*
  ID_MODEL_FROM_DATABASE=Family 17h (Models 00h-0fh) Internal PCIe GPP Bridge 0 to Bus B
 
+pci:v00001022d00001456*
+ ID_MODEL_FROM_DATABASE=Family 17h (Models 00h-0fh) Platform Security Processor
+
+pci:v00001022d00001457*
+ ID_MODEL_FROM_DATABASE=Family 17h (Models 00h-0fh) HD Audio Controller
+
 pci:v00001022d0000145B*
  ID_MODEL_FROM_DATABASE=Zeppelin Non-Transparent Bridge
 
 pci:v00001022d0000145C*
- ID_MODEL_FROM_DATABASE=USB3 Host Controller
+ ID_MODEL_FROM_DATABASE=Family 17h (Models 00h-0fh) USB 3.0 Host Controller
 
 pci:v00001022d0000145F*
  ID_MODEL_FROM_DATABASE=USB 3.0 Host controller
@@ -12167,8 +12275,14 @@ pci:v00001022d000043A2*
 pci:v00001022d000043A3*
  ID_MODEL_FROM_DATABASE=Hudson PCI to PCI bridge (PCIE port 3)
 
+pci:v00001022d000043B4*
+ ID_MODEL_FROM_DATABASE=300 Series Chipset PCIe Port
+
+pci:v00001022d000043B7*
+ ID_MODEL_FROM_DATABASE=300 Series Chipset SATA Controller
+
 pci:v00001022d000043BB*
- ID_MODEL_FROM_DATABASE=USB 3.1 XHCI Controller
+ ID_MODEL_FROM_DATABASE=300 Series Chipset USB 3.1 xHCI Controller
 
 pci:v00001022d00007006*
  ID_MODEL_FROM_DATABASE=AMD-751 [Irongate] System Controller
@@ -13641,115 +13755,115 @@ pci:v0000102Bd00002527sv0000102Bsd00002300*
  ID_MODEL_FROM_DATABASE=Millennium G550 (LP PCIE)
 
 pci:v0000102Bd00002537*
- ID_MODEL_FROM_DATABASE=Millenium P650/P750
+ ID_MODEL_FROM_DATABASE=Millennium P650/P750
 
 pci:v0000102Bd00002537sv0000102Bsd00001820*
- ID_MODEL_FROM_DATABASE=Millenium P650/P750 (Millennium P750 64MB)
+ ID_MODEL_FROM_DATABASE=Millennium P650/P750 (Millennium P750 64MB)
 
 pci:v0000102Bd00002537sv0000102Bsd00001830*
- ID_MODEL_FROM_DATABASE=Millenium P650/P750 (Millennium P650 64MB)
+ ID_MODEL_FROM_DATABASE=Millennium P650/P750 (Millennium P650 64MB)
 
 pci:v0000102Bd00002537sv0000102Bsd00001850*
- ID_MODEL_FROM_DATABASE=Millenium P650/P750 (RAD2mp)
+ ID_MODEL_FROM_DATABASE=Millennium P650/P750 (RAD2mp)
 
 pci:v0000102Bd00002537sv0000102Bsd00001860*
- ID_MODEL_FROM_DATABASE=Millenium P650/P750 (RAD3mp)
+ ID_MODEL_FROM_DATABASE=Millennium P650/P750 (RAD3mp)
 
 pci:v0000102Bd00002537sv0000102Bsd00001880*
- ID_MODEL_FROM_DATABASE=Millenium P650/P750 (Sono S10)
+ ID_MODEL_FROM_DATABASE=Millennium P650/P750 (Sono S10)
 
 pci:v0000102Bd00002537sv0000102Bsd00001C10*
- ID_MODEL_FROM_DATABASE=Millenium P650/P750 (QID 128MB)
+ ID_MODEL_FROM_DATABASE=Millennium P650/P750 (QID 128MB)
 
 pci:v0000102Bd00002537sv0000102Bsd00002811*
- ID_MODEL_FROM_DATABASE=Millenium P650/P750 (Millennium P650 Low-profile PCI 64MB)
+ ID_MODEL_FROM_DATABASE=Millennium P650/P750 (Millennium P650 Low-profile PCI 64MB)
 
 pci:v0000102Bd00002537sv0000102Bsd00002821*
- ID_MODEL_FROM_DATABASE=Millenium P650/P750 (Millenium P650 Low-profile PCI)
+ ID_MODEL_FROM_DATABASE=Millennium P650/P750 (Millennium P650 Low-profile PCI)
 
 pci:v0000102Bd00002537sv0000102Bsd00002841*
- ID_MODEL_FROM_DATABASE=Millenium P650/P750 (RAD PCI)
+ ID_MODEL_FROM_DATABASE=Millennium P650/P750 (RAD PCI)
 
 pci:v0000102Bd00002537sv0000102Bsd00002851*
- ID_MODEL_FROM_DATABASE=Millenium P650/P750 (Spectrum PCI)
+ ID_MODEL_FROM_DATABASE=Millennium P650/P750 (Spectrum PCI)
 
 pci:v0000102Bd00002537sv0000102Bsd00002871*
- ID_MODEL_FROM_DATABASE=Millenium P650/P750 (EpicA TC2)
+ ID_MODEL_FROM_DATABASE=Millennium P650/P750 (EpicA TC2)
 
 pci:v0000102Bd00002537sv0000102Bsd00002C11*
- ID_MODEL_FROM_DATABASE=Millenium P650/P750 (QID Low-profile PCI)
+ ID_MODEL_FROM_DATABASE=Millennium P650/P750 (QID Low-profile PCI)
 
 pci:v0000102Bd00002537sv0000102Bsd00002C21*
- ID_MODEL_FROM_DATABASE=Millenium P650/P750 (QID LP PCI LW)
+ ID_MODEL_FROM_DATABASE=Millennium P650/P750 (QID LP PCI LW)
 
 pci:v0000102Bd00002537sv0000102Bsd00002C31*
- ID_MODEL_FROM_DATABASE=Millenium P650/P750 (QID LP PCI)
+ ID_MODEL_FROM_DATABASE=Millennium P650/P750 (QID LP PCI)
 
 pci:v0000102Bd00002537sv0000102Bsd00002C41*
- ID_MODEL_FROM_DATABASE=Millenium P650/P750 (EpicA TC4)
+ ID_MODEL_FROM_DATABASE=Millennium P650/P750 (EpicA TC4)
 
 pci:v0000102Bd00002537sv0000102Bsd00003001*
- ID_MODEL_FROM_DATABASE=Millenium P650/P750 (Extio F1400)
+ ID_MODEL_FROM_DATABASE=Millennium P650/P750 (Extio F1400)
 
 pci:v0000102Bd00002537sv0000102Bsd00003011*
- ID_MODEL_FROM_DATABASE=Millenium P650/P750 (Extio F1220)
+ ID_MODEL_FROM_DATABASE=Millennium P650/P750 (Extio F1220)
 
 pci:v0000102Bd00002537sv0000102Bsd00003041*
- ID_MODEL_FROM_DATABASE=Millenium P650/P750 (RG-200DL)
+ ID_MODEL_FROM_DATABASE=Millennium P650/P750 (RG-200DL)
 
 pci:v0000102Bd00002537sv0000102Bsd00003051*
- ID_MODEL_FROM_DATABASE=Millenium P650/P750 (RG-400SL)
+ ID_MODEL_FROM_DATABASE=Millennium P650/P750 (RG-400SL)
 
 pci:v0000102Bd00002537sv0000102Bsd00003061*
- ID_MODEL_FROM_DATABASE=Millenium P650/P750 (Extio F1420)
+ ID_MODEL_FROM_DATABASE=Millennium P650/P750 (Extio F1420)
 
 pci:v0000102Bd00002537sv0000102Bsd00003081*
- ID_MODEL_FROM_DATABASE=Millenium P650/P750 (Extio F1240)
+ ID_MODEL_FROM_DATABASE=Millennium P650/P750 (Extio F1240)
 
 pci:v0000102Bd00002538*
- ID_MODEL_FROM_DATABASE=Millenium P650 PCIe
+ ID_MODEL_FROM_DATABASE=Millennium P650 PCIe
 
 pci:v0000102Bd00002538sv0000102Bsd00000847*
- ID_MODEL_FROM_DATABASE=Millenium P650 PCIe (RAD PCIe)
+ ID_MODEL_FROM_DATABASE=Millennium P650 PCIe (RAD PCIe)
 
 pci:v0000102Bd00002538sv0000102Bsd000008C7*
- ID_MODEL_FROM_DATABASE=Millenium P650 PCIe (Millennium P650 PCIe 128MB)
+ ID_MODEL_FROM_DATABASE=Millennium P650 PCIe (128MB)
 
 pci:v0000102Bd00002538sv0000102Bsd00000907*
- ID_MODEL_FROM_DATABASE=Millenium P650 PCIe (Millennium P650 PCIe 64MB)
+ ID_MODEL_FROM_DATABASE=Millennium P650 PCIe (64MB)
 
 pci:v0000102Bd00002538sv0000102Bsd00000947*
- ID_MODEL_FROM_DATABASE=Millenium P650 PCIe (Parhelia APVe)
+ ID_MODEL_FROM_DATABASE=Millennium P650 PCIe (Parhelia APVe)
 
 pci:v0000102Bd00002538sv0000102Bsd00000987*
- ID_MODEL_FROM_DATABASE=Millenium P650 PCIe (ATC PCIe 4MP)
+ ID_MODEL_FROM_DATABASE=Millennium P650 PCIe (ATC PCIe 4MP)
 
 pci:v0000102Bd00002538sv0000102Bsd00001047*
- ID_MODEL_FROM_DATABASE=Millenium P650 PCIe (Millennium P650 LP PCIe 128MB)
+ ID_MODEL_FROM_DATABASE=Millennium P650 PCIe (Millennium P650 LP PCIe 128MB)
 
 pci:v0000102Bd00002538sv0000102Bsd00001087*
- ID_MODEL_FROM_DATABASE=Millenium P650 PCIe (Millennium P650 LP PCIe 64MB)
+ ID_MODEL_FROM_DATABASE=Millennium P650 PCIe (Millennium P650 LP PCIe 64MB)
 
 pci:v0000102Bd00002538sv0000102Bsd00001801*
- ID_MODEL_FROM_DATABASE=Millenium P650 PCIe (x1)
+ ID_MODEL_FROM_DATABASE=Millennium P650 PCIe (x1)
 
 pci:v0000102Bd00002538sv0000102Bsd00002538*
- ID_MODEL_FROM_DATABASE=Millenium P650 PCIe (Parhelia APVe)
+ ID_MODEL_FROM_DATABASE=Millennium P650 PCIe (Parhelia APVe)
 
 pci:v0000102Bd00002538sv0000102Bsd00003007*
- ID_MODEL_FROM_DATABASE=Millenium P650 PCIe (QID Low-profile PCIe)
+ ID_MODEL_FROM_DATABASE=Millennium P650 PCIe (QID Low-profile PCIe)
 
 pci:v0000102Bd00002538sv0000102Bsd00003087*
- ID_MODEL_FROM_DATABASE=Millenium P650 PCIe (Aurora VX3mp)
+ ID_MODEL_FROM_DATABASE=Millennium P650 PCIe (Aurora VX3mp)
 
 pci:v0000102Bd00002538sv0000102Bsd000030C7*
- ID_MODEL_FROM_DATABASE=Millenium P650 PCIe (QID LP PCIe)
+ ID_MODEL_FROM_DATABASE=Millennium P650 PCIe (QID LP PCIe)
 
 pci:v0000102Bd00002539*
  ID_MODEL_FROM_DATABASE=Millennium P690
 
 pci:v0000102Bd00002539sv0000102Bsd00000040*
- ID_MODEL_FROM_DATABASE=Millennium P690 (Millenium P690 PCIe x16)
+ ID_MODEL_FROM_DATABASE=Millennium P690 (PCIe x16)
 
 pci:v0000102Bd00002539sv0000102Bsd00000042*
  ID_MODEL_FROM_DATABASE=Millennium P690 (ONYX)
@@ -13758,28 +13872,28 @@ pci:v0000102Bd00002539sv0000102Bsd00000043*
  ID_MODEL_FROM_DATABASE=Millennium P690 (SPECTRA)
 
 pci:v0000102Bd00002539sv0000102Bsd00000080*
- ID_MODEL_FROM_DATABASE=Millennium P690 (Millenium P690 Plus LP PCIe x16)
+ ID_MODEL_FROM_DATABASE=Millennium P690 (Plus LP PCIe x16)
 
 pci:v0000102Bd00002539sv0000102Bsd00000081*
- ID_MODEL_FROM_DATABASE=Millennium P690 (Millenium P690 LP PCIe x16)
+ ID_MODEL_FROM_DATABASE=Millennium P690 (LP PCIe x16)
 
 pci:v0000102Bd00002539sv0000102Bsd00000082*
  ID_MODEL_FROM_DATABASE=Millennium P690 (RAD LPX PCIe x16)
 
 pci:v0000102Bd00002539sv0000102Bsd000000C0*
- ID_MODEL_FROM_DATABASE=Millennium P690 (Millenium P690 Plus LP PCI)
+ ID_MODEL_FROM_DATABASE=Millennium P690 (Plus LP PCI)
 
 pci:v0000102Bd00002539sv0000102Bsd000000C2*
- ID_MODEL_FROM_DATABASE=Millennium P690 (Millenium P690 LP PCI)
+ ID_MODEL_FROM_DATABASE=Millennium P690 (LP PCI)
 
 pci:v0000102Bd00002539sv0000102Bsd000000C3*
  ID_MODEL_FROM_DATABASE=Millennium P690 (RAD LPX PCI)
 
 pci:v0000102Bd00002539sv0000102Bsd00000101*
- ID_MODEL_FROM_DATABASE=Millennium P690 (Millenium P690 PCI)
+ ID_MODEL_FROM_DATABASE=Millennium P690 (PCI)
 
 pci:v0000102Bd00002539sv0000102Bsd00000140*
- ID_MODEL_FROM_DATABASE=Millennium P690 (Millenium P690 LP PCIe x1)
+ ID_MODEL_FROM_DATABASE=Millennium P690 (LP PCIe x1)
 
 pci:v0000102Bd00002539sv0000102Bsd00000180*
  ID_MODEL_FROM_DATABASE=Millennium P690 (Display Wall IP Decode 128 MB)
@@ -15314,9 +15428,6 @@ pci:v0000103Cd00003308sv0000103Csd0000330E*
 pci:v0000103Cd00003308sv0000103Csd00003381*
  ID_MODEL_FROM_DATABASE=Integrated Lights-Out Standard MS Watchdog Timer (iLO4)
 
-pci:v0000103Cd0000402F*
- ID_MODEL_FROM_DATABASE=PCIe Root Port
-
 pci:v0000103Cd00004030*
  ID_MODEL_FROM_DATABASE=zx2 System Bus Adapter
 
@@ -15326,9 +15437,6 @@ pci:v0000103Cd00004031*
 pci:v0000103Cd00004037*
  ID_MODEL_FROM_DATABASE=PCIe Local Bus Adapter
 
-pci:v0000103Cd0000403B*
- ID_MODEL_FROM_DATABASE=PCIe Root Port
-
 pci:v0000103E*
  ID_VENDOR_FROM_DATABASE=Solliday Engineering
 
@@ -15365,6 +15473,9 @@ pci:v00001043*
 pci:v00001043d00000464*
  ID_MODEL_FROM_DATABASE=Radeon R9 270x GPU
 
+pci:v00001043d00000521*
+ ID_MODEL_FROM_DATABASE=RX580 [RX 580 Dual O8G]
+
 pci:v00001043d00000675*
  ID_MODEL_FROM_DATABASE=ISDNLink P-IN100-ST-D
 
@@ -15377,9 +15488,6 @@ pci:v00001043d00000675sv00000675sd00001707*
 pci:v00001043d00000675sv000010CFsd0000105E*
  ID_MODEL_FROM_DATABASE=ISDNLink P-IN100-ST-D (ISDN Adapter (PCI Bus, DV, W))
 
-pci:v00001043d000013A0*
- ID_MODEL_FROM_DATABASE=Transformer Book T101HA-GR030R
-
 pci:v00001043d00009602*
  ID_MODEL_FROM_DATABASE=AMD RS780/RS880 PCI to PCI bridge (int gfx)
 
@@ -18221,6 +18329,9 @@ pci:v00001077d00002432*
 pci:v00001077d00002432sv0000103Csd00007040*
  ID_MODEL_FROM_DATABASE=ISP2432-based 4Gb Fibre Channel to PCI Express HBA (FC1142SR 4Gb 1-port PCIe Fibre Channel Host Bus Adapter [HPAE311A])
 
+pci:v00001077d00002432sv00001077sd00000137*
+ ID_MODEL_FROM_DATABASE=ISP2432-based 4Gb Fibre Channel to PCI Express HBA (QLE2460 4 GB PCI-X Host-Bus-Adapter)
+
 pci:v00001077d00002532*
  ID_MODEL_FROM_DATABASE=ISP2532-based 8Gb Fibre Channel to PCI Express HBA
 
@@ -18248,6 +18359,9 @@ pci:v00001077d00002532sv00001077sd00000167*
 pci:v00001077d00002532sv00001590sd000000FC*
  ID_MODEL_FROM_DATABASE=ISP2532-based 8Gb Fibre Channel to PCI Express HBA (StoreFabric 84Q 8Gb Quad Port Fibre Channel Host Bus Adapter)
 
+pci:v00001077d00002971*
+ ID_MODEL_FROM_DATABASE=ISP2684
+
 pci:v00001077d00003022*
  ID_MODEL_FROM_DATABASE=ISP4022-based Ethernet NIC
 
@@ -18371,6 +18485,18 @@ pci:v00001077d00008070sv00001077sd00000011*
 pci:v00001077d00008070sv00001077sd00000012*
  ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (FastLinQ QL41112H 10GbE Adapter)
 
+pci:v00001077d00008070sv00001590sd0000021D*
+ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (10/25GbE 2P QL41222HLCU-HP Adapter)
+
+pci:v00001077d00008070sv00001590sd0000021E*
+ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (10/25GbE 2P QL41162HMRJ-HP Adapter)
+
+pci:v00001077d00008070sv00001590sd0000021F*
+ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (10/25GbE 2P QL41262HMCU-HP Adapter)
+
+pci:v00001077d00008070sv00001590sd00000220*
+ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (10/25GbE 2P QL41122HLRJ-HP Adapter)
+
 pci:v00001077d00008080*
  ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (FCoE)
 
@@ -18431,6 +18557,12 @@ pci:v00001077d00008090sv00001077sd00000011*
 pci:v00001077d00008090sv00001077sd00000012*
  ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series Gigabit Ethernet Controller (SR-IOV VF) (FastLinQ QL41112H 10GbE Adapter (SR-IOV VF))
 
+pci:v00001077d00008090sv00001590sd0000021E*
+ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series Gigabit Ethernet Controller (SR-IOV VF) (10/25GbE 2P QL41162HMRJ-HP Adapter)
+
+pci:v00001077d00008090sv00001590sd0000021F*
+ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series Gigabit Ethernet Controller (SR-IOV VF) (10/25GbE 2P QL41262HMCU-HP Adapter)
+
 pci:v00001077d00008430*
  ID_MODEL_FROM_DATABASE=ISP8324 1/10GbE Converged Network Controller (NIC VF)
 
@@ -27465,7 +27597,7 @@ pci:v000010DEd0000053B*
  ID_MODEL_FROM_DATABASE=C68 [GeForce 7050 PV / nForce 630a]
 
 pci:v000010DEd0000053Bsv00001043sd00008308*
- ID_MODEL_FROM_DATABASE=C68 [GeForce 7050 PV / nForce 630a] (M2N68-AM Motherbord)
+ ID_MODEL_FROM_DATABASE=C68 [GeForce 7050 PV / nForce 630a] (M2N68-AM Motherboard)
 
 pci:v000010DEd0000053E*
  ID_MODEL_FROM_DATABASE=C68 [GeForce 7025 / nForce 630a]
@@ -27477,7 +27609,7 @@ pci:v000010DEd00000542*
  ID_MODEL_FROM_DATABASE=MCP67 SMBus
 
 pci:v000010DEd00000542sv00001043sd00008308*
- ID_MODEL_FROM_DATABASE=MCP67 SMBus (M2N68-AM Motherbord)
+ ID_MODEL_FROM_DATABASE=MCP67 SMBus (M2N68-AM Motherboard)
 
 pci:v000010DEd00000543*
  ID_MODEL_FROM_DATABASE=MCP67 Co-processor
@@ -27486,7 +27618,7 @@ pci:v000010DEd00000547*
  ID_MODEL_FROM_DATABASE=MCP67 Memory Controller
 
 pci:v000010DEd00000547sv00001043sd00008308*
- ID_MODEL_FROM_DATABASE=MCP67 Memory Controller (M2N68-AM Motherbord)
+ ID_MODEL_FROM_DATABASE=MCP67 Memory Controller (M2N68-AM Motherboard)
 
 pci:v000010DEd00000547sv00001849sd00000547*
  ID_MODEL_FROM_DATABASE=MCP67 Memory Controller (ALiveNF7G-HDready)
@@ -27501,7 +27633,7 @@ pci:v000010DEd0000054C*
  ID_MODEL_FROM_DATABASE=MCP67 Ethernet
 
 pci:v000010DEd0000054Csv00001043sd00008308*
- ID_MODEL_FROM_DATABASE=MCP67 Ethernet (M2N68-AM Motherbord)
+ ID_MODEL_FROM_DATABASE=MCP67 Ethernet (M2N68-AM Motherboard)
 
 pci:v000010DEd0000054Csv00001849sd0000054C*
  ID_MODEL_FROM_DATABASE=MCP67 Ethernet (ALiveNF7G-HDready, MCP67 Gigabit Ethernet)
@@ -31722,16 +31854,16 @@ pci:v000010DEd00001286*
  ID_MODEL_FROM_DATABASE=GK208 [GeForce GT 720]
 
 pci:v000010DEd00001287*
- ID_MODEL_FROM_DATABASE=GK208 [GeForce GT 730]
+ ID_MODEL_FROM_DATABASE=GK208B [GeForce GT 730]
 
 pci:v000010DEd00001288*
- ID_MODEL_FROM_DATABASE=GK208 [GeForce GT 720]
+ ID_MODEL_FROM_DATABASE=GK208B [GeForce GT 720]
 
 pci:v000010DEd00001289*
  ID_MODEL_FROM_DATABASE=GK208 [GeForce GT 710]
 
 pci:v000010DEd0000128B*
- ID_MODEL_FROM_DATABASE=GK208 [GeForce GT 710B]
+ ID_MODEL_FROM_DATABASE=GK208B [GeForce GT 710]
 
 pci:v000010DEd00001290*
  ID_MODEL_FROM_DATABASE=GK208M [GeForce GT 730M]
@@ -31803,19 +31935,22 @@ pci:v000010DEd00001298*
  ID_MODEL_FROM_DATABASE=GK208M [GeForce GT 720M]
 
 pci:v000010DEd00001299*
- ID_MODEL_FROM_DATABASE=GK208M [GeForce 920M]
+ ID_MODEL_FROM_DATABASE=GK208BM [GeForce 920M]
 
 pci:v000010DEd00001299sv000017AAsd000030BB*
- ID_MODEL_FROM_DATABASE=GK208M [GeForce 920M] (GeForce 920A)
+ ID_MODEL_FROM_DATABASE=GK208BM [GeForce 920M] (GeForce 920A)
+
+pci:v000010DEd00001299sv000017AAsd000030DF*
+ ID_MODEL_FROM_DATABASE=GK208BM [GeForce 920M] (GeForce 920A)
 
 pci:v000010DEd00001299sv000017AAsd000036A7*
- ID_MODEL_FROM_DATABASE=GK208M [GeForce 920M] (GeForce 920A)
+ ID_MODEL_FROM_DATABASE=GK208BM [GeForce 920M] (GeForce 920A)
 
 pci:v000010DEd00001299sv000017AAsd000036AF*
- ID_MODEL_FROM_DATABASE=GK208M [GeForce 920M] (GeForce 920M)
+ ID_MODEL_FROM_DATABASE=GK208BM [GeForce 920M] (GeForce 920M)
 
 pci:v000010DEd0000129A*
- ID_MODEL_FROM_DATABASE=GK208M [GeForce 910M]
+ ID_MODEL_FROM_DATABASE=GK208BM [GeForce 910M]
 
 pci:v000010DEd000012A0*
  ID_MODEL_FROM_DATABASE=GK208
@@ -32055,7 +32190,7 @@ pci:v000010DEd00001402*
  ID_MODEL_FROM_DATABASE=GM206 [GeForce GTX 950]
 
 pci:v000010DEd00001406*
- ID_MODEL_FROM_DATABASE=GM206 [GeForce GTX 960]
+ ID_MODEL_FROM_DATABASE=GM206 [GeForce GTX 960 OEM]
 
 pci:v000010DEd00001407*
  ID_MODEL_FROM_DATABASE=GM206 [GeForce GTX 750 v2]
@@ -32085,7 +32220,7 @@ pci:v000010DEd000015F8*
  ID_MODEL_FROM_DATABASE=GP100GL [Tesla P100 PCIe 16GB]
 
 pci:v000010DEd000015F9*
- ID_MODEL_FROM_DATABASE=GP100GL [Tesla P100 SMX2 16GB]
+ ID_MODEL_FROM_DATABASE=GP100GL [Tesla P100 SXM2 16GB]
 
 pci:v000010DEd00001617*
  ID_MODEL_FROM_DATABASE=GM204M [GeForce GTX 980M]
@@ -32111,6 +32246,12 @@ pci:v000010DEd0000172E*
 pci:v000010DEd0000172F*
  ID_MODEL_FROM_DATABASE=GP100
 
+pci:v000010DEd0000174D*
+ ID_MODEL_FROM_DATABASE=GM108M [GeForce MX130]
+
+pci:v000010DEd0000174E*
+ ID_MODEL_FROM_DATABASE=GM108M [GeForce MX110]
+
 pci:v000010DEd000017C2*
  ID_MODEL_FROM_DATABASE=GM200 [GeForce GTX TITAN X]
 
@@ -32157,7 +32298,7 @@ pci:v000010DEd00001B81*
  ID_MODEL_FROM_DATABASE=GP104 [GeForce GTX 1070]
 
 pci:v000010DEd00001B82*
- ID_MODEL_FROM_DATABASE=GP104
+ ID_MODEL_FROM_DATABASE=GP104 [GeForce GTX 1070 Ti]
 
 pci:v000010DEd00001B83*
  ID_MODEL_FROM_DATABASE=GP104
@@ -32186,6 +32327,9 @@ pci:v000010DEd00001BA1sv00001462sd000011E9*
 pci:v000010DEd00001BA1sv00001558sd00009501*
  ID_MODEL_FROM_DATABASE=GP104M [GeForce GTX 1070 Mobile] (GeForce GTX 1070 Max-Q)
 
+pci:v000010DEd00001BAD*
+ ID_MODEL_FROM_DATABASE=GP104 [GeForce GTX 1070 Engineering Sample]
+
 pci:v000010DEd00001BB0*
  ID_MODEL_FROM_DATABASE=GP104GL [Quadro P5000]
 
@@ -32196,7 +32340,10 @@ pci:v000010DEd00001BB3*
  ID_MODEL_FROM_DATABASE=GP104GL [Tesla P4]
 
 pci:v000010DEd00001BB4*
- ID_MODEL_FROM_DATABASE=GP104GL
+ ID_MODEL_FROM_DATABASE=GP104GL [Tesla P6]
+
+pci:v000010DEd00001BB5*
+ ID_MODEL_FROM_DATABASE=GP104GLM [Quadro P5200 Mobile]
 
 pci:v000010DEd00001BB6*
  ID_MODEL_FROM_DATABASE=GP104GLM [Quadro P5000 Mobile]
@@ -32241,10 +32388,10 @@ pci:v000010DEd00001C09*
  ID_MODEL_FROM_DATABASE=GP106 [P106-090]
 
 pci:v000010DEd00001C20*
- ID_MODEL_FROM_DATABASE=GP106M [GeForce GTX 1060 Mobile 3GB]
+ ID_MODEL_FROM_DATABASE=GP106M [GeForce GTX 1060 Mobile]
 
 pci:v000010DEd00001C20sv000017AAsd000039B9*
- ID_MODEL_FROM_DATABASE=GP106M [GeForce GTX 1060 Mobile 3GB] (GeForce GTX 1060 Max-Q 3GB)
+ ID_MODEL_FROM_DATABASE=GP106M [GeForce GTX 1060 Mobile] (GeForce GTX 1060 Max-Q 3GB)
 
 pci:v000010DEd00001C21*
  ID_MODEL_FROM_DATABASE=GP106M [GeForce GTX 1050 Ti Mobile]
@@ -32318,6 +32465,12 @@ pci:v000010DEd00001D10*
 pci:v000010DEd00001D81*
  ID_MODEL_FROM_DATABASE=GV100
 
+pci:v000010DEd00001DB1*
+ ID_MODEL_FROM_DATABASE=GV100 [Tesla V100 SXM2]
+
+pci:v000010DEd00001DB4*
+ ID_MODEL_FROM_DATABASE=GV100 [Tesla V100 PCIe]
+
 pci:v000010DF*
  ID_VENDOR_FROM_DATABASE=Emulex Corporation
 
@@ -32339,6 +32492,9 @@ pci:v000010DFd00000720sv0000103Csd0000220A*
 pci:v000010DFd00000720sv0000103Csd0000803F*
  ID_MODEL_FROM_DATABASE=OneConnect NIC (Skyhawk) (Ethernet 10Gb 2-port 557SFP+ Adapter)
 
+pci:v000010DFd00000720sv0000103Csd00008144*
+ ID_MODEL_FROM_DATABASE=OneConnect NIC (Skyhawk) (FlexFabric 10GB 2-port 556FLR-T Adapter)
+
 pci:v000010DFd00000720sv000017AAsd00001056*
  ID_MODEL_FROM_DATABASE=OneConnect NIC (Skyhawk) (ThinkServer OCm14102-UX-L AnyFabric)
 
@@ -32489,6 +32645,15 @@ pci:v000010DFd0000F112*
 pci:v000010DFd0000F180*
  ID_MODEL_FROM_DATABASE=LPSe12002 EmulexSecure Fibre Channel Adapter
 
+pci:v000010DFd0000F400*
+ ID_MODEL_FROM_DATABASE=LPe36000 Fibre Channel Host Adapter [Prism]
+
+pci:v000010DFd0000F400sv000010DFsd0000F401*
+ ID_MODEL_FROM_DATABASE=LPe36000 Fibre Channel Host Adapter [Prism] (LPe35000 Fibre Channel Host Adapter [Prism])
+
+pci:v000010DFd0000F400sv000010DFsd0000F402*
+ ID_MODEL_FROM_DATABASE=LPe36000 Fibre Channel Host Adapter [Prism] (LPe35000 Fibre Channel Host Adapter [Prism])
+
 pci:v000010DFd0000F700*
  ID_MODEL_FROM_DATABASE=LP7000 Fibre Channel Host Adapter
 
@@ -32898,25 +33063,25 @@ pci:v000010ECd00008129sv000011ECsd00008129*
  ID_MODEL_FROM_DATABASE=RTL-8129 (RTL8111/8168 PCIe Gigabit Ethernet (misconfigured))
 
 pci:v000010ECd00008136*
- ID_MODEL_FROM_DATABASE=RTL8101/2/6E PCI Express Fast/Gigabit Ethernet controller
+ ID_MODEL_FROM_DATABASE=RTL8101/2/6E PCI Express Fast Ethernet controller
 
 pci:v000010ECd00008136sv0000103Csd00001985*
- ID_MODEL_FROM_DATABASE=RTL8101/2/6E PCI Express Fast/Gigabit Ethernet controller (Pavilion 17-e163sg Notebook PC)
+ ID_MODEL_FROM_DATABASE=RTL8101/2/6E PCI Express Fast Ethernet controller (RTL8106E on Pavilion 17-e163sg Notebook PC)
 
 pci:v000010ECd00008136sv0000103Csd00002A8C*
- ID_MODEL_FROM_DATABASE=RTL8101/2/6E PCI Express Fast/Gigabit Ethernet controller (Compaq 500B Microtower)
+ ID_MODEL_FROM_DATABASE=RTL8101/2/6E PCI Express Fast Ethernet controller (Compaq 500B Microtower)
 
 pci:v000010ECd00008136sv0000103Csd00002AB1*
- ID_MODEL_FROM_DATABASE=RTL8101/2/6E PCI Express Fast/Gigabit Ethernet controller (Pavilion p6774)
+ ID_MODEL_FROM_DATABASE=RTL8101/2/6E PCI Express Fast Ethernet controller (Pavilion p6774)
 
 pci:v000010ECd00008136sv0000103Csd000030CC*
- ID_MODEL_FROM_DATABASE=RTL8101/2/6E PCI Express Fast/Gigabit Ethernet controller (Pavilion dv6700)
+ ID_MODEL_FROM_DATABASE=RTL8101/2/6E PCI Express Fast Ethernet controller (Pavilion dv6700)
 
 pci:v000010ECd00008136sv00001179sd0000FF64*
- ID_MODEL_FROM_DATABASE=RTL8101/2/6E PCI Express Fast/Gigabit Ethernet controller (RTL8102E PCI-E Fast Ethernet NIC)
+ ID_MODEL_FROM_DATABASE=RTL8101/2/6E PCI Express Fast Ethernet controller (RTL8102E PCI-E Fast Ethernet NIC)
 
 pci:v000010ECd00008136sv000017C0sd00001053*
- ID_MODEL_FROM_DATABASE=RTL8101/2/6E PCI Express Fast/Gigabit Ethernet controller (RTL8101e Medion WIM 2210 Notebook PC [MD96850])
+ ID_MODEL_FROM_DATABASE=RTL8101/2/6E PCI Express Fast Ethernet controller (RTL8101e Medion WIM 2210 Notebook PC [MD96850])
 
 pci:v000010ECd00008138*
  ID_MODEL_FROM_DATABASE=RT8139 (B/C) Cardbus Fast Ethernet Adapter
@@ -33080,6 +33245,9 @@ pci:v000010ECd00008139sv0000A0A0sd00000007*
 pci:v000010ECd00008167*
  ID_MODEL_FROM_DATABASE=RTL-8110SC/8169SC Gigabit Ethernet
 
+pci:v000010ECd00008167sv0000105Bsd00000E10*
+ ID_MODEL_FROM_DATABASE=RTL-8110SC/8169SC Gigabit Ethernet (RTL-8110SC-GR on a N15235/A74MX mainboard)
+
 pci:v000010ECd00008167sv00001458sd0000E000*
  ID_MODEL_FROM_DATABASE=RTL-8110SC/8169SC Gigabit Ethernet (GA-MA69G-S3H Motherboard)
 
@@ -33311,6 +33479,9 @@ pci:v000010ECd0000B723*
 pci:v000010ECd0000B723sv000010ECsd00008739*
  ID_MODEL_FROM_DATABASE=RTL8723BE PCIe Wireless Network Adapter (Dell Wireless 1801)
 
+pci:v000010ECd0000C821*
+ ID_MODEL_FROM_DATABASE=RTL8821CE 802.11ac PCIe Wireless Network Adapter
+
 pci:v000010ED*
  ID_VENDOR_FROM_DATABASE=Ascii Corporation
 
@@ -37148,6 +37319,12 @@ pci:v00001131d00007146sv00001131sd00005F61*
 pci:v00001131d00007146sv0000114Bsd00002003*
  ID_MODEL_FROM_DATABASE=SAA7146 (DVRaptor Video Edit/Capture Card)
 
+pci:v00001131d00007146sv00001159sd00000040*
+ ID_MODEL_FROM_DATABASE=SAA7146 (MuTech M-Vision 500 (MV-500 rev. E))
+
+pci:v00001131d00007146sv00001159sd00000050*
+ ID_MODEL_FROM_DATABASE=SAA7146 (MuTech M-Vision 500 (MV-500 rev. F))
+
 pci:v00001131d00007146sv000011BDsd00000006*
  ID_MODEL_FROM_DATABASE=SAA7146 (DV500 Overlay)
 
@@ -38511,7 +38688,7 @@ pci:v00001158d00009051*
  ID_MODEL_FROM_DATABASE=Lanfleet/Truevalue
 
 pci:v00001159*
- ID_VENDOR_FROM_DATABASE=Mutech Corp
+ ID_VENDOR_FROM_DATABASE=MuTech Corporation
 
 pci:v00001159d00000001*
  ID_MODEL_FROM_DATABASE=MV-1000
@@ -44264,6 +44441,9 @@ pci:v000012D8*
 pci:v000012D8d000001A7*
  ID_MODEL_FROM_DATABASE=7C21P100 2-port PCI-X to PCI-X Bridge
 
+pci:v000012D8d00002608*
+ ID_MODEL_FROM_DATABASE=PI7C9X2G608GP PCIe2 6-Port/8-Lane Packet Switch
+
 pci:v000012D8d0000400A*
  ID_MODEL_FROM_DATABASE=PI7C9X442SL PCI Express Bridge Port
 
@@ -45318,7 +45498,7 @@ pci:v0000135Cd00000060*
  ID_MODEL_FROM_DATABASE=ESC-100M
 
 pci:v0000135Cd000000F0*
- ID_MODEL_FROM_DATABASE=MPAC-100 Syncronous Serial Card (Zilog 85230)
+ ID_MODEL_FROM_DATABASE=MPAC-100 Synchronous Serial Card (Zilog 85230)
 
 pci:v0000135Cd00000170*
  ID_MODEL_FROM_DATABASE=QSCLP-100
@@ -45804,13 +45984,13 @@ pci:v00001393d00000001*
  ID_MODEL_FROM_DATABASE=UC7000 Serial
 
 pci:v00001393d00001020*
- ID_MODEL_FROM_DATABASE=CP102 (2-port RS-232 PCI)
+ ID_MODEL_FROM_DATABASE=CP-102 (2-port RS-232 PCI)
 
 pci:v00001393d00001021*
- ID_MODEL_FROM_DATABASE=CP102UL (2-port RS-232 Universal PCI)
+ ID_MODEL_FROM_DATABASE=CP-102UL (2-port RS-232 Universal PCI)
 
 pci:v00001393d00001022*
- ID_MODEL_FROM_DATABASE=CP102U (2-port RS-232 Universal PCI)
+ ID_MODEL_FROM_DATABASE=CP-102U (2-port RS-232 Universal PCI)
 
 pci:v00001393d00001023*
  ID_MODEL_FROM_DATABASE=CP-102UF
@@ -45891,7 +46071,7 @@ pci:v00001393d00001681*
  ID_MODEL_FROM_DATABASE=CP-168U V2 Smart Serial Board (8-port RS-232)
 
 pci:v00001393d00001682*
- ID_MODEL_FROM_DATABASE=CP168EL (8-port RS-232 Smart PCI Express)
+ ID_MODEL_FROM_DATABASE=CP-168EL (8-port RS-232 Smart PCI Express)
 
 pci:v00001393d00001683*
  ID_MODEL_FROM_DATABASE=CP-168EL-A (8-port RS-232 PCI Express Serial Board)
@@ -46724,6 +46904,9 @@ pci:v000013F6d00008788sv00001043sd00008428*
 pci:v000013F6d00008788sv00001043sd00008467*
  ID_MODEL_FROM_DATABASE=CMI8788 [Oxygen HD Audio] (CMI8786 (Xonar DG))
 
+pci:v000013F6d00008788sv00001043sd00008521*
+ ID_MODEL_FROM_DATABASE=CMI8788 [Oxygen HD Audio] (CMI8786 (Xonar DGX))
+
 pci:v000013F6d00008788sv00001043sd000085F4*
  ID_MODEL_FROM_DATABASE=CMI8788 [Oxygen HD Audio] (Virtuoso 100 (Xonar Essence STX II))
 
@@ -48179,6 +48362,12 @@ pci:v00001425d000050A8*
 pci:v00001425d000050A9*
  ID_MODEL_FROM_DATABASE=T580-50A9 Unified Wire Ethernet Controller
 
+pci:v00001425d000050AA*
+ ID_MODEL_FROM_DATABASE=T580-50AA Unified Wire Ethernet Controller
+
+pci:v00001425d000050AB*
+ ID_MODEL_FROM_DATABASE=T520-50AB Unified Wire Ethernet Controller
+
 pci:v00001425d00005401*
  ID_MODEL_FROM_DATABASE=T520-CR Unified Wire Ethernet Controller
 
@@ -48359,6 +48548,12 @@ pci:v00001425d000054A8*
 pci:v00001425d000054A9*
  ID_MODEL_FROM_DATABASE=T580-50A9 Unified Wire Ethernet Controller
 
+pci:v00001425d000054AA*
+ ID_MODEL_FROM_DATABASE=T580-50AA Unified Wire Ethernet Controller
+
+pci:v00001425d000054AB*
+ ID_MODEL_FROM_DATABASE=T520-50AB Unified Wire Ethernet Controller
+
 pci:v00001425d00005501*
  ID_MODEL_FROM_DATABASE=T520-CR Unified Wire Storage Controller
 
@@ -48719,6 +48914,12 @@ pci:v00001425d000056A8*
 pci:v00001425d000056A9*
  ID_MODEL_FROM_DATABASE=T580-50A9 Unified Wire Storage Controller
 
+pci:v00001425d000056AA*
+ ID_MODEL_FROM_DATABASE=T580-50AA Unified Wire Storage Controller
+
+pci:v00001425d000056AB*
+ ID_MODEL_FROM_DATABASE=T520-50AB Unified Wire Storage Controller
+
 pci:v00001425d00005701*
  ID_MODEL_FROM_DATABASE=T520-CR Unified Wire Ethernet Controller
 
@@ -49016,6 +49217,12 @@ pci:v00001425d000058A8*
 pci:v00001425d000058A9*
  ID_MODEL_FROM_DATABASE=T580-50A9 Unified Wire Ethernet Controller [VF]
 
+pci:v00001425d000058AA*
+ ID_MODEL_FROM_DATABASE=T580-50AA Unified Wire Ethernet Controller [VF]
+
+pci:v00001425d000058AB*
+ ID_MODEL_FROM_DATABASE=T520-50AB Unified Wire Ethernet Controller [VF]
+
 pci:v00001425d00006001*
  ID_MODEL_FROM_DATABASE=T6225-CR Unified Wire Ethernet Controller
 
@@ -49070,6 +49277,12 @@ pci:v00001425d00006083*
 pci:v00001425d00006084*
  ID_MODEL_FROM_DATABASE=T64100-6084 Unified Wire Ethernet Controller
 
+pci:v00001425d00006085*
+ ID_MODEL_FROM_DATABASE=T6240-6085 Unified Wire Ethernet Controller
+
+pci:v00001425d00006086*
+ ID_MODEL_FROM_DATABASE=T6225-6086 Unified Wire Ethernet Controller
+
 pci:v00001425d00006401*
  ID_MODEL_FROM_DATABASE=T6225-CR Unified Wire Ethernet Controller
 
@@ -49124,6 +49337,12 @@ pci:v00001425d00006483*
 pci:v00001425d00006484*
  ID_MODEL_FROM_DATABASE=T64100-6084 Unified Wire Ethernet Controller
 
+pci:v00001425d00006485*
+ ID_MODEL_FROM_DATABASE=T6240-6085 Unified Wire Ethernet Controller
+
+pci:v00001425d00006486*
+ ID_MODEL_FROM_DATABASE=T6225-6086 Unified Wire Ethernet Controller
+
 pci:v00001425d00006501*
  ID_MODEL_FROM_DATABASE=T6225-CR Unified Wire Storage Controller
 
@@ -49178,6 +49397,12 @@ pci:v00001425d00006583*
 pci:v00001425d00006584*
  ID_MODEL_FROM_DATABASE=T64100-6084 Unified Wire Storage Controller
 
+pci:v00001425d00006585*
+ ID_MODEL_FROM_DATABASE=T6240-6085 Unified Wire Storage Controller
+
+pci:v00001425d00006586*
+ ID_MODEL_FROM_DATABASE=T6225-6086 Unified Wire Storage Controller
+
 pci:v00001425d00006601*
  ID_MODEL_FROM_DATABASE=T6225-CR Unified Wire Storage Controller
 
@@ -49232,6 +49457,12 @@ pci:v00001425d00006683*
 pci:v00001425d00006684*
  ID_MODEL_FROM_DATABASE=T64100-6084 Unified Wire Storage Controller
 
+pci:v00001425d00006685*
+ ID_MODEL_FROM_DATABASE=T6240-6085 Unified Wire Storage Controller
+
+pci:v00001425d00006686*
+ ID_MODEL_FROM_DATABASE=T6225-6086 Unified Wire Storage Controller
+
 pci:v00001425d00006801*
  ID_MODEL_FROM_DATABASE=T6225-CR Unified Wire Ethernet Controller [VF]
 
@@ -49286,6 +49517,12 @@ pci:v00001425d00006883*
 pci:v00001425d00006884*
  ID_MODEL_FROM_DATABASE=T64100-6084 Unified Wire Ethernet Controller [VF]
 
+pci:v00001425d00006885*
+ ID_MODEL_FROM_DATABASE=T6240-6085 Unified Wire Ethernet Controller [VF]
+
+pci:v00001425d00006886*
+ ID_MODEL_FROM_DATABASE=T6225-6086 Unified Wire Ethernet Controller [VF]
+
 pci:v00001425d0000A000*
  ID_MODEL_FROM_DATABASE=PE10K Unified Wire Ethernet Controller
 
@@ -51164,6 +51401,9 @@ pci:v000014E4d000016A0*
 pci:v000014E4d000016A1*
  ID_MODEL_FROM_DATABASE=BCM57840 NetXtreme II 10 Gigabit Ethernet
 
+pci:v000014E4d000016A1sv00001043sd0000866E*
+ ID_MODEL_FROM_DATABASE=BCM57840 NetXtreme II 10 Gigabit Ethernet (PEB-10G/57840-2T 10GBase-T Network Adapter)
+
 pci:v000014E4d000016A2*
  ID_MODEL_FROM_DATABASE=BCM57840 NetXtreme II 10/20-Gigabit Ethernet
 
@@ -51531,13 +51771,16 @@ pci:v000014E4d000016D7sv00001590sd00000211*
  ID_MODEL_FROM_DATABASE=BCM57414 NetXtreme-E 10Gb/25Gb RDMA Ethernet Controller (Ethernet 25Gb 2-port 631FLR-SFP28 Adapter)
 
 pci:v000014E4d000016D8*
- ID_MODEL_FROM_DATABASE=BCM57416 NetXtreme-E 10GBase-T RDMA Ethernet Controller
+ ID_MODEL_FROM_DATABASE=BCM57416 NetXtreme-E Dual-Media 10G RDMA Ethernet Controller
+
+pci:v000014E4d000016D8sv00001028sd00001FEB*
+ ID_MODEL_FROM_DATABASE=BCM57416 NetXtreme-E Dual-Media 10G RDMA Ethernet Controller (NetXtreme-E 10Gb SFP+ Adapter)
 
 pci:v000014E4d000016D8sv00001590sd0000020C*
- ID_MODEL_FROM_DATABASE=BCM57416 NetXtreme-E 10GBase-T RDMA Ethernet Controller (Ethernet 10Gb 2-port 535T Adapter)
+ ID_MODEL_FROM_DATABASE=BCM57416 NetXtreme-E Dual-Media 10G RDMA Ethernet Controller (Ethernet 10Gb 2-port 535T Adapter)
 
 pci:v000014E4d000016D8sv00001590sd00000212*
- ID_MODEL_FROM_DATABASE=BCM57416 NetXtreme-E 10GBase-T RDMA Ethernet Controller (Ethernet 10Gb 2-port 535FLR-T Adapter)
+ ID_MODEL_FROM_DATABASE=BCM57416 NetXtreme-E Dual-Media 10G RDMA Ethernet Controller (Ethernet 10Gb 2-port 535FLR-T Adapter)
 
 pci:v000014E4d000016D9*
  ID_MODEL_FROM_DATABASE=BCM57417 NetXtreme-E 10GBASE-T RDMA Ethernet Controller
@@ -56705,6 +56948,9 @@ pci:v000016D5d00007017*
 pci:v000016D5d00007018*
  ID_MODEL_FROM_DATABASE=AP408: 32-Channel Digital I/O Module
 
+pci:v000016D5d00007019*
+ ID_MODEL_FROM_DATABASE=AP341 14-bit, 16-Channel Simultaneous Conversion Analog Input Module
+
 pci:v000016D5d0000701A*
  ID_MODEL_FROM_DATABASE=AP220-16 12-Bit, 16-Channel Analog Output Module
 
@@ -56723,6 +56969,9 @@ pci:v000016D5d00007023*
 pci:v000016D5d00007024*
  ID_MODEL_FROM_DATABASE=APA7-204 Reconfigurable Artix-7 FPGA module 24 LVDS channels
 
+pci:v000016D5d00007027*
+ ID_MODEL_FROM_DATABASE=AP418 16-Channel High Voltage Digital Input/Output Module
+
 pci:v000016D5d00007042*
  ID_MODEL_FROM_DATABASE=AP482 Counter Timer Module with TTL Level Input/Output
 
@@ -57902,6 +58151,9 @@ pci:v00001805*
 pci:v00001809*
  ID_VENDOR_FROM_DATABASE=Lumanate, Inc.
 
+pci:v0000180C*
+ ID_VENDOR_FROM_DATABASE=IEI Integration Corp
+
 pci:v00001813*
  ID_VENDOR_FROM_DATABASE=Ambient Technologies Inc
 
@@ -59180,6 +59432,9 @@ pci:v00001924d00000A03sv00001924sd00008019*
 pci:v00001924d00000A03sv00001924sd0000801A*
  ID_MODEL_FROM_DATABASE=SFC9220 10/40G Ethernet Controller (SFN8722-R1 8000 Series OCP 10G Adapter)
 
+pci:v00001924d00000A03sv00001924sd0000801B*
+ ID_MODEL_FROM_DATABASE=SFC9220 10/40G Ethernet Controller (SFN8522-R3 8000 Series 10G Adapter)
+
 pci:v00001924d00001803*
  ID_MODEL_FROM_DATABASE=SFC9020 10G Ethernet Controller (Virtual Function)
 
@@ -59720,6 +59975,9 @@ pci:v00001969d0000E091*
 pci:v00001969d0000E0A1*
  ID_MODEL_FROM_DATABASE=Killer E2400 Gigabit Ethernet Controller
 
+pci:v00001969d0000E0B1*
+ ID_MODEL_FROM_DATABASE=Killer E2500 Gigabit Ethernet Controller
+
 pci:v0000196A*
  ID_VENDOR_FROM_DATABASE=Sensory Networks Inc.
 
@@ -61304,6 +61562,12 @@ pci:v00001CC7d00000200*
 pci:v00001CC7d00000250*
  ID_MODEL_FROM_DATABASE=RMS-250
 
+pci:v00001CCF*
+ ID_VENDOR_FROM_DATABASE=Zoom Corporation
+
+pci:v00001CCFd00000001*
+ ID_MODEL_FROM_DATABASE=TAC-2 Thunderbolt Audio Converter
+
 pci:v00001CD2*
  ID_VENDOR_FROM_DATABASE=SesKion GmbH
 
@@ -61700,6 +61964,15 @@ pci:v00001DE1d0000690C*
 pci:v00001DE1d0000DC29*
  ID_MODEL_FROM_DATABASE=DC290
 
+pci:v00001DE5*
+ ID_VENDOR_FROM_DATABASE=Eideticom, Inc
+
+pci:v00001DE5d00001000*
+ ID_MODEL_FROM_DATABASE=IO Memory Controller
+
+pci:v00001DE5d00002000*
+ ID_MODEL_FROM_DATABASE=NoLoad Hardware Development Kit
+
 pci:v00001FC0*
  ID_VENDOR_FROM_DATABASE=Ascom (Finland) Oy
 
@@ -61796,6 +62069,9 @@ pci:v00001FC9d00004010*
 pci:v00001FC9d00004020*
  ID_MODEL_FROM_DATABASE=TN9030 10GbE CX4 Ethernet Adapter
 
+pci:v00001FC9d00004020sv0000180Csd00002040*
+ ID_MODEL_FROM_DATABASE=TN9030 10GbE CX4 Ethernet Adapter (Mustang-200 10GbE Ethernet Adapter)
+
 pci:v00001FC9d00004022*
  ID_MODEL_FROM_DATABASE=TN9310 10GbE SFP+ Ethernet Adapter
 
@@ -64196,6 +64472,9 @@ pci:v00008086d00000150*
 pci:v00008086d00000150sv00001043sd000084CA*
  ID_MODEL_FROM_DATABASE=Xeon E3-1200 v2/3rd Gen Core processor DRAM Controller (P8 series motherboard)
 
+pci:v00008086d00000150sv00001458sd0000D000*
+ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v2/3rd Gen Core processor DRAM Controller (Ivy Bridge GT1 [HD Graphics])
+
 pci:v00008086d00000150sv000015D9sd00000624*
  ID_MODEL_FROM_DATABASE=Xeon E3-1200 v2/3rd Gen Core processor DRAM Controller (X9SCM-F Motherboard)
 
@@ -64814,6 +65093,9 @@ pci:v00008086d00000897sv00008086sd00005015*
 pci:v00008086d00000897sv00008086sd00005017*
  ID_MODEL_FROM_DATABASE=Centrino Wireless-N 130 (BG)
 
+pci:v00008086d000008A7*
+ ID_MODEL_FROM_DATABASE=Quark SoC X1000 SDIO / eMMC Controller
+
 pci:v00008086d000008AE*
  ID_MODEL_FROM_DATABASE=Centrino Wireless-N 100
 
@@ -65129,6 +65411,24 @@ pci:v00008086d000008B4sv00008086sd00008370*
 pci:v00008086d000008CF*
  ID_MODEL_FROM_DATABASE=Atom Processor Z2760 Integrated Graphics Controller
 
+pci:v00008086d00000934*
+ ID_MODEL_FROM_DATABASE=Quark SoC X1000 I2C Controller and GPIO Controller
+
+pci:v00008086d00000935*
+ ID_MODEL_FROM_DATABASE=Quark SoC X1000 SPI Controller
+
+pci:v00008086d00000936*
+ ID_MODEL_FROM_DATABASE=Quark SoC X1000 HS-UART
+
+pci:v00008086d00000937*
+ ID_MODEL_FROM_DATABASE=Quark SoC X1000 10/100 Ethernet MAC
+
+pci:v00008086d00000939*
+ ID_MODEL_FROM_DATABASE=Quark SoC X1000 USB EHCI Host Controller / USB 2.0 Device
+
+pci:v00008086d0000093A*
+ ID_MODEL_FROM_DATABASE=Quark SoC X1000 USB OHCI Host Controller
+
 pci:v00008086d00000953*
  ID_MODEL_FROM_DATABASE=PCIe Data Center SSD
 
@@ -65156,6 +65456,9 @@ pci:v00008086d00000953sv00008086sd0000370D*
 pci:v00008086d00000953sv00008086sd0000370E*
  ID_MODEL_FROM_DATABASE=PCIe Data Center SSD (SSD 750 Series [2.5" SFF])
 
+pci:v00008086d00000958*
+ ID_MODEL_FROM_DATABASE=Quark SoC X1000 Host Bridge
+
 pci:v00008086d0000095A*
  ID_MODEL_FROM_DATABASE=Wireless 7265
 
@@ -65288,6 +65591,9 @@ pci:v00008086d0000095Bsv00008086sd00005310*
 pci:v00008086d0000095Bsv00008086sd00009200*
  ID_MODEL_FROM_DATABASE=Wireless 7265 (Dual Band Wireless-AC 7265)
 
+pci:v00008086d0000095E*
+ ID_MODEL_FROM_DATABASE=Quark SoC X1000 Legacy Bridge
+
 pci:v00008086d00000960*
  ID_MODEL_FROM_DATABASE=80960RP (i960RP) Microprocessor/Bridge
 
@@ -65297,6 +65603,9 @@ pci:v00008086d00000962*
 pci:v00008086d00000964*
  ID_MODEL_FROM_DATABASE=80960RP (i960RP) Microprocessor/Bridge
 
+pci:v00008086d00000A03*
+ ID_MODEL_FROM_DATABASE=Haswell-ULT Thermal Subsystem
+
 pci:v00008086d00000A04*
  ID_MODEL_FROM_DATABASE=Haswell-ULT DRAM Controller
 
@@ -65336,9 +65645,36 @@ pci:v00008086d00000A53*
 pci:v00008086d00000A54*
  ID_MODEL_FROM_DATABASE=Express Flash NVMe P4500
 
+pci:v00008086d00000A54sv00001028sd00001FE1*
+ ID_MODEL_FROM_DATABASE=Express Flash NVMe P4500 (Express Flash NVMe 1TB 2.5" U.2 (P4500))
+
+pci:v00008086d00000A54sv00001028sd00001FE2*
+ ID_MODEL_FROM_DATABASE=Express Flash NVMe P4500 (Express Flash NVMe 2TB 2.5" U.2 (P4500))
+
+pci:v00008086d00000A54sv00001028sd00001FE3*
+ ID_MODEL_FROM_DATABASE=Express Flash NVMe P4500 (Express Flash NVMe 4TB 2.5" U.2 (P4500))
+
+pci:v00008086d00000A54sv00001028sd00001FE4*
+ ID_MODEL_FROM_DATABASE=Express Flash NVMe P4500 (Express Flash NVMe 4TB HHHL AIC (P4500))
+
 pci:v00008086d00000A55*
  ID_MODEL_FROM_DATABASE=Express Flash NVMe P4600
 
+pci:v00008086d00000A55sv00001028sd00001FE5*
+ ID_MODEL_FROM_DATABASE=Express Flash NVMe P4600 (Express Flash NVMe 1.6TB 2.5" U.2 (P4600))
+
+pci:v00008086d00000A55sv00001028sd00001FE6*
+ ID_MODEL_FROM_DATABASE=Express Flash NVMe P4600 (Express Flash NVMe 2TB 2.5" U.2 (P4600))
+
+pci:v00008086d00000A55sv00001028sd00001FE7*
+ ID_MODEL_FROM_DATABASE=Express Flash NVMe P4600 (Express Flash NVMe 3.2TB 2.5" U.2 (P4600))
+
+pci:v00008086d00000A55sv00001028sd00001FE8*
+ ID_MODEL_FROM_DATABASE=Express Flash NVMe P4600 (Express Flash NVMe 2.0TB HHHL AIC (P4600))
+
+pci:v00008086d00000A55sv00001028sd00001FE9*
+ ID_MODEL_FROM_DATABASE=Express Flash NVMe P4600 (Express Flash NVMe 4.0TB HHHL AIC (P4600))
+
 pci:v00008086d00000BE0*
  ID_MODEL_FROM_DATABASE=Atom Processor D2xxx/N2xxx Integrated Graphics Controller
 
@@ -67658,6 +67994,12 @@ pci:v00008086d000011A2*
 pci:v00008086d000011A5*
  ID_MODEL_FROM_DATABASE=Merrifield Serial IO PWM Controller
 
+pci:v00008086d000011C3*
+ ID_MODEL_FROM_DATABASE=Quark SoC X1000 PCIe Root Port 0
+
+pci:v00008086d000011C4*
+ ID_MODEL_FROM_DATABASE=Quark SoC X1000 PCIe Root Port 1
+
 pci:v00008086d00001200*
  ID_MODEL_FROM_DATABASE=IXP1200 Network Processor
 
@@ -68603,6 +68945,9 @@ pci:v00008086d00001528sv0000108Esd00007B15*
 pci:v00008086d00001528sv00001137sd000000BF*
  ID_MODEL_FROM_DATABASE=Ethernet Controller 10-Gigabit X540-AT2 (Ethernet Converged Network Adapter X540-T2)
 
+pci:v00008086d00001528sv00001170sd00000052*
+ ID_MODEL_FROM_DATABASE=Ethernet Controller 10-Gigabit X540-AT2
+
 pci:v00008086d00001528sv000017AAsd00001073*
  ID_MODEL_FROM_DATABASE=Ethernet Controller 10-Gigabit X540-AT2 (ThinkServer X540-T2 AnyFabric)
 
@@ -68963,6 +69308,9 @@ pci:v00008086d00001572sv00008086sd0000000D*
 pci:v00008086d00001572sv00008086sd0000000E*
  ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (Ethernet Server Adapter OCP X710-2)
 
+pci:v00008086d00001572sv00008086sd0000000F*
+ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (Ethernet Server Adapter OCP X710-2)
+
 pci:v00008086d00001572sv00008086sd00000010*
  ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (Ethernet Converged Network Adapter X710)
 
@@ -69293,6 +69641,9 @@ pci:v00008086d000015CE*
 pci:v00008086d000015D0*
  ID_MODEL_FROM_DATABASE=Ethernet SDI Adapter FM10420-100GbE-QDA2
 
+pci:v00008086d000015D0sv00008086sd00000001*
+ ID_MODEL_FROM_DATABASE=Ethernet SDI Adapter FM10420-100GbE-QDA2
+
 pci:v00008086d000015D1*
  ID_MODEL_FROM_DATABASE=Ethernet Controller 10G X550T
 
@@ -69540,10 +69891,10 @@ pci:v00008086d00001912*
  ID_MODEL_FROM_DATABASE=HD Graphics 530
 
 pci:v00008086d00001916*
- ID_MODEL_FROM_DATABASE=HD Graphics 520
+ ID_MODEL_FROM_DATABASE=Skylake GT2 [HD Graphics 520]
 
 pci:v00008086d00001916sv00001028sd000006F3*
- ID_MODEL_FROM_DATABASE=HD Graphics 520 (Latitude 3570)
+ ID_MODEL_FROM_DATABASE=Skylake GT2 [HD Graphics 520] (Latitude 3570)
 
 pci:v00008086d00001918*
  ID_MODEL_FROM_DATABASE=Xeon E3-1200 v5/E3-1500 v5/6th Gen Core Processor Host Bridge/DRAM Registers
@@ -72927,7 +73278,7 @@ pci:v00008086d000024D5sv00008086sd0000E001*
  ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) AC'97 Audio Controller (Desktop Board D865GBF)
 
 pci:v00008086d000024D5sv00008086sd0000E002*
- ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) AC'97 Audio Controller (SoundMax Intergrated Digital Audio)
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) AC'97 Audio Controller (SoundMax Integrated Digital Audio)
 
 pci:v00008086d000024D6*
  ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) AC'97 Modem Controller
@@ -75906,7 +76257,7 @@ pci:v00008086d00002822sv0000103Csd00002A6F*
  ID_MODEL_FROM_DATABASE=SATA Controller [RAID mode] (Asus IPIBL-LB Motherboard)
 
 pci:v00008086d00002822sv00001043sd00008277*
- ID_MODEL_FROM_DATABASE=SATA Controller [RAID mode] (P5K PRO Motherboard)
+ ID_MODEL_FROM_DATABASE=SATA Controller [RAID mode] (P5K PRO Motherboard: 82801IR [ICH9R])
 
 pci:v00008086d00002823*
  ID_MODEL_FROM_DATABASE=C610/X99 series chipset sSATA Controller [RAID mode]
@@ -76431,7 +76782,7 @@ pci:v00008086d0000284Bsv00001025sd00000121*
  ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) HD Audio Controller (Aspire 5920G)
 
 pci:v00008086d0000284Bsv00001025sd00000145*
- ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) HD Audio Controller (Realtek ALC889 (Aspire 8920G w. Dolby Theather))
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) HD Audio Controller (Realtek ALC889 (Aspire 8920G w. Dolby Theater))
 
 pci:v00008086d0000284Bsv00001028sd000001DA*
  ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) HD Audio Controller (OptiPlex 745)
@@ -76596,7 +76947,7 @@ pci:v00008086d00002920sv00001028sd0000023C*
  ID_MODEL_FROM_DATABASE=82801IR/IO/IH (ICH9R/DO/DH) 4 port SATA Controller [IDE mode] (PowerEdge R200 onboard SATA Controller)
 
 pci:v00008086d00002920sv00001043sd00008277*
- ID_MODEL_FROM_DATABASE=82801IR/IO/IH (ICH9R/DO/DH) 4 port SATA Controller [IDE mode] (P5K PRO Motherboard)
+ ID_MODEL_FROM_DATABASE=82801IR/IO/IH (ICH9R/DO/DH) 4 port SATA Controller [IDE mode] (P5K PRO Motherboard: 82801IR [ICH9R])
 
 pci:v00008086d00002921*
  ID_MODEL_FROM_DATABASE=82801IB (ICH9) 2 port SATA Controller [IDE mode]
@@ -76617,7 +76968,7 @@ pci:v00008086d00002922*
  ID_MODEL_FROM_DATABASE=82801IR/IO/IH (ICH9R/DO/DH) 6 port SATA Controller [AHCI mode]
 
 pci:v00008086d00002922sv00001043sd00008277*
- ID_MODEL_FROM_DATABASE=82801IR/IO/IH (ICH9R/DO/DH) 6 port SATA Controller [AHCI mode] (P5K PRO Motherboard)
+ ID_MODEL_FROM_DATABASE=82801IR/IO/IH (ICH9R/DO/DH) 6 port SATA Controller [AHCI mode] (P5K PRO Motherboard: 82801IR [ICH9R])
 
 pci:v00008086d00002922sv00001AF4sd00001100*
  ID_MODEL_FROM_DATABASE=82801IR/IO/IH (ICH9R/DO/DH) 6 port SATA Controller [AHCI mode] (QEMU Virtual Machine)
@@ -76653,7 +77004,7 @@ pci:v00008086d00002926sv00001028sd00000211*
  ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) 2 port SATA Controller [IDE mode] (Optiplex 755)
 
 pci:v00008086d00002926sv00001043sd00008277*
- ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) 2 port SATA Controller [IDE mode] (P5K PRO Motherboard)
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) 2 port SATA Controller [IDE mode] (P5K PRO Motherboard: 82801IR [ICH9R])
 
 pci:v00008086d00002926sv00001462sd00007360*
  ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) 2 port SATA Controller [IDE mode] (G33/P35 Neo)
@@ -76695,7 +77046,7 @@ pci:v00008086d00002930sv0000103Csd00003628*
  ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) SMBus Controller (dv6-1190en)
 
 pci:v00008086d00002930sv00001043sd00008277*
- ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) SMBus Controller (P5K PRO Motherboard)
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) SMBus Controller (P5K PRO Motherboard: 82801IR [ICH9R])
 
 pci:v00008086d00002930sv00001462sd00007360*
  ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) SMBus Controller (G33/P35 Neo)
@@ -76755,7 +77106,7 @@ pci:v00008086d00002934sv0000103Csd00002A6F*
  ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #1 (Asus IPIBL-LB Motherboard)
 
 pci:v00008086d00002934sv00001043sd00008277*
- ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #1 (P5K PRO Motherboard)
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #1 (P5K PRO Motherboard: 82801IR [ICH9R])
 
 pci:v00008086d00002934sv00001462sd00007360*
  ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #1 (G33/P35 Neo)
@@ -76806,7 +77157,7 @@ pci:v00008086d00002935sv0000103Csd00002A6F*
  ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #2 (Asus IPIBL-LB Motherboard)
 
 pci:v00008086d00002935sv00001043sd00008277*
- ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #2 (P5K PRO Motherboard)
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #2 (P5K PRO Motherboard: 82801IR [ICH9R])
 
 pci:v00008086d00002935sv00001462sd00007360*
  ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #2 (G33/P35 Neo)
@@ -76851,7 +77202,7 @@ pci:v00008086d00002936sv0000103Csd00002A6F*
  ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #3 (Asus IPIBL-LB Motherboard)
 
 pci:v00008086d00002936sv00001043sd00008277*
- ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #3 (P5K PRO Motherboard)
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #3 (P5K PRO Motherboard: 82801IR [ICH9R])
 
 pci:v00008086d00002936sv00001462sd00007360*
  ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #3 (G33/P35 Neo)
@@ -76896,7 +77247,7 @@ pci:v00008086d00002937sv0000103Csd00002A6F*
  ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #4 (Asus IPIBL-LB Motherboard)
 
 pci:v00008086d00002937sv00001043sd00008277*
- ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #4 (P5K PRO Motherboard)
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #4 (P5K PRO Motherboard: 82801IR [ICH9R])
 
 pci:v00008086d00002937sv00001462sd00007360*
  ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #4 (G33/P35 Neo)
@@ -76944,7 +77295,7 @@ pci:v00008086d00002938sv0000103Csd00002A6F*
  ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #5 (Asus IPIBL-LB Motherboard)
 
 pci:v00008086d00002938sv00001043sd00008277*
- ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #5 (P5K PRO Motherboard)
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #5 (P5K PRO Motherboard: 82801IR [ICH9R])
 
 pci:v00008086d00002938sv00001462sd00007360*
  ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #5 (G33/P35 Neo)
@@ -76977,7 +77328,7 @@ pci:v00008086d00002939sv0000103Csd00002A6F*
  ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #6 (Asus IPIBL-LB Motherboard)
 
 pci:v00008086d00002939sv00001043sd00008277*
- ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #6 (P5K PRO Motherboard)
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #6 (P5K PRO Motherboard: 82801IR [ICH9R])
 
 pci:v00008086d00002939sv00001462sd00007360*
  ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #6 (G33/P35 Neo)
@@ -77028,7 +77379,7 @@ pci:v00008086d0000293Asv0000103Csd00002A6F*
  ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB2 EHCI Controller #1 (Asus IPIBL-LB Motherboard)
 
 pci:v00008086d0000293Asv00001043sd00008277*
- ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB2 EHCI Controller #1 (P5K PRO Motherboard)
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB2 EHCI Controller #1 (P5K PRO Motherboard: 82801IR [ICH9R])
 
 pci:v00008086d0000293Asv00001462sd00007360*
  ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB2 EHCI Controller #1 (G33/P35 Neo)
@@ -77070,7 +77421,7 @@ pci:v00008086d0000293Csv0000103Csd00002A6F*
  ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB2 EHCI Controller #2 (Asus IPIBL-LB Motherboard)
 
 pci:v00008086d0000293Csv00001043sd00008277*
- ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB2 EHCI Controller #2 (P5K PRO Motherboard)
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB2 EHCI Controller #2 (P5K PRO Motherboard: 82801IR [ICH9R])
 
 pci:v00008086d0000293Csv00001462sd00007360*
  ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB2 EHCI Controller #2 (G33/P35 Neo)
@@ -77103,7 +77454,7 @@ pci:v00008086d0000293Esv0000103Csd00003628*
  ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) HD Audio Controller (dv6-1190en)
 
 pci:v00008086d0000293Esv00001043sd0000829F*
- ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) HD Audio Controller (P5K PRO Motherboard)
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) HD Audio Controller (P5K PRO Motherboard: 82801IR [ICH9R])
 
 pci:v00008086d0000293Esv00001462sd00007360*
  ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) HD Audio Controller (G33/P35 Neo)
@@ -77133,7 +77484,7 @@ pci:v00008086d00002940sv0000103Csd00002A6F*
  ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) PCI Express Port 1 (Asus IPIBL-LB Motherboard)
 
 pci:v00008086d00002940sv00001043sd00008277*
- ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) PCI Express Port 1 (P5K PRO Motherboard)
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) PCI Express Port 1 (P5K PRO Motherboard: 82801IR [ICH9R])
 
 pci:v00008086d00002940sv00008086sd00002940*
  ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) PCI Express Port 1 (Optiplex 755)
@@ -77166,7 +77517,7 @@ pci:v00008086d00002948sv00001028sd0000020D*
  ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) PCI Express Port 5 (Inspiron 530)
 
 pci:v00008086d00002948sv00001043sd00008277*
- ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) PCI Express Port 5 (P5K PRO Motherboard)
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) PCI Express Port 5 (P5K PRO Motherboard: 82801IR [ICH9R])
 
 pci:v00008086d0000294A*
  ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) PCI Express Port 6
@@ -77175,7 +77526,7 @@ pci:v00008086d0000294Asv00001028sd0000020D*
  ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) PCI Express Port 6 (Inspiron 530)
 
 pci:v00008086d0000294Asv00001043sd00008277*
- ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) PCI Express Port 6 (P5K PRO Motherboard)
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) PCI Express Port 6 (P5K PRO Motherboard: 82801IR [ICH9R])
 
 pci:v00008086d0000294C*
  ID_MODEL_FROM_DATABASE=82566DC-2 Gigabit Network Connection
@@ -77337,7 +77688,7 @@ pci:v00008086d000029C0sv0000103Csd00002A6F*
  ID_MODEL_FROM_DATABASE=82G33/G31/P35/P31 Express DRAM Controller (Asus IPIBL-LB Motherboard)
 
 pci:v00008086d000029C0sv00001043sd00008276*
- ID_MODEL_FROM_DATABASE=82G33/G31/P35/P31 Express DRAM Controller (P5K PRO Motherboard)
+ ID_MODEL_FROM_DATABASE=82G33/G31/P35/P31 Express DRAM Controller (P5K PRO Motherboard: Intel 82P35 Northbridge)
 
 pci:v00008086d000029C0sv00001043sd000082B0*
  ID_MODEL_FROM_DATABASE=82G33/G31/P35/P31 Express DRAM Controller (P5KPL-VM Motherboard)
@@ -77358,7 +77709,7 @@ pci:v00008086d000029C1sv00001028sd0000020D*
  ID_MODEL_FROM_DATABASE=82G33/G31/P35/P31 Express PCI Express Root Port (Inspiron 530)
 
 pci:v00008086d000029C1sv00001043sd00008276*
- ID_MODEL_FROM_DATABASE=82G33/G31/P35/P31 Express PCI Express Root Port (P5K PRO Motherboard)
+ ID_MODEL_FROM_DATABASE=82G33/G31/P35/P31 Express PCI Express Root Port (P5K PRO Motherboard: Intel 82P35 Northbridge)
 
 pci:v00008086d000029C2*
  ID_MODEL_FROM_DATABASE=82G33/G31 Express Integrated Graphics Controller
@@ -85322,6 +85673,90 @@ pci:v00009005d0000028Fsv0000103Csd00001100*
 pci:v00009005d0000028Fsv0000103Csd00001101*
  ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (Smart Array P416ie-m SR G10)
 
+pci:v00009005d0000028Fsv00009005sd00000800*
+ ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (SmartRAID 3154-8i)
+
+pci:v00009005d0000028Fsv00009005sd00000801*
+ ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (SmartRAID 3152-8i)
+
+pci:v00009005d0000028Fsv00009005sd00000802*
+ ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (SmartRAID 3151-4i)
+
+pci:v00009005d0000028Fsv00009005sd00000803*
+ ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (SmartRAID 3101-4i)
+
+pci:v00009005d0000028Fsv00009005sd00000804*
+ ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (SmartRAID 3154-8e)
+
+pci:v00009005d0000028Fsv00009005sd00000805*
+ ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (SmartRAID 3102-8i)
+
+pci:v00009005d0000028Fsv00009005sd00000806*
+ ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (SmartRAID 3100)
+
+pci:v00009005d0000028Fsv00009005sd00000807*
+ ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (SmartRAID 3162-8i)
+
+pci:v00009005d0000028Fsv00009005sd00000900*
+ ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (SmartHBA 2100-8i)
+
+pci:v00009005d0000028Fsv00009005sd00000901*
+ ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (SmartHBA 2100-4i)
+
+pci:v00009005d0000028Fsv00009005sd00000902*
+ ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (HBA 1100-8i)
+
+pci:v00009005d0000028Fsv00009005sd00000903*
+ ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (HBA 1100-4i)
+
+pci:v00009005d0000028Fsv00009005sd00000904*
+ ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (SmartHBA 2100-8e)
+
+pci:v00009005d0000028Fsv00009005sd00000905*
+ ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (HBA 1100-8e)
+
+pci:v00009005d0000028Fsv00009005sd00000906*
+ ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (SmartHBA 2100-4i4e)
+
+pci:v00009005d0000028Fsv00009005sd00000907*
+ ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (HBA 1100)
+
+pci:v00009005d0000028Fsv00009005sd00000908*
+ ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (SmartHBA 2100)
+
+pci:v00009005d0000028Fsv00009005sd0000090A*
+ ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (SmartHBA 2100A-8i)
+
+pci:v00009005d0000028Fsv00009005sd00001200*
+ ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (SmartRAID 3154-24i)
+
+pci:v00009005d0000028Fsv00009005sd00001201*
+ ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (SmartRAID 3154-8i16e)
+
+pci:v00009005d0000028Fsv00009005sd00001202*
+ ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (SmartRAID 3154-8i8e)
+
+pci:v00009005d0000028Fsv00009005sd00001280*
+ ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (HBA 1100-16i)
+
+pci:v00009005d0000028Fsv00009005sd00001281*
+ ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (HBA 1100-16e)
+
+pci:v00009005d0000028Fsv00009005sd00001300*
+ ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (HBA 1100-8i8e)
+
+pci:v00009005d0000028Fsv00009005sd00001301*
+ ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (HBA 1100-24i)
+
+pci:v00009005d0000028Fsv00009005sd00001302*
+ ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (SmartHBA 2100-8i8e)
+
+pci:v00009005d0000028Fsv00009005sd00001303*
+ ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (SmartHBA 2100-24i)
+
+pci:v00009005d0000028Fsv00009005sd00001380*
+ ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (SmartRAID 3154-16i)
+
 pci:v00009005d00000410*
  ID_MODEL_FROM_DATABASE=AIC-9410W SAS (Razor HBA RAID)
 
index 549f6da..632c46f 100644 (file)
@@ -125,6 +125,12 @@ usb:v03DA*
 usb:v03DAp0002*
  ID_MODEL_FROM_DATABASE=HD44780 LCD interface
 
+usb:v03E7*
+ ID_VENDOR_FROM_DATABASE=Intel
+
+usb:v03E7p2150*
+ ID_MODEL_FROM_DATABASE=Myriad VPU [Movidius Neural Compute Stick]
+
 usb:v03E8*
  ID_VENDOR_FROM_DATABASE=EndPoints, Inc.
 
@@ -269,6 +275,9 @@ usb:v03EBp2107*
 usb:v03EBp2109*
  ID_MODEL_FROM_DATABASE=STK541 ZigBee Development Board
 
+usb:v03EBp210A*
+ ID_MODEL_FROM_DATABASE=AT86RF230 [RZUSBSTICK] transceiver
+
 usb:v03EBp210D*
  ID_MODEL_FROM_DATABASE=XPLAIN evaluation kit (CDC ACM)
 
@@ -548,6 +557,9 @@ usb:v03F0p0218*
 usb:v03F0p0221*
  ID_MODEL_FROM_DATABASE=StreamSmart 400 [F2235AA]
 
+usb:v03F0p0223*
+ ID_MODEL_FROM_DATABASE=Digital Drive Flash Reader
+
 usb:v03F0p022A*
  ID_MODEL_FROM_DATABASE=Laserjet CP1525nw
 
@@ -650,6 +662,9 @@ usb:v03F0p0612*
 usb:v03F0p0624*
  ID_MODEL_FROM_DATABASE=Bluetooth Dongle
 
+usb:v03F0p0641*
+ ID_MODEL_FROM_DATABASE=X1200 Optical Mouse
+
 usb:v03F0p0701*
  ID_MODEL_FROM_DATABASE=ScanJet 5300c/5370c
 
@@ -884,6 +899,9 @@ usb:v03F0p1539*
 usb:v03F0p1541*
  ID_MODEL_FROM_DATABASE=Prime [G8X92AA]
 
+usb:v03F0p154A*
+ ID_MODEL_FROM_DATABASE=Laser Mouse
+
 usb:v03F0p1602*
  ID_MODEL_FROM_DATABASE=PhotoSmart 330 series
 
@@ -1526,6 +1544,9 @@ usb:v03F0p5311*
 usb:v03F0p5312*
  ID_MODEL_FROM_DATABASE=Officejet Pro 8500A
 
+usb:v03F0p5317*
+ ID_MODEL_FROM_DATABASE=Color LaserJet CP2025 series
+
 usb:v03F0p5411*
  ID_MODEL_FROM_DATABASE=OfficeJet 4300
 
@@ -1886,6 +1907,9 @@ usb:v03F0pA004*
 usb:v03F0pA011*
  ID_MODEL_FROM_DATABASE=Deskjet 3050A
 
+usb:v03F0pA407*
+ ID_MODEL_FROM_DATABASE=Wireless Optical Comfort Mouse
+
 usb:v03F0pB002*
  ID_MODEL_FROM_DATABASE=PhotoSmart 7200 series
 
@@ -2285,6 +2309,12 @@ usb:v0403pA9A0*
 usb:v0403pABB8*
  ID_MODEL_FROM_DATABASE=Lego Mindstorms NXTCam
 
+usb:v0403pB0C2*
+ ID_MODEL_FROM_DATABASE=iID contactless RFID device
+
+usb:v0403pB0C3*
+ ID_MODEL_FROM_DATABASE=iID contactless RFID device
+
 usb:v0403pB810*
  ID_MODEL_FROM_DATABASE=US Interface Navigator (CAT and 2nd PTT lines)
 
@@ -3284,6 +3314,9 @@ usb:v040B*
 usb:v040Bp0A68*
  ID_MODEL_FROM_DATABASE=Func MS-3 gaming mouse [WT6573F MCU]
 
+usb:v040Bp2367*
+ ID_MODEL_FROM_DATABASE=Human Interface Device [HP CalcPad 200 Calculator and Numeric Keypad]
+
 usb:v040Bp6510*
  ID_MODEL_FROM_DATABASE=Weltrend Bar Code Reader
 
@@ -4235,6 +4268,18 @@ usb:v0421p0105*
 usb:v0421p0106*
  ID_MODEL_FROM_DATABASE=ROM Parent
 
+usb:v0421p010D*
+ ID_MODEL_FROM_DATABASE=E75 (Storage Mode)
+
+usb:v0421p010E*
+ ID_MODEL_FROM_DATABASE=E75 (PC Suite mode)
+
+usb:v0421p010F*
+ ID_MODEL_FROM_DATABASE=E75 (Media transfer mode)
+
+usb:v0421p0110*
+ ID_MODEL_FROM_DATABASE=E75 (Imaging Mode)
+
 usb:v0421p0154*
  ID_MODEL_FROM_DATABASE=5800 XpressMusic (PC Suite mode)
 
@@ -6896,6 +6941,9 @@ usb:v045Ep0737*
 usb:v045Ep0745*
  ID_MODEL_FROM_DATABASE=Nano Transceiver v1.0 for Bluetooth
 
+usb:v045Ep074A*
+ ID_MODEL_FROM_DATABASE=LifeCam VX-500 [1357]
+
 usb:v045Ep0750*
  ID_MODEL_FROM_DATABASE=Wired Keyboard 600
 
@@ -6923,6 +6971,9 @@ usb:v045Ep076C*
 usb:v045Ep076D*
  ID_MODEL_FROM_DATABASE=LifeCam HD-5000
 
+usb:v045Ep0770*
+ ID_MODEL_FROM_DATABASE=LifeCam VX-700
+
 usb:v045Ep0772*
  ID_MODEL_FROM_DATABASE=LifeCam Studio
 
@@ -6938,6 +6989,9 @@ usb:v045Ep0780*
 usb:v045Ep0797*
  ID_MODEL_FROM_DATABASE=Optical Mouse 200
 
+usb:v045Ep0799*
+ ID_MODEL_FROM_DATABASE=Surface Pro embedded keyboard
+
 usb:v045Ep07A5*
  ID_MODEL_FROM_DATABASE=Wireless Receiver 1461C
 
@@ -7104,7 +7158,7 @@ usb:v0461p0A00*
  ID_MODEL_FROM_DATABASE=Micro Innovations Web Cam 320
 
 usb:v0461p4D01*
- ID_MODEL_FROM_DATABASE=Comfort Keyboard
+ ID_MODEL_FROM_DATABASE=Comfort Keyboard / Kensington Orbit Elite
 
 usb:v0461p4D02*
  ID_MODEL_FROM_DATABASE=Mouse-in-a-Box
@@ -7157,6 +7211,9 @@ usb:v0461p4D81*
 usb:v0461p4DE7*
  ID_MODEL_FROM_DATABASE=webcam
 
+usb:v0461p4E04*
+ ID_MODEL_FROM_DATABASE=Lenovo Keyboard KB1021
+
 usb:v0463*
  ID_VENDOR_FROM_DATABASE=MGE UPS Systems
 
@@ -7700,6 +7757,9 @@ usb:v046Dp0A4D*
 usb:v046Dp0A5B*
  ID_MODEL_FROM_DATABASE=G933 Wireless Headset Dongle
 
+usb:v046Dp0A66*
+ ID_MODEL_FROM_DATABASE=[G533 Wireless Headset Dongle]
+
 usb:v046Dp0B02*
  ID_MODEL_FROM_DATABASE=C-UV35 [Bluetooth Mini-Receiver] (HID proxy mode)
 
@@ -8216,6 +8276,9 @@ usb:v046DpC31D*
 usb:v046DpC31F*
  ID_MODEL_FROM_DATABASE=Comfort Keyboard K290
 
+usb:v046DpC328*
+ ID_MODEL_FROM_DATABASE=Corded Keyboard K280e
+
 usb:v046DpC332*
  ID_MODEL_FROM_DATABASE=G502 Proteus Spectrum Optical Mouse
 
@@ -9305,6 +9368,9 @@ usb:v0482p0204*
 usb:v0482p0408*
  ID_MODEL_FROM_DATABASE=FS-1320D Printer
 
+usb:v0482p069B*
+ ID_MODEL_FROM_DATABASE=ECOSYS M2635dn
+
 usb:v0483*
  ID_VENDOR_FROM_DATABASE=STMicroelectronics
 
@@ -9695,6 +9761,9 @@ usb:v0499p160F*
 usb:v0499p1613*
  ID_MODEL_FROM_DATABASE=Clavinova CLP535
 
+usb:v0499p1704*
+ ID_MODEL_FROM_DATABASE=Steinberg UR44
+
 usb:v0499p2000*
  ID_MODEL_FROM_DATABASE=DGP-7
 
@@ -10962,7 +11031,7 @@ usb:v04A9p2603*
  ID_MODEL_FROM_DATABASE=MultiPASS C755
 
 usb:v04A9p260A*
- ID_MODEL_FROM_DATABASE=CAPT Printer
+ ID_MODEL_FROM_DATABASE=LBP810
 
 usb:v04A9p260E*
  ID_MODEL_FROM_DATABASE=LBP-2000
@@ -10977,7 +11046,7 @@ usb:v04A9p2612*
  ID_MODEL_FROM_DATABASE=MultiPASS C855
 
 usb:v04A9p2617*
- ID_MODEL_FROM_DATABASE=CAPT Printer
+ ID_MODEL_FROM_DATABASE=LBP1210
 
 usb:v04A9p261A*
  ID_MODEL_FROM_DATABASE=iR1600
@@ -11142,13 +11211,13 @@ usb:v04A9p2673*
  ID_MODEL_FROM_DATABASE=iR 3170C EUR
 
 usb:v04A9p2674*
- ID_MODEL_FROM_DATABASE=L120
+ ID_MODEL_FROM_DATABASE=FAX-L120
 
 usb:v04A9p2675*
  ID_MODEL_FROM_DATABASE=iR2830
 
 usb:v04A9p2676*
- ID_MODEL_FROM_DATABASE=CAPT Device
+ ID_MODEL_FROM_DATABASE=LBP2900
 
 usb:v04A9p2677*
  ID_MODEL_FROM_DATABASE=iR C2570
@@ -11180,6 +11249,9 @@ usb:v04A9p2687*
 usb:v04A9p2688*
  ID_MODEL_FROM_DATABASE=LBP3460
 
+usb:v04A9p2689*
+ ID_MODEL_FROM_DATABASE=FAX-L180/L380S/L398S
+
 usb:v04A9p268C*
  ID_MODEL_FROM_DATABASE=iR C6870
 
@@ -11213,6 +11285,9 @@ usb:v04A9p26DA*
 usb:v04A9p26E6*
  ID_MODEL_FROM_DATABASE=iR1024
 
+usb:v04A9p271A*
+ ID_MODEL_FROM_DATABASE=LBP6000
+
 usb:v04A9p2736*
  ID_MODEL_FROM_DATABASE=I-SENSYS MF4550d
 
@@ -12143,6 +12218,9 @@ usb:v04A9p32B1*
 usb:v04A9p32B2*
  ID_MODEL_FROM_DATABASE=PowerShot G9 X
 
+usb:v04A9p32B4*
+ ID_MODEL_FROM_DATABASE=EOS Rebel T6
+
 usb:v04A9p32BB*
  ID_MODEL_FROM_DATABASE=EOS M5
 
@@ -13526,6 +13604,12 @@ usb:v04C5p1150*
 usb:v04C5p125A*
  ID_MODEL_FROM_DATABASE=PalmSecure Sensor Device - MP
 
+usb:v04C5p200F*
+ ID_MODEL_FROM_DATABASE=Sigma DP2 (Mass Storage)
+
+usb:v04C5p2010*
+ ID_MODEL_FROM_DATABASE=Sigma DP2 (PictBridge)
+
 usb:v04C5p201D*
  ID_MODEL_FROM_DATABASE=SATA 3.0 6Gbit/s Adaptor [GROOVY]
 
@@ -13841,6 +13925,9 @@ usb:v04CBp01C0*
 usb:v04CBp01C1*
  ID_MODEL_FROM_DATABASE=FinePix F31fd (PTP)
 
+usb:v04CBp01C3*
+ ID_MODEL_FROM_DATABASE=FinePix S5 Pro
+
 usb:v04CBp01C4*
  ID_MODEL_FROM_DATABASE=FinePix S5700 Zoom (PTP)
 
@@ -13880,6 +13967,12 @@ usb:v04CBp0241*
 usb:v04CBp0278*
  ID_MODEL_FROM_DATABASE=FinePix JV300
 
+usb:v04CBp02C5*
+ ID_MODEL_FROM_DATABASE=FinePix S9900W Digital Camera (PTP)
+
+usb:v04CBp5006*
+ ID_MODEL_FROM_DATABASE=ASK-300
+
 usb:v04CC*
  ID_VENDOR_FROM_DATABASE=ST-Ericsson
 
@@ -14177,6 +14270,9 @@ usb:v04D9pA050*
 usb:v04D9pA055*
  ID_MODEL_FROM_DATABASE=Keyboard
 
+usb:v04D9pA096*
+ ID_MODEL_FROM_DATABASE=Keyboard
+
 usb:v04D9pA09F*
  ID_MODEL_FROM_DATABASE=E-Signal LUOM G10 Mechanical Gaming Mouse
 
@@ -14186,6 +14282,9 @@ usb:v04D9pA100*
 usb:v04D9pA11B*
  ID_MODEL_FROM_DATABASE=Mouse [MX-3200]
 
+usb:v04D9pE002*
+ ID_MODEL_FROM_DATABASE=MCU
+
 usb:v04DA*
  ID_VENDOR_FROM_DATABASE=Panasonic (Matsushita)
 
@@ -15644,6 +15743,9 @@ usb:v04F2pB107*
 usb:v04F2pB14C*
  ID_MODEL_FROM_DATABASE=CNF8050 Webcam
 
+usb:v04F2pB159*
+ ID_MODEL_FROM_DATABASE=CNF8243 Webcam
+
 usb:v04F2pB15C*
  ID_MODEL_FROM_DATABASE=Sony Vaio Integrated Camera
 
@@ -15737,6 +15839,9 @@ usb:v04F3p000A*
 usb:v04F3p0103*
  ID_MODEL_FROM_DATABASE=ActiveJet K-2024 Multimedia Keyboard
 
+usb:v04F3p016F*
+ ID_MODEL_FROM_DATABASE=Touchscreen
+
 usb:v04F3p01A4*
  ID_MODEL_FROM_DATABASE=Wireless Keyboard
 
@@ -15902,6 +16007,9 @@ usb:v04F9p002D*
 usb:v04F9p0039*
  ID_MODEL_FROM_DATABASE=HL-5340 series
 
+usb:v04F9p0041*
+ ID_MODEL_FROM_DATABASE=HL-2250DN Laser Printer
+
 usb:v04F9p0042*
  ID_MODEL_FROM_DATABASE=HL-2270DW Laser Printer
 
@@ -16463,6 +16571,9 @@ usb:v04F9p021D*
 usb:v04F9p021E*
  ID_MODEL_FROM_DATABASE=DCP-9010CN
 
+usb:v04F9p021F*
+ ID_MODEL_FROM_DATABASE=DCP-8085DN
+
 usb:v04F9p0220*
  ID_MODEL_FROM_DATABASE=MFC-9010CN
 
@@ -16535,6 +16646,9 @@ usb:v04F9p0240*
 usb:v04F9p0248*
  ID_MODEL_FROM_DATABASE=DCP-7055 scanner/printer
 
+usb:v04F9p024E*
+ ID_MODEL_FROM_DATABASE=MFC-7460DN
+
 usb:v04F9p0253*
  ID_MODEL_FROM_DATABASE=DCP-J125
 
@@ -16592,6 +16706,9 @@ usb:v04F9p026E*
 usb:v04F9p026F*
  ID_MODEL_FROM_DATABASE=MFC-J270W
 
+usb:v04F9p0270*
+ ID_MODEL_FROM_DATABASE=MFC-7360N
+
 usb:v04F9p0273*
  ID_MODEL_FROM_DATABASE=DCP-7057 scanner/printer
 
@@ -17285,6 +17402,9 @@ usb:v04F9p2028*
 usb:v04F9p202B*
  ID_MODEL_FROM_DATABASE=PT-7600 P-touch Label Printer
 
+usb:v04F9p2041*
+ ID_MODEL_FROM_DATABASE=PT-2730 P-touch Label Printer
+
 usb:v04F9p2061*
  ID_MODEL_FROM_DATABASE=PT-P700 P-touch Label Printer
 
@@ -18428,6 +18548,9 @@ usb:v0547p2750*
 usb:v0547p2810*
  ID_MODEL_FROM_DATABASE=Cypress ATAPI Bridge
 
+usb:v0547p4018*
+ ID_MODEL_FROM_DATABASE=AmScope MU1803
+
 usb:v0547p4D90*
  ID_MODEL_FROM_DATABASE=AmScope MD1900 camera
 
@@ -19016,6 +19139,9 @@ usb:v054Cp06C3*
 usb:v054Cp07C4*
  ID_MODEL_FROM_DATABASE=ILCE-6000 (aka Alpha-6000) in Mass Storage mode
 
+usb:v054Cp0847*
+ ID_MODEL_FROM_DATABASE=WG-C10 Portable Wireless Server
+
 usb:v054Cp088C*
  ID_MODEL_FROM_DATABASE=Portable Headphone Amplifier
 
@@ -19934,6 +20060,12 @@ usb:v056Ap0357*
 usb:v056Ap0358*
  ID_MODEL_FROM_DATABASE=PTH-860 [Intuos Pro (L)]
 
+usb:v056Ap035A*
+ ID_MODEL_FROM_DATABASE=DTH-1152 tablet
+
+usb:v056Ap0368*
+ ID_MODEL_FROM_DATABASE=DTH-1152 touchscreen
+
 usb:v056Ap0400*
  ID_MODEL_FROM_DATABASE=PenPartner 4x5
 
@@ -19994,6 +20126,9 @@ usb:v056E*
 usb:v056Ep0002*
  ID_MODEL_FROM_DATABASE=29UO Mouse
 
+usb:v056Ep0057*
+ ID_MODEL_FROM_DATABASE=M-PGDL Mouse
+
 usb:v056Ep0072*
  ID_MODEL_FROM_DATABASE=Mouse
 
@@ -24941,6 +25076,9 @@ usb:v0657*
 usb:v0658*
  ID_VENDOR_FROM_DATABASE=Sigma Designs, Inc.
 
+usb:v0658p0200*
+ ID_MODEL_FROM_DATABASE=Aeotec Z-Stick Gen5 (ZW090) - UZB
+
 usb:v0659*
  ID_VENDOR_FROM_DATABASE=Aethra
 
index f688ef2..eb04de6 100644 (file)
@@ -161,10 +161,10 @@ evdev:name:AlpsPS/2 ALPS DualPoint TouchPad:dmi:bvn*:bvr*:bd*:svnDellInc.:pnLati
 
 # Dell Latitude E7470
 evdev:name:AlpsPS/2 ALPS DualPoint TouchPad:dmi:bvn*:bvr*:bd*:svnDellInc.:pnLatitudeE7470*
- EVDEV_ABS_00=39:5856:59
- EVDEV_ABS_01=10:1532:29
- EVDEV_ABS_35=39:5856:59
- EVDEV_ABS_36=10:1532:29
+ EVDEV_ABS_00=29:2930:30
+ EVDEV_ABS_01=26:1533:29
+ EVDEV_ABS_35=29:2930:30
+ EVDEV_ABS_36=26:1533:29
 
 # Dell Precision 5510
 evdev:name:SynPS/2 Synaptics TouchPad:dmi:bvn*:bvr*:bd*:svnDellInc.:pnPrecision5510*
diff --git a/hwdb/60-input-id.hwdb b/hwdb/60-input-id.hwdb
new file mode 100644 (file)
index 0000000..b05b402
--- /dev/null
@@ -0,0 +1,64 @@
+# This file is part of systemd.
+#
+# The lookup keys are composed in:
+#   60-input-id.rules
+#
+# Note: The format of the "input-id:" prefix match key is a
+# contract between the rules file and the hardware data, it might
+# change in later revisions to support more or better matches, it
+# is not necessarily expected to be a stable ABI.
+#
+# Match string formats:
+# id-input:modalias:<modalias>
+#
+# To add local entries, create a new file
+#   /etc/udev/hwdb.d/61-input-id-local.hwdb
+# and add your rules there. To load the new rules execute (as root):
+#   systemd-hwdb update
+#   udevadm trigger /dev/input/eventXX
+# where /dev/input/eventXX is the device in question. If in
+# doubt, simply use /dev/input/event* to reload all input rules.
+#
+# If your changes are generally applicable, preferably send them as a pull
+# request to
+#   https://github.com/systemd/systemd
+# or create a bug report on https://github.com/systemd/systemd/issues and
+# include your new rules, a description of the device, and the output of
+#   udevadm info /dev/input/eventXX.
+#
+# This file must only be used where the input_id builtin assigns the wrong
+# properties or lacks the assignment of some properties. This is almost
+# always caused by a device not adhering to the standard of the device's
+# type.
+#
+# Allowed properties are:
+#    ID_INPUT
+#    ID_INPUT_ACCELEROMETER, ID_INPUT_MOUSE,
+#    ID_INPUT_POINTINGSTICK, ID_INPUT_TOUCHSCREEN, ID_INPUT_TOUCHPAD,
+#    ID_INPUT_TABLET, ID_INPUT_TABLET_PAD, ID_INPUT_JOYSTICK, ID_INPUT_KEY,
+#    ID_INPUT_KEYBOARD, ID_INPUT_SWITCH, ID_INPUT_TRACKBALL
+#
+#    ID_INPUT
+#       * MUST be set when ANY of ID_INPUT_* is set
+#       * MUST be unset when ALL of ID_INPUT_*  are unset
+#
+#    ID_INPUT_TABLET
+#       * MUST be set when setting ID_INPUT_TABLET_PAD
+#
+# Allowed values are 1 and 0 to set or unset, repsectively.
+#
+# NOT allowed in this file are:
+#    ID_INPUT_WIDTH_MM, ID_INPUT_HEIGHT_MM, ID_INPUT_TOUCHPAD_INTEGRATION
+#
+
+# Example:
+# id-input:modalias:input:b0003v1234pABCD*
+#  ID_INPUT_TOUCHPAD=1
+#  ID_INPUT=1
+
+# Sort by brand, model
+
+# UC-Logic TABLET 1060N Pad
+id-input:modalias:input:b0003v5543p0081*
+ ID_INPUT_TABLET=1
+ ID_INPUT_TABLET_PAD=1
index 9dca1dd..b46e056 100644 (file)
 #
 # [1]: https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=dfc57732ad38f93ae6232a3b4e64fd077383a0f1
 #
+# Note for devices where the display (LCD panel) is mounted non upright
+# in the device's casing, e.g. mounted upside-down or 90 degree rotated,
+# the ACCEL_MOUNT_MATRIX should be such that the x and y axis matches the
+# x and y axis of the display, not those of the casing, so that desktop
+# environments using the accelerometer data for rotation will e.g.
+# automatically flip their output for an upside-down display when the device
+# is held upright.
 #
 # Sort by brand, model
 
 #########################################
 # Acer
 #########################################
+sensor:modalias:acpi:INVN6500*:dmi:*svn*Acer*:*pn*AspireSW5-012*
+ ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1
+
 sensor:modalias:acpi:BMA250E*:dmi:*:svnAcer:pnIconiaW1-810:*
  ACCEL_MOUNT_MATRIX=1, 0, 0; 0, -1, 0; 0, 0, 1
 
@@ -63,6 +73,12 @@ sensor:modalias:acpi:SMO8500*:dmi:*svn*ASUSTeK*:*pn*TP300LJ*
  ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1
 
 #########################################
+# Axxo
+#########################################
+sensor:modalias:acpi:SMO8500*:dmi:*:svnStandard:pnWCBT1011:*
+ ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, 1, 0; 0, 0, 1
+
+#########################################
 # Chuwi
 #########################################
 
@@ -78,6 +94,13 @@ sensor:modalias:acpi:BOSC0200*:dmi:*:svnHampoo:pnX1D3_C806N:*
 sensor:modalias:acpi:KIOX000A*:dmi:svnChuwi*:pnHi13
  ACCEL_MOUNT_MATRIX=1, 0, 0; 0, -1, 0; 0, 0, 1
 
+# Chuwi HiBook
+# Chuwi HiBook does not have its product name filled, so we
+# match the entire dmi-alias, assuming that the use of a BOSC0200 +
+# bios-version + bios-date combo is unique
+sensor:modalias:acpi:BOSC0200*:dmi:bvnAmericanMegatrendsInc.:bvr5.11:bd05/07/2016:svnDefaultstring:pnDefaultstring:pvrDefaultstring:rvnHampoo:rnCherryTrailCR:rvrDefaultstring:cvnDefaultstring:ct3:cvrDefaultstring:
+ ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1
+
 #########################################
 # Cube
 #########################################
@@ -100,7 +123,7 @@ sensor:modalias:acpi:ACCE0001*:dmi:*svnEndless*:*pnELT-NL3*
 # GP-electronic
 #########################################
 sensor:modalias:acpi:KIOX000A*:dmi:bvnINSYDECorp.:bvrBYT70A.YNCHENG.WIN.007:*:svnInsyde:pnT701:*
- ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1
+ ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1
 
 #########################################
 # HP
@@ -110,6 +133,7 @@ sensor:modalias:platform:lis3lv02d:dmi:*svn*Hewlett-Packard*:*pn*HPEliteBook8560
   ACCEL_MOUNT_MATRIX=1, 0, 0; 0, 0, -1; 0, 1, 0
 
 sensor:modalias:acpi:SMO8500*:dmi:*:svnHewlett-Packard:pnHPStream7Tablet:*
+sensor:modalias:acpi:SMO8500*:dmi:*:svnHewlett-Packard:pnHPStream8Tablet:*
   ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1
 
 #########################################
@@ -145,6 +169,9 @@ sensor:modalias:acpi:KIOX000A*:dmi:*svnLAMINA:pnT-1016BNORD*
 sensor:modalias:acpi:NCPE0388*:dmi:*:rnLenovoYOGA510-14IKB:*
  ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, -1, 0; 0, 0, 1
 
+sensor:modalias:acpi:BOSC0200:BOSC0200:dmi:*ThinkPadYoga11e3rdGen*
+ ACCEL_MOUNT_MATRIX=0, 1, 0; -1, 0, 0; 0, 0, 1
+
 #########################################
 # Peaq
 #########################################
@@ -184,4 +211,3 @@ sensor:modalias:acpi:BMA250*:dmi:*:bvrTREK.G.WI71C.JGBMRBA*:*:svnInsyde:pnST7041
 #########################################
 sensor:modalias:acpi:*KIOX000A*:dmi:*svn*CytrixTechnology:*pn*Complex11t*
  ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, 1, 0; 0, 0, 1
-
index bade5e4..840fa4c 100644 (file)
@@ -451,6 +451,15 @@ mouse:usb:v046dp4041:name:Logitech MX Master:
  MOUSE_WHEEL_CLICK_COUNT=24
  MOUSE_WHEEL_CLICK_COUNT_HORIZONTAL=14
 
+# Logitech MX Master 2s
+# Horiz wheel has 14 stops, angle is rounded up
+mouse:usb:v046dp4069:name:Logitech MX Master 2s:
+ MOUSE_DPI=1000@125
+ MOUSE_WHEEL_CLICK_ANGLE=15
+ MOUSE_WHEEL_CLICK_ANGLE_HORIZONTAL=26
+ MOUSE_WHEEL_CLICK_COUNT=24
+ MOUSE_WHEEL_CLICK_COUNT_HORIZONTAL=14
+
 # Logitech MK260 Wireless Combo Receiver aka M-R0011
 mouse:usb:v046dpc52e:name:Logitech USB Receiver:
  MOUSE_DPI=1000@200
index 12d97de..9796353 100644 (file)
 
 touchpad:i8042:*
 touchpad:rmi:*
+touchpad:usb:*
  ID_INPUT_TOUCHPAD_INTEGRATION=internal
 
 touchpad:bluetooth:*
-touchpad:usb:*
  ID_INPUT_TOUCHPAD_INTEGRATION=external
 
 ###########################################################
-# Apple
-###########################################################
-touchpad:usb:v05ac*
- ID_INPUT_TOUCHPAD_INTEGRATION=internal
-
-###########################################################
 # Wacom
 ###########################################################
 touchpad:usb:v056a*
  ID_INPUT_TOUCHPAD_INTEGRATION=external
 
-###########################################################
-# Microsoft (Surface Type Covers)
-###########################################################
-touchpad:usb:v045ep07*
- ID_INPUT_TOUCHPAD_INTEGRATION=internal
index d5ddc87..df9158b 100644 (file)
@@ -83,6 +83,8 @@
  <tr class="odd"><td>Coreboot Project</td><td>BOOT</td><td>02/28/2017</td> </tr>
  <tr class="even"><td>Marvell Technology Group Ltd.</td><td>MRVL</td><td>05/25/2017</td> </tr>
  <tr class="odd"><td>IHSE GmbH</td><td>IHSE</td><td>06/22/2017</td> </tr>
+ <tr class="even"><td>Insyde Software</td><td>INSY</td><td>11/10/2017</td> </tr>
+ <tr class="odd"><td>Nexstgo Company Limited</td><td>NXGO</td><td>11/13/2017</td> </tr>
       </tbody>
     </table>
   </body>
index 3c43649..c80d222 100755 (executable)
@@ -344,17 +344,17 @@ if __name__ == '__main__':
     args = sys.argv[1:]
 
     if not args or 'usb' in args:
-        p = usb_ids_grammar().parseFile(open('usb.ids'))
+        p = usb_ids_grammar().parseFile(open('usb.ids', errors='replace'))
         usb_vendor_model(p)
         usb_classes(p)
 
     if not args or 'pci' in args:
-        p = pci_ids_grammar().parseFile(open('pci.ids'))
+        p = pci_ids_grammar().parseFile(open('pci.ids', errors='replace'))
         pci_vendor_model(p)
         pci_classes(p)
 
     if not args or 'sdio' in args:
-        p = pci_ids_grammar().parseFile(open('sdio.ids'))
+        p = pci_ids_grammar().parseFile(open('sdio.ids', errors='replace'))
         sdio_vendor_model(p)
         sdio_classes(p)
 
index 37fcee3..f05f35a 100644 (file)
@@ -176,12 +176,6 @@ CC46D6     (base 16)               Cisco Systems, Inc
                                Dongguan  Guangdong  523808 \r
                                CN\r
 \r
-00-CD-FE   (hex)               Apple, Inc.\r
-00CDFE     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 38-F2-3E   (hex)               Microsoft Mobile Oy\r
 38F23E     (base 16)           Microsoft Mobile Oy\r
                                Keilalahdentie 4\r
@@ -242,12 +236,6 @@ D83C69     (base 16)               Shenzhen TINNO Mobile Technology Corp.
                                ShenZhen  GuangDong  518000\r
                                CN\r
 \r
-18-AF-61   (hex)               Apple, Inc.\r
-18AF61     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 BC-83-A7   (hex)               SHENZHEN CHUANGWEI-RGB ELECTRONICS CO.,LTD\r
 BC83A7     (base 16)           SHENZHEN CHUANGWEI-RGB ELECTRONICS CO.,LTD\r
                                Unit A 13-16/F,Skyworth Bldg., Gaoxin Ave.1.S.,Nanshan District\r
@@ -590,18 +578,6 @@ BC4699     (base 16)               TP-LINK TECHNOLOGIES CO.,LTD.
                                Palo Alto  CA  94303\r
                                US\r
 \r
-CC-44-63   (hex)               Apple, Inc.\r
-CC4463     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-6C-72-E7   (hex)               Apple, Inc.\r
-6C72E7     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 CC-A2-23   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
 CCA223     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
                                No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park\r
@@ -1160,30 +1136,6 @@ ACF2C5     (base 16)             Cisco Systems, Inc
                                San Jose  CA  95134\r
                                US\r
 \r
-CC-C7-60   (hex)               Apple, Inc.\r
-CCC760     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-08-74-02   (hex)               Apple, Inc.\r
-087402     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-28-5A-EB   (hex)               Apple, Inc.\r
-285AEB     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-28-F0-76   (hex)               Apple, Inc.\r
-28F076     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 84-28-5A   (hex)               Saffron Solutions Inc\r
 84285A     (base 16)           Saffron Solutions Inc\r
                                1337 Mass Ave #273\r
@@ -1196,180 +1148,12 @@ CCC760     (base 16)           Apple, Inc.
                                San Diego  CA  92121\r
                                US\r
 \r
-44-D8-84   (hex)               Apple, Inc.\r
-44D884     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-EC-85-2F   (hex)               Apple, Inc.\r
-EC852F     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-28-6A-BA   (hex)               Apple, Inc.\r
-286ABA     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-70-56-81   (hex)               Apple, Inc.\r
-705681     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-7C-D1-C3   (hex)               Apple, Inc.\r
-7CD1C3     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-F0-DC-E2   (hex)               Apple, Inc.\r
-F0DCE2     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-B0-65-BD   (hex)               Apple, Inc.\r
-B065BD     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-A8-20-66   (hex)               Apple, Inc.\r
-A82066     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-BC-67-78   (hex)               Apple, Inc.\r
-BC6778     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-68-96-7B   (hex)               Apple, Inc.\r
-68967B     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-84-85-06   (hex)               Apple, Inc.\r
-848506     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-B4-F0-AB   (hex)               Apple, Inc.\r
-B4F0AB     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-10-DD-B1   (hex)               Apple, Inc.\r
-10DDB1     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-04-F7-E4   (hex)               Apple, Inc.\r
-04F7E4     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-34-C0-59   (hex)               Apple, Inc.\r
-34C059     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-F0-D1-A9   (hex)               Apple, Inc.\r
-F0D1A9     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-F8-27-93   (hex)               Apple, Inc.\r
-F82793     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-AC-FD-EC   (hex)               Apple, Inc.\r
-ACFDEC     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-D0-E1-40   (hex)               Apple, Inc.\r
-D0E140     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 F8-32-E4   (hex)               ASUSTek COMPUTER INC.\r
 F832E4     (base 16)           ASUSTek COMPUTER INC.\r
                                15,Li-Te Rd., Peitou, Taipei 112, Taiwan\r
                                Taipei  Taiwan  112\r
                                TW\r
 \r
-8C-7C-92   (hex)               Apple, Inc.\r
-8C7C92     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-78-31-C1   (hex)               Apple, Inc.\r
-7831C1     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-F4-37-B7   (hex)               Apple, Inc.\r
-F437B7     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-54-AE-27   (hex)               Apple, Inc.\r
-54AE27     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-64-76-BA   (hex)               Apple, Inc.\r
-6476BA     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-84-B1-53   (hex)               Apple, Inc.\r
-84B153     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-78-3A-84   (hex)               Apple, Inc.\r
-783A84     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-2C-BE-08   (hex)               Apple, Inc.\r
-2CBE08     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-24-E3-14   (hex)               Apple, Inc.\r
-24E314     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 00-10-FF   (hex)               Cisco Systems, Inc\r
 0010FF     (base 16)           Cisco Systems, Inc\r
                                170 WEST TASMAN DRIVE\r
@@ -1400,252 +1184,6 @@ F437B7     (base 16)            Apple, Inc.
                                San Jose  CA  95134\r
                                US\r
 \r
-60-FE-C5   (hex)               Apple, Inc.\r
-60FEC5     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-00-A0-40   (hex)               Apple, Inc.\r
-00A040     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-BC-3B-AF   (hex)               Apple, Inc.\r
-BC3BAF     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-78-6C-1C   (hex)               Apple, Inc.\r
-786C1C     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-04-15-52   (hex)               Apple, Inc.\r
-041552     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-38-48-4C   (hex)               Apple, Inc.\r
-38484C     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-70-11-24   (hex)               Apple, Inc.\r
-701124     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-C8-6F-1D   (hex)               Apple, Inc.\r
-C86F1D     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-68-5B-35   (hex)               Apple, Inc.\r
-685B35     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-38-0F-4A   (hex)               Apple, Inc.\r
-380F4A     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-30-10-E4   (hex)               Apple, Inc.\r
-3010E4     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-04-DB-56   (hex)               Apple, Inc.\r
-04DB56     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-88-1F-A1   (hex)               Apple, Inc.\r
-881FA1     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-04-E5-36   (hex)               Apple, Inc.\r
-04E536     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-10-9A-DD   (hex)               Apple, Inc.\r
-109ADD     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-40-A6-D9   (hex)               Apple, Inc.\r
-40A6D9     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-7C-F0-5F   (hex)               Apple, Inc.\r
-7CF05F     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-A4-B1-97   (hex)               Apple, Inc.\r
-A4B197     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-0C-74-C2   (hex)               Apple, Inc.\r
-0C74C2     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-40-30-04   (hex)               Apple, Inc.\r
-403004     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-48-60-BC   (hex)               Apple, Inc.\r
-4860BC     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-50-EA-D6   (hex)               Apple, Inc.\r
-50EAD6     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-28-E0-2C   (hex)               Apple, Inc.\r
-28E02C     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-60-C5-47   (hex)               Apple, Inc.\r
-60C547     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-7C-11-BE   (hex)               Apple, Inc.\r
-7C11BE     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-00-3E-E1   (hex)               Apple, Inc.\r
-003EE1     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-68-D9-3C   (hex)               Apple, Inc.\r
-68D93C     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-2C-F0-EE   (hex)               Apple, Inc.\r
-2CF0EE     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-84-78-8B   (hex)               Apple, Inc.\r
-84788B     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-6C-94-F8   (hex)               Apple, Inc.\r
-6C94F8     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-70-3E-AC   (hex)               Apple, Inc.\r
-703EAC     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-C0-1A-DA   (hex)               Apple, Inc.\r
-C01ADA     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-34-36-3B   (hex)               Apple, Inc.\r
-34363B     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-C8-1E-E7   (hex)               Apple, Inc.\r
-C81EE7     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-9C-FC-01   (hex)               Apple, Inc.\r
-9CFC01     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-00-0D-93   (hex)               Apple, Inc.\r
-000D93     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-00-1C-B3   (hex)               Apple, Inc.\r
-001CB3     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-64-B9-E8   (hex)               Apple, Inc.\r
-64B9E8     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-34-15-9E   (hex)               Apple, Inc.\r
-34159E     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-58-B0-35   (hex)               Apple, Inc.\r
-58B035     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-F0-B4-79   (hex)               Apple, Inc.\r
-F0B479     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
 14-13-57   (hex)               ATP Electronics, Inc.\r
 141357     (base 16)           ATP Electronics, Inc.\r
                                2590 North First Street Suite 150\r
@@ -1865,12 +1403,6 @@ C025A2     (base 16)             NEC Platforms, Ltd.
                                Moscow  Moscow  109316\r
                                RU\r
 \r
-AC-BC-32   (hex)               Apple, Inc.\r
-ACBC32     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 94-BB-AE   (hex)               Husqvarna AB\r
 94BBAE     (base 16)           Husqvarna AB\r
                                Drottninggatan 2\r
@@ -2519,12 +2051,6 @@ DC2F03     (base 16)             Step forward Group Co., Ltd.
                                Nagaokakyo-shi  Kyoto  617-8555\r
                                JP\r
 \r
-5C-AA-FD   (hex)               Sonos, Inc.\r
-5CAAFD     (base 16)           Sonos, Inc.\r
-                               223 E. De La Guerra Street\r
-                               Santa Barbara  CA  93101\r
-                               US\r
-\r
 8C-DF-9D   (hex)               NEC Corporation\r
 8CDF9D     (base 16)           NEC Corporation\r
                                7-1, Shiba 5-chome,\r
@@ -2807,12 +2333,6 @@ A4A4D3     (base 16)             Bluebank Communication Technology Co.Ltd
                                Peiking    100190\r
                                CN\r
 \r
-88-29-50   (hex)               Dalian Netmoon Tech Develop Co.,Ltd\r
-882950     (base 16)           Dalian Netmoon Tech Develop Co.,Ltd\r
-                               Shahekou District NO.19-2 Wansui Street\r
-                               Dalian  Liaoning  116000\r
-                               CN\r
-\r
 08-CD-9B   (hex)               samtec automotive electronics & software GmbH\r
 08CD9B     (base 16)           samtec automotive electronics & software GmbH\r
                                Saarstrasse 27\r
@@ -4466,12 +3986,6 @@ B49842     (base 16)             zte corporation
                                Eden Prairie  MN  55344\r
                                US\r
 \r
-90-CC-24   (hex)               Synaptics, Inc\r
-90CC24     (base 16)           Synaptics, Inc\r
-                               3120 Scott Blvd.\r
-                               Santa Clara  CA  95054\r
-                               US\r
-\r
 AC-17-02   (hex)               Fibar Group sp. z o.o.\r
 AC1702     (base 16)           Fibar Group sp. z o.o.\r
                                ul. Lotnicza 1\r
@@ -7274,12 +6788,6 @@ A0DDE5     (base 16)             SHARP Corporation
                                Richmond  BC  V6V 3A4\r
                                CA\r
 \r
-A4-50-55   (hex)               busware.de\r
-A45055     (base 16)           busware.de\r
-                               Loessnitzgrundstrasse 115a\r
-                               Moritzburg  Saxony  01468\r
-                               DE\r
-\r
 C8-93-83   (hex)               Embedded Automation, Inc.\r
 C89383     (base 16)           Embedded Automation, Inc.\r
                                17345 Abbey Drive\r
@@ -9344,12 +8852,6 @@ A8CE90     (base 16)             CVC
                                Sheffield  South Yorkshire  S9 3TY\r
                                GB\r
 \r
-00-21-94   (hex)               Ping Communication\r
-002194     (base 16)           Ping Communication\r
-                               Sandakerveien 24C\r
-                               Oslo    0473\r
-                               NO\r
-\r
 00-21-8F   (hex)               Avantgarde Acoustic Lautsprechersysteme GmbH\r
 00218F     (base 16)           Avantgarde Acoustic Lautsprechersysteme GmbH\r
                                Nibelungenstraße 349\r
@@ -12710,12 +12212,6 @@ A8CE90     (base 16)           CVC
                                Santa Clara  California  95054\r
                                US\r
 \r
-00-13-86   (hex)               ABB Inc./Totalflow\r
-001386     (base 16)           ABB Inc./Totalflow\r
-                               \r
-                               Bartlesville  OK  74006\r
-                               US\r
-\r
 00-13-74   (hex)               Atheros Communications, Inc.\r
 001374     (base 16)           Atheros Communications, Inc.\r
                                529 Almanor Avenue\r
@@ -20252,12 +19748,6 @@ A8CE90     (base 16)           CVC
                                RESTON  VA  22096\r
                                US\r
 \r
-00-A0-D5   (hex)               SIERRA WIRELESS INC.\r
-00A0D5     (base 16)           SIERRA WIRELESS INC.\r
-                               13811 Wireless Way\r
-                                 RICHMOND B.C.  V6V 3A4\r
-                               CA\r
-\r
 00-20-0F   (hex)               EBRAINS Inc\r
 00200F     (base 16)           EBRAINS Inc\r
                                Tachibana Bldg\r
@@ -23240,18 +22730,6 @@ F4F5A5     (base 16)           Nokia Corporation
                                Boston  MA  02205\r
                                US\r
 \r
-AC-61-EA   (hex)               Apple, Inc.\r
-AC61EA     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-38-B5-4D   (hex)               Apple, Inc.\r
-38B54D     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 90-A6-2F   (hex)               NAVER\r
 90A62F     (base 16)           NAVER\r
                                NAVER Green Factory, 6, Buljeong-ro, Bundang-gu\r
@@ -23300,12 +22778,6 @@ B47443     (base 16)           Samsung Electronics Co.,Ltd
                                New Taipei City  Taiwan  22101\r
                                TW\r
 \r
-A4-F1-E8   (hex)               Apple, Inc.\r
-A4F1E8     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 00-35-1A   (hex)               Cisco Systems, Inc\r
 00351A     (base 16)           Cisco Systems, Inc\r
                                80 West Tasman Drive\r
@@ -23840,30 +23312,6 @@ D8E56D     (base 16)           TCT mobile ltd
                                Hui Zhou  Guang Dong  516006\r
                                CN\r
 \r
-90-C1-C6   (hex)               Apple, Inc.\r
-90C1C6     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-70-A2-B3   (hex)               Apple, Inc.\r
-70A2B3     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-4C-57-CA   (hex)               Apple, Inc.\r
-4C57CA     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-68-FB-7E   (hex)               Apple, Inc.\r
-68FB7E     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 44-2C-05   (hex)               AMPAK Technology, Inc.\r
 442C05     (base 16)           AMPAK Technology, Inc.\r
                                No.1,Jen Ai Road Hsinchu Industrial Park, Hukou\r
@@ -25496,18 +24944,6 @@ A01081     (base 16)           Samsung Electronics Co.,Ltd
                                Deer Park  IL  60010\r
                                US\r
 \r
-9C-F4-8E   (hex)               Apple, Inc.\r
-9CF48E     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-FC-D8-48   (hex)               Apple, Inc.\r
-FCD848     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 80-48-A5   (hex)               SICHUAN TIANYI COMHEART TELECOMCO.,LTD\r
 8048A5     (base 16)           SICHUAN TIANYI COMHEART TELECOMCO.,LTD\r
                                FL12,TowerB,TianYi International Hotel\r
@@ -25718,12 +25154,6 @@ AC233F     (base 16)           Shenzhen Minew Technologies Co., Ltd.
                                Shenzhen    518109\r
                                CN\r
 \r
-00-0E-58   (hex)               Sonos, Inc.\r
-000E58     (base 16)           Sonos, Inc.\r
-                               223 E. De La Guerra St.\r
-                               Santa Barbara  CA  93101\r
-                               US\r
-\r
 E0-50-8B   (hex)               Zhejiang Dahua Technology Co., Ltd.\r
 E0508B     (base 16)           Zhejiang Dahua Technology Co., Ltd.\r
                                No.1199,Waterfront Road \r
@@ -25922,12 +25352,6 @@ F015B9     (base 16)           PlayFusion Limited
                                Cambridge    CB4 0WS\r
                                GB\r
 \r
-70-70-0D   (hex)               Apple, Inc.\r
-70700D     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 24-A7-DC   (hex)               BSkyB Ltd\r
 24A7DC     (base 16)           BSkyB Ltd\r
                                130 Kings Road\r
@@ -26270,12 +25694,6 @@ F0D2F1     (base 16)           Amazon Technologies Inc.
                                Reno  NV  89507\r
                                US\r
 \r
-7C-50-49   (hex)               Apple, Inc.\r
-7C5049     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 F0-A2-25   (hex)               Private\r
 F0A225     (base 16)           Private\r
 \r
@@ -26372,54 +25790,6 @@ A04C5B     (base 16)           Shenzhen TINNO Mobile Technology Corp.
                                HongKong  HongKong  999077\r
                                HK\r
 \r
-D4-61-9D   (hex)               Apple, Inc.\r
-D4619D     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-B0-48-1A   (hex)               Apple, Inc.\r
-B0481A     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-98-9E-63   (hex)               Apple, Inc.\r
-989E63     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-DC-A9-04   (hex)               Apple, Inc.\r
-DCA904     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-48-A1-95   (hex)               Apple, Inc.\r
-48A195     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-6C-AB-31   (hex)               Apple, Inc.\r
-6CAB31     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-50-32-37   (hex)               Apple, Inc.\r
-503237     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-00-08-89   (hex)               Echostar Technologies Corp\r
-000889     (base 16)           Echostar Technologies Corp\r
-                               94 Inverness Terrace E\r
-                               Englewood  CO  80112\r
-                               US\r
-\r
 2C-02-9F   (hex)               3ALogics\r
 2C029F     (base 16)           3ALogics\r
                                #704, Hyundai office B'd, Sunae-dong, Bundang-gu\r
@@ -27785,30 +27155,6 @@ BC88C3     (base 16)           Ningbo Dooya Mechanic & Electronic Technology Co., Ltd
                                Ningbo  Zhejiang  315202\r
                                CN\r
 \r
-A8-BE-27   (hex)               Apple, Inc.\r
-A8BE27     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-B8-63-4D   (hex)               Apple, Inc.\r
-B8634D     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-6C-96-CF   (hex)               Apple, Inc.\r
-6C96CF     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-30-35-AD   (hex)               Apple, Inc.\r
-3035AD     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 68-1F-40   (hex)               Blu Wireless Technology Ltd\r
 681F40     (base 16)           Blu Wireless Technology Ltd\r
                                Bluwireless Technology, 5th Floor, 1 Temple Way\r
@@ -28175,42 +27521,6 @@ DC5583     (base 16)           GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
                                Taipei City  Neihu Dist  248\r
                                TW\r
 \r
-9C-E3-3F   (hex)               Apple, Inc.\r
-9CE33F     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-F0-98-9D   (hex)               Apple, Inc.\r
-F0989D     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-AC-E4-B5   (hex)               Apple, Inc.\r
-ACE4B5     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-E4-2B-34   (hex)               Apple, Inc.\r
-E42B34     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-1C-36-BB   (hex)               Apple, Inc.\r
-1C36BB     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-3C-2E-FF   (hex)               Apple, Inc.\r
-3C2EFF     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 24-8B-E0   (hex)               SICHUAN TIANYI COMHEART TELECOMCO., LTD\r
 248BE0     (base 16)           SICHUAN TIANYI COMHEART TELECOMCO., LTD\r
                                FL12, TowerB,Tianyi international Hotel,No.2 West Section One, Second Ring Road,\r
@@ -28691,12 +28001,6 @@ D89C67     (base 16)           Hon Hai Precision Ind. Co.,Ltd.
                                Gumi  Gyeongbuk  730-350\r
                                KR\r
 \r
-28-BF-89   (hex)               Fiberhome Telecommunication Technologies Co.,LTD\r
-28BF89     (base 16)           Fiberhome Telecommunication Technologies Co.,LTD\r
-                               No.5 DongXin Road\r
-                               Wuhan  Hubei  430074\r
-                               CN\r
-\r
 C8-40-29   (hex)               Fiberhome Telecommunication Technologies Co.,LTD\r
 C84029     (base 16)           Fiberhome Telecommunication Technologies Co.,LTD\r
                                No.5 DongXin Road\r
@@ -28709,10 +28013,16 @@ CC0677     (base 16)          Fiberhome Telecommunication Technologies Co.,LTD
                                Wuhan  Hubei  430074\r
                                CN\r
 \r
-B0-E2-E5   (hex)               Fiberhome Telecommunication Technologies Co.,LTD\r
-B0E2E5     (base 16)           Fiberhome Telecommunication Technologies Co.,LTD\r
+1C-39-8A   (hex)               Fiberhome Telecommunication Technologies Co.,LTD\r
+1C398A     (base 16)           Fiberhome Telecommunication Technologies Co.,LTD\r
                                No.5 DongXin Road\r
-                               Wuhan City  Hubei Province  430074\r
+                               Wuhan  Hubei  430074\r
+                               CN\r
+\r
+10-77-B0   (hex)               Fiberhome Telecommunication Technologies Co.,LTD\r
+1077B0     (base 16)           Fiberhome Telecommunication Technologies Co.,LTD\r
+                               No.5 DongXin Road\r
+                               Wuhan  Hubei  430074\r
                                CN\r
 \r
 88-94-7E   (hex)               Fiberhome Telecommunication Technologies Co.,LTD\r
@@ -28727,16 +28037,16 @@ F4573E     (base 16)          Fiberhome Telecommunication Technologies Co.,LTD
                                Wuhan  Hubei  430074\r
                                CN\r
 \r
-1C-39-8A   (hex)               Fiberhome Telecommunication Technologies Co.,LTD\r
-1C398A     (base 16)           Fiberhome Telecommunication Technologies Co.,LTD\r
+28-BF-89   (hex)               Fiberhome Telecommunication Technologies Co.,LTD\r
+28BF89     (base 16)           Fiberhome Telecommunication Technologies Co.,LTD\r
                                No.5 DongXin Road\r
                                Wuhan  Hubei  430074\r
                                CN\r
 \r
-10-77-B0   (hex)               Fiberhome Telecommunication Technologies Co.,LTD\r
-1077B0     (base 16)           Fiberhome Telecommunication Technologies Co.,LTD\r
+B0-E2-E5   (hex)               Fiberhome Telecommunication Technologies Co.,LTD\r
+B0E2E5     (base 16)           Fiberhome Telecommunication Technologies Co.,LTD\r
                                No.5 DongXin Road\r
-                               Wuhan  Hubei  430074\r
+                               Wuhan City  Hubei Province  430074\r
                                CN\r
 \r
 E4-30-22   (hex)               Hanwha Techwin Security Vietnam\r
@@ -28745,536 +28055,1544 @@ E43022     (base 16)               Hanwha Techwin Security Vietnam
                                Nam Son Commune, Bac Ninh City  Bac Ninh Province  000\r
                                VN\r
 \r
-0C-6F-9C   (hex)               Shaw Communications Inc.\r
-0C6F9C     (base 16)           Shaw Communications Inc.\r
-                               Suite 900, 630 3rd Avenue S.W.\r
-                               CALGARY  ALBERTA  T2P 4L4\r
-                               CA\r
+B4-E6-2D   (hex)               Espressif Inc.\r
+B4E62D     (base 16)           Espressif Inc.\r
+                               Room 204, Building 2, 690 Bibo Road, Pudong New Area\r
+                               Shanghai  Shanghai  201203\r
+                               CN\r
 \r
-18-01-E3   (hex)               Bittium Wireless Ltd\r
-1801E3     (base 16)           Bittium Wireless Ltd\r
-                               Tutkijantie 8\r
-                               Oulu    50590\r
-                               FI\r
+F0-B5-B7   (hex)               Disruptive Technologies Research AS\r
+F0B5B7     (base 16)           Disruptive Technologies Research AS\r
+                               Ytrebygdsvegen 215\r
+                               Blomsterdalen  Hordaland  5258\r
+                               NO\r
 \r
-C0-AC-54   (hex)               Sagemcom Broadband SAS\r
-C0AC54     (base 16)           Sagemcom Broadband SAS\r
-                               250 route de l'Empereur\r
-                               Rueil Malmaison  HAUTS DE SEINE  92848\r
-                               FR\r
+54-AE-27   (hex)               Apple, Inc.\r
+54AE27     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-40-F2-01   (hex)               Sagemcom Broadband SAS\r
-40F201     (base 16)           Sagemcom Broadband SAS\r
-                               250 route de l'Empereur\r
-                               Rueil Malmaison  HAUTS DE SEINE  92848\r
-                               FR\r
+F4-37-B7   (hex)               Apple, Inc.\r
+F437B7     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-C8-91-F9   (hex)               Sagemcom Broadband SAS\r
-C891F9     (base 16)           Sagemcom Broadband SAS\r
-                               250 route de l'Empereur\r
-                               Rueil Malmaison  HAUTS DE SEINE  92848\r
-                               FR\r
+78-31-C1   (hex)               Apple, Inc.\r
+7831C1     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-4C-FF-12   (hex)               Fuze Entertainment Co., ltd\r
-4CFF12     (base 16)           Fuze Entertainment Co., ltd\r
-                               3rd Floor Harbour Centre\r
-                               George Town  George Town  P.O. Box 613GT\r
-                               KY\r
+8C-7C-92   (hex)               Apple, Inc.\r
+8C7C92     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-00-59-AC   (hex)               KPN. B.V.\r
-0059AC     (base 16)           KPN. B.V.\r
-                               Maanplein 55\r
-                               Den Haag  Zuid holland  2516 CK\r
-                               NL\r
+D0-E1-40   (hex)               Apple, Inc.\r
+D0E140     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-AC-9A-22   (hex)               NXP Semiconductors\r
-AC9A22     (base 16)           NXP Semiconductors\r
-                               411 E. Plumeria Drive\r
-                               San Jose  CA  95134\r
+AC-FD-EC   (hex)               Apple, Inc.\r
+ACFDEC     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-00-60-37   (hex)               NXP Semiconductors\r
-006037     (base 16)           NXP Semiconductors\r
-                               High Tech Campus 32, Office 1.21\r
-                               SAF  AD  13456\r
-                               NL\r
+24-E3-14   (hex)               Apple, Inc.\r
+24E314     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-54-60-09   (hex)               Google, Inc.\r
-546009     (base 16)           Google, Inc.\r
-                               1600 Amphitheatre Parkway\r
-                               Mountain View  CA  94043\r
+2C-BE-08   (hex)               Apple, Inc.\r
+2CBE08     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-A4-77-33   (hex)               Google, Inc.\r
-A47733     (base 16)           Google, Inc.\r
-                               1600 Ampitheatre Parkway\r
-                               Mountain View    94043\r
+78-3A-84   (hex)               Apple, Inc.\r
+783A84     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-94-EB-2C   (hex)               Google, Inc.\r
-94EB2C     (base 16)           Google, Inc.\r
-                               1600 Amphitheatre Parkway\r
-                               Mountain View    94043\r
+84-B1-53   (hex)               Apple, Inc.\r
+84B153     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-28-BC-56   (hex)               EMAC, Inc.\r
-28BC56     (base 16)           EMAC, Inc.\r
-                               2390 EMAC Way\r
-                               Carbondale  IL  62902\r
+64-76-BA   (hex)               Apple, Inc.\r
+6476BA     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-28-7C-DB   (hex)               Hefei  Toycloud Technology Co.,ltd\r
-287CDB     (base 16)           Hefei  Toycloud Technology Co.,ltd\r
-                               FLOOR 13,XUNFEI BUILDING,NO.666 WANGJIANG ROAD,HIGH & NEW TECHNOLOGY DEVELOPMENT ZONE.HEFEI.\r
-                               Hefei  Anhui  230088\r
-                               CN\r
+70-3E-AC   (hex)               Apple, Inc.\r
+703EAC     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-D0-B3-3F   (hex)               Shenzhen TINNO Mobile Technology Corp.\r
-D0B33F     (base 16)           Shenzhen TINNO Mobile Technology Corp.\r
-                               4/F.,H-3 Building,OCT Eastern lndustrial Park. NO.1 XiangShan East Road.,\r
-                               GUANGDONG  SHENZHEN  518053\r
-                               CN\r
+6C-94-F8   (hex)               Apple, Inc.\r
+6C94F8     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-00-73-8D   (hex)               Shenzhen TINNO Mobile Technology Corp.\r
-00738D     (base 16)           Shenzhen TINNO Mobile Technology Corp.\r
-                               4/F.,H-3 Building,OCT Eastern lndustrial Park. NO.1 XiangShan East Road.\r
-                               GuangDong    518053\r
+84-78-8B   (hex)               Apple, Inc.\r
+84788B     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-A8-CA-7B   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
-A8CA7B     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
-                               No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park\r
-                               Dongguan    523808\r
-                               CN\r
+2C-F0-EE   (hex)               Apple, Inc.\r
+2CF0EE     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-AC-CF-85   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
-ACCF85     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
-                               No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park\r
-                               Dongguan  Guangdong  523808 \r
-                               CN\r
+68-D9-3C   (hex)               Apple, Inc.\r
+68D93C     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-0C-D7-46   (hex)               Apple, Inc.\r
-0CD746     (base 16)           Apple, Inc.\r
+F8-27-93   (hex)               Apple, Inc.\r
+F82793     (base 16)           Apple, Inc.\r
                                1 Infinite Loop\r
                                Cupertino  CA  95014\r
                                US\r
 \r
-44-00-10   (hex)               Apple, Inc.\r
-440010     (base 16)           Apple, Inc.\r
+04-E5-36   (hex)               Apple, Inc.\r
+04E536     (base 16)           Apple, Inc.\r
                                1 Infinite Loop\r
                                Cupertino  CA  95014\r
                                US\r
 \r
-24-35-CC   (hex)               Zhongshan Scinan Internet of Things Co.,Ltd.\r
-2435CC     (base 16)           Zhongshan Scinan Internet of Things Co.,Ltd.\r
-                               15/F Bldg 1·Dezhong Plaza Torch Development Zone Zhongshan·Guangdong\r
-                               ZhongShan  GuangDong  528437\r
-                               CN\r
+88-1F-A1   (hex)               Apple, Inc.\r
+881FA1     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-2C-27-D7   (hex)               Hewlett Packard\r
-2C27D7     (base 16)           Hewlett Packard\r
-                               11445 Compaq Center Drive\r
-                               Houston    77070\r
+04-DB-56   (hex)               Apple, Inc.\r
+04DB56     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-00-0F-3D   (hex)               D-Link Corporation\r
-000F3D     (base 16)           D-Link Corporation\r
-                               No.8,Li-shing Seventh Road,Science-based Industrial Park,Hsimchu,\r
-                               Hsimchu    300\r
-                               TW\r
+C8-1E-E7   (hex)               Apple, Inc.\r
+C81EE7     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-00-11-95   (hex)               D-Link Corporation\r
-001195     (base 16)           D-Link Corporation\r
-                               2F No. 233-2, Pao-Chiao Road\r
-                               Taipei  Taiwan  0000\r
-                               TW\r
+34-36-3B   (hex)               Apple, Inc.\r
+34363B     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-00-15-E9   (hex)               D-Link Corporation\r
-0015E9     (base 16)           D-Link Corporation\r
-                               2F, No.233-2, Pao-Chiao Road\r
-                               Hsin-Tien,  Taipei  231\r
-                               TW\r
+C0-1A-DA   (hex)               Apple, Inc.\r
+C01ADA     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-0C-FD-37   (hex)               SUSE Linux GmbH\r
-0CFD37     (base 16)           SUSE Linux GmbH\r
-                               Maxfeldstraße 5\r
-                               Nürnberg  Bavaria  90409\r
-                               DE\r
+80-CE-62   (hex)               Hewlett Packard\r
+80CE62     (base 16)           Hewlett Packard\r
+                               11445 Compaq Center Drive\r
+                               Houston  TX  77070\r
+                               US\r
 \r
-2C-FF-65   (hex)               Oki Electric Industry Co., Ltd.\r
-2CFF65     (base 16)           Oki Electric Industry Co., Ltd.\r
-                               1-7-12 Toranomon\r
-                               Tokyo 105-8460    \r
-                               JP\r
+80-1F-12   (hex)               Microchip Technology Inc.\r
+801F12     (base 16)           Microchip Technology Inc.\r
+                               2355 W. Chandler Blvd.\r
+                               Chandler  AZ  85224\r
+                               US\r
 \r
-00-1C-F0   (hex)               D-Link Corporation\r
-001CF0     (base 16)           D-Link Corporation\r
-                               NO.289, Sinhu 3rd Rd.,\r
-                               Neihu District,  Taipei City  114\r
-                               TW\r
+50-6C-BE   (hex)               InnosiliconTechnology Ltd\r
+506CBE     (base 16)           InnosiliconTechnology Ltd\r
+                               WuHan East Lake Wuhan New Technology Development Zone \r
+                               Wuhan  Hubei Province  430223\r
+                               CN\r
 \r
-00-26-5A   (hex)               D-Link Corporation\r
-00265A     (base 16)           D-Link Corporation\r
-                               No.289, Sinhu 3rd Rd.,\r
-                               Neihu District    114\r
-                               TW\r
+90-CC-24   (hex)               Synaptics, Inc\r
+90CC24     (base 16)           Synaptics, Inc\r
+                               1251 McKay Drive\r
+                               San Jose  CA   95131-1709\r
+                               US\r
 \r
-AC-F1-DF   (hex)               D-Link International\r
-ACF1DF     (base 16)           D-Link International\r
-                               1 International Business Park, #03-12, The Synergy \r
-                               SINGAPORE    609917\r
-                               SG\r
+80-41-26   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
+804126     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
+                               No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park\r
+                               Dongguan    523808\r
+                               CN\r
 \r
-FC-75-16   (hex)               D-Link International\r
-FC7516     (base 16)           D-Link International\r
-                               1 International Business Park, #03-12, The Synergy \r
-                               SINGAPORE    609917\r
-                               SG\r
+0C-C6-CC   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
+0CC6CC     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
+                               No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park\r
+                               Dongguan    523808\r
+                               CN\r
 \r
-7C-18-CD   (hex)               E-TRON Co.,Ltd.\r
-7C18CD     (base 16)           E-TRON Co.,Ltd.\r
-                               66-11, Nonhyeon 2-dong, Gangnam-gu\r
-                               Seoul    06049\r
-                               KR\r
+3C-04-61   (hex)               ARRIS Group, Inc.\r
+3C0461     (base 16)           ARRIS Group, Inc.\r
+                               6450 Sequence Drive\r
+                               San Diego  CA  92121\r
+                               US\r
 \r
-38-97-D6   (hex)               Hangzhou H3C Technologies Co., Limited\r
-3897D6     (base 16)           Hangzhou H3C Technologies Co., Limited\r
+04-C2-41   (hex)               Nokia\r
+04C241     (base 16)           Nokia\r
+                               600 March Road\r
+                               Kanata  Ontario  K2K 2E6\r
+                               CA\r
+\r
+30-7B-AC   (hex)               New H3C Technologies Co., Ltd\r
+307BAC     (base 16)           New H3C Technologies Co., Ltd\r
                                466 Changhe Road, Binjiang District\r
-                               Hangzhou  Zhejiang, P.R.China  310052\r
+                               Hangzhou  Zhejiang  310052\r
                                CN\r
 \r
-C8-47-8C   (hex)               Beken Corporation\r
-C8478C     (base 16)           Beken Corporation\r
-                               Building 41, Capital of Tech Leaders, 1387 Zhangdong Road, Zhangjiang High-Tech Park, Pudong New District\r
-                               Shanghai    201203\r
-                               CN\r
+8C-F7-73   (hex)               Nokia\r
+8CF773     (base 16)           Nokia\r
+                               600 March Road\r
+                               Kanata  Ontario  K2K 2E6\r
+                               CA\r
 \r
-E4-98-D6   (hex)               Apple, Inc.\r
-E498D6     (base 16)           Apple, Inc.\r
+3C-47-9B   (hex)               Theissen Training Systems, Inc.\r
+3C479B     (base 16)           Theissen Training Systems, Inc.\r
+                               1225 SE 4th Terrace\r
+                               Chiefland  FL  32626\r
+                               US\r
+\r
+70-5A-AC   (hex)               Samsung Electronics Co.,Ltd\r
+705AAC     (base 16)           Samsung Electronics Co.,Ltd\r
+                               #94-1, Imsoo-Dong\r
+                               Gumi  Gyeongbuk  730-350\r
+                               KR\r
+\r
+FC-64-3A   (hex)               Samsung Electronics Co.,Ltd\r
+FC643A     (base 16)           Samsung Electronics Co.,Ltd\r
+                               #94-1, Imsoo-Dong\r
+                               Gumi  Gyeongbuk  730-350\r
+                               KR\r
+\r
+D4-E6-B7   (hex)               Samsung Electronics Co.,Ltd\r
+D4E6B7     (base 16)           Samsung Electronics Co.,Ltd\r
+                               #94-1, Imsoo-Dong\r
+                               Gumi  Gyeongbuk  730-350\r
+                               KR\r
+\r
+28-02-D8   (hex)               Samsung Electronics Co.,Ltd\r
+2802D8     (base 16)           Samsung Electronics Co.,Ltd\r
+                               #94-1, Imsoo-Dong\r
+                               Gumi  Gyeongbuk  730-350\r
+                               KR\r
+\r
+C4-64-E3   (hex)               Texas Instruments\r
+C464E3     (base 16)           Texas Instruments\r
+                               12500 TI Blvd\r
+                               Dallas  TX  75243\r
+                               US\r
+\r
+F4-84-4C   (hex)               Texas Instruments\r
+F4844C     (base 16)           Texas Instruments\r
+                               12500 TI Blvd\r
+                               Dallas  TX  75243\r
+                               US\r
+\r
+00-08-89   (hex)               Dish Technologies Corp\r
+000889     (base 16)           Dish Technologies Corp\r
+                               94 Inverness Terrace E\r
+                               Englewood  CO  80112\r
+                               US\r
+\r
+6C-C4-D5   (hex)               HMD Global Oy\r
+6CC4D5     (base 16)           HMD Global Oy\r
+                               Karaportti 2\r
+                               Espoo    02610\r
+                               FI\r
+\r
+60-C5-47   (hex)               Apple, Inc.\r
+60C547     (base 16)           Apple, Inc.\r
                                1 Infinite Loop\r
                                Cupertino  CA  95014\r
                                US\r
 \r
-60-69-44   (hex)               Apple, Inc.\r
-606944     (base 16)           Apple, Inc.\r
+28-E0-2C   (hex)               Apple, Inc.\r
+28E02C     (base 16)           Apple, Inc.\r
                                1 Infinite Loop\r
                                Cupertino  CA  95014\r
                                US\r
 \r
-88-96-B6   (hex)               Global Fire Equipment S.A.\r
-8896B6     (base 16)           Global Fire Equipment S.A.\r
-                               Sitio dos Barrabés, Armazém Nave Y,\r
-                               São Brás de Alportel  Faro  8150-016\r
-                               PT\r
+50-EA-D6   (hex)               Apple, Inc.\r
+50EAD6     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-18-87-96   (hex)               HTC Corporation\r
-188796     (base 16)           HTC Corporation\r
-                               No. 23, Xinghua Rd., Taoyuan City\r
-                               Taoyuan County  Taiwan  330\r
-                               TW\r
+48-60-BC   (hex)               Apple, Inc.\r
+4860BC     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-AC-2A-0C   (hex)               CSR ZHUZHOU INSTITUTE CO.,LTD.\r
-AC2A0C     (base 16)           CSR ZHUZHOU INSTITUTE CO.,LTD.\r
-                               Times Ave.,Zhuzhou,hunan,China\r
-                               zhuzhou  Hunan  412001\r
-                               CN\r
+40-30-04   (hex)               Apple, Inc.\r
+403004     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-F4-CA-24   (hex)               FreeBit Co., Ltd.\r
-F4CA24     (base 16)           FreeBit Co., Ltd.\r
-                               E.Space Tower 3-6 Maruyama-Cho\r
-                               Shibuya-ku  Tokyo  150-0044\r
-                               JP\r
+0C-74-C2   (hex)               Apple, Inc.\r
+0C74C2     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-00-0A-57   (hex)               Hewlett Packard\r
-000A57     (base 16)           Hewlett Packard\r
-                               10955 Tantau Avenue\r
+A4-B1-97   (hex)               Apple, Inc.\r
+A4B197     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
                                Cupertino  CA  95014\r
                                US\r
 \r
-64-31-50   (hex)               Hewlett Packard\r
-643150     (base 16)           Hewlett Packard\r
-                               11445 Compaq Center Drive\r
-                               Houston    77070\r
+7C-F0-5F   (hex)               Apple, Inc.\r
+7CF05F     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-00-23-76   (hex)               HTC Corporation\r
-002376     (base 16)           HTC Corporation\r
-                               No.23 Xinghua Road\r
-                               Taoyuan County    330\r
-                               TW\r
+78-6C-1C   (hex)               Apple, Inc.\r
+786C1C     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-00-07-E9   (hex)               Intel Corporation\r
-0007E9     (base 16)           Intel Corporation\r
-                               2111 NE 25th Avenue\r
-                               Hillsboro  OR  97124\r
+BC-3B-AF   (hex)               Apple, Inc.\r
+BC3BAF     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-B4-6D-83   (hex)               Intel Corporate\r
-B46D83     (base 16)           Intel Corporate\r
-                               Lot 8, Jalan Hi-Tech 2/3\r
-                               Kulim  Kedah  09000\r
-                               MY\r
+F0-D1-A9   (hex)               Apple, Inc.\r
+F0D1A9     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-E4-FA-FD   (hex)               Intel Corporate\r
-E4FAFD     (base 16)           Intel Corporate\r
-                               Lot 8, Jalan Hi-Tech 2/3\r
-                               Kulim  Kedah  09000\r
-                               MY\r
+34-C0-59   (hex)               Apple, Inc.\r
+34C059     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-DC-53-60   (hex)               Intel Corporate\r
-DC5360     (base 16)           Intel Corporate\r
-                               Lot 8, Jalan Hi-Tech 2/3\r
-                               Kulim  Kedah  09000\r
-                               MY\r
+04-F7-E4   (hex)               Apple, Inc.\r
+04F7E4     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-78-0C-B8   (hex)               Intel Corporate\r
-780CB8     (base 16)           Intel Corporate\r
-                               Lot 8, Jalan Hi-Tech 2/3\r
-                               Kulim  Kedah  09000\r
-                               MY\r
+10-DD-B1   (hex)               Apple, Inc.\r
+10DDB1     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-48-45-20   (hex)               Intel Corporate\r
-484520     (base 16)           Intel Corporate\r
-                               Lot 8, Jalan Hi-Tech 2/3\r
-                               Kulim  Kedah  09000\r
-                               MY\r
+B4-F0-AB   (hex)               Apple, Inc.\r
+B4F0AB     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-00-40-26   (hex)               BUFFALO.INC\r
-004026     (base 16)           BUFFALO.INC\r
-                               AKAMONDORI Bldg., 30-20,Ohsu 3-chome\r
-                               Naka-ku,Nagoya  Aichi Pref.  460-8315\r
-                               JP\r
+00-A0-40   (hex)               Apple, Inc.\r
+00A040     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-00-02-A5   (hex)               Hewlett Packard\r
-0002A5     (base 16)           Hewlett Packard\r
-                               20555 State Highway 249\r
-                               Houston  TX  77070\r
+60-FE-C5   (hex)               Apple, Inc.\r
+60FEC5     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-A0-2B-B8   (hex)               Hewlett Packard\r
-A02BB8     (base 16)           Hewlett Packard\r
-                               11445 Compaq Center Drive\r
-                               Houston    77070\r
+CC-44-63   (hex)               Apple, Inc.\r
+CC4463     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-6C-C2-17   (hex)               Hewlett Packard\r
-6CC217     (base 16)           Hewlett Packard\r
-                               11445 Compaq Center Drive\r
-                               Houston    77070\r
+6C-72-E7   (hex)               Apple, Inc.\r
+6C72E7     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-38-63-BB   (hex)               Hewlett Packard\r
-3863BB     (base 16)           Hewlett Packard\r
-                               11445 Compaq Center Drive\r
-                               Houston    77070\r
+18-AF-61   (hex)               Apple, Inc.\r
+18AF61     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-CC-3E-5F   (hex)               Hewlett Packard\r
-CC3E5F     (base 16)           Hewlett Packard\r
-                               11445 Compaq Center Drive\r
-                               Houston    77070\r
+00-CD-FE   (hex)               Apple, Inc.\r
+00CDFE     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-74-46-A0   (hex)               Hewlett Packard\r
-7446A0     (base 16)           Hewlett Packard\r
-                               11445 Compaq Center Drive\r
-                               Houston    77070\r
+30-10-E4   (hex)               Apple, Inc.\r
+3010E4     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-44-31-92   (hex)               Hewlett Packard\r
-443192     (base 16)           Hewlett Packard\r
-                               11445 Compaq Center Drive\r
-                               Houston    77070\r
+38-0F-4A   (hex)               Apple, Inc.\r
+380F4A     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-FC-15-B4   (hex)               Hewlett Packard\r
-FC15B4     (base 16)           Hewlett Packard\r
-                               11445 Compaq Center Drive\r
-                               Houston    77070\r
+68-5B-35   (hex)               Apple, Inc.\r
+685B35     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-EC-9A-74   (hex)               Hewlett Packard\r
-EC9A74     (base 16)           Hewlett Packard\r
-                               11445 Compaq Center Drive\r
-                               Houston    77070\r
+C8-6F-1D   (hex)               Apple, Inc.\r
+C86F1D     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-80-C1-6E   (hex)               Hewlett Packard\r
-80C16E     (base 16)           Hewlett Packard\r
-                               11445 Compaq Center Drive\r
-                               Houston    77070\r
+70-11-24   (hex)               Apple, Inc.\r
+701124     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-D0-7E-28   (hex)               Hewlett Packard\r
-D07E28     (base 16)           Hewlett Packard\r
-                               11445 Compaq Center Drive\r
-                               Houston    77070\r
+38-48-4C   (hex)               Apple, Inc.\r
+38484C     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-74-03-BD   (hex)               BUFFALO.INC\r
-7403BD     (base 16)           BUFFALO.INC\r
-                                AKAMONDORI Bldg, 30-20, Ohsu 3-chome,\r
-                               Minami-ku, Nagoya  Aichi Pref.  457-8520\r
-                               JP\r
+04-15-52   (hex)               Apple, Inc.\r
+041552     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-10-1F-74   (hex)               Hewlett Packard\r
-101F74     (base 16)           Hewlett Packard\r
-                               11445 Compaq Center Drive\r
-                               Houston    77070\r
+40-A6-D9   (hex)               Apple, Inc.\r
+40A6D9     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-00-1A-4B   (hex)               Hewlett Packard\r
-001A4B     (base 16)           Hewlett Packard\r
-                               20555 State Highway 249\r
-                               Houston  TX  77070\r
+10-9A-DD   (hex)               Apple, Inc.\r
+109ADD     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-00-1F-29   (hex)               Hewlett Packard\r
-001F29     (base 16)           Hewlett Packard\r
-                               20555 State Highway 249\r
-                               Houston  TX  77070\r
+F0-B4-79   (hex)               Apple, Inc.\r
+F0B479     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-00-21-5A   (hex)               Hewlett Packard\r
-00215A     (base 16)           Hewlett Packard\r
-                               20555 State Highway 249\r
-                               Houston  TX  77070\r
+58-B0-35   (hex)               Apple, Inc.\r
+58B035     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-00-0F-61   (hex)               Hewlett Packard\r
-000F61     (base 16)           Hewlett Packard\r
-                               20555 State Highway 249\r
-                               Houston  TX  77070\r
+34-15-9E   (hex)               Apple, Inc.\r
+34159E     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-00-11-85   (hex)               Hewlett Packard\r
-001185     (base 16)           Hewlett Packard\r
-                               20555 State Highway 249\r
-                               Houston  TX  77070\r
+28-6A-BA   (hex)               Apple, Inc.\r
+286ABA     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-00-12-79   (hex)               Hewlett Packard\r
-001279     (base 16)           Hewlett Packard\r
-                               20555 State Highway 249\r
-                               Houston  TX  77070\r
+EC-85-2F   (hex)               Apple, Inc.\r
+EC852F     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-00-17-08   (hex)               Hewlett Packard\r
-001708     (base 16)           Hewlett Packard\r
-                               20555 State Highway 249\r
-                               Houston  TX  77070\r
+44-D8-84   (hex)               Apple, Inc.\r
+44D884     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-28-32-C5   (hex)               HUMAX Co., Ltd.\r
-2832C5     (base 16)           HUMAX Co., Ltd.\r
-                               HUMAX Village,216,Hwangsaeul-ro,Bundang-gu\r
-                               Seongnam-si  Gyeonggi-do  463-875\r
-                               KR\r
+00-3E-E1   (hex)               Apple, Inc.\r
+003EE1     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-EC-4D-47   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
-EC4D47     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
-                               No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park\r
-                               Dongguan    523808\r
-                               CN\r
+7C-11-BE   (hex)               Apple, Inc.\r
+7C11BE     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-88-CF-98   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
-88CF98     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
-                               No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park\r
-                               Dongguan    523808\r
-                               CN\r
+28-F0-76   (hex)               Apple, Inc.\r
+28F076     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-6C-E3-B6   (hex)               Nera Telecommunications Ltd.\r
-6CE3B6     (base 16)           Nera Telecommunications Ltd.\r
-                               109 Defu Lane 10\r
-                               Singapore  Singapore  539225\r
-                               SG\r
+28-5A-EB   (hex)               Apple, Inc.\r
+285AEB     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-94-2C-B3   (hex)               HUMAX Co., Ltd.\r
-942CB3     (base 16)           HUMAX Co., Ltd.\r
-                               HUMAX Village, 216, Hwangsaeul-ro, Bu\r
-                               Seongnam-si  Gyeonggi-do  463-875\r
-                               KR\r
+08-74-02   (hex)               Apple, Inc.\r
+087402     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-04-52-F3   (hex)               Apple, Inc.\r
-0452F3     (base 16)           Apple, Inc.\r
+64-B9-E8   (hex)               Apple, Inc.\r
+64B9E8     (base 16)           Apple, Inc.\r
                                1 Infinite Loop\r
                                Cupertino  CA  95014\r
                                US\r
 \r
-24-1E-EB   (hex)               Apple, Inc.\r
-241EEB     (base 16)           Apple, Inc.\r
+00-1C-B3   (hex)               Apple, Inc.\r
+001CB3     (base 16)           Apple, Inc.\r
                                1 Infinite Loop\r
                                Cupertino  CA  95014\r
                                US\r
 \r
-F4-31-C3   (hex)               Apple, Inc.\r
-F431C3     (base 16)           Apple, Inc.\r
+00-0D-93   (hex)               Apple, Inc.\r
+000D93     (base 16)           Apple, Inc.\r
                                1 Infinite Loop\r
                                Cupertino  CA  95014\r
                                US\r
 \r
-C8-7B-5B   (hex)               zte corporation\r
-C87B5B     (base 16)           zte corporation\r
-                               12/F.,zte R&D building,kejinan Road,\r
-                               shenzhen  guangdong  518057\r
-                               CN\r
+CC-C7-60   (hex)               Apple, Inc.\r
+CCC760     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-98-F5-37   (hex)               zte corporation\r
-98F537     (base 16)           zte corporation\r
-                               12/F.,zte R&D building,kejinan Road,\r
-                               shenzhen  guangdong  518057\r
-                               CN\r
+9C-FC-01   (hex)               Apple, Inc.\r
+9CFC01     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-00-1E-73   (hex)               zte corporation\r
-001E73     (base 16)           zte corporation\r
-                               12/F ZTE Plaza,Keji Road South,Hi-Tech Industrial Park,Nanshan District,\r
-                               Shenzhen  GUANGDONG  518057\r
-                               CN\r
+AC-BC-32   (hex)               Apple, Inc.\r
+ACBC32     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-00-19-C6   (hex)               zte corporation\r
-0019C6     (base 16)           zte corporation\r
-                               Technology Management Department, \r
-                               Shenzhen  Guangdong  518057\r
-                               CN\r
+A8-BE-27   (hex)               Apple, Inc.\r
+A8BE27     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-00-15-EB   (hex)               zte corporation\r
-0015EB     (base 16)           zte corporation\r
-                               5/F,A Wing,ZTE Plaza,Keji Road South,Hi-Tech Industrial Park,Nanshan District\r
-                               Shenzhen    518057\r
+B8-63-4D   (hex)               Apple, Inc.\r
+B8634D     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-F0-EB-D0   (hex)               Shanghai Feixun Communication Co.,Ltd.\r
-F0EBD0     (base 16)           Shanghai Feixun Communication Co.,Ltd.\r
-                               Building 90,No,4855,Guangfulin Road\r
-                               shanghai  Shanghai  201616\r
-                               CN\r
+9C-E3-3F   (hex)               Apple, Inc.\r
+9CE33F     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-D8-49-0B   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
-D8490B     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
-                               D1,Huawei Industrial Base,Bantian,Longgang,Shenzhen\r
-                               Shenzhen    518129\r
-                               CN\r
+F0-98-9D   (hex)               Apple, Inc.\r
+F0989D     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-88-86-03   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
-888603     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
-                               D1,Huawei Industrial Base,Bantian,Longgang,Shenzhen\r
-                               Shenzhen    518129\r
-                               CN\r
+AC-E4-B5   (hex)               Apple, Inc.\r
+ACE4B5     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-F8-E8-11   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
-F8E811     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
-                               D1,Huawei Industrial Base,Bantian,Longgang,Shenzhen\r
-                               Shenzhen  Guangdong  518129\r
-                               CN\r
+E4-2B-34   (hex)               Apple, Inc.\r
+E42B34     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-E0-97-96   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
-E09796     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
-                               D1,Huawei Industrial Base,Bantian,Longgang,Shenzhen\r
-                               Shenzhen  Guangdong  518129\r
-                               CN\r
+1C-36-BB   (hex)               Apple, Inc.\r
+1C36BB     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-CC-CC-81   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
-CCCC81     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
+3C-2E-FF   (hex)               Apple, Inc.\r
+3C2EFF     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+F0-76-6F   (hex)               Apple, Inc.\r
+F0766F     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+40-CB-C0   (hex)               Apple, Inc.\r
+40CBC0     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+40-98-AD   (hex)               Apple, Inc.\r
+4098AD     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+6C-4D-73   (hex)               Apple, Inc.\r
+6C4D73     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+C4-84-66   (hex)               Apple, Inc.\r
+C48466     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+D0-2B-20   (hex)               Apple, Inc.\r
+D02B20     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+70-70-0D   (hex)               Apple, Inc.\r
+70700D     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+7C-50-49   (hex)               Apple, Inc.\r
+7C5049     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+50-32-37   (hex)               Apple, Inc.\r
+503237     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+D4-61-9D   (hex)               Apple, Inc.\r
+D4619D     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+B0-48-1A   (hex)               Apple, Inc.\r
+B0481A     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+98-9E-63   (hex)               Apple, Inc.\r
+989E63     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+DC-A9-04   (hex)               Apple, Inc.\r
+DCA904     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+48-A1-95   (hex)               Apple, Inc.\r
+48A195     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+6C-AB-31   (hex)               Apple, Inc.\r
+6CAB31     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+6C-96-CF   (hex)               Apple, Inc.\r
+6C96CF     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+30-35-AD   (hex)               Apple, Inc.\r
+3035AD     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+AC-61-EA   (hex)               Apple, Inc.\r
+AC61EA     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+38-B5-4D   (hex)               Apple, Inc.\r
+38B54D     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+A4-F1-E8   (hex)               Apple, Inc.\r
+A4F1E8     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+70-A2-B3   (hex)               Apple, Inc.\r
+70A2B3     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+4C-57-CA   (hex)               Apple, Inc.\r
+4C57CA     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+68-FB-7E   (hex)               Apple, Inc.\r
+68FB7E     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+90-C1-C6   (hex)               Apple, Inc.\r
+90C1C6     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+9C-F4-8E   (hex)               Apple, Inc.\r
+9CF48E     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+FC-D8-48   (hex)               Apple, Inc.\r
+FCD848     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+84-85-06   (hex)               Apple, Inc.\r
+848506     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+68-96-7B   (hex)               Apple, Inc.\r
+68967B     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+BC-67-78   (hex)               Apple, Inc.\r
+BC6778     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+A8-20-66   (hex)               Apple, Inc.\r
+A82066     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+B0-65-BD   (hex)               Apple, Inc.\r
+B065BD     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+F0-DC-E2   (hex)               Apple, Inc.\r
+F0DCE2     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+7C-D1-C3   (hex)               Apple, Inc.\r
+7CD1C3     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+70-56-81   (hex)               Apple, Inc.\r
+705681     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+1C-A0-B8   (hex)               Hon Hai Precision Ind. Co., Ltd.\r
+1CA0B8     (base 16)           Hon Hai Precision Ind. Co., Ltd.\r
+                               GuangDongShenZhen\r
+                               ShenZhen  GuangDong  518109\r
+                               CN\r
+\r
+E8-C1-B8   (hex)                Nanjing Bangzhong Electronic Commerce Limited\r
+E8C1B8     (base 16)            Nanjing Bangzhong Electronic Commerce Limited\r
+                               No.22, Liuzhou East Road, High - tech Zone\r
+                               Nanjing    210000\r
+                               CN\r
+\r
+1C-B0-44   (hex)               ASKEY COMPUTER CORP\r
+1CB044     (base 16)           ASKEY COMPUTER CORP\r
+                               10F,No.119,JIANKANG RD,ZHONGHE DIST\r
+                               NEW TAIPEI  TAIWAN  23585\r
+                               TW\r
+\r
+90-03-72   (hex)               Longnan Junya Digital Technology Co. Ltd. \r
+900372     (base 16)           Longnan Junya Digital Technology Co. Ltd. \r
+                               Champion Asia Road, Xinzhen industrial Park, Longnan national economic and technological development zone, Ganzhou city, JiangXi Province , China\r
+                               ganzhou  jiangxi  341700\r
+                               CN\r
+\r
+F0-41-C8   (hex)               IEEE Registration Authority\r
+F041C8     (base 16)           IEEE Registration Authority\r
+                               445 Hoes Lane\r
+                               Piscataway  NJ  08554\r
+                               US\r
+\r
+A4-38-CC   (hex)               Nintendo Co.,Ltd\r
+A438CC     (base 16)           Nintendo Co.,Ltd\r
+                               11-1 HOKOTATE-CHO KAMITOBA,MINAMI-KU\r
+                               KYOTO  KYOTO  601-8501\r
+                               JP\r
+\r
+94-6A-B0   (hex)               Arcadyan Corporation\r
+946AB0     (base 16)           Arcadyan Corporation\r
+                               No.8, Sec.2, Guangfu Rd.\r
+                               Hsinchu City  Hsinchu  30071\r
+                               TW\r
+\r
+B4-DE-31   (hex)               Cisco Systems, Inc\r
+B4DE31     (base 16)           Cisco Systems, Inc\r
+                               80 West Tasman Drive\r
+                               San Jose  CA  94568\r
+                               US\r
+\r
+70-16-9F   (hex)               EtherCAT Technology Group\r
+70169F     (base 16)           EtherCAT Technology Group\r
+                               Ostendstr. 196\r
+                               NUremberg    90482\r
+                               DE\r
+\r
+64-98-29   (hex)               Integrated Device Technology (Malaysia) Sdn. Bhd.\r
+649829     (base 16)           Integrated Device Technology (Malaysia) Sdn. Bhd.\r
+                               Phase 3, Bayan Lepas FIZ\r
+                               Bayan Lepas  Penang  11900\r
+                               MY\r
+\r
+08-1D-C4   (hex)               Thermo Fisher Scientific Messtechnik GmbH\r
+081DC4     (base 16)           Thermo Fisher Scientific Messtechnik GmbH\r
+                               Frauenauracher Strasse 96\r
+                               Erlangen    91056\r
+                               DE\r
+\r
+68-98-61   (hex)               Beacon Inc\r
+689861     (base 16)           Beacon Inc\r
+                               82-1, Anyangcheondong-ro, Dongan-gu\r
+                               anyang  Gyeonggi-do  14042\r
+                               KR\r
+\r
+88-B3-62   (hex)               Nokia Shanghai Bell Co. Ltd.)\r
+88B362     (base 16)           Nokia Shanghai Bell Co. Ltd.)\r
+                               No.388 Ning Qiao Road,Jin Qiao Pudong Shanghai 201206,P.R.China\r
+                               Shanghai   Pudong  201206\r
+                               CN\r
+\r
+10-A4-B9   (hex)               Baidu Online Network Technology (Beijing) Co., Ltd\r
+10A4B9     (base 16)           Baidu Online Network Technology (Beijing) Co., Ltd\r
+                               Baidu Campus, No.10 Shangdi 10th Street, Haidian District\r
+                                Beijing    100085\r
+                               CN\r
+\r
+34-7E-CA   (hex)               NEXTWILL\r
+347ECA     (base 16)           NEXTWILL\r
+                               JJ-Building, 20, Deongmyeong-ro 71beon-gil1, Yuseong-gu\r
+                               Daejeon    34155\r
+                               KR\r
+\r
+50-14-79   (hex)               iRobot Corporation \r
+501479     (base 16)           iRobot Corporation \r
+                               8 Crosby Drive\r
+                               Bedford  MA  01730\r
+                               US\r
+\r
+60-84-BD   (hex)               BUFFALO.INC\r
+6084BD     (base 16)           BUFFALO.INC\r
+                               AKAMONDORI Bld.,30-20,Ohsu 3-chome,Naka-ku\r
+                               Nagoya  Aichi Pref.  460-8315\r
+                               JP\r
+\r
+10-F9-EB   (hex)               Industria Fueguina de Relojería Electrónica s.a.\r
+10F9EB     (base 16)           Industria Fueguina de Relojería Electrónica s.a.\r
+                               Sarmiento 2920\r
+                               Rio Grande  Tierra de Fuego  V9420GIV\r
+                               AR\r
+\r
+B8-94-36   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
+B89436     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
+                               No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park\r
+                               Dongguan    523808\r
+                               CN\r
+\r
+F8-DF-15   (hex)               Sunitec Enterprise Co.,Ltd\r
+F8DF15     (base 16)           Sunitec Enterprise Co.,Ltd\r
+                               3F.,No.98-1,Mincyuan Rd.Sindian City\r
+                               Taipei County 231    231141\r
+                               CN\r
+\r
+A8-DA-01   (hex)               Shenzhen NUOLIJIA Digital Technology Co.,Ltd\r
+A8DA01     (base 16)           Shenzhen NUOLIJIA Digital Technology Co.,Ltd\r
+                               A Area of The Second Flood and D Area of The First Floor,Factory Building A,Youxinda Industrial Park,Gengyu Road,Tianliao Community,Gongming Street Office,Guangming New District,Shenzhen City,Guangdong,P.R.China\r
+                               Shenzhen  Guangdong  518000\r
+                               CN\r
+\r
+90-94-97   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
+909497     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
+                               No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park\r
+                               Dongguan    523808\r
+                               CN\r
+\r
+EC-89-14   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
+EC8914     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
+                               No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park\r
+                               Dongguan    523808\r
+                               CN\r
+\r
+DC-72-9B   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
+DC729B     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
+                               No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park\r
+                               Dongguan    523808\r
+                               CN\r
+\r
+5C-5A-EA   (hex)               FORD\r
+5C5AEA     (base 16)           FORD\r
+                               17425 Federal Drive \r
+                               Allen Park  MI  48101\r
+                               US\r
+\r
+5C-AA-FD   (hex)               Sonos, Inc.\r
+5CAAFD     (base 16)           Sonos, Inc.\r
+                               614 Chapala St\r
+                               Santa Barbara  CA  93101\r
+                               US\r
+\r
+00-0E-58   (hex)               Sonos, Inc.\r
+000E58     (base 16)           Sonos, Inc.\r
+                               614 Chapala St\r
+                               Santa Barbara  CA  93101\r
+                               US\r
+\r
+88-29-50   (hex)               Netmoon Technology Co., Ltd\r
+882950     (base 16)           Netmoon Technology Co., Ltd\r
+                               2nd Floor, Building No.1, NO.319, Qingpi Avenue\r
+                               Wenjiang District  Chengdu  611130\r
+                               CN\r
+\r
+00-21-94   (hex)               Ping Communication\r
+002194     (base 16)           Ping Communication\r
+                               Brenden 18\r
+                               Appenzell Meistersrüte  AI  9050\r
+                               CH\r
+\r
+7C-FF-4D   (hex)               AVM Audiovisuelles Marketing und Computersysteme GmbH\r
+7CFF4D     (base 16)           AVM Audiovisuelles Marketing und Computersysteme GmbH\r
+                               Alt-Moabit 95\r
+                               Berlin  Berlin  10559\r
+                               DE\r
+\r
+74-70-FD   (hex)               Intel Corporate\r
+7470FD     (base 16)           Intel Corporate\r
+                               Lot 8, Jalan Hi-Tech 2/3\r
+                               Kulim  Kedah  09000\r
+                               MY\r
+\r
+CC-99-16   (hex)               Integrated Device Technology (Malaysia) Sdn. Bhd.\r
+CC9916     (base 16)           Integrated Device Technology (Malaysia) Sdn. Bhd.\r
+                               Phase 3, Bayan Lepas FIZ\r
+                               Bayan Lepas  Penang  11900\r
+                               MY\r
+\r
+A4-50-55   (hex)               BUSWARE.DE\r
+A45055     (base 16)           BUSWARE.DE\r
+                               Lindenstrasse 18\r
+                               Scharbeutz    23684\r
+                               DE\r
+\r
+00-13-86   (hex)               ABB Inc/Totalflow\r
+001386     (base 16)           ABB Inc/Totalflow\r
+                               \r
+                               Bartlesville  OK  74006\r
+                               US\r
+\r
+A0-66-10   (hex)               FUJITSU LIMITED\r
+A06610     (base 16)           FUJITSU LIMITED\r
+                               Mushashi-kosuge Tower Place 13F\r
+                               Kawasaki  Kanagawa  211-0063\r
+                               JP\r
+\r
+64-CB-5D   (hex)               SIA TeleSet\r
+64CB5D     (base 16)           SIA TeleSet\r
+                               Krāslavas iela 5\r
+                               Vecstropi, Naujenes par., Daugavpils distr.    LV-5413\r
+                               LV\r
+\r
+70-69-5A   (hex)               Cisco Systems, Inc\r
+70695A     (base 16)           Cisco Systems, Inc\r
+                               80 West Tasman Drive\r
+                               San Jose  CA  94568\r
+                               US\r
+\r
+58-21-E9   (hex)               TWPI\r
+5821E9     (base 16)           TWPI\r
+                               PMB# 335; 1121 Annapolis Road\r
+                               Odenton  MD  21113\r
+                               US\r
+\r
+68-D4-82   (hex)               SHENZHEN GONGJIN ELECTRONICS CO.,LT\r
+68D482     (base 16)           SHENZHEN GONGJIN ELECTRONICS CO.,LT\r
+                               SONGGANG\r
+                               SHENZHEN  GUANGDONG  518105\r
+                               CN\r
+\r
+30-1F-9A   (hex)               IEEE Registration Authority\r
+301F9A     (base 16)           IEEE Registration Authority\r
+                               445 Hoes Lane\r
+                               Piscataway  NJ  08554\r
+                               US\r
+\r
+90-79-10   (hex)               Integrated Device Technology (Malaysia) Sdn. Bhd.\r
+907910     (base 16)           Integrated Device Technology (Malaysia) Sdn. Bhd.\r
+                               Phase 3, Bayan Lepas FIZ\r
+                               Bayan Lepas  Penang  11900\r
+                               MY\r
+\r
+00-A0-D5   (hex)               Sierra Wireless Inc\r
+00A0D5     (base 16)           Sierra Wireless Inc\r
+                               13811 Wireless Way\r
+                                 RICHMOND B.C.  V6V 3A4\r
+                               CA\r
+\r
+0C-6F-9C   (hex)               Shaw Communications Inc.\r
+0C6F9C     (base 16)           Shaw Communications Inc.\r
+                               Suite 900, 630 3rd Avenue S.W.\r
+                               CALGARY  ALBERTA  T2P 4L4\r
+                               CA\r
+\r
+18-01-E3   (hex)               Bittium Wireless Ltd\r
+1801E3     (base 16)           Bittium Wireless Ltd\r
+                               Tutkijantie 8\r
+                               Oulu    50590\r
+                               FI\r
+\r
+C0-AC-54   (hex)               Sagemcom Broadband SAS\r
+C0AC54     (base 16)           Sagemcom Broadband SAS\r
+                               250 route de l'Empereur\r
+                               Rueil Malmaison  HAUTS DE SEINE  92848\r
+                               FR\r
+\r
+40-F2-01   (hex)               Sagemcom Broadband SAS\r
+40F201     (base 16)           Sagemcom Broadband SAS\r
+                               250 route de l'Empereur\r
+                               Rueil Malmaison  HAUTS DE SEINE  92848\r
+                               FR\r
+\r
+C8-91-F9   (hex)               Sagemcom Broadband SAS\r
+C891F9     (base 16)           Sagemcom Broadband SAS\r
+                               250 route de l'Empereur\r
+                               Rueil Malmaison  HAUTS DE SEINE  92848\r
+                               FR\r
+\r
+4C-FF-12   (hex)               Fuze Entertainment Co., ltd\r
+4CFF12     (base 16)           Fuze Entertainment Co., ltd\r
+                               3rd Floor Harbour Centre\r
+                               George Town  George Town  P.O. Box 613GT\r
+                               KY\r
+\r
+00-59-AC   (hex)               KPN. B.V.\r
+0059AC     (base 16)           KPN. B.V.\r
+                               Maanplein 55\r
+                               Den Haag  Zuid holland  2516 CK\r
+                               NL\r
+\r
+AC-9A-22   (hex)               NXP Semiconductors\r
+AC9A22     (base 16)           NXP Semiconductors\r
+                               411 E. Plumeria Drive\r
+                               San Jose  CA  95134\r
+                               US\r
+\r
+00-60-37   (hex)               NXP Semiconductors\r
+006037     (base 16)           NXP Semiconductors\r
+                               High Tech Campus 32, Office 1.21\r
+                               SAF  AD  13456\r
+                               NL\r
+\r
+54-60-09   (hex)               Google, Inc.\r
+546009     (base 16)           Google, Inc.\r
+                               1600 Amphitheatre Parkway\r
+                               Mountain View  CA  94043\r
+                               US\r
+\r
+A4-77-33   (hex)               Google, Inc.\r
+A47733     (base 16)           Google, Inc.\r
+                               1600 Ampitheatre Parkway\r
+                               Mountain View    94043\r
+                               US\r
+\r
+94-EB-2C   (hex)               Google, Inc.\r
+94EB2C     (base 16)           Google, Inc.\r
+                               1600 Amphitheatre Parkway\r
+                               Mountain View    94043\r
+                               US\r
+\r
+28-BC-56   (hex)               EMAC, Inc.\r
+28BC56     (base 16)           EMAC, Inc.\r
+                               2390 EMAC Way\r
+                               Carbondale  IL  62902\r
+                               US\r
+\r
+28-7C-DB   (hex)               Hefei  Toycloud Technology Co.,ltd\r
+287CDB     (base 16)           Hefei  Toycloud Technology Co.,ltd\r
+                               FLOOR 13,XUNFEI BUILDING,NO.666 WANGJIANG ROAD,HIGH & NEW TECHNOLOGY DEVELOPMENT ZONE.HEFEI.\r
+                               Hefei  Anhui  230088\r
+                               CN\r
+\r
+D0-B3-3F   (hex)               Shenzhen TINNO Mobile Technology Corp.\r
+D0B33F     (base 16)           Shenzhen TINNO Mobile Technology Corp.\r
+                               4/F.,H-3 Building,OCT Eastern lndustrial Park. NO.1 XiangShan East Road.,\r
+                               GUANGDONG  SHENZHEN  518053\r
+                               CN\r
+\r
+00-73-8D   (hex)               Shenzhen TINNO Mobile Technology Corp.\r
+00738D     (base 16)           Shenzhen TINNO Mobile Technology Corp.\r
+                               4/F.,H-3 Building,OCT Eastern lndustrial Park. NO.1 XiangShan East Road.\r
+                               GuangDong    518053\r
+                               US\r
+\r
+A8-CA-7B   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
+A8CA7B     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
+                               No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park\r
+                               Dongguan    523808\r
+                               CN\r
+\r
+AC-CF-85   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
+ACCF85     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
+                               No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park\r
+                               Dongguan  Guangdong  523808 \r
+                               CN\r
+\r
+24-35-CC   (hex)               Zhongshan Scinan Internet of Things Co.,Ltd.\r
+2435CC     (base 16)           Zhongshan Scinan Internet of Things Co.,Ltd.\r
+                               15/F Bldg 1·Dezhong Plaza Torch Development Zone Zhongshan·Guangdong\r
+                               ZhongShan  GuangDong  528437\r
+                               CN\r
+\r
+2C-27-D7   (hex)               Hewlett Packard\r
+2C27D7     (base 16)           Hewlett Packard\r
+                               11445 Compaq Center Drive\r
+                               Houston    77070\r
+                               US\r
+\r
+00-0F-3D   (hex)               D-Link Corporation\r
+000F3D     (base 16)           D-Link Corporation\r
+                               No.8,Li-shing Seventh Road,Science-based Industrial Park,Hsimchu,\r
+                               Hsimchu    300\r
+                               TW\r
+\r
+00-11-95   (hex)               D-Link Corporation\r
+001195     (base 16)           D-Link Corporation\r
+                               2F No. 233-2, Pao-Chiao Road\r
+                               Taipei  Taiwan  0000\r
+                               TW\r
+\r
+00-15-E9   (hex)               D-Link Corporation\r
+0015E9     (base 16)           D-Link Corporation\r
+                               2F, No.233-2, Pao-Chiao Road\r
+                               Hsin-Tien,  Taipei  231\r
+                               TW\r
+\r
+0C-FD-37   (hex)               SUSE Linux GmbH\r
+0CFD37     (base 16)           SUSE Linux GmbH\r
+                               Maxfeldstraße 5\r
+                               Nürnberg  Bavaria  90409\r
+                               DE\r
+\r
+2C-FF-65   (hex)               Oki Electric Industry Co., Ltd.\r
+2CFF65     (base 16)           Oki Electric Industry Co., Ltd.\r
+                               1-7-12 Toranomon\r
+                               Tokyo 105-8460    \r
+                               JP\r
+\r
+00-1C-F0   (hex)               D-Link Corporation\r
+001CF0     (base 16)           D-Link Corporation\r
+                               NO.289, Sinhu 3rd Rd.,\r
+                               Neihu District,  Taipei City  114\r
+                               TW\r
+\r
+00-26-5A   (hex)               D-Link Corporation\r
+00265A     (base 16)           D-Link Corporation\r
+                               No.289, Sinhu 3rd Rd.,\r
+                               Neihu District    114\r
+                               TW\r
+\r
+AC-F1-DF   (hex)               D-Link International\r
+ACF1DF     (base 16)           D-Link International\r
+                               1 International Business Park, #03-12, The Synergy \r
+                               SINGAPORE    609917\r
+                               SG\r
+\r
+FC-75-16   (hex)               D-Link International\r
+FC7516     (base 16)           D-Link International\r
+                               1 International Business Park, #03-12, The Synergy \r
+                               SINGAPORE    609917\r
+                               SG\r
+\r
+7C-18-CD   (hex)               E-TRON Co.,Ltd.\r
+7C18CD     (base 16)           E-TRON Co.,Ltd.\r
+                               66-11, Nonhyeon 2-dong, Gangnam-gu\r
+                               Seoul    06049\r
+                               KR\r
+\r
+38-97-D6   (hex)               Hangzhou H3C Technologies Co., Limited\r
+3897D6     (base 16)           Hangzhou H3C Technologies Co., Limited\r
+                               466 Changhe Road, Binjiang District\r
+                               Hangzhou  Zhejiang, P.R.China  310052\r
+                               CN\r
+\r
+C8-47-8C   (hex)               Beken Corporation\r
+C8478C     (base 16)           Beken Corporation\r
+                               Building 41, Capital of Tech Leaders, 1387 Zhangdong Road, Zhangjiang High-Tech Park, Pudong New District\r
+                               Shanghai    201203\r
+                               CN\r
+\r
+88-96-B6   (hex)               Global Fire Equipment S.A.\r
+8896B6     (base 16)           Global Fire Equipment S.A.\r
+                               Sitio dos Barrabés, Armazém Nave Y,\r
+                               São Brás de Alportel  Faro  8150-016\r
+                               PT\r
+\r
+18-87-96   (hex)               HTC Corporation\r
+188796     (base 16)           HTC Corporation\r
+                               No. 23, Xinghua Rd., Taoyuan City\r
+                               Taoyuan County  Taiwan  330\r
+                               TW\r
+\r
+AC-2A-0C   (hex)               CSR ZHUZHOU INSTITUTE CO.,LTD.\r
+AC2A0C     (base 16)           CSR ZHUZHOU INSTITUTE CO.,LTD.\r
+                               Times Ave.,Zhuzhou,hunan,China\r
+                               zhuzhou  Hunan  412001\r
+                               CN\r
+\r
+F4-CA-24   (hex)               FreeBit Co., Ltd.\r
+F4CA24     (base 16)           FreeBit Co., Ltd.\r
+                               E.Space Tower 3-6 Maruyama-Cho\r
+                               Shibuya-ku  Tokyo  150-0044\r
+                               JP\r
+\r
+00-0A-57   (hex)               Hewlett Packard\r
+000A57     (base 16)           Hewlett Packard\r
+                               10955 Tantau Avenue\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+64-31-50   (hex)               Hewlett Packard\r
+643150     (base 16)           Hewlett Packard\r
+                               11445 Compaq Center Drive\r
+                               Houston    77070\r
+                               US\r
+\r
+00-23-76   (hex)               HTC Corporation\r
+002376     (base 16)           HTC Corporation\r
+                               No.23 Xinghua Road\r
+                               Taoyuan County    330\r
+                               TW\r
+\r
+00-07-E9   (hex)               Intel Corporation\r
+0007E9     (base 16)           Intel Corporation\r
+                               2111 NE 25th Avenue\r
+                               Hillsboro  OR  97124\r
+                               US\r
+\r
+B4-6D-83   (hex)               Intel Corporate\r
+B46D83     (base 16)           Intel Corporate\r
+                               Lot 8, Jalan Hi-Tech 2/3\r
+                               Kulim  Kedah  09000\r
+                               MY\r
+\r
+E4-FA-FD   (hex)               Intel Corporate\r
+E4FAFD     (base 16)           Intel Corporate\r
+                               Lot 8, Jalan Hi-Tech 2/3\r
+                               Kulim  Kedah  09000\r
+                               MY\r
+\r
+DC-53-60   (hex)               Intel Corporate\r
+DC5360     (base 16)           Intel Corporate\r
+                               Lot 8, Jalan Hi-Tech 2/3\r
+                               Kulim  Kedah  09000\r
+                               MY\r
+\r
+78-0C-B8   (hex)               Intel Corporate\r
+780CB8     (base 16)           Intel Corporate\r
+                               Lot 8, Jalan Hi-Tech 2/3\r
+                               Kulim  Kedah  09000\r
+                               MY\r
+\r
+48-45-20   (hex)               Intel Corporate\r
+484520     (base 16)           Intel Corporate\r
+                               Lot 8, Jalan Hi-Tech 2/3\r
+                               Kulim  Kedah  09000\r
+                               MY\r
+\r
+00-40-26   (hex)               BUFFALO.INC\r
+004026     (base 16)           BUFFALO.INC\r
+                               AKAMONDORI Bldg., 30-20,Ohsu 3-chome\r
+                               Naka-ku,Nagoya  Aichi Pref.  460-8315\r
+                               JP\r
+\r
+00-02-A5   (hex)               Hewlett Packard\r
+0002A5     (base 16)           Hewlett Packard\r
+                               20555 State Highway 249\r
+                               Houston  TX  77070\r
+                               US\r
+\r
+A0-2B-B8   (hex)               Hewlett Packard\r
+A02BB8     (base 16)           Hewlett Packard\r
+                               11445 Compaq Center Drive\r
+                               Houston    77070\r
+                               US\r
+\r
+6C-C2-17   (hex)               Hewlett Packard\r
+6CC217     (base 16)           Hewlett Packard\r
+                               11445 Compaq Center Drive\r
+                               Houston    77070\r
+                               US\r
+\r
+38-63-BB   (hex)               Hewlett Packard\r
+3863BB     (base 16)           Hewlett Packard\r
+                               11445 Compaq Center Drive\r
+                               Houston    77070\r
+                               US\r
+\r
+CC-3E-5F   (hex)               Hewlett Packard\r
+CC3E5F     (base 16)           Hewlett Packard\r
+                               11445 Compaq Center Drive\r
+                               Houston    77070\r
+                               US\r
+\r
+74-46-A0   (hex)               Hewlett Packard\r
+7446A0     (base 16)           Hewlett Packard\r
+                               11445 Compaq Center Drive\r
+                               Houston    77070\r
+                               US\r
+\r
+44-31-92   (hex)               Hewlett Packard\r
+443192     (base 16)           Hewlett Packard\r
+                               11445 Compaq Center Drive\r
+                               Houston    77070\r
+                               US\r
+\r
+FC-15-B4   (hex)               Hewlett Packard\r
+FC15B4     (base 16)           Hewlett Packard\r
+                               11445 Compaq Center Drive\r
+                               Houston    77070\r
+                               US\r
+\r
+EC-9A-74   (hex)               Hewlett Packard\r
+EC9A74     (base 16)           Hewlett Packard\r
+                               11445 Compaq Center Drive\r
+                               Houston    77070\r
+                               US\r
+\r
+80-C1-6E   (hex)               Hewlett Packard\r
+80C16E     (base 16)           Hewlett Packard\r
+                               11445 Compaq Center Drive\r
+                               Houston    77070\r
+                               US\r
+\r
+D0-7E-28   (hex)               Hewlett Packard\r
+D07E28     (base 16)           Hewlett Packard\r
+                               11445 Compaq Center Drive\r
+                               Houston    77070\r
+                               US\r
+\r
+74-03-BD   (hex)               BUFFALO.INC\r
+7403BD     (base 16)           BUFFALO.INC\r
+                                AKAMONDORI Bldg, 30-20, Ohsu 3-chome,\r
+                               Minami-ku, Nagoya  Aichi Pref.  457-8520\r
+                               JP\r
+\r
+10-1F-74   (hex)               Hewlett Packard\r
+101F74     (base 16)           Hewlett Packard\r
+                               11445 Compaq Center Drive\r
+                               Houston    77070\r
+                               US\r
+\r
+00-1A-4B   (hex)               Hewlett Packard\r
+001A4B     (base 16)           Hewlett Packard\r
+                               20555 State Highway 249\r
+                               Houston  TX  77070\r
+                               US\r
+\r
+00-1F-29   (hex)               Hewlett Packard\r
+001F29     (base 16)           Hewlett Packard\r
+                               20555 State Highway 249\r
+                               Houston  TX  77070\r
+                               US\r
+\r
+00-21-5A   (hex)               Hewlett Packard\r
+00215A     (base 16)           Hewlett Packard\r
+                               20555 State Highway 249\r
+                               Houston  TX  77070\r
+                               US\r
+\r
+00-0F-61   (hex)               Hewlett Packard\r
+000F61     (base 16)           Hewlett Packard\r
+                               20555 State Highway 249\r
+                               Houston  TX  77070\r
+                               US\r
+\r
+00-11-85   (hex)               Hewlett Packard\r
+001185     (base 16)           Hewlett Packard\r
+                               20555 State Highway 249\r
+                               Houston  TX  77070\r
+                               US\r
+\r
+00-12-79   (hex)               Hewlett Packard\r
+001279     (base 16)           Hewlett Packard\r
+                               20555 State Highway 249\r
+                               Houston  TX  77070\r
+                               US\r
+\r
+00-17-08   (hex)               Hewlett Packard\r
+001708     (base 16)           Hewlett Packard\r
+                               20555 State Highway 249\r
+                               Houston  TX  77070\r
+                               US\r
+\r
+28-32-C5   (hex)               HUMAX Co., Ltd.\r
+2832C5     (base 16)           HUMAX Co., Ltd.\r
+                               HUMAX Village,216,Hwangsaeul-ro,Bundang-gu\r
+                               Seongnam-si  Gyeonggi-do  463-875\r
+                               KR\r
+\r
+EC-4D-47   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
+EC4D47     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
+                               No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park\r
+                               Dongguan    523808\r
+                               CN\r
+\r
+88-CF-98   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
+88CF98     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
+                               No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park\r
+                               Dongguan    523808\r
+                               CN\r
+\r
+6C-E3-B6   (hex)               Nera Telecommunications Ltd.\r
+6CE3B6     (base 16)           Nera Telecommunications Ltd.\r
+                               109 Defu Lane 10\r
+                               Singapore  Singapore  539225\r
+                               SG\r
+\r
+94-2C-B3   (hex)               HUMAX Co., Ltd.\r
+942CB3     (base 16)           HUMAX Co., Ltd.\r
+                               HUMAX Village, 216, Hwangsaeul-ro, Bu\r
+                               Seongnam-si  Gyeonggi-do  463-875\r
+                               KR\r
+\r
+C8-7B-5B   (hex)               zte corporation\r
+C87B5B     (base 16)           zte corporation\r
+                               12/F.,zte R&D building,kejinan Road,\r
+                               shenzhen  guangdong  518057\r
+                               CN\r
+\r
+98-F5-37   (hex)               zte corporation\r
+98F537     (base 16)           zte corporation\r
+                               12/F.,zte R&D building,kejinan Road,\r
+                               shenzhen  guangdong  518057\r
+                               CN\r
+\r
+00-1E-73   (hex)               zte corporation\r
+001E73     (base 16)           zte corporation\r
+                               12/F ZTE Plaza,Keji Road South,Hi-Tech Industrial Park,Nanshan District,\r
+                               Shenzhen  GUANGDONG  518057\r
+                               CN\r
+\r
+00-19-C6   (hex)               zte corporation\r
+0019C6     (base 16)           zte corporation\r
+                               Technology Management Department, \r
+                               Shenzhen  Guangdong  518057\r
+                               CN\r
+\r
+00-15-EB   (hex)               zte corporation\r
+0015EB     (base 16)           zte corporation\r
+                               5/F,A Wing,ZTE Plaza,Keji Road South,Hi-Tech Industrial Park,Nanshan District\r
+                               Shenzhen    518057\r
+                               US\r
+\r
+F0-EB-D0   (hex)               Shanghai Feixun Communication Co.,Ltd.\r
+F0EBD0     (base 16)           Shanghai Feixun Communication Co.,Ltd.\r
+                               Building 90,No,4855,Guangfulin Road\r
+                               shanghai  Shanghai  201616\r
+                               CN\r
+\r
+D8-49-0B   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
+D8490B     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
+                               D1,Huawei Industrial Base,Bantian,Longgang,Shenzhen\r
+                               Shenzhen    518129\r
+                               CN\r
+\r
+88-86-03   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
+888603     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
+                               D1,Huawei Industrial Base,Bantian,Longgang,Shenzhen\r
+                               Shenzhen    518129\r
+                               CN\r
+\r
+F8-E8-11   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
+F8E811     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
+                               D1,Huawei Industrial Base,Bantian,Longgang,Shenzhen\r
+                               Shenzhen  Guangdong  518129\r
+                               CN\r
+\r
+E0-97-96   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
+E09796     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
+                               D1,Huawei Industrial Base,Bantian,Longgang,Shenzhen\r
+                               Shenzhen  Guangdong  518129\r
+                               CN\r
+\r
+CC-CC-81   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
+CCCC81     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
                                D1-4,Huawei Industrial Base,Bantian,Longgang\r
                                ShenZhen  GuangDong  518129\r
                                CN\r
@@ -29411,12 +29729,6 @@ F4559C     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD
                                Shenzhen  Guangdong  518057\r
                                CN\r
 \r
-64-A5-C3   (hex)               Apple, Inc.\r
-64A5C3     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 00-1D-0F   (hex)               TP-LINK TECHNOLOGIES CO.,LTD.\r
 001D0F     (base 16)           TP-LINK TECHNOLOGIES CO.,LTD.\r
                                3/F, Bldg. R1-B,\r
@@ -29723,90 +30035,6 @@ C8D719     (base 16)           Cisco-Linksys, LLC
                                Irvine    92612\r
                                US\r
 \r
-CC-08-E0   (hex)               Apple, Inc.\r
-CC08E0     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-58-55-CA   (hex)               Apple, Inc.\r
-5855CA     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-8C-7B-9D   (hex)               Apple, Inc.\r
-8C7B9D     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-88-C6-63   (hex)               Apple, Inc.\r
-88C663     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-C8-2A-14   (hex)               Apple, Inc.\r
-C82A14     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-98-03-D8   (hex)               Apple, Inc.\r
-9803D8     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-8C-58-77   (hex)               Apple, Inc.\r
-8C5877     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-34-51-C9   (hex)               Apple, Inc.\r
-3451C9     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-E0-B9-BA   (hex)               Apple, Inc.\r
-E0B9BA     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-D0-23-DB   (hex)               Apple, Inc.\r
-D023DB     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-B8-8D-12   (hex)               Apple, Inc.\r
-B88D12     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-B8-17-C2   (hex)               Apple, Inc.\r
-B817C2     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-68-A8-6D   (hex)               Apple, Inc.\r
-68A86D     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-78-A3-E4   (hex)               Apple, Inc.\r
-78A3E4     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
 54-78-1A   (hex)               Cisco Systems, Inc\r
 54781A     (base 16)           Cisco Systems, Inc\r
                                170 West Tasman Drive\r
@@ -29969,472 +30197,76 @@ F45FD4     (base 16)         Cisco SPVTG
                                Soma-city,  Fukushima-pref.,  976-8501\r
                                JP\r
 \r
-BC-92-6B   (hex)               Apple, Inc.\r
-BC926B     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
+84-7D-50   (hex)               Holley Metering Limited\r
+847D50     (base 16)           Holley Metering Limited\r
+                               181 Wuchang Avenue\r
+                               Hangzhou  Zhejiang  310023\r
+                               CN\r
 \r
-00-50-E4   (hex)               Apple, Inc.\r
-0050E4     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
+6C-4A-39   (hex)               BITA\r
+6C4A39     (base 16)           BITA\r
+                               6/F, New Century Hotel Office Tower\r
+                                 BEI JING  100044\r
+                               CN\r
 \r
-00-30-65   (hex)               Apple, Inc.\r
-003065     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
+04-21-4C   (hex)               Insight Energy Ventures LLC\r
+04214C     (base 16)           Insight Energy Ventures LLC\r
+                               123 W. Fifth St\r
+                               Royal Oak  MI  48067\r
                                US\r
 \r
-00-0A-27   (hex)               Apple, Inc.\r
-000A27     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
+4C-8E-CC   (hex)               SILKAN SA\r
+4C8ECC     (base 16)           SILKAN SA\r
+                               Immeuble le Sirius\r
+                               Meudon La Foret  Ile de France  92360\r
+                               FR\r
 \r
-00-14-51   (hex)               Apple, Inc.\r
-001451     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
+98-F4-28   (hex)               zte corporation\r
+98F428     (base 16)           zte corporation\r
+                               12/F.,zte R&D building ,kejinan Road,Shenzhen,P.R.China\r
+                               shenzhen  guangdong  518057\r
+                               CN\r
 \r
-00-19-E3   (hex)               Apple, Inc.\r
-0019E3     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
+7C-5A-67   (hex)               JNC Systems, Inc.\r
+7C5A67     (base 16)           JNC Systems, Inc.\r
+                               #611, Gyeonggi Venture Yeonsung University\r
+                               Anyang-si  Gyeonggi-do  430731\r
+                               KR\r
 \r
-00-23-12   (hex)               Apple, Inc.\r
-002312     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
+C4-BB-EA   (hex)               Pakedge Device and Software Inc\r
+C4BBEA     (base 16)           Pakedge Device and Software Inc\r
+                               3847 Breakwater Ave\r
+                               Hayward  CA  94545\r
                                US\r
 \r
-00-23-32   (hex)               Apple, Inc.\r
-002332     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
+84-10-0D   (hex)               Motorola Mobility LLC, a Lenovo Company\r
+84100D     (base 16)           Motorola Mobility LLC, a Lenovo Company\r
+                               222 West Merchandise Mart Plaza\r
+                               Chicago  IL  60654\r
                                US\r
 \r
-00-24-36   (hex)               Apple, Inc.\r
-002436     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
+D8-8B-4C   (hex)               KingTing Tech.\r
+D88B4C     (base 16)           KingTing Tech.\r
+                               8 Holly St\r
+                               Irvine  California  92612\r
                                US\r
 \r
-00-25-4B   (hex)               Apple, Inc.\r
-00254B     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
+6C-93-54   (hex)               Yaojin Technology (Shenzhen) Co., LTD.\r
+6C9354     (base 16)           Yaojin Technology (Shenzhen) Co., LTD.\r
+                                No.18,Zhulong Tian Road,Shuitian No.4 Industrial Area,Shiyan Street, Baoan District,Shenzhen,China\r
+                               Shenzhen  Guangdong  518108\r
+                               CN\r
+\r
+40-54-E4   (hex)               Wearsafe Labs Inc\r
+4054E4     (base 16)           Wearsafe Labs Inc\r
+                               1429 Park Street\r
+                               Hartford  CT  06106\r
                                US\r
 \r
-00-26-BB   (hex)               Apple, Inc.\r
-0026BB     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-E8-06-88   (hex)               Apple, Inc.\r
-E80688     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-98-5A-EB   (hex)               Apple, Inc.\r
-985AEB     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-20-78-F0   (hex)               Apple, Inc.\r
-2078F0     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-78-D7-5F   (hex)               Apple, Inc.\r
-78D75F     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-E0-AC-CB   (hex)               Apple, Inc.\r
-E0ACCB     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-98-E0-D9   (hex)               Apple, Inc.\r
-98E0D9     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-C0-CE-CD   (hex)               Apple, Inc.\r
-C0CECD     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-70-E7-2C   (hex)               Apple, Inc.\r
-70E72C     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-D0-33-11   (hex)               Apple, Inc.\r
-D03311     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-84-7D-50   (hex)               Holley Metering Limited\r
-847D50     (base 16)           Holley Metering Limited\r
-                               181 Wuchang Avenue\r
-                               Hangzhou  Zhejiang  310023\r
-                               CN\r
-\r
-6C-4A-39   (hex)               BITA\r
-6C4A39     (base 16)           BITA\r
-                               6/F, New Century Hotel Office Tower\r
-                                 BEI JING  100044\r
-                               CN\r
-\r
-C8-B5-B7   (hex)               Apple, Inc.\r
-C8B5B7     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-A8-BB-CF   (hex)               Apple, Inc.\r
-A8BBCF     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-90-B2-1F   (hex)               Apple, Inc.\r
-90B21F     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-B8-E8-56   (hex)               Apple, Inc.\r
-B8E856     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-14-99-E2   (hex)               Apple, Inc.\r
-1499E2     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-04-21-4C   (hex)               Insight Energy Ventures LLC\r
-04214C     (base 16)           Insight Energy Ventures LLC\r
-                               123 W. Fifth St\r
-                               Royal Oak  MI  48067\r
-                               US\r
-\r
-B4-18-D1   (hex)               Apple, Inc.\r
-B418D1     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-80-00-6E   (hex)               Apple, Inc.\r
-80006E     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-60-D9-C7   (hex)               Apple, Inc.\r
-60D9C7     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-C8-F6-50   (hex)               Apple, Inc.\r
-C8F650     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-1C-1A-C0   (hex)               Apple, Inc.\r
-1C1AC0     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-E0-66-78   (hex)               Apple, Inc.\r
-E06678     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-5C-8D-4E   (hex)               Apple, Inc.\r
-5C8D4E     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-64-A3-CB   (hex)               Apple, Inc.\r
-64A3CB     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-44-FB-42   (hex)               Apple, Inc.\r
-44FB42     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-F4-1B-A1   (hex)               Apple, Inc.\r
-F41BA1     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-3C-E0-72   (hex)               Apple, Inc.\r
-3CE072     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-E8-8D-28   (hex)               Apple, Inc.\r
-E88D28     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-CC-78-5F   (hex)               Apple, Inc.\r
-CC785F     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-AC-3C-0B   (hex)               Apple, Inc.\r
-AC3C0B     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-88-CB-87   (hex)               Apple, Inc.\r
-88CB87     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-EC-35-86   (hex)               Apple, Inc.\r
-EC3586     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-F0-C1-F1   (hex)               Apple, Inc.\r
-F0C1F1     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-F4-F9-51   (hex)               Apple, Inc.\r
-F4F951     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-18-AF-8F   (hex)               Apple, Inc.\r
-18AF8F     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-C0-F2-FB   (hex)               Apple, Inc.\r
-C0F2FB     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-00-F7-6F   (hex)               Apple, Inc.\r
-00F76F     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-AC-87-A3   (hex)               Apple, Inc.\r
-AC87A3     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-48-43-7C   (hex)               Apple, Inc.\r
-48437C     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-34-A3-95   (hex)               Apple, Inc.\r
-34A395     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-9C-F3-87   (hex)               Apple, Inc.\r
-9CF387     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-A8-5B-78   (hex)               Apple, Inc.\r
-A85B78     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-90-8D-6C   (hex)               Apple, Inc.\r
-908D6C     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-0C-15-39   (hex)               Apple, Inc.\r
-0C1539     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-BC-4C-C4   (hex)               Apple, Inc.\r
-BC4CC4     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-0C-BC-9F   (hex)               Apple, Inc.\r
-0CBC9F     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-A4-5E-60   (hex)               Apple, Inc.\r
-A45E60     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-68-09-27   (hex)               Apple, Inc.\r
-680927     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-60-FA-CD   (hex)               Apple, Inc.\r
-60FACD     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-1C-AB-A7   (hex)               Apple, Inc.\r
-1CABA7     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-8C-FA-BA   (hex)               Apple, Inc.\r
-8CFABA     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-5C-95-AE   (hex)               Apple, Inc.\r
-5C95AE     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-E0-C9-7A   (hex)               Apple, Inc.\r
-E0C97A     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-BC-52-B7   (hex)               Apple, Inc.\r
-BC52B7     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-14-10-9F   (hex)               Apple, Inc.\r
-14109F     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-54-26-96   (hex)               Apple, Inc.\r
-542696     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-D8-D1-CB   (hex)               Apple, Inc.\r
-D8D1CB     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-4C-8E-CC   (hex)               SILKAN SA\r
-4C8ECC     (base 16)           SILKAN SA\r
-                               Immeuble le Sirius\r
-                               Meudon La Foret  Ile de France  92360\r
-                               FR\r
-\r
-98-F4-28   (hex)               zte corporation\r
-98F428     (base 16)           zte corporation\r
-                               12/F.,zte R&D building ,kejinan Road,Shenzhen,P.R.China\r
-                               shenzhen  guangdong  518057\r
-                               CN\r
-\r
-7C-5A-67   (hex)               JNC Systems, Inc.\r
-7C5A67     (base 16)           JNC Systems, Inc.\r
-                               #611, Gyeonggi Venture Yeonsung University\r
-                               Anyang-si  Gyeonggi-do  430731\r
-                               KR\r
-\r
-C4-BB-EA   (hex)               Pakedge Device and Software Inc\r
-C4BBEA     (base 16)           Pakedge Device and Software Inc\r
-                               3847 Breakwater Ave\r
-                               Hayward  CA  94545\r
-                               US\r
-\r
-84-10-0D   (hex)               Motorola Mobility LLC, a Lenovo Company\r
-84100D     (base 16)           Motorola Mobility LLC, a Lenovo Company\r
-                               222 West Merchandise Mart Plaza\r
-                               Chicago  IL  60654\r
-                               US\r
-\r
-D8-8B-4C   (hex)               KingTing Tech.\r
-D88B4C     (base 16)           KingTing Tech.\r
-                               8 Holly St\r
-                               Irvine  California  92612\r
-                               US\r
-\r
-6C-93-54   (hex)               Yaojin Technology (Shenzhen) Co., LTD.\r
-6C9354     (base 16)           Yaojin Technology (Shenzhen) Co., LTD.\r
-                                No.18,Zhulong Tian Road,Shuitian No.4 Industrial Area,Shiyan Street, Baoan District,Shenzhen,China\r
-                               Shenzhen  Guangdong  518108\r
-                               CN\r
-\r
-40-54-E4   (hex)               Wearsafe Labs Inc\r
-4054E4     (base 16)           Wearsafe Labs Inc\r
-                               1429 Park Street\r
-                               Hartford  CT  06106\r
-                               US\r
-\r
-8C-E2-DA   (hex)               Circle Media Inc\r
-8CE2DA     (base 16)           Circle Media Inc\r
-                               1319 SE Martin Luther King Jr. Blvd.\r
-                               Portland  Oregon  97214\r
+8C-E2-DA   (hex)               Circle Media Inc\r
+8CE2DA     (base 16)           Circle Media Inc\r
+                               1319 SE Martin Luther King Jr. Blvd.\r
+                               Portland  Oregon  97214\r
                                US\r
 \r
 74-D7-CA   (hex)               Panasonic Corporation Automotive\r
@@ -30515,12 +30347,6 @@ D48304     (base 16)           SHENZHEN FAST TECHNOLOGIES CO.,LTD
                                Lawrenceville  GA  30044\r
                                US\r
 \r
-54-4E-90   (hex)               Apple, Inc.\r
-544E90     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 58-FC-73   (hex)               Arria Live Media, Inc.\r
 58FC73     (base 16)           Arria Live Media, Inc.\r
                                2388 NE Lindsey Drive\r
@@ -30533,18 +30359,6 @@ D48304     (base 16)           SHENZHEN FAST TECHNOLOGIES CO.,LTD
                                Changsha  Hunan  410208\r
                                CN\r
 \r
-5C-AD-CF   (hex)               Apple, Inc.\r
-5CADCF     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-00-6D-52   (hex)               Apple, Inc.\r
-006D52     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 D8-88-CE   (hex)               RF Technology Pty Ltd\r
 D888CE     (base 16)           RF Technology Pty Ltd\r
                                46/7 Sefton Rd\r
@@ -30605,12 +30419,6 @@ DCA3AC     (base 16)           RBcloudtech
                                Dalian  Liaoning  116600\r
                                CN\r
 \r
-0C-91-60   (hex)               Hui Zhou Gaoshengda Technology Co.,LTD\r
-0C9160     (base 16)           Hui Zhou Gaoshengda Technology Co.,LTD\r
-                               No.75,Zhongkai High-Tech Development District,Huizhou\r
-                               Hui Zhou  Guangdong  516006\r
-                               CN\r
-\r
 EC-A9-FA   (hex)               GUANGDONG GENIUS TECHNOLOGY CO.,LTD.\r
 ECA9FA     (base 16)           GUANGDONG GENIUS TECHNOLOGY CO.,LTD.\r
                                #126,BBK Road,Wusha,Chang'An\r
@@ -39800,12 +39608,6 @@ D0D286     (base 16)           Beckman Coulter K.K.
                                Ljubljana  Slovenia  1000\r
                                SI\r
 \r
-00-1B-D8   (hex)               DVTel LTD\r
-001BD8     (base 16)           DVTel LTD\r
-                               5 Sapir\r
-                               46852  Herzelia  \r
-                               IL\r
-\r
 00-1B-CC   (hex)               KINGTEK CCTV ALLIANCE CO., LTD.\r
 001BCC     (base 16)           KINGTEK CCTV ALLIANCE CO., LTD.\r
                                5F-3, NO. 106, SEC. 3, HSIN YI ROAD\r
@@ -46019,12 +45821,6 @@ D0D286     (base 16)           Beckman Coulter K.K.
                                Mountain View  CA  94041\r
                                US\r
 \r
-00-03-97   (hex)               Watchfront Limited\r
-000397     (base 16)           Watchfront Limited\r
-                               3 Victoria Walk\r
-                               Wokingham    RG40 5YL\r
-                               GB\r
-\r
 00-03-9E   (hex)               Tera System Co., Ltd.\r
 00039E     (base 16)           Tera System Co., Ltd.\r
                                Doosung B/F Rm 302\r
@@ -46811,12 +46607,6 @@ D0D286     (base 16)           Beckman Coulter K.K.
                                    \r
                                IL\r
 \r
-00-01-B9   (hex)               SKF Condition Monitoring\r
-0001B9     (base 16)           SKF Condition Monitoring\r
-                               4141 Ruffin Road\r
-                               San Diego  CA  92123\r
-                               US\r
-\r
 00-01-B5   (hex)               Turin Networks, Inc.\r
 0001B5     (base 16)           Turin Networks, Inc.\r
                                1415 North McDowell Blvd.\r
@@ -51932,12 +51722,6 @@ A444D1     (base 16)            Wingtech Group (HongKong)Limited
                                Hong Kong  Hong Kong  999077\r
                                HK\r
 \r
-1C-9E-46   (hex)               Apple, Inc.\r
-1C9E46     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 00-50-58   (hex)               Sangoma Technologies\r
 005058     (base 16)           Sangoma Technologies\r
                                100 Renfrew Drive, Suite 100\r
@@ -52004,12 +51788,6 @@ E45D75     (base 16)           Samsung Electronics Co.,Ltd
                                Shanghai  Shanghai  200072\r
                                CN\r
 \r
-E0-C7-67   (hex)               Apple, Inc.\r
-E0C767     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 2C-09-CB   (hex)               COBS AB\r
 2C09CB     (base 16)           COBS AB\r
                                Box 9242\r
@@ -52601,42 +52379,6 @@ D8209F     (base 16)           Cubro Acronet GesmbH
                                Vienna  Vienna  1110\r
                                AT\r
 \r
-A8-60-B6   (hex)               Apple, Inc.\r
-A860B6     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-24-F0-94   (hex)               Apple, Inc.\r
-24F094     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-90-B0-ED   (hex)               Apple, Inc.\r
-90B0ED     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-C4-B3-01   (hex)               Apple, Inc.\r
-C4B301     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-E0-5F-45   (hex)               Apple, Inc.\r
-E05F45     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-48-3B-38   (hex)               Apple, Inc.\r
-483B38     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 E4-7B-3F   (hex)               BEIJING CO-CLOUD TECHNOLOGY LTD.\r
 E47B3F     (base 16)           BEIJING CO-CLOUD TECHNOLOGY LTD.\r
                                903 Room,Power Create E ,No.1 Shangdi East Road\r
@@ -53693,42 +53435,12 @@ F01DBC     (base 16)          Microsoft Corporation
                                REDMOND  WA  98052\r
                                US\r
 \r
-40-4D-7F   (hex)               Apple, Inc.\r
-404D7F     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-7C-04-D0   (hex)               Apple, Inc.\r
-7C04D0     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-BC-9F-EF   (hex)               Apple, Inc.\r
-BC9FEF     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-88-66-A5   (hex)               Apple, Inc.\r
-8866A5     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 AC-DC-E5   (hex)               Procter & Gamble Company\r
 ACDCE5     (base 16)           Procter & Gamble Company\r
                                2 Procter & Gamble Plaza\r
                                Cincinnati  OH  45202\r
                                US\r
 \r
-78-4F-43   (hex)               Apple, Inc.\r
-784F43     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 98-D2-93   (hex)               Google, Inc.\r
 98D293     (base 16)           Google, Inc.\r
                                1600 Amphitheatre Parkway\r
@@ -54095,12 +53807,6 @@ BC60A7     (base 16)           Sony Interactive Entertainment Inc.
                                Palo Alto  CA  94301\r
                                US\r
 \r
-20-F5-43   (hex)               Hui Zhou Gaoshengda Technology Co.,LTD\r
-20F543     (base 16)           Hui Zhou Gaoshengda Technology Co.,LTD\r
-                               No.75,Zhongkai High-Tech Development District,Huizhou\r
-                               Hui Zhou  Guangdong  516006\r
-                               CN\r
-\r
 68-53-88   (hex)               P&S Technology\r
 685388     (base 16)           P&S Technology\r
                                216 Deajiro\r
@@ -54530,18 +54236,6 @@ BC39D9     (base 16)           Z-TEC
                                Paju  Kyeongkido  10832\r
                                KR\r
 \r
-88-E8-7F   (hex)               Apple, Inc.\r
-88E87F     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-B8-53-AC   (hex)               Apple, Inc.\r
-B853AC     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 B0-4B-BF   (hex)               PT HAN SUNG ELECTORONICS INDONESIA\r
 B04BBF     (base 16)           PT HAN SUNG ELECTORONICS INDONESIA\r
                                JL.PALEM 1 BLOK DS-6\r
@@ -54554,12 +54248,6 @@ B04BBF     (base 16)           PT HAN SUNG ELECTORONICS INDONESIA
                                CALGARY, ALBERTA T2E 8M4    \r
                                CA\r
 \r
-2C-33-61   (hex)               Apple, Inc.\r
-2C3361     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 78-B8-4B   (hex)               SICHUAN TIANYI COMHEART TELECOMCO.,LTD\r
 78B84B     (base 16)           SICHUAN TIANYI COMHEART TELECOMCO.,LTD\r
                                FL12,TowerB,Tianyi international Hotel,No.2 West Section One, Second Ring Road,\r
@@ -55133,12 +54821,6 @@ E05163     (base 16)           Arcadyan Corporation
                                Dongguan  Guangdong  523770\r
                                CN\r
 \r
-1C-1E-E3   (hex)               Hui Zhou Gaoshengda Technology Co.,LTD\r
-1C1EE3     (base 16)           Hui Zhou Gaoshengda Technology Co.,LTD\r
-                               No.75,Zhongkai High-Tech Development District,Huizhou\r
-                               Hui Zhou  Guangdong  516006\r
-                               CN\r
-\r
 F0-27-2D   (hex)               Amazon Technologies Inc.\r
 F0272D     (base 16)           Amazon Technologies Inc.\r
                                P.O Box 8102\r
@@ -55223,42 +54905,6 @@ F0D7AA     (base 16)           Motorola Mobility LLC, a Lenovo Company
                                shenzhen  guangdong  518057\r
                                CN\r
 \r
-88-6B-6E   (hex)               Apple, Inc.\r
-886B6E     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-4C-74-BF   (hex)               Apple, Inc.\r
-4C74BF     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-70-F0-87   (hex)               Apple, Inc.\r
-70F087     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-28-57-67   (hex)               Echostar Technologies Corp\r
-285767     (base 16)           Echostar Technologies Corp\r
-                               94 Inverness Terrace E\r
-                               Englewood  CO  80112\r
-                               US\r
-\r
-00-24-AF   (hex)               Echostar Technologies Corp\r
-0024AF     (base 16)           Echostar Technologies Corp\r
-                               94 Inverness Terrace E\r
-                               Englewood  CO  80112\r
-                               US\r
-\r
-04-C9-D9   (hex)               Echostar Technologies Corp\r
-04C9D9     (base 16)           Echostar Technologies Corp\r
-                               94 Inverness Terrace E\r
-                               Englewood  CO  80112\r
-                               US\r
-\r
 D0-49-8B   (hex)               ZOOM SERVER\r
 D0498B     (base 16)           ZOOM SERVER\r
                                North keyuan Road\r
@@ -56279,9 +55925,6 @@ B05508     (base 16)            HUAWEI TECHNOLOGIES CO.,LTD
                                Suwon  Gyeonggi-Do  16677\r
                                KR\r
 \r
-00-A0-85   (hex)               Private\r
-00A085     (base 16)           Private\r
-\r
 AC-DE-48   (hex)               Private\r
 ACDE48     (base 16)           Private\r
 \r
@@ -56555,18 +56198,6 @@ B009DA     (base 16)           Ring Solutions
                                Ningbo  Zhejiang  315202\r
                                CN\r
 \r
-84-41-67   (hex)               Apple, Inc.\r
-844167     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-B4-F6-1C   (hex)               Apple, Inc.\r
-B4F61C     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 EC-FA-03   (hex)               FCA\r
 ECFA03     (base 16)           FCA\r
                                800 Chrylser Dr\r
@@ -56969,24 +56600,6 @@ AC84C6     (base 16)           TP-LINK TECHNOLOGIES CO.,LTD.
                                Shenzhen  Guangdong  518057\r
                                CN\r
 \r
-E4-9A-DC   (hex)               Apple, Inc.\r
-E49ADC     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-B8-C1-11   (hex)               Apple, Inc.\r
-B8C111     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-34-08-BC   (hex)               Apple, Inc.\r
-3408BC     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 34-D0-B8   (hex)               IEEE Registration Authority\r
 34D0B8     (base 16)           IEEE Registration Authority\r
                                445 Hoes Lane\r
@@ -57533,575 +57146,1646 @@ CC3ADF     (base 16)               Neptune Technology Group Inc.
                                Hsinchu  Taiwan ROC.  30352 \r
                                TW\r
 \r
-58-46-E1   (hex)               Baxter International Inc\r
-5846E1     (base 16)           Baxter International Inc\r
-                               One Baxter Parkway\r
-                               Deerfield  IL  60015\r
+A8-5B-78   (hex)               Apple, Inc.\r
+A85B78     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-00-D0-BD   (hex)               Lattice Semiconductor Corp. (LPA)\r
-00D0BD     (base 16)           Lattice Semiconductor Corp. (LPA)\r
-                               2115 O’Nel Drive\r
-                               San Jose  CA  95131\r
+9C-F3-87   (hex)               Apple, Inc.\r
+9CF387     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-F0-82-61   (hex)               Sagemcom Broadband SAS\r
-F08261     (base 16)           Sagemcom Broadband SAS\r
-                               250 route de l'Empereur\r
-                               Rueil Malmaison  HAUTS DE SEINE  92848\r
-                               FR\r
-\r
-D0-84-B0   (hex)               Sagemcom Broadband SAS\r
-D084B0     (base 16)           Sagemcom Broadband SAS\r
-                               250 route de l'Empereur\r
-                               Rueil Malmaison  HAUTS DE SEINE  92848\r
-                               FR\r
+34-A3-95   (hex)               Apple, Inc.\r
+34A395     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-00-FE-C8   (hex)               Cisco Systems, Inc\r
-00FEC8     (base 16)           Cisco Systems, Inc\r
-                               80 West Tasman Drive\r
-                               San Jose  CA  94568\r
+48-43-7C   (hex)               Apple, Inc.\r
+48437C     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-EC-22-80   (hex)               D-Link International\r
-EC2280     (base 16)           D-Link International\r
-                               1 Internal Business Park, #03-12,\r
-                               SINGAPORE  Singapore  609917\r
-                               SG\r
+AC-87-A3   (hex)               Apple, Inc.\r
+AC87A3     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-04-78-63   (hex)               Shanghai MXCHIP Information Technology Co., Ltd.\r
-047863     (base 16)           Shanghai MXCHIP Information Technology Co., Ltd.\r
-                               9th Floor, No. 5 Building, 2145 Jinshajiang Rd., Putuo District\r
-                               Shanghai    200333\r
-                               CN\r
+00-F7-6F   (hex)               Apple, Inc.\r
+00F76F     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-24-BA-13   (hex)               RISO KAGAKU CORPORATION\r
-24BA13     (base 16)           RISO KAGAKU CORPORATION\r
-                               2-8-1 Gakuen-minami\r
-                               Thukuba-shi  Ibaraki  305-0818\r
-                               JP\r
+A4-5E-60   (hex)               Apple, Inc.\r
+A45E60     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-24-DA-11   (hex)               NO NDA Inc\r
-24DA11     (base 16)           NO NDA Inc\r
-                               828 Bryant St \r
-                               Palo Alto  IA  94301\r
+0C-BC-9F   (hex)               Apple, Inc.\r
+0CBC9F     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-70-CA-4D   (hex)               Shenzhen lnovance Technology Co.,Ltd.\r
-70CA4D     (base 16)           Shenzhen lnovance Technology Co.,Ltd.\r
-                               LiuXian 2 Road\r
-                               Shenzhen  Guangdong  518000\r
-                               CN\r
+BC-4C-C4   (hex)               Apple, Inc.\r
+BC4CC4     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-DC-C0-EB   (hex)               ASSA ABLOY CÔTE PICARDE\r
-DCC0EB     (base 16)           ASSA ABLOY CÔTE PICARDE\r
-                               rue Alexandre Fichet\r
-                               Oust-Marest    80460\r
-                               FR\r
+0C-15-39   (hex)               Apple, Inc.\r
+0C1539     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-00-17-35   (hex)               Intel Wireless Network Group\r
-001735     (base 16)           Intel Wireless Network Group\r
-                               2111 NE 25th Ave\r
-                               Hillsboro  OR  97124\r
+90-8D-6C   (hex)               Apple, Inc.\r
+908D6C     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-9C-DF-B1   (hex)               Shenzhen Crave Communication Co., LTD\r
-9CDFB1     (base 16)           Shenzhen Crave Communication Co., LTD\r
-                               F3,8Building,DongFangMing IndustryZone,No.83 DabaoRD.,33 District BaoAn\r
-                               Shenzhen  Guangdong  518000\r
-                               CN\r
+D0-33-11   (hex)               Apple, Inc.\r
+D03311     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-5C-F9-38   (hex)               Apple, Inc.\r
-5CF938     (base 16)           Apple, Inc.\r
+70-E7-2C   (hex)               Apple, Inc.\r
+70E72C     (base 16)           Apple, Inc.\r
                                1 Infinite Loop\r
                                Cupertino  CA  95014\r
                                US\r
 \r
-38-71-DE   (hex)               Apple, Inc.\r
-3871DE     (base 16)           Apple, Inc.\r
+C0-CE-CD   (hex)               Apple, Inc.\r
+C0CECD     (base 16)           Apple, Inc.\r
                                1 Infinite Loop\r
                                Cupertino  CA  95014\r
                                US\r
 \r
-BC-54-36   (hex)               Apple, Inc.\r
-BC5436     (base 16)           Apple, Inc.\r
+98-E0-D9   (hex)               Apple, Inc.\r
+98E0D9     (base 16)           Apple, Inc.\r
                                1 Infinite Loop\r
                                Cupertino  CA  95014\r
                                US\r
 \r
-0C-C7-31   (hex)               Currant, Inc.\r
-0CC731     (base 16)           Currant, Inc.\r
-                               927 Industrial Ave\r
-                               Palo Alto  CA  94303\r
+E0-AC-CB   (hex)               Apple, Inc.\r
+E0ACCB     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-00-14-2F   (hex)               Savvius\r
-00142F     (base 16)           Savvius\r
-                               1340 Treat Boulevard, Suite 500\r
-                               Walnut Creek  CA  94597\r
+78-D7-5F   (hex)               Apple, Inc.\r
+78D75F     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-2C-DD-A3   (hex)               Point Grey Research Inc.\r
-2CDDA3     (base 16)           Point Grey Research Inc.\r
-                               305-1847 West Broadway\r
-                               Vancouver  British Columbia V6J 1Y6  \r
-                               CA\r
+20-78-F0   (hex)               Apple, Inc.\r
+2078F0     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-24-FD-5B   (hex)               SmartThings, Inc.\r
-24FD5B     (base 16)           SmartThings, Inc.\r
-                               456 University Avenue\r
-                               Palo Alto  CA  94301\r
+98-5A-EB   (hex)               Apple, Inc.\r
+985AEB     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-28-76-CD   (hex)               Funshion Online Technologies Co.,Ltd\r
-2876CD     (base 16)           Funshion Online Technologies Co.,Ltd\r
-                               Tower B 1201, Jinqiu International Building, No.6, Zhichun Road, Haidian District\r
-                               Beijing    100088\r
-                               CN\r
+54-4E-90   (hex)               Apple, Inc.\r
+544E90     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-F4-F5-D8   (hex)               Google, Inc.\r
-F4F5D8     (base 16)           Google, Inc.\r
-                               1600 Amphitheatre Parkway\r
-                               Mountain View  CA  94043\r
+00-6D-52   (hex)               Apple, Inc.\r
+006D52     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-F4-F5-E8   (hex)               Google, Inc.\r
-F4F5E8     (base 16)           Google, Inc.\r
-                               1600 Amphitheatre Parkway\r
-                               Mountain View    94043\r
+5C-AD-CF   (hex)               Apple, Inc.\r
+5CADCF     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-F8-8F-CA   (hex)               Google, Inc.\r
-F88FCA     (base 16)           Google, Inc.\r
-                               1600 Amphitheatre Parkway\r
-                               Mountain View    94043\r
+B8-E8-56   (hex)               Apple, Inc.\r
+B8E856     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-BC-D1-D3   (hex)               Shenzhen TINNO Mobile Technology Corp.\r
-BCD1D3     (base 16)           Shenzhen TINNO Mobile Technology Corp.\r
-                               4/F.,H-3 Building,OCT Eastern lndustrial Park.\r
-                               Nanshan, Shenzhen  GUANGDONG  518053\r
-                               CN\r
+90-B2-1F   (hex)               Apple, Inc.\r
+90B21F     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-BC-44-34   (hex)               Shenzhen TINNO Mobile Technology Corp.\r
-BC4434     (base 16)           Shenzhen TINNO Mobile Technology Corp.\r
-                               4/F, H-3 Building, Qiao Cheng Eastern Industrial Park, Overseas Chinese Town, Shenzhen \r
-                               Shenzhen   guangdong  518053\r
-                               CN\r
+A8-BB-CF   (hex)               Apple, Inc.\r
+A8BBCF     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-00-41-D2   (hex)               Cisco Systems, Inc\r
-0041D2     (base 16)           Cisco Systems, Inc\r
-                               80 West Tasman Drive\r
-                               San Jose  CA  94568\r
+C8-B5-B7   (hex)               Apple, Inc.\r
+C8B5B7     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-4C-FB-45   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
-4CFB45     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
-                               No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park\r
-                               Dongguan  Guangdong  523808 \r
-                               CN\r
+18-AF-8F   (hex)               Apple, Inc.\r
+18AF8F     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-A4-BA-76   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
-A4BA76     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
-                               No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park\r
-                               Dongguan  Guangdong  523808 \r
-                               CN\r
+F4-F9-51   (hex)               Apple, Inc.\r
+F4F951     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-78-E3-B5   (hex)               Hewlett Packard\r
-78E3B5     (base 16)           Hewlett Packard\r
-                               11445 Compaq Center Drive\r
-                               Houston    77070\r
+F0-C1-F1   (hex)               Apple, Inc.\r
+F0C1F1     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-98-4B-E1   (hex)               Hewlett Packard\r
-984BE1     (base 16)           Hewlett Packard\r
-                               11445 Compaq Center Drive\r
-                               Houston    77070\r
+98-03-D8   (hex)               Apple, Inc.\r
+9803D8     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-68-B5-99   (hex)               Hewlett Packard\r
-68B599     (base 16)           Hewlett Packard\r
-                               11445 Compaq Center Drive\r
-                               Houston    77070\r
+C8-2A-14   (hex)               Apple, Inc.\r
+C82A14     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-14-D6-4D   (hex)               D-Link International\r
-14D64D     (base 16)           D-Link International\r
-                               1 INTERNATIONAL BUSINESS PARK\r
-                               SINGAPORE    609917\r
-                               SG\r
+88-C6-63   (hex)               Apple, Inc.\r
+88C663     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-C8-BE-19   (hex)               D-Link International\r
-C8BE19     (base 16)           D-Link International\r
-                               1 International Business Park, #03-12, The Synergy \r
-                               SINGAPORE    609917\r
-                               SG\r
+8C-7B-9D   (hex)               Apple, Inc.\r
+8C7B9D     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-BC-F6-85   (hex)               D-Link International\r
-BCF685     (base 16)           D-Link International\r
-                               1 International Business Park, #03-12, The Synergy \r
-                               SINGAPORE    609917\r
-                               SG\r
+58-55-CA   (hex)               Apple, Inc.\r
+5855CA     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-CC-B2-55   (hex)               D-Link International\r
-CCB255     (base 16)           D-Link International\r
-                               1 International Business Park, #03-12, The Synergy \r
-                               SINGAPORE    609917\r
-                               SG\r
+CC-08-E0   (hex)               Apple, Inc.\r
+CC08E0     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-84-C9-B2   (hex)               D-Link International\r
-84C9B2     (base 16)           D-Link International\r
-                               1 International Business Park, #03-12, The Synergy \r
-                               SINGAPORE    609917\r
-                               SG\r
+E8-06-88   (hex)               Apple, Inc.\r
+E80688     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-DC-D3-21   (hex)               HUMAX Co., Ltd.\r
-DCD321     (base 16)           HUMAX Co., Ltd.\r
-                               HUMAX Village, 11-4, Sunae-dong, Bundang-gu\r
-                               Seongnam-si  Gyeonggi-do  463-825\r
-                               KR\r
+B8-17-C2   (hex)               Apple, Inc.\r
+B817C2     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-CC-4E-EC   (hex)               HUMAX Co., Ltd.\r
-CC4EEC     (base 16)           HUMAX Co., Ltd.\r
-                               HUMAX Village, 216, Hwangsaeul-ro, Bundang-gu,\r
-                               Seongnam-si  Gyeonggi-do  463-875\r
-                               KR\r
+B8-8D-12   (hex)               Apple, Inc.\r
+B88D12     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-DC-33-0D   (hex)               Qingdao Haier Telecom Co.,Ltd\r
-DC330D     (base 16)           Qingdao Haier Telecom Co.,Ltd\r
-                               No 1  Haier road,Hi-tech Zone,Qingdao,PR.China\r
-                               Qingdao  Shandong  266101\r
-                               CN\r
+D0-23-DB   (hex)               Apple, Inc.\r
+D023DB     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-00-80-E1   (hex)               STMicroelectronics SRL\r
-0080E1     (base 16)           STMicroelectronics SRL\r
-                               1000 AZTEC WEST\r
-                               london    12345\r
-                               GB\r
+E0-B9-BA   (hex)               Apple, Inc.\r
+E0B9BA     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-58-DC-6D   (hex)               Exceptional Innovation, Inc.\r
-58DC6D     (base 16)           Exceptional Innovation, Inc.\r
-                               480 Olde Worthington Rd, Suite 350\r
-                               Westerville  OH  43082\r
+34-51-C9   (hex)               Apple, Inc.\r
+3451C9     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-00-09-2D   (hex)               HTC Corporation\r
-00092D     (base 16)           HTC Corporation\r
-                               No.23 Xinghua Road,\r
-                               Taoyuan County     330\r
-                               TW\r
+8C-58-77   (hex)               Apple, Inc.\r
+8C5877     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-F8-DB-7F   (hex)               HTC Corporation\r
-F8DB7F     (base 16)           HTC Corporation\r
-                               No.23 Xinghua Road\r
-                               Taoyuan County    330\r
-                               TW\r
+C0-F2-FB   (hex)               Apple, Inc.\r
+C0F2FB     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-E8-99-C4   (hex)               HTC Corporation\r
-E899C4     (base 16)           HTC Corporation\r
-                               No. 23, Xinghua Rd., Taoyuan City\r
-                               Taoyuan County  Taiwan  330\r
-                               TW\r
+5C-8D-4E   (hex)               Apple, Inc.\r
+5C8D4E     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-7C-B1-5D   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
-7CB15D     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
-                               No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park\r
-                               Dongguan  Guangdong  523808 \r
-                               CN\r
+E0-66-78   (hex)               Apple, Inc.\r
+E06678     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-18-68-6A   (hex)               zte corporation\r
-18686A     (base 16)           zte corporation\r
-                               12/F.,zte R&D building ,kejinan Road,Shenzhen,P.R.China\r
-                               shenzhen  guangdong  518057\r
-                               CN\r
+1C-1A-C0   (hex)               Apple, Inc.\r
+1C1AC0     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-0C-05-35   (hex)               Juniper Systems\r
-0C0535     (base 16)           Juniper Systems\r
-                               1132 W. 1700 N.\r
-                               Logan  UT  84321\r
+C8-F6-50   (hex)               Apple, Inc.\r
+C8F650     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-8C-F2-28   (hex)               SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD.\r
-8CF228     (base 16)           SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD.\r
-                               Mid-Fourth Flr.,Building 28,Cui Xi Fourth Road,Ke Yuan West,Nanshan\r
-                               Shenzhen  Guangdong  518057\r
-                               CN\r
+60-D9-C7   (hex)               Apple, Inc.\r
+60D9C7     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-88-51-FB   (hex)               Hewlett Packard\r
-8851FB     (base 16)           Hewlett Packard\r
-                               11445 Compaq Center Drive\r
-                               Houston    77070\r
+3C-E0-72   (hex)               Apple, Inc.\r
+3CE072     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-AC-16-2D   (hex)               Hewlett Packard\r
-AC162D     (base 16)           Hewlett Packard\r
-                               11445 Compaq Center Drive\r
-                               Houston    77070\r
+F4-1B-A1   (hex)               Apple, Inc.\r
+F41BA1     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-A0-B3-CC   (hex)               Hewlett Packard\r
-A0B3CC     (base 16)           Hewlett Packard\r
-                               11445 Compaq Center Drive\r
-                               Houston    77070\r
+44-FB-42   (hex)               Apple, Inc.\r
+44FB42     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-E4-11-5B   (hex)               Hewlett Packard\r
-E4115B     (base 16)           Hewlett Packard\r
-                               11445 Compaq Center Drive\r
-                               Houston    77070\r
+64-A3-CB   (hex)               Apple, Inc.\r
+64A3CB     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-C8-CB-B8   (hex)               Hewlett Packard\r
-C8CBB8     (base 16)           Hewlett Packard\r
-                               11445 Compaq Center Drive\r
-                               Houston    77070\r
+D8-D1-CB   (hex)               Apple, Inc.\r
+D8D1CB     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-94-57-A5   (hex)               Hewlett Packard\r
-9457A5     (base 16)           Hewlett Packard\r
-                               11445 Compaq Center Drive\r
-                               Houston    77070\r
+54-26-96   (hex)               Apple, Inc.\r
+542696     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-00-01-E7   (hex)               Hewlett Packard\r
-0001E7     (base 16)           Hewlett Packard\r
-                               11000 Wolfe Road, Mailstop 42LE\r
+EC-35-86   (hex)               Apple, Inc.\r
+EC3586     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
                                Cupertino  CA  95014\r
                                US\r
 \r
-08-00-09   (hex)               Hewlett Packard\r
-080009     (base 16)           Hewlett Packard\r
-                               ENTERPRISE SYSTEMS TECH.CENTER\r
-                               CUPERTINO  CA  95014\r
+88-CB-87   (hex)               Apple, Inc.\r
+88CB87     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-00-80-A0   (hex)               Hewlett Packard\r
-0080A0     (base 16)           Hewlett Packard\r
-                               ALAMEDA RIO NEGRO,\r
-                               houston  tx  77070\r
-                               BR\r
+AC-3C-0B   (hex)               Apple, Inc.\r
+AC3C0B     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-D4-85-64   (hex)               Hewlett Packard\r
-D48564     (base 16)           Hewlett Packard\r
-                               11445 Compaq Center Drive\r
-                               Houston    77070\r
+CC-78-5F   (hex)               Apple, Inc.\r
+CC785F     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-3C-4A-92   (hex)               Hewlett Packard\r
-3C4A92     (base 16)           Hewlett Packard\r
-                               11445 Compaq Center Drive\r
-                               Houston    77070\r
+E8-8D-28   (hex)               Apple, Inc.\r
+E88D28     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-78-0A-C7   (hex)               Baofeng TV Co., Ltd.\r
-780AC7     (base 16)           Baofeng TV Co., Ltd.\r
-                               Room 2D, Building 5D, Nanshan District Software Industry Base\r
-                               ShenZhen  GuangDong  518000\r
-                               CN\r
+14-10-9F   (hex)               Apple, Inc.\r
+14109F     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-00-1D-73   (hex)               BUFFALO.INC\r
-001D73     (base 16)           BUFFALO.INC\r
-                               15,Shibata Hondori 4-chome,\r
-                               Nagoya  Aichi Pref.  457-8520\r
-                               JP\r
+BC-52-B7   (hex)               Apple, Inc.\r
+BC52B7     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-00-16-01   (hex)               BUFFALO.INC\r
-001601     (base 16)           BUFFALO.INC\r
-                               AKAMONDORI Bldg., 30-20,Ohsu 3-chome\r
-                               Naka-ku,Nagoya  Aichi Pref.  460-8315\r
-                               JP\r
+E0-C9-7A   (hex)               Apple, Inc.\r
+E0C97A     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-10-6F-3F   (hex)               BUFFALO.INC\r
-106F3F     (base 16)           BUFFALO.INC\r
-                               AKAMONDORI Bldg., 30-20,Ohsu 3-chome\r
-                               Naka-ku,Nagoya  Aichi Pref.  460-8315\r
-                               JP\r
+5C-95-AE   (hex)               Apple, Inc.\r
+5C95AE     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-88-57-EE   (hex)               BUFFALO.INC\r
-8857EE     (base 16)           BUFFALO.INC\r
-                               AKAMONDORI Bld.,30-20,Ohsu 3-chome,Naka-ku\r
-                               Nagoya  Aichi Pref.  460-8315\r
-                               JP\r
+8C-FA-BA   (hex)               Apple, Inc.\r
+8CFABA     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-00-9C-02   (hex)               Hewlett Packard\r
-009C02     (base 16)           Hewlett Packard\r
-                               11445 Compaq Center Drive\r
-                               Houston    77070\r
+1C-AB-A7   (hex)               Apple, Inc.\r
+1CABA7     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-78-E7-D1   (hex)               Hewlett Packard\r
-78E7D1     (base 16)           Hewlett Packard\r
-                               11445 Compaq Center Drive\r
-                               Houston    77070\r
+60-FA-CD   (hex)               Apple, Inc.\r
+60FACD     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-00-1B-78   (hex)               Hewlett Packard\r
-001B78     (base 16)           Hewlett Packard\r
-                               20555 State Highway 249\r
-                               Houston  TX  77070\r
+68-09-27   (hex)               Apple, Inc.\r
+680927     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-00-1E-0B   (hex)               Hewlett Packard\r
-001E0B     (base 16)           Hewlett Packard\r
-                               20555 State Highway 249\r
-                               Houston  TX  77070\r
+78-A3-E4   (hex)               Apple, Inc.\r
+78A3E4     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-2C-6E-85   (hex)               Intel Corporate\r
-2C6E85     (base 16)           Intel Corporate\r
-                               Lot 8, Jalan Hi-Tech 2/3\r
-                               Kulim  Kedah  09000\r
-                               MY\r
+68-A8-6D   (hex)               Apple, Inc.\r
+68A86D     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-00-D0-B7   (hex)               Intel Corporation\r
-00D0B7     (base 16)           Intel Corporation\r
-                               5200 NE ELAM YOUNG PARKWAY\r
-                               HILLSBORO  OR  97124\r
+80-00-6E   (hex)               Apple, Inc.\r
+80006E     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-00-02-B3   (hex)               Intel Corporation\r
-0002B3     (base 16)           Intel Corporation\r
-                               M/S:  JF3-420\r
-                               Hillsboro  OR  97124\r
+B4-18-D1   (hex)               Apple, Inc.\r
+B418D1     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-00-11-11   (hex)               Intel Corporation\r
-001111     (base 16)           Intel Corporation\r
-                               2111 NE 25th Avenue\r
-                               Hillsboro  OR  97124\r
+14-99-E2   (hex)               Apple, Inc.\r
+1499E2     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-00-13-20   (hex)               Intel Corporate\r
-001320     (base 16)           Intel Corporate\r
-                               Lot 8, Jalan Hi-tech 2/3\r
-                               Kulim  Kedah  09000\r
-                               MY\r
+1C-9E-46   (hex)               Apple, Inc.\r
+1C9E46     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-00-12-F0   (hex)               Intel Corporate\r
-0012F0     (base 16)           Intel Corporate\r
-                               Lot 8, Jalan Hi-tech 2/3\r
-                               Kulim  Kedah  09000\r
-                               MY\r
+E0-C7-67   (hex)               Apple, Inc.\r
+E0C767     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-90-49-FA   (hex)               Intel Corporate\r
-9049FA     (base 16)           Intel Corporate\r
-                               Lot 8, Jalan Hi-Tech 2/3\r
-                               Kulim  Kedah  09000\r
-                               MY\r
+A8-60-B6   (hex)               Apple, Inc.\r
+A860B6     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-C8-34-8E   (hex)               Intel Corporate\r
-C8348E     (base 16)           Intel Corporate\r
-                               Lot 8, Jalan Hi-Tech 2/3\r
-                               Kulim  Kedah  09000\r
-                               MY\r
+24-F0-94   (hex)               Apple, Inc.\r
+24F094     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-00-50-8B   (hex)               Hewlett Packard\r
-00508B     (base 16)           Hewlett Packard\r
-                               20555 State Highway 249\r
-                               Houston  TX  77070\r
+90-B0-ED   (hex)               Apple, Inc.\r
+90B0ED     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-78-48-59   (hex)               Hewlett Packard\r
-784859     (base 16)           Hewlett Packard\r
-                               11445 Compaq Center Drive\r
-                               Houston    77070\r
+C4-B3-01   (hex)               Apple, Inc.\r
+C4B301     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-14-58-D0   (hex)               Hewlett Packard\r
-1458D0     (base 16)           Hewlett Packard\r
-                               11445 Compaq Center Drive\r
-                               Houston    77070\r
+E0-5F-45   (hex)               Apple, Inc.\r
+E05F45     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-50-65-F3   (hex)               Hewlett Packard\r
-5065F3     (base 16)           Hewlett Packard\r
-                               11445 Compaq Center Drive\r
-                               Houston    77070\r
+48-3B-38   (hex)               Apple, Inc.\r
+483B38     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-A0-48-1C   (hex)               Hewlett Packard\r
-A0481C     (base 16)           Hewlett Packard\r
-                               11445 Compaq Center Drive\r
-                               Houston    77070\r
+88-E8-7F   (hex)               Apple, Inc.\r
+88E87F     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-A0-1D-48   (hex)               Hewlett Packard\r
-A01D48     (base 16)           Hewlett Packard\r
-                               11445 Compaq Center Drive\r
-                               Houston    77070\r
+B8-53-AC   (hex)               Apple, Inc.\r
+B853AC     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-94-B2-CC   (hex)               PIONEER CORPORATION\r
-94B2CC     (base 16)           PIONEER CORPORATION\r
-                               1-1 Shin-ogura\r
-                               Kawasaki-shi  Kanagawa Prefecture  2120031\r
-                               JP\r
+2C-33-61   (hex)               Apple, Inc.\r
+2C3361     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-88-7F-03   (hex)               Comper Technology Investment Limited\r
-887F03     (base 16)           Comper Technology Investment Limited\r
-                               Room 710, Wangjing SOHO Tower 1-B\r
-                               Beijing  Beijing  100102\r
-                               CN\r
+00-0A-27   (hex)               Apple, Inc.\r
+000A27     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-E0-60-66   (hex)               Sercomm Corporation\r
-E06066     (base 16)           Sercomm Corporation\r
-                               8F, 3-1, YuanQu St., NanKang,\r
-                               Taipei  Taiwan  115\r
-                               TW\r
+00-30-65   (hex)               Apple, Inc.\r
+003065     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-00-19-E0   (hex)               TP-LINK TECHNOLOGIES CO.,LTD.\r
-0019E0     (base 16)           TP-LINK TECHNOLOGIES CO.,LTD.\r
-                               South Building, No.5 Keyuan Road\r
-                               Nanshan  Shenzhen  518057\r
-                               CN\r
+00-50-E4   (hex)               Apple, Inc.\r
+0050E4     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-00-23-CD   (hex)               TP-LINK TECHNOLOGIES CO.,LTD.\r
-0023CD     (base 16)           TP-LINK TECHNOLOGIES CO.,LTD.\r
-                               South Building, No.5 Keyuan Road, Central Zone,\r
-                               Shenzhen  Guangdong  518000\r
-                               CN\r
+BC-92-6B   (hex)               Apple, Inc.\r
+BC926B     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-00-27-19   (hex)               TP-LINK TECHNOLOGIES CO.,LTD.\r
-002719     (base 16)           TP-LINK TECHNOLOGIES CO.,LTD.\r
-                               Building 7, Second Part, Honghualing Industrial Zone\r
-                               Shenzhen  Guangdong  518057\r
-                               CN\r
+04-52-F3   (hex)               Apple, Inc.\r
+0452F3     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-40-16-9F   (hex)               TP-LINK TECHNOLOGIES CO.,LTD.\r
-40169F     (base 16)           TP-LINK TECHNOLOGIES CO.,LTD.\r
-                               1-6F, Building 2, Pingshandayuan Industrial, South Zone,\r
-                               Shenzhen  Guangdong  518000\r
-                               CN\r
+24-1E-EB   (hex)               Apple, Inc.\r
+241EEB     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-94-0C-6D   (hex)               TP-LINK TECHNOLOGIES CO.,LTD.\r
-940C6D     (base 16)           TP-LINK TECHNOLOGIES CO.,LTD.\r
-                               Building 7, Second Part, Honghualing Industrial Zone\r
-                               Shenzhen  Guangdong  518000\r
-                               CN\r
+F4-31-C3   (hex)               Apple, Inc.\r
+F431C3     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-74-EA-3A   (hex)               TP-LINK TECHNOLOGIES CO.,LTD.\r
-74EA3A     (base 16)           TP-LINK TECHNOLOGIES CO.,LTD.\r
-                               Building 7, Second Part, Honghualing Industrial Zone\r
-                               Shenzhen  Guangdong  518000\r
-                               CN\r
+64-A5-C3   (hex)               Apple, Inc.\r
+64A5C3     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-90-F6-52   (hex)               TP-LINK TECHNOLOGIES CO.,LTD.\r
-90F652     (base 16)           TP-LINK TECHNOLOGIES CO.,LTD.\r
-                               Building 24 (floors 1,3,4,5) and 28 (floors1-4)  Central Science and Technology Park,Shennan Rd, Nanshan,\r
-                               Shenzhen  Guangdong Province,  518057\r
-                               CN\r
+60-69-44   (hex)               Apple, Inc.\r
+606944     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-10-FE-ED   (hex)               TP-LINK TECHNOLOGIES CO.,LTD.\r
-10FEED     (base 16)           TP-LINK TECHNOLOGIES CO.,LTD.\r
-                               Building 24 (floors 1,3,4,5) and 28 (floors1-4)  Central Science and Technology Park\r
-                               Shenzhen  Guangdong  518057\r
-                               CN\r
+E4-98-D6   (hex)               Apple, Inc.\r
+E498D6     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-C4-6E-1F   (hex)               TP-LINK TECHNOLOGIES CO.,LTD.\r
-C46E1F     (base 16)           TP-LINK TECHNOLOGIES CO.,LTD.\r
-                               Building 24 (floors 1,3,4,5) and 28 (floors1-4)\r
-                               Shennan Rd, Nanshan  Shenzhen,Guangdong Province  518057\r
-                               CN\r
+0C-D7-46   (hex)               Apple, Inc.\r
+0CD746     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+44-00-10   (hex)               Apple, Inc.\r
+440010     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+78-4F-43   (hex)               Apple, Inc.\r
+784F43     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+40-4D-7F   (hex)               Apple, Inc.\r
+404D7F     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+7C-04-D0   (hex)               Apple, Inc.\r
+7C04D0     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+BC-9F-EF   (hex)               Apple, Inc.\r
+BC9FEF     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+88-66-A5   (hex)               Apple, Inc.\r
+8866A5     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+70-F0-87   (hex)               Apple, Inc.\r
+70F087     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+88-6B-6E   (hex)               Apple, Inc.\r
+886B6E     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+4C-74-BF   (hex)               Apple, Inc.\r
+4C74BF     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+84-41-67   (hex)               Apple, Inc.\r
+844167     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+B4-F6-1C   (hex)               Apple, Inc.\r
+B4F61C     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+E4-9A-DC   (hex)               Apple, Inc.\r
+E49ADC     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+B8-C1-11   (hex)               Apple, Inc.\r
+B8C111     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+34-08-BC   (hex)               Apple, Inc.\r
+3408BC     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+D0-81-7A   (hex)               Apple, Inc.\r
+D0817A     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+C4-61-8B   (hex)               Apple, Inc.\r
+C4618B     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+68-AB-1E   (hex)               Apple, Inc.\r
+68AB1E     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+2C-61-F6   (hex)               Apple, Inc.\r
+2C61F6     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+00-26-BB   (hex)               Apple, Inc.\r
+0026BB     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+00-25-4B   (hex)               Apple, Inc.\r
+00254B     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+00-24-36   (hex)               Apple, Inc.\r
+002436     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+00-23-32   (hex)               Apple, Inc.\r
+002332     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+00-23-12   (hex)               Apple, Inc.\r
+002312     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+00-19-E3   (hex)               Apple, Inc.\r
+0019E3     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+00-14-51   (hex)               Apple, Inc.\r
+001451     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+50-DC-E7   (hex)               Amazon Technologies Inc.\r
+50DCE7     (base 16)           Amazon Technologies Inc.\r
+                               P.O Box 8102\r
+                               Reno  NV  89507\r
+                               US\r
+\r
+04-09-73   (hex)               Hewlett Packard Enterprise\r
+040973     (base 16)           Hewlett Packard Enterprise\r
+                               8000 Foothills Blvd.\r
+                               Roseville  CA  95747\r
+                               US\r
+\r
+4C-C2-06   (hex)               Somfy\r
+4CC206     (base 16)           Somfy\r
+                               50 avenue du nouveau monde\r
+                               Cluses    74300\r
+                               FR\r
+\r
+70-F2-20   (hex)               Actiontec Electronics, Inc\r
+70F220     (base 16)           Actiontec Electronics, Inc\r
+                               760 North Mary Ave\r
+                               Sunnyvale  CA  94085\r
+                               US\r
+\r
+28-57-67   (hex)               Dish Technologies Corp\r
+285767     (base 16)           Dish Technologies Corp\r
+                               94 Inverness Terrace E\r
+                               Englewood  CO  80112\r
+                               US\r
+\r
+70-55-F8   (hex)               Cerebras Systems Inc\r
+7055F8     (base 16)           Cerebras Systems Inc\r
+                               175 S San Antonio Rd #100\r
+                               Los Altos  CA  94022\r
+                               US\r
+\r
+04-C9-D9   (hex)               Dish Technologies Corp\r
+04C9D9     (base 16)           Dish Technologies Corp\r
+                               94 Inverness Terrace E\r
+                               Englewood  CO  80112\r
+                               US\r
+\r
+00-24-AF   (hex)               Dish Technologies Corp\r
+0024AF     (base 16)           Dish Technologies Corp\r
+                               94 Inverness Terrace E\r
+                               Englewood  CO  80112\r
+                               US\r
+\r
+9C-43-1E   (hex)               IEEE Registration Authority\r
+9C431E     (base 16)           IEEE Registration Authority\r
+                               445 Hoes Lane\r
+                               Piscataway  NJ  08554\r
+                               US\r
+\r
+80-C5-48   (hex)               Shenzhen Zowee Technology Co.,Ltd\r
+80C548     (base 16)           Shenzhen Zowee Technology Co.,Ltd\r
+                               NO.5 Zowee technology building, Science & Technology industrial park of privately  Science & Technology industrial park of privately owned enterprises\r
+                               Shenzhen  GuangDong  518055\r
+                               CN\r
+\r
+6C-54-CD   (hex)               LAMPEX ELECTRONICS LIMITED\r
+6C54CD     (base 16)           LAMPEX ELECTRONICS LIMITED\r
+                               6-2/231/B, Kukatpally,\r
+                               Hyderabad  Telangana  500072\r
+                               IN\r
+\r
+88-3D-24   (hex)               Google, Inc.\r
+883D24     (base 16)           Google, Inc.\r
+                               1600 Amphitheatre Parkway\r
+                               Mountain View  CA  94043\r
+                               US\r
+\r
+E8-DE-FB   (hex)               MESOTIC SAS\r
+E8DEFB     (base 16)           MESOTIC SAS\r
+                               11, Avenue de la Division Leclerc\r
+                               Cachan    94230\r
+                               FR\r
+\r
+90-84-8B   (hex)               HDR10+ Technologies, LLC\r
+90848B     (base 16)           HDR10+ Technologies, LLC\r
+                               3855 SW 153rd Drive\r
+                               Beaverton  OR  97006\r
+                               US\r
+\r
+0C-23-69   (hex)               Honeywell SPS\r
+0C2369     (base 16)           Honeywell SPS\r
+                               700 Visions Dr.\r
+                               Skaneateles Falls  NY  13153\r
+                               US\r
+\r
+8C-16-45   (hex)               LCFC(HeFei) Electronics Technology co., ltd\r
+8C1645     (base 16)           LCFC(HeFei) Electronics Technology co., ltd\r
+                               YunGu Road 3188-1\r
+                               Hefei  Anhui  230000\r
+                               CN\r
+\r
+B4-E9-A3   (hex)               port GmbH\r
+B4E9A3     (base 16)           port GmbH\r
+                               Regensburger Str. 7b\r
+                               Halle (S.)    06132\r
+                               DE\r
+\r
+6C-B6-CA   (hex)               DIVUS GmbH\r
+6CB6CA     (base 16)           DIVUS GmbH\r
+                               Pillhof 51\r
+                               Eppan    39057\r
+                               IT\r
+\r
+B8-DE-5E   (hex)               LONGCHEER TELECOMMUNICATION LIMITED\r
+B8DE5E     (base 16)           LONGCHEER TELECOMMUNICATION LIMITED\r
+                               Building 1,No.401,Caobao Rd\r
+                               Shanghai  Xuhui District  200233\r
+                               CN\r
+\r
+DC-DD-24   (hex)               Energica Motor Company SpA\r
+DCDD24     (base 16)           Energica Motor Company SpA\r
+                               Via Cesare della Chiesa, 150\r
+                               MODENA (MO)  Mo  41126\r
+                               IT\r
+\r
+94-63-72   (hex)               vivo Mobile Communication Co., Ltd.\r
+946372     (base 16)           vivo Mobile Communication Co., Ltd.\r
+                               #283,BBK Road\r
+                               Wusha,Chang'An  DongGuan City,Guangdong,  523860\r
+                               CN\r
+\r
+44-9E-F9   (hex)               vivo Mobile Communication Co., Ltd.\r
+449EF9     (base 16)           vivo Mobile Communication Co., Ltd.\r
+                               #283,BBK Road\r
+                               Wusha,Chang'An  DongGuan City,Guangdong,  523860\r
+                               CN\r
+\r
+64-1C-B0   (hex)               Samsung Electronics Co.,Ltd\r
+641CB0     (base 16)           Samsung Electronics Co.,Ltd\r
+                               129, Samsung-ro, Youngtongl-Gu\r
+                               Suwon  Gyeonggi-Do  16677\r
+                               KR\r
+\r
+8C-F9-57   (hex)               RuiXingHengFang Network (Shenzhen) Co.,Ltd\r
+8CF957     (base 16)           RuiXingHengFang Network (Shenzhen) Co.,Ltd\r
+                               Room 507, 2nd tower of KangTai biological building  NO.6 KeFa Rd. NanShan District\r
+                               Shenzhen  Guangdong  518057\r
+                               CN\r
+\r
+00-1B-D8   (hex)               FLIR Systems Inc\r
+001BD8     (base 16)           FLIR Systems Inc\r
+                               65 Challenger Road\r
+                               Ridgefield Park  NJ  07660-2103\r
+                               US\r
+\r
+20-36-5B   (hex)               Megafone Limited\r
+20365B     (base 16)           Megafone Limited\r
+                               Unit 702,7/F,Bankok Bank Building,NO.18 Bonham Strand West\r
+                               Hong Kong    999077\r
+                               HK\r
+\r
+E8-DE-00   (hex)               ChongQing GuanFang Technology Co.,LTD\r
+E8DE00     (base 16)           ChongQing GuanFang Technology Co.,LTD\r
+                               2F, A District,No.3 Middle Section of Mount Huangshan Avenue\r
+                               ChongQing  ChongQing  401121\r
+                               CN\r
+\r
+3C-DC-BC   (hex)               Samsung Electronics Co.,Ltd\r
+3CDCBC     (base 16)           Samsung Electronics Co.,Ltd\r
+                               #94-1, Imsoo-Dong\r
+                               Gumi  Gyeongbuk  730-350\r
+                               KR\r
+\r
+F4-71-90   (hex)               Samsung Electronics Co.,Ltd\r
+F47190     (base 16)           Samsung Electronics Co.,Ltd\r
+                               #94-1, Imsoo-Dong\r
+                               Gumi  Gyeongbuk  730-350\r
+                               KR\r
+\r
+4C-77-6D   (hex)               Cisco Systems, Inc\r
+4C776D     (base 16)           Cisco Systems, Inc\r
+                               80 West Tasman Drive\r
+                               San Jose  CA  94568\r
+                               US\r
+\r
+FC-A6-CD   (hex)               Fiberhome Telecommunication Technologies Co.,LTD\r
+FCA6CD     (base 16)           Fiberhome Telecommunication Technologies Co.,LTD\r
+                               No.5 DongXin Road\r
+                               Wuhan  Hubei  430074\r
+                               CN\r
+\r
+64-DB-8B   (hex)               Hangzhou Hikvision Digital Technology Co.,Ltd.\r
+64DB8B     (base 16)           Hangzhou Hikvision Digital Technology Co.,Ltd.\r
+                               No.555 Qianmo Road\r
+                               Hangzhou  Zhejiang  310052\r
+                               CN\r
+\r
+78-25-7A   (hex)               LEO Innovation Lab\r
+78257A     (base 16)           LEO Innovation Lab\r
+                               Silkegade 8\r
+                               Copenhagen K  Denmark  1113\r
+                               DK\r
+\r
+A4-DA-22   (hex)               IEEE Registration Authority\r
+A4DA22     (base 16)           IEEE Registration Authority\r
+                               445 Hoes Lane\r
+                               Piscataway  NJ  08554\r
+                               US\r
+\r
+00-03-97   (hex)               FireBrick Limited\r
+000397     (base 16)           FireBrick Limited\r
+                               C/O Andrews & Arnold Ltd, \r
+                               Enterprise Court, Downmill Road  Bracknell, Berks  RG12 1QS\r
+                               GB\r
+\r
+A8-61-0A   (hex)               ARDUINO AG\r
+A8610A     (base 16)           ARDUINO AG\r
+                               Corso San Gottardo 6A\r
+                               Chiasso    6830\r
+                               CH\r
+\r
+60-97-DD   (hex)               MicroSys Electronics GmbH\r
+6097DD     (base 16)           MicroSys Electronics GmbH\r
+                               Muehlweg 1\r
+                               Sauerlach    82054\r
+                               DE\r
+\r
+04-79-70   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
+047970     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
+                               No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park\r
+                               Dongguan    523808\r
+                               CN\r
+\r
+C4-9F-4C   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
+C49F4C     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
+                               No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park\r
+                               Dongguan    523808\r
+                               CN\r
+\r
+A0-57-E3   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
+A057E3     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
+                               No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park\r
+                               Dongguan    523808\r
+                               CN\r
+\r
+E0-E6-2E   (hex)               TCT mobile ltd\r
+E0E62E     (base 16)           TCT mobile ltd\r
+                               No.86 hechang 7th road, zhongkai, Hi-Tech District\r
+                               Hui Zhou  Guang Dong  516006\r
+                               CN\r
+\r
+00-A0-85   (hex)               Private\r
+00A085     (base 16)           Private\r
+\r
+94-B8-6D   (hex)               Intel Corporate\r
+94B86D     (base 16)           Intel Corporate\r
+                               Lot 8, Jalan Hi-Tech 2/3\r
+                               Kulim  Kedah  09000\r
+                               MY\r
+\r
+F8-8B-37   (hex)               ARRIS Group, Inc.\r
+F88B37     (base 16)           ARRIS Group, Inc.\r
+                               6450 Sequence Drive\r
+                               San Diego  CA  92121\r
+                               US\r
+\r
+30-FD-38   (hex)               Google, Inc.\r
+30FD38     (base 16)           Google, Inc.\r
+                               1600 Amphitheatre Parkway\r
+                               Mountain View  CA  94043\r
+                               US\r
+\r
+18-50-2A   (hex)               SOARNEX\r
+18502A     (base 16)           SOARNEX\r
+                               NO.158, RUIHU ST., NEIHU DIST.,\r
+                               TAIPEI CITY  TAIWAN (R.O.C.)  11494\r
+                               TW\r
+\r
+58-7A-6A   (hex)               GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD\r
+587A6A     (base 16)           GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD\r
+                               NO.18 HAIBIN ROAD,\r
+                               DONG GUAN  GUANG DONG  523860\r
+                               CN\r
+\r
+E4-C4-83   (hex)               GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD\r
+E4C483     (base 16)           GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD\r
+                               NO.18 HAIBIN ROAD,\r
+                               DONG GUAN  GUANG DONG  523860\r
+                               CN\r
+\r
+F4-E1-1E   (hex)               Texas Instruments\r
+F4E11E     (base 16)           Texas Instruments\r
+                               12500 TI Blvd\r
+                               Dallas  TX  75243\r
+                               US\r
+\r
+30-45-11   (hex)               Texas Instruments\r
+304511     (base 16)           Texas Instruments\r
+                               12500 TI Blvd\r
+                               Dallas  TX  75243\r
+                               US\r
+\r
+34-03-DE   (hex)               Texas Instruments\r
+3403DE     (base 16)           Texas Instruments\r
+                               12500 TI Blvd\r
+                               Dallas  TX  75243\r
+                               US\r
+\r
+10-E7-C6   (hex)               Hewlett Packard\r
+10E7C6     (base 16)           Hewlett Packard\r
+                               11445 Compaq Center Drive\r
+                               Houston  TX  77070\r
+                               US\r
+\r
+20-F5-43   (hex)               Hui Zhou Gaoshengda Technology Co.,LTD\r
+20F543     (base 16)           Hui Zhou Gaoshengda Technology Co.,LTD\r
+                               No.75,Zhongkai High-Tech Development District,Huizhou\r
+                               Hui Zhou  Guangdong  516006\r
+                               CN\r
+\r
+1C-1E-E3   (hex)               Hui Zhou Gaoshengda Technology Co.,LTD\r
+1C1EE3     (base 16)           Hui Zhou Gaoshengda Technology Co.,LTD\r
+                               No.75,Zhongkai High-Tech Development District,Huizhou\r
+                               Hui Zhou  Guangdong  516006\r
+                               CN\r
+\r
+0C-91-60   (hex)               Hui Zhou Gaoshengda Technology Co.,LTD\r
+0C9160     (base 16)           Hui Zhou Gaoshengda Technology Co.,LTD\r
+                               No.75,Zhongkai High-Tech Development District,Huizhou\r
+                               Hui Zhou  Guangdong  516006\r
+                               CN\r
+\r
+0C-62-A6   (hex)               Hui Zhou Gaoshengda Technology Co.,LTD\r
+0C62A6     (base 16)           Hui Zhou Gaoshengda Technology Co.,LTD\r
+                               No.75,Zhongkai High-Tech Development District,Huizhou\r
+                               Hui Zhou  Guangdong  516006\r
+                               CN\r
+\r
+7C-49-EB   (hex)               XIAOMI Electronics,CO.,LTD\r
+7C49EB     (base 16)           XIAOMI Electronics,CO.,LTD\r
+                               Xiaomi Building, No.68 Qinghe Middle Street,Haidian District\r
+                               Beijing  Beijing  100085\r
+                               CN\r
+\r
+C4-33-06   (hex)               China Mobile Group Device Co.,Ltd.\r
+C43306     (base 16)           China Mobile Group Device Co.,Ltd.\r
+                               32 Xuanwumen West Street,Xicheng District\r
+                               Beijing    100053\r
+                               CN\r
+\r
+68-FE-DA   (hex)               Fiberhome Telecommunication Technologies Co.,LTD\r
+68FEDA     (base 16)           Fiberhome Telecommunication Technologies Co.,LTD\r
+                               No.5 DongXin Road\r
+                               Wuhan  Hubei  430074\r
+                               CN\r
+\r
+0C-6A-BC   (hex)               Fiberhome Telecommunication Technologies Co.,LTD\r
+0C6ABC     (base 16)           Fiberhome Telecommunication Technologies Co.,LTD\r
+                               No.5 DongXin Road\r
+                               Wuhan  Hubei  430074\r
+                               CN\r
+\r
+D4-C1-9E   (hex)               Ruckus Wireless\r
+D4C19E     (base 16)           Ruckus Wireless\r
+                               350 West Java Drive\r
+                               Sunnyvale  CA  94089\r
+                               US\r
+\r
+00-01-B9   (hex)               SKF (U.K.) Limited\r
+0001B9     (base 16)           SKF (U.K.) Limited\r
+                               2 Michaelson Square Kirkton Campus\r
+                               Livingston    West Lothian  EH54 7DP\r
+                               GB\r
+\r
+64-C3-D6   (hex)               Juniper Networks\r
+64C3D6     (base 16)           Juniper Networks\r
+                               1133 Innovation Way\r
+                               Sunnyvale  CA  94089\r
+                               US\r
+\r
+58-46-E1   (hex)               Baxter International Inc\r
+5846E1     (base 16)           Baxter International Inc\r
+                               One Baxter Parkway\r
+                               Deerfield  IL  60015\r
+                               US\r
+\r
+00-D0-BD   (hex)               Lattice Semiconductor Corp. (LPA)\r
+00D0BD     (base 16)           Lattice Semiconductor Corp. (LPA)\r
+                               2115 O’Nel Drive\r
+                               San Jose  CA  95131\r
+                               US\r
+\r
+F0-82-61   (hex)               Sagemcom Broadband SAS\r
+F08261     (base 16)           Sagemcom Broadband SAS\r
+                               250 route de l'Empereur\r
+                               Rueil Malmaison  HAUTS DE SEINE  92848\r
+                               FR\r
+\r
+D0-84-B0   (hex)               Sagemcom Broadband SAS\r
+D084B0     (base 16)           Sagemcom Broadband SAS\r
+                               250 route de l'Empereur\r
+                               Rueil Malmaison  HAUTS DE SEINE  92848\r
+                               FR\r
+\r
+00-FE-C8   (hex)               Cisco Systems, Inc\r
+00FEC8     (base 16)           Cisco Systems, Inc\r
+                               80 West Tasman Drive\r
+                               San Jose  CA  94568\r
+                               US\r
+\r
+EC-22-80   (hex)               D-Link International\r
+EC2280     (base 16)           D-Link International\r
+                               1 Internal Business Park, #03-12,\r
+                               SINGAPORE  Singapore  609917\r
+                               SG\r
+\r
+04-78-63   (hex)               Shanghai MXCHIP Information Technology Co., Ltd.\r
+047863     (base 16)           Shanghai MXCHIP Information Technology Co., Ltd.\r
+                               9th Floor, No. 5 Building, 2145 Jinshajiang Rd., Putuo District\r
+                               Shanghai    200333\r
+                               CN\r
+\r
+24-BA-13   (hex)               RISO KAGAKU CORPORATION\r
+24BA13     (base 16)           RISO KAGAKU CORPORATION\r
+                               2-8-1 Gakuen-minami\r
+                               Thukuba-shi  Ibaraki  305-0818\r
+                               JP\r
+\r
+24-DA-11   (hex)               NO NDA Inc\r
+24DA11     (base 16)           NO NDA Inc\r
+                               828 Bryant St \r
+                               Palo Alto  IA  94301\r
+                               US\r
+\r
+70-CA-4D   (hex)               Shenzhen lnovance Technology Co.,Ltd.\r
+70CA4D     (base 16)           Shenzhen lnovance Technology Co.,Ltd.\r
+                               LiuXian 2 Road\r
+                               Shenzhen  Guangdong  518000\r
+                               CN\r
+\r
+DC-C0-EB   (hex)               ASSA ABLOY CÔTE PICARDE\r
+DCC0EB     (base 16)           ASSA ABLOY CÔTE PICARDE\r
+                               rue Alexandre Fichet\r
+                               Oust-Marest    80460\r
+                               FR\r
+\r
+00-17-35   (hex)               Intel Wireless Network Group\r
+001735     (base 16)           Intel Wireless Network Group\r
+                               2111 NE 25th Ave\r
+                               Hillsboro  OR  97124\r
+                               US\r
+\r
+9C-DF-B1   (hex)               Shenzhen Crave Communication Co., LTD\r
+9CDFB1     (base 16)           Shenzhen Crave Communication Co., LTD\r
+                               F3,8Building,DongFangMing IndustryZone,No.83 DabaoRD.,33 District BaoAn\r
+                               Shenzhen  Guangdong  518000\r
+                               CN\r
+\r
+0C-C7-31   (hex)               Currant, Inc.\r
+0CC731     (base 16)           Currant, Inc.\r
+                               927 Industrial Ave\r
+                               Palo Alto  CA  94303\r
+                               US\r
+\r
+00-14-2F   (hex)               Savvius\r
+00142F     (base 16)           Savvius\r
+                               1340 Treat Boulevard, Suite 500\r
+                               Walnut Creek  CA  94597\r
+                               US\r
+\r
+2C-DD-A3   (hex)               Point Grey Research Inc.\r
+2CDDA3     (base 16)           Point Grey Research Inc.\r
+                               305-1847 West Broadway\r
+                               Vancouver  British Columbia V6J 1Y6  \r
+                               CA\r
+\r
+24-FD-5B   (hex)               SmartThings, Inc.\r
+24FD5B     (base 16)           SmartThings, Inc.\r
+                               456 University Avenue\r
+                               Palo Alto  CA  94301\r
+                               US\r
+\r
+28-76-CD   (hex)               Funshion Online Technologies Co.,Ltd\r
+2876CD     (base 16)           Funshion Online Technologies Co.,Ltd\r
+                               Tower B 1201, Jinqiu International Building, No.6, Zhichun Road, Haidian District\r
+                               Beijing    100088\r
+                               CN\r
+\r
+F4-F5-D8   (hex)               Google, Inc.\r
+F4F5D8     (base 16)           Google, Inc.\r
+                               1600 Amphitheatre Parkway\r
+                               Mountain View  CA  94043\r
+                               US\r
+\r
+F4-F5-E8   (hex)               Google, Inc.\r
+F4F5E8     (base 16)           Google, Inc.\r
+                               1600 Amphitheatre Parkway\r
+                               Mountain View    94043\r
+                               US\r
+\r
+F8-8F-CA   (hex)               Google, Inc.\r
+F88FCA     (base 16)           Google, Inc.\r
+                               1600 Amphitheatre Parkway\r
+                               Mountain View    94043\r
+                               US\r
+\r
+BC-D1-D3   (hex)               Shenzhen TINNO Mobile Technology Corp.\r
+BCD1D3     (base 16)           Shenzhen TINNO Mobile Technology Corp.\r
+                               4/F.,H-3 Building,OCT Eastern lndustrial Park.\r
+                               Nanshan, Shenzhen  GUANGDONG  518053\r
+                               CN\r
+\r
+BC-44-34   (hex)               Shenzhen TINNO Mobile Technology Corp.\r
+BC4434     (base 16)           Shenzhen TINNO Mobile Technology Corp.\r
+                               4/F, H-3 Building, Qiao Cheng Eastern Industrial Park, Overseas Chinese Town, Shenzhen \r
+                               Shenzhen   guangdong  518053\r
+                               CN\r
+\r
+00-41-D2   (hex)               Cisco Systems, Inc\r
+0041D2     (base 16)           Cisco Systems, Inc\r
+                               80 West Tasman Drive\r
+                               San Jose  CA  94568\r
+                               US\r
+\r
+4C-FB-45   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
+4CFB45     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
+                               No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park\r
+                               Dongguan  Guangdong  523808 \r
+                               CN\r
+\r
+A4-BA-76   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
+A4BA76     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
+                               No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park\r
+                               Dongguan  Guangdong  523808 \r
+                               CN\r
+\r
+78-E3-B5   (hex)               Hewlett Packard\r
+78E3B5     (base 16)           Hewlett Packard\r
+                               11445 Compaq Center Drive\r
+                               Houston    77070\r
+                               US\r
+\r
+98-4B-E1   (hex)               Hewlett Packard\r
+984BE1     (base 16)           Hewlett Packard\r
+                               11445 Compaq Center Drive\r
+                               Houston    77070\r
+                               US\r
+\r
+68-B5-99   (hex)               Hewlett Packard\r
+68B599     (base 16)           Hewlett Packard\r
+                               11445 Compaq Center Drive\r
+                               Houston    77070\r
+                               US\r
+\r
+14-D6-4D   (hex)               D-Link International\r
+14D64D     (base 16)           D-Link International\r
+                               1 INTERNATIONAL BUSINESS PARK\r
+                               SINGAPORE    609917\r
+                               SG\r
+\r
+C8-BE-19   (hex)               D-Link International\r
+C8BE19     (base 16)           D-Link International\r
+                               1 International Business Park, #03-12, The Synergy \r
+                               SINGAPORE    609917\r
+                               SG\r
+\r
+BC-F6-85   (hex)               D-Link International\r
+BCF685     (base 16)           D-Link International\r
+                               1 International Business Park, #03-12, The Synergy \r
+                               SINGAPORE    609917\r
+                               SG\r
+\r
+CC-B2-55   (hex)               D-Link International\r
+CCB255     (base 16)           D-Link International\r
+                               1 International Business Park, #03-12, The Synergy \r
+                               SINGAPORE    609917\r
+                               SG\r
+\r
+84-C9-B2   (hex)               D-Link International\r
+84C9B2     (base 16)           D-Link International\r
+                               1 International Business Park, #03-12, The Synergy \r
+                               SINGAPORE    609917\r
+                               SG\r
+\r
+DC-D3-21   (hex)               HUMAX Co., Ltd.\r
+DCD321     (base 16)           HUMAX Co., Ltd.\r
+                               HUMAX Village, 11-4, Sunae-dong, Bundang-gu\r
+                               Seongnam-si  Gyeonggi-do  463-825\r
+                               KR\r
+\r
+CC-4E-EC   (hex)               HUMAX Co., Ltd.\r
+CC4EEC     (base 16)           HUMAX Co., Ltd.\r
+                               HUMAX Village, 216, Hwangsaeul-ro, Bundang-gu,\r
+                               Seongnam-si  Gyeonggi-do  463-875\r
+                               KR\r
+\r
+DC-33-0D   (hex)               Qingdao Haier Telecom Co.,Ltd\r
+DC330D     (base 16)           Qingdao Haier Telecom Co.,Ltd\r
+                               No 1  Haier road,Hi-tech Zone,Qingdao,PR.China\r
+                               Qingdao  Shandong  266101\r
+                               CN\r
+\r
+00-80-E1   (hex)               STMicroelectronics SRL\r
+0080E1     (base 16)           STMicroelectronics SRL\r
+                               1000 AZTEC WEST\r
+                               london    12345\r
+                               GB\r
+\r
+58-DC-6D   (hex)               Exceptional Innovation, Inc.\r
+58DC6D     (base 16)           Exceptional Innovation, Inc.\r
+                               480 Olde Worthington Rd, Suite 350\r
+                               Westerville  OH  43082\r
+                               US\r
+\r
+00-09-2D   (hex)               HTC Corporation\r
+00092D     (base 16)           HTC Corporation\r
+                               No.23 Xinghua Road,\r
+                               Taoyuan County     330\r
+                               TW\r
+\r
+F8-DB-7F   (hex)               HTC Corporation\r
+F8DB7F     (base 16)           HTC Corporation\r
+                               No.23 Xinghua Road\r
+                               Taoyuan County    330\r
+                               TW\r
+\r
+E8-99-C4   (hex)               HTC Corporation\r
+E899C4     (base 16)           HTC Corporation\r
+                               No. 23, Xinghua Rd., Taoyuan City\r
+                               Taoyuan County  Taiwan  330\r
+                               TW\r
+\r
+7C-B1-5D   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
+7CB15D     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
+                               No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park\r
+                               Dongguan  Guangdong  523808 \r
+                               CN\r
+\r
+18-68-6A   (hex)               zte corporation\r
+18686A     (base 16)           zte corporation\r
+                               12/F.,zte R&D building ,kejinan Road,Shenzhen,P.R.China\r
+                               shenzhen  guangdong  518057\r
+                               CN\r
+\r
+0C-05-35   (hex)               Juniper Systems\r
+0C0535     (base 16)           Juniper Systems\r
+                               1132 W. 1700 N.\r
+                               Logan  UT  84321\r
+                               US\r
+\r
+8C-F2-28   (hex)               SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD.\r
+8CF228     (base 16)           SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD.\r
+                               Mid-Fourth Flr.,Building 28,Cui Xi Fourth Road,Ke Yuan West,Nanshan\r
+                               Shenzhen  Guangdong  518057\r
+                               CN\r
+\r
+88-51-FB   (hex)               Hewlett Packard\r
+8851FB     (base 16)           Hewlett Packard\r
+                               11445 Compaq Center Drive\r
+                               Houston    77070\r
+                               US\r
+\r
+AC-16-2D   (hex)               Hewlett Packard\r
+AC162D     (base 16)           Hewlett Packard\r
+                               11445 Compaq Center Drive\r
+                               Houston    77070\r
+                               US\r
+\r
+A0-B3-CC   (hex)               Hewlett Packard\r
+A0B3CC     (base 16)           Hewlett Packard\r
+                               11445 Compaq Center Drive\r
+                               Houston    77070\r
+                               US\r
+\r
+E4-11-5B   (hex)               Hewlett Packard\r
+E4115B     (base 16)           Hewlett Packard\r
+                               11445 Compaq Center Drive\r
+                               Houston    77070\r
+                               US\r
+\r
+C8-CB-B8   (hex)               Hewlett Packard\r
+C8CBB8     (base 16)           Hewlett Packard\r
+                               11445 Compaq Center Drive\r
+                               Houston    77070\r
+                               US\r
+\r
+94-57-A5   (hex)               Hewlett Packard\r
+9457A5     (base 16)           Hewlett Packard\r
+                               11445 Compaq Center Drive\r
+                               Houston    77070\r
+                               US\r
+\r
+00-01-E7   (hex)               Hewlett Packard\r
+0001E7     (base 16)           Hewlett Packard\r
+                               11000 Wolfe Road, Mailstop 42LE\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+08-00-09   (hex)               Hewlett Packard\r
+080009     (base 16)           Hewlett Packard\r
+                               ENTERPRISE SYSTEMS TECH.CENTER\r
+                               CUPERTINO  CA  95014\r
+                               US\r
+\r
+00-80-A0   (hex)               Hewlett Packard\r
+0080A0     (base 16)           Hewlett Packard\r
+                               ALAMEDA RIO NEGRO,\r
+                               houston  tx  77070\r
+                               BR\r
+\r
+D4-85-64   (hex)               Hewlett Packard\r
+D48564     (base 16)           Hewlett Packard\r
+                               11445 Compaq Center Drive\r
+                               Houston    77070\r
+                               US\r
+\r
+3C-4A-92   (hex)               Hewlett Packard\r
+3C4A92     (base 16)           Hewlett Packard\r
+                               11445 Compaq Center Drive\r
+                               Houston    77070\r
+                               US\r
+\r
+78-0A-C7   (hex)               Baofeng TV Co., Ltd.\r
+780AC7     (base 16)           Baofeng TV Co., Ltd.\r
+                               Room 2D, Building 5D, Nanshan District Software Industry Base\r
+                               ShenZhen  GuangDong  518000\r
+                               CN\r
+\r
+00-1D-73   (hex)               BUFFALO.INC\r
+001D73     (base 16)           BUFFALO.INC\r
+                               15,Shibata Hondori 4-chome,\r
+                               Nagoya  Aichi Pref.  457-8520\r
+                               JP\r
+\r
+00-16-01   (hex)               BUFFALO.INC\r
+001601     (base 16)           BUFFALO.INC\r
+                               AKAMONDORI Bldg., 30-20,Ohsu 3-chome\r
+                               Naka-ku,Nagoya  Aichi Pref.  460-8315\r
+                               JP\r
+\r
+10-6F-3F   (hex)               BUFFALO.INC\r
+106F3F     (base 16)           BUFFALO.INC\r
+                               AKAMONDORI Bldg., 30-20,Ohsu 3-chome\r
+                               Naka-ku,Nagoya  Aichi Pref.  460-8315\r
+                               JP\r
+\r
+88-57-EE   (hex)               BUFFALO.INC\r
+8857EE     (base 16)           BUFFALO.INC\r
+                               AKAMONDORI Bld.,30-20,Ohsu 3-chome,Naka-ku\r
+                               Nagoya  Aichi Pref.  460-8315\r
+                               JP\r
+\r
+00-9C-02   (hex)               Hewlett Packard\r
+009C02     (base 16)           Hewlett Packard\r
+                               11445 Compaq Center Drive\r
+                               Houston    77070\r
+                               US\r
+\r
+78-E7-D1   (hex)               Hewlett Packard\r
+78E7D1     (base 16)           Hewlett Packard\r
+                               11445 Compaq Center Drive\r
+                               Houston    77070\r
+                               US\r
+\r
+00-1B-78   (hex)               Hewlett Packard\r
+001B78     (base 16)           Hewlett Packard\r
+                               20555 State Highway 249\r
+                               Houston  TX  77070\r
+                               US\r
+\r
+00-1E-0B   (hex)               Hewlett Packard\r
+001E0B     (base 16)           Hewlett Packard\r
+                               20555 State Highway 249\r
+                               Houston  TX  77070\r
+                               US\r
+\r
+2C-6E-85   (hex)               Intel Corporate\r
+2C6E85     (base 16)           Intel Corporate\r
+                               Lot 8, Jalan Hi-Tech 2/3\r
+                               Kulim  Kedah  09000\r
+                               MY\r
+\r
+00-D0-B7   (hex)               Intel Corporation\r
+00D0B7     (base 16)           Intel Corporation\r
+                               5200 NE ELAM YOUNG PARKWAY\r
+                               HILLSBORO  OR  97124\r
+                               US\r
+\r
+00-02-B3   (hex)               Intel Corporation\r
+0002B3     (base 16)           Intel Corporation\r
+                               M/S:  JF3-420\r
+                               Hillsboro  OR  97124\r
+                               US\r
+\r
+00-11-11   (hex)               Intel Corporation\r
+001111     (base 16)           Intel Corporation\r
+                               2111 NE 25th Avenue\r
+                               Hillsboro  OR  97124\r
+                               US\r
+\r
+00-13-20   (hex)               Intel Corporate\r
+001320     (base 16)           Intel Corporate\r
+                               Lot 8, Jalan Hi-tech 2/3\r
+                               Kulim  Kedah  09000\r
+                               MY\r
+\r
+00-12-F0   (hex)               Intel Corporate\r
+0012F0     (base 16)           Intel Corporate\r
+                               Lot 8, Jalan Hi-tech 2/3\r
+                               Kulim  Kedah  09000\r
+                               MY\r
+\r
+90-49-FA   (hex)               Intel Corporate\r
+9049FA     (base 16)           Intel Corporate\r
+                               Lot 8, Jalan Hi-Tech 2/3\r
+                               Kulim  Kedah  09000\r
+                               MY\r
+\r
+C8-34-8E   (hex)               Intel Corporate\r
+C8348E     (base 16)           Intel Corporate\r
+                               Lot 8, Jalan Hi-Tech 2/3\r
+                               Kulim  Kedah  09000\r
+                               MY\r
+\r
+00-50-8B   (hex)               Hewlett Packard\r
+00508B     (base 16)           Hewlett Packard\r
+                               20555 State Highway 249\r
+                               Houston  TX  77070\r
+                               US\r
+\r
+78-48-59   (hex)               Hewlett Packard\r
+784859     (base 16)           Hewlett Packard\r
+                               11445 Compaq Center Drive\r
+                               Houston    77070\r
+                               US\r
+\r
+14-58-D0   (hex)               Hewlett Packard\r
+1458D0     (base 16)           Hewlett Packard\r
+                               11445 Compaq Center Drive\r
+                               Houston    77070\r
+                               US\r
+\r
+50-65-F3   (hex)               Hewlett Packard\r
+5065F3     (base 16)           Hewlett Packard\r
+                               11445 Compaq Center Drive\r
+                               Houston    77070\r
+                               US\r
+\r
+A0-48-1C   (hex)               Hewlett Packard\r
+A0481C     (base 16)           Hewlett Packard\r
+                               11445 Compaq Center Drive\r
+                               Houston    77070\r
+                               US\r
+\r
+A0-1D-48   (hex)               Hewlett Packard\r
+A01D48     (base 16)           Hewlett Packard\r
+                               11445 Compaq Center Drive\r
+                               Houston    77070\r
+                               US\r
+\r
+94-B2-CC   (hex)               PIONEER CORPORATION\r
+94B2CC     (base 16)           PIONEER CORPORATION\r
+                               1-1 Shin-ogura\r
+                               Kawasaki-shi  Kanagawa Prefecture  2120031\r
+                               JP\r
+\r
+88-7F-03   (hex)               Comper Technology Investment Limited\r
+887F03     (base 16)           Comper Technology Investment Limited\r
+                               Room 710, Wangjing SOHO Tower 1-B\r
+                               Beijing  Beijing  100102\r
+                               CN\r
+\r
+E0-60-66   (hex)               Sercomm Corporation\r
+E06066     (base 16)           Sercomm Corporation\r
+                               8F, 3-1, YuanQu St., NanKang,\r
+                               Taipei  Taiwan  115\r
+                               TW\r
+\r
+00-19-E0   (hex)               TP-LINK TECHNOLOGIES CO.,LTD.\r
+0019E0     (base 16)           TP-LINK TECHNOLOGIES CO.,LTD.\r
+                               South Building, No.5 Keyuan Road\r
+                               Nanshan  Shenzhen  518057\r
+                               CN\r
+\r
+00-23-CD   (hex)               TP-LINK TECHNOLOGIES CO.,LTD.\r
+0023CD     (base 16)           TP-LINK TECHNOLOGIES CO.,LTD.\r
+                               South Building, No.5 Keyuan Road, Central Zone,\r
+                               Shenzhen  Guangdong  518000\r
+                               CN\r
+\r
+00-27-19   (hex)               TP-LINK TECHNOLOGIES CO.,LTD.\r
+002719     (base 16)           TP-LINK TECHNOLOGIES CO.,LTD.\r
+                               Building 7, Second Part, Honghualing Industrial Zone\r
+                               Shenzhen  Guangdong  518057\r
+                               CN\r
+\r
+40-16-9F   (hex)               TP-LINK TECHNOLOGIES CO.,LTD.\r
+40169F     (base 16)           TP-LINK TECHNOLOGIES CO.,LTD.\r
+                               1-6F, Building 2, Pingshandayuan Industrial, South Zone,\r
+                               Shenzhen  Guangdong  518000\r
+                               CN\r
+\r
+94-0C-6D   (hex)               TP-LINK TECHNOLOGIES CO.,LTD.\r
+940C6D     (base 16)           TP-LINK TECHNOLOGIES CO.,LTD.\r
+                               Building 7, Second Part, Honghualing Industrial Zone\r
+                               Shenzhen  Guangdong  518000\r
+                               CN\r
+\r
+74-EA-3A   (hex)               TP-LINK TECHNOLOGIES CO.,LTD.\r
+74EA3A     (base 16)           TP-LINK TECHNOLOGIES CO.,LTD.\r
+                               Building 7, Second Part, Honghualing Industrial Zone\r
+                               Shenzhen  Guangdong  518000\r
+                               CN\r
+\r
+90-F6-52   (hex)               TP-LINK TECHNOLOGIES CO.,LTD.\r
+90F652     (base 16)           TP-LINK TECHNOLOGIES CO.,LTD.\r
+                               Building 24 (floors 1,3,4,5) and 28 (floors1-4)  Central Science and Technology Park,Shennan Rd, Nanshan,\r
+                               Shenzhen  Guangdong Province,  518057\r
+                               CN\r
+\r
+10-FE-ED   (hex)               TP-LINK TECHNOLOGIES CO.,LTD.\r
+10FEED     (base 16)           TP-LINK TECHNOLOGIES CO.,LTD.\r
+                               Building 24 (floors 1,3,4,5) and 28 (floors1-4)  Central Science and Technology Park\r
+                               Shenzhen  Guangdong  518057\r
+                               CN\r
+\r
+C4-6E-1F   (hex)               TP-LINK TECHNOLOGIES CO.,LTD.\r
+C46E1F     (base 16)           TP-LINK TECHNOLOGIES CO.,LTD.\r
+                               Building 24 (floors 1,3,4,5) and 28 (floors1-4)\r
+                               Shennan Rd, Nanshan  Shenzhen,Guangdong Province  518057\r
+                               CN\r
 \r
 50-FA-84   (hex)               TP-LINK TECHNOLOGIES CO.,LTD.\r
 50FA84     (base 16)           TP-LINK TECHNOLOGIES CO.,LTD.\r
@@ -58385,108 +59069,6 @@ F83DFF     (base 16)          HUAWEI TECHNOLOGIES CO.,LTD
                                Shenzhen  Guangdong  518129\r
                                CN\r
 \r
-00-C6-10   (hex)               Apple, Inc.\r
-00C610     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-70-DE-E2   (hex)               Apple, Inc.\r
-70DEE2     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-18-20-32   (hex)               Apple, Inc.\r
-182032     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-6C-C2-6B   (hex)               Apple, Inc.\r
-6CC26B     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-10-40-F3   (hex)               Apple, Inc.\r
-1040F3     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-FC-25-3F   (hex)               Apple, Inc.\r
-FC253F     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-18-34-51   (hex)               Apple, Inc.\r
-183451     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-C0-84-7A   (hex)               Apple, Inc.\r
-C0847A     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-64-20-0C   (hex)               Apple, Inc.\r
-64200C     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-74-E1-B6   (hex)               Apple, Inc.\r
-74E1B6     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-0C-77-1A   (hex)               Apple, Inc.\r
-0C771A     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-00-F4-B9   (hex)               Apple, Inc.\r
-00F4B9     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-C8-33-4B   (hex)               Apple, Inc.\r
-C8334B     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-B8-F6-B1   (hex)               Apple, Inc.\r
-B8F6B1     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-C0-9F-42   (hex)               Apple, Inc.\r
-C09F42     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-18-9E-FC   (hex)               Apple, Inc.\r
-189EFC     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-6C-3E-6D   (hex)               Apple, Inc.\r
-6C3E6D     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
 00-16-FE   (hex)               ALPS ELECTRIC CO.,LTD.\r
 0016FE     (base 16)           ALPS ELECTRIC CO.,LTD.\r
                                1-2-1, Okinouchi,\r
@@ -58685,72 +59267,6 @@ B0FAEB     (base 16)           Cisco Systems, Inc
                                San Jose  CA  95134\r
                                US\r
 \r
-7C-FA-DF   (hex)               Apple, Inc.\r
-7CFADF     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-10-1C-0C   (hex)               Apple, Inc.\r
-101C0C     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-00-11-24   (hex)               Apple, Inc.\r
-001124     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-00-1D-4F   (hex)               Apple, Inc.\r
-001D4F     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-00-1E-52   (hex)               Apple, Inc.\r
-001E52     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-00-1F-5B   (hex)               Apple, Inc.\r
-001F5B     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-00-1F-F3   (hex)               Apple, Inc.\r
-001FF3     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-00-21-E9   (hex)               Apple, Inc.\r
-0021E9     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-00-23-6C   (hex)               Apple, Inc.\r
-00236C     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-00-25-00   (hex)               Apple, Inc.\r
-002500     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-60-FB-42   (hex)               Apple, Inc.\r
-60FB42     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
 14-DA-E9   (hex)               ASUSTek COMPUTER INC.\r
 14DAE9     (base 16)           ASUSTek COMPUTER INC.\r
                                15,Li-Te Rd.,Peitou,\r
@@ -58799,60 +59315,6 @@ D072DC     (base 16)           Cisco Systems, Inc
                                San Jose  CA  95134\r
                                US\r
 \r
-F8-1E-DF   (hex)               Apple, Inc.\r
-F81EDF     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-90-84-0D   (hex)               Apple, Inc.\r
-90840D     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-D8-A2-5E   (hex)               Apple, Inc.\r
-D8A25E     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-C8-BC-C8   (hex)               Apple, Inc.\r
-C8BCC8     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-28-E7-CF   (hex)               Apple, Inc.\r
-28E7CF     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-D8-9E-3F   (hex)               Apple, Inc.\r
-D89E3F     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-04-0C-CE   (hex)               Apple, Inc.\r
-040CCE     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-A4-D1-D2   (hex)               Apple, Inc.\r
-A4D1D2     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-40-6C-8F   (hex)               Apple, Inc.\r
-406C8F     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
 C0-67-AF   (hex)               Cisco Systems, Inc\r
 C067AF     (base 16)           Cisco Systems, Inc\r
                                170 West Tasman Drive\r
@@ -58937,258 +59399,12 @@ C067AF     (base 16)         Cisco Systems, Inc
                                SAN JOSE  CA  95134-1706\r
                                US\r
 \r
-64-9A-BE   (hex)               Apple, Inc.\r
-649ABE     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-94-E9-6A   (hex)               Apple, Inc.\r
-94E96A     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-AC-29-3A   (hex)               Apple, Inc.\r
-AC293A     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-10-41-7F   (hex)               Apple, Inc.\r
-10417F     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-70-14-A6   (hex)               Apple, Inc.\r
-7014A6     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-A8-66-7F   (hex)               Apple, Inc.\r
-A8667F     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-D0-25-98   (hex)               Apple, Inc.\r
-D02598     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-CC-29-F5   (hex)               Apple, Inc.\r
-CC29F5     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-6C-70-9F   (hex)               Apple, Inc.\r
-6C709F     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-0C-3E-9F   (hex)               Apple, Inc.\r
-0C3E9F     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-34-E2-FD   (hex)               Apple, Inc.\r
-34E2FD     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-60-92-17   (hex)               Apple, Inc.\r
-609217     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-88-63-DF   (hex)               Apple, Inc.\r
-8863DF     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-80-E6-50   (hex)               Apple, Inc.\r
-80E650     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-00-61-71   (hex)               Apple, Inc.\r
-006171     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-90-FD-61   (hex)               Apple, Inc.\r
-90FD61     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-5C-97-F3   (hex)               Apple, Inc.\r
-5C97F3     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-6C-40-08   (hex)               Apple, Inc.\r
-6C4008     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-24-A0-74   (hex)               Apple, Inc.\r
-24A074     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-F0-24-75   (hex)               Apple, Inc.\r
-F02475     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-20-A2-E4   (hex)               Apple, Inc.\r
-20A2E4     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-5C-F5-DA   (hex)               Apple, Inc.\r
-5CF5DA     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 D4-B8-FF   (hex)               Home Control Singapore Pte Ltd\r
 D4B8FF     (base 16)           Home Control Singapore Pte Ltd\r
                                620A Lorong 1 Toa Payoh\r
                                Singapore  Singapore  217909\r
                                SG\r
 \r
-28-E1-4C   (hex)               Apple, Inc.\r
-28E14C     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-54-E4-3A   (hex)               Apple, Inc.\r
-54E43A     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-C8-E0-EB   (hex)               Apple, Inc.\r
-C8E0EB     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-A8-88-08   (hex)               Apple, Inc.\r
-A88808     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-90-72-40   (hex)               Apple, Inc.\r
-907240     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-0C-4D-E9   (hex)               Apple, Inc.\r
-0C4DE9     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-D8-96-95   (hex)               Apple, Inc.\r
-D89695     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-0C-30-21   (hex)               Apple, Inc.\r
-0C3021     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-F0-F6-1C   (hex)               Apple, Inc.\r
-F0F61C     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-B0-34-95   (hex)               Apple, Inc.\r
-B03495     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-84-8E-0C   (hex)               Apple, Inc.\r
-848E0C     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-8C-2D-AA   (hex)               Apple, Inc.\r
-8C2DAA     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-44-4C-0C   (hex)               Apple, Inc.\r
-444C0C     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-84-FC-FE   (hex)               Apple, Inc.\r
-84FCFE     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-E4-8B-7F   (hex)               Apple, Inc.\r
-E48B7F     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-5C-96-9D   (hex)               Apple, Inc.\r
-5C969D     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-A8-FA-D8   (hex)               Apple, Inc.\r
-A8FAD8     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-94-94-26   (hex)               Apple, Inc.\r
-949426     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-E0-F5-C6   (hex)               Apple, Inc.\r
-E0F5C6     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
 AC-64-62   (hex)               zte corporation\r
 AC6462     (base 16)           zte corporation\r
                                12/F.,zte R&D building ,kejinan Road,Shenzhen,P.R.China\r
@@ -59315,18 +59531,6 @@ E8DED6     (base 16)           Intrising Networks, Inc.
                                Taipei    \r
                                TW\r
 \r
-B8-44-D9   (hex)               Apple, Inc.\r
-B844D9     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-DC-2B-2A   (hex)               Apple, Inc.\r
-DC2B2A     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 8C-10-D4   (hex)               Sagemcom Broadband SAS\r
 8C10D4     (base 16)           Sagemcom Broadband SAS\r
                                250, route de l'Empereur\r
@@ -62051,12 +62255,6 @@ D0D6CC     (base 16)           Wintop
                                Songjiang District  Shanghai  201612\r
                                CN\r
 \r
-10-1D-51   (hex)               ON-Q LLC dba ON-Q Mesh Networks\r
-101D51     (base 16)           ON-Q LLC dba ON-Q Mesh Networks\r
-                               2859 Mandela Parkway\r
-                               Oakland  CA  94611\r
-                               US\r
-\r
 34-C9-9D   (hex)               EIDOLON COMMUNICATIONS TECHNOLOGY CO. LTD.\r
 34C99D     (base 16)           EIDOLON COMMUNICATIONS TECHNOLOGY CO. LTD.\r
                                Room 603, 6/F., Wanchai Central Building, 89 Lockhart Road, Wanchai, \r
@@ -63002,12 +63200,6 @@ C85645     (base 16)           Intermas France
                                Phoenixville  PA  19460\r
                                US\r
 \r
-30-B2-16   (hex)               Hytec Geraetebau GmbH\r
-30B216     (base 16)           Hytec Geraetebau GmbH\r
-                               Cochemer Straße 12 - 14\r
-                               Mannheim    68309\r
-                               DE\r
-\r
 34-FC-6F   (hex)               ALCEA\r
 34FC6F     (base 16)           ALCEA\r
                                3 Rue Joly de Bammeville\r
@@ -66203,12 +66395,6 @@ A893E6     (base 16)           JIANGXI JINGGANGSHAN CKING COMMUNICATION TECHNOLOGY CO.,LT
                                ANKARA    06370\r
                                TR\r
 \r
-00-23-A8   (hex)               Marshall Electronics\r
-0023A8     (base 16)           Marshall Electronics\r
-                               1910 E Maple Ave\r
-                               El Segundo  Ca  90245\r
-                               US\r
-\r
 00-23-9B   (hex)               Elster Solutions, LLC\r
 00239B     (base 16)           Elster Solutions, LLC\r
                                208 South Rogers Lane\r
@@ -75632,12 +75818,6 @@ A06A00     (base 16)           Verilink Corporation
                                    \r
                                CN\r
 \r
-00-D0-CE   (hex)               ASYST ELECTRONIC\r
-00D0CE     (base 16)           ASYST ELECTRONIC\r
-                               BRODISCE 7, 10C TRZIN\r
-                                   \r
-                               SI\r
-\r
 00-D0-90   (hex)               Cisco Systems, Inc\r
 00D090     (base 16)           Cisco Systems, Inc\r
                                80 West Tasman Drive\r
@@ -80222,18 +80402,6 @@ B83241     (base 16)           Wuhan Tianyu Information Industry Co., Ltd.
                                Minato-ku  Tokyo  108-0022\r
                                JP\r
 \r
-9C-4F-DA   (hex)               Apple, Inc.\r
-9C4FDA     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-1C-5C-F2   (hex)               Apple, Inc.\r
-1C5CF2     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 08-21-EF   (hex)               Samsung Electronics Co.,Ltd\r
 0821EF     (base 16)           Samsung Electronics Co.,Ltd\r
                                #94-1, Imsoo-Dong\r
@@ -80294,36 +80462,12 @@ B8A175     (base 16)          Roku, Inc.
                                Wichita  KS  67226-1397\r
                                US\r
 \r
-E4-9A-79   (hex)               Apple, Inc.\r
-E49A79     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-28-A0-2B   (hex)               Apple, Inc.\r
-28A02B     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-B4-4B-D2   (hex)               Apple, Inc.\r
-B44BD2     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 00-23-40   (hex)               MiXTelematics\r
 002340     (base 16)           MiXTelematics\r
                                Blaauwklip Office Park 2\r
                                Stellenbosch  Western Cape  7600\r
                                ZA\r
 \r
-B4-8B-19   (hex)               Apple, Inc.\r
-B48B19     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 00-AF-1F   (hex)               Cisco Systems, Inc\r
 00AF1F     (base 16)           Cisco Systems, Inc\r
                                80 West Tasman Drive\r
@@ -80912,24 +81056,6 @@ A81559     (base 16)           Breathometer, Inc.
                                Burlingame  CA  94010\r
                                US\r
 \r
-EC-AD-B8   (hex)               Apple, Inc.\r
-ECADB8     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-98-01-A7   (hex)               Apple, Inc.\r
-9801A7     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-2C-F0-A2   (hex)               Apple, Inc.\r
-2CF0A2     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 C0-97-27   (hex)               SAMSUNG ELECTRO-MECHANICS(THAILAND)\r
 C09727     (base 16)           SAMSUNG ELECTRO-MECHANICS(THAILAND)\r
                                93Moo5T. Bangsamak SEMTHAI, WELLGROW INDUSTRIAL ESTATE\r
@@ -82616,24 +82742,6 @@ E00DB9     (base 16)           Cree, Inc.
                                anyang-si  kyunggi-do  14057\r
                                KR\r
 \r
-60-9A-C1   (hex)               Apple, Inc.\r
-609AC1     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-F0-79-60   (hex)               Apple, Inc.\r
-F07960     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-9C-8B-A0   (hex)               Apple, Inc.\r
-9C8BA0     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 98-40-BB   (hex)               Dell Inc.\r
 9840BB     (base 16)           Dell Inc.\r
                                One Dell Way\r
@@ -82652,12 +82760,6 @@ E04FBD     (base 16)           SICHUAN TIANYI COMHEART TELECOMCO.,LTD
                                San Jose  CA  94568\r
                                US\r
 \r
-4C-32-75   (hex)               Apple, Inc.\r
-4C3275     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 00-06-F4   (hex)               Prime Electronics & Satellitics Inc.\r
 0006F4     (base 16)           Prime Electronics & Satellitics Inc.\r
                                69,Tung-Yuan Rd\r
@@ -83081,30 +83183,6 @@ B0F963     (base 16)           Hangzhou H3C Technologies Co., Limited
                                Hangzhou  Zhejiang, P.R.China  310052\r
                                CN\r
 \r
-E4-E4-AB   (hex)               Apple, Inc.\r
-E4E4AB     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-58-40-4E   (hex)               Apple, Inc.\r
-58404E     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-DC-0C-5C   (hex)               Apple, Inc.\r
-DC0C5C     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-2C-20-0B   (hex)               Apple, Inc.\r
-2C200B     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 98-B6-E9   (hex)               Nintendo Co.,Ltd\r
 98B6E9     (base 16)           Nintendo Co.,Ltd\r
                                11-1 HOKOTATE-CHO KAMITOBA,MINAMI-KU\r
@@ -83447,18 +83525,6 @@ AC63BE     (base 16)           Amazon Technologies Inc.
                                Reno  NV  89507\r
                                US\r
 \r
-DC-A4-CA   (hex)               Apple, Inc.\r
-DCA4CA     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-8C-8F-E9   (hex)               Apple, Inc.\r
-8C8FE9     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 40-FA-7F   (hex)               Preh Car Connect GmbH\r
 40FA7F     (base 16)           Preh Car Connect GmbH\r
                                Gewerbepark 5\r
@@ -83513,24 +83579,6 @@ F85971     (base 16)           Intel Corporate
                                Kulim  Kedah  09000\r
                                MY\r
 \r
-98-10-E8   (hex)               Apple, Inc.\r
-9810E8     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-B4-9C-DF   (hex)               Apple, Inc.\r
-B49CDF     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-4C-82-CF   (hex)               Echostar Technologies Corp\r
-4C82CF     (base 16)           Echostar Technologies Corp\r
-                               94 Inverness Terrace E\r
-                               Englewood  CO  80112\r
-                               US\r
-\r
 F4-96-34   (hex)               Intel Corporate\r
 F49634     (base 16)           Intel Corporate\r
                                Lot 8, Jalan Hi-Tech 2/3\r
@@ -84932,54 +84980,6 @@ CC7EE7     (base 16)           Panasonic Corporation AVC Networks Company
                                San Jose  CA  94568\r
                                US\r
 \r
-A4-E9-75   (hex)               Apple, Inc.\r
-A4E975     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-C0-A5-3E   (hex)               Apple, Inc.\r
-C0A53E     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-98-00-C6   (hex)               Apple, Inc.\r
-9800C6     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-78-7B-8A   (hex)               Apple, Inc.\r
-787B8A     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-38-66-F0   (hex)               Apple, Inc.\r
-3866F0     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-20-EE-28   (hex)               Apple, Inc.\r
-20EE28     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-08-F4-AB   (hex)               Apple, Inc.\r
-08F4AB     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-8C-85-90   (hex)               Apple, Inc.\r
-8C8590     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 FC-01-7C   (hex)               Hon Hai Precision Ind. Co.,Ltd.\r
 FC017C     (base 16)           Hon Hai Precision Ind. Co.,Ltd.\r
                                Building D21,No.1, East Zone 1st Road\r
@@ -85133,12 +85133,6 @@ C850E9     (base 16)           Raisecom Technology CO., LTD
                                Austin  TX  78701\r
                                US\r
 \r
-50-4E-DC   (hex)               Ping Communication\r
-504EDC     (base 16)           Ping Communication\r
-                               Brenden 18\r
-                               Appenzell Meistersrüte  AI  9050\r
-                               CH\r
-\r
 50-F7-22   (hex)               Cisco Systems, Inc\r
 50F722     (base 16)           Cisco Systems, Inc\r
                                80 West Tasman Drive\r
@@ -85271,599 +85265,1637 @@ F092B4     (base 16)               SICHUAN TIANYI COMHEART TELECOMCO., LTD
                                Draper  UT  84020-9021\r
                                US\r
 \r
-00-50-FC   (hex)               Edimax Technology Co. Ltd.\r
-0050FC     (base 16)           Edimax Technology Co. Ltd.\r
-                               No. 278, Xinhu 1st Road\r
-                               Taipei City  Neihu Dist  248\r
-                               TW\r
-\r
-74-83-EF   (hex)               Arista Networks\r
-7483EF     (base 16)           Arista Networks\r
-                               5453 Great America Parkway\r
-                               Santa Clara  CA  95054\r
+00-50-FC   (hex)               Edimax Technology Co. Ltd.\r
+0050FC     (base 16)           Edimax Technology Co. Ltd.\r
+                               No. 278, Xinhu 1st Road\r
+                               Taipei City  Neihu Dist  248\r
+                               TW\r
+\r
+74-83-EF   (hex)               Arista Networks\r
+7483EF     (base 16)           Arista Networks\r
+                               5453 Great America Parkway\r
+                               Santa Clara  CA  95054\r
+                               US\r
+\r
+00-1C-73   (hex)               Arista Networks\r
+001C73     (base 16)           Arista Networks\r
+                               5470 Great America Pkwy\r
+                               Santa Clara  California  95054\r
+                               US\r
+\r
+38-AD-8E   (hex)               New H3C Technologies Co., Ltd\r
+38AD8E     (base 16)           New H3C Technologies Co., Ltd\r
+                               466 Changhe Road, Binjiang District\r
+                               Hangzhou  Zhejiang  310052\r
+                               CN\r
+\r
+00-12-48   (hex)               Dell EMC\r
+001248     (base 16)           Dell EMC\r
+                               176 South Street\r
+                               Hopkinton  MA  01748\r
+                               US\r
+\r
+00-01-44   (hex)               Dell EMC\r
+000144     (base 16)           Dell EMC\r
+                               228 South St.\r
+                               Hopkinton  MA  01748\r
+                               US\r
+\r
+00-BF-61   (hex)               Samsung Electronics Co.,Ltd\r
+00BF61     (base 16)           Samsung Electronics Co.,Ltd\r
+                               129, Samsung-ro, Youngtongl-Gu\r
+                               Suwon  Gyeonggi-Do  16677\r
+                               KR\r
+\r
+30-9F-FB   (hex)               Ardomus Networks Corporation\r
+309FFB     (base 16)           Ardomus Networks Corporation\r
+                               4F,No. 6 Innovation Road II, Hsinchu Science Park  \r
+                               Hsinchu    300\r
+                               TW\r
+\r
+E4-BD-4B   (hex)               zte corporation\r
+E4BD4B     (base 16)           zte corporation\r
+                               12/F.,zte R&D building ,kejinan Road,Shenzhen,P.R.China\r
+                               shenzhen  guangdong  518057\r
+                               CN\r
+\r
+6C-56-97   (hex)               Amazon Technologies Inc.\r
+6C5697     (base 16)           Amazon Technologies Inc.\r
+                               P.O Box 8102\r
+                               Reno  NV  89507\r
+                               US\r
+\r
+3C-A5-81   (hex)               vivo Mobile Communication Co., Ltd.\r
+3CA581     (base 16)           vivo Mobile Communication Co., Ltd.\r
+                               #283,BBK Road\r
+                               Wusha,Chang'An  DongGuan City,Guangdong,  523860\r
+                               CN\r
+\r
+F4-EA-B5   (hex)               Aerohive Networks Inc.\r
+F4EAB5     (base 16)           Aerohive Networks Inc.\r
+                               1011 McCarthy Blvd\r
+                               Milpitas  CA  95035\r
+                               US\r
+\r
+F8-20-55   (hex)               Green Information System\r
+F82055     (base 16)           Green Information System\r
+                               #202(Shopping center), Woldong-ro 28, Buk-gu\r
+                               Gwangju    61153\r
+                               KR\r
+\r
+78-5C-28   (hex)               Prime Motion Inc.\r
+785C28     (base 16)           Prime Motion Inc.\r
+                               Akaho 1134-12\r
+                               Komagane  Nagano  399-4117\r
+                               JP\r
+\r
+94-49-96   (hex)               WiSilica Inc\r
+944996     (base 16)           WiSilica Inc\r
+                               23282 Mill Creek Dr #340\r
+                               Laguna Hills  CA  92653\r
+                               US\r
+\r
+00-26-A8   (hex)               DAEHAP HYPER-TECH\r
+0026A8     (base 16)           DAEHAP HYPER-TECH\r
+                               Mega center #1108, SK Techno-Park, #190-1, Sangdaewon-Dong, Jungwon-Gu\r
+                               Seongnam  Gyeonggi-Do  462-807\r
+                               KR\r
+\r
+F8-7B-20   (hex)               Cisco Systems, Inc\r
+F87B20     (base 16)           Cisco Systems, Inc\r
+                               80 West Tasman Drive\r
+                               San Jose  CA  94568\r
+                               US\r
+\r
+F8-1D-0F   (hex)               Hitron Technologies. Inc\r
+F81D0F     (base 16)           Hitron Technologies. Inc\r
+                               No. 1-8, Lising 1st Rd. Hsinchu Science Park, Hsinchu, 300, Taiwan, R.O.C\r
+                               Hsin-chu  Taiwan  300\r
+                               TW\r
+\r
+30-FB-94   (hex)               Shanghai Fangzhiwei Information Technology CO.,Ltd.\r
+30FB94     (base 16)           Shanghai Fangzhiwei Information Technology CO.,Ltd.\r
+                               The 17th  Building A Unit,No. 1688 Lianhang Road,Minhang District,Shanghai City\r
+                               Shanghai    201100\r
+                               CN\r
+\r
+08-BA-22   (hex)               Swaive Corporation\r
+08BA22     (base 16)           Swaive Corporation\r
+                               3565 Kettmann Road\r
+                               San Jose  CA  95121\r
+                               US\r
+\r
+F8-0C-F3   (hex)               LG Electronics (Mobile Communications)\r
+F80CF3     (base 16)           LG Electronics (Mobile Communications)\r
+                               60-39, Gasan-dong, Geumcheon-gu\r
+                               Seoul    153-801\r
+                               KR\r
+\r
+30-76-6F   (hex)               LG Electronics (Mobile Communications)\r
+30766F     (base 16)           LG Electronics (Mobile Communications)\r
+                               60-39, Gasan-dong, Geumcheon-gu\r
+                               Seoul    153-801\r
+                               KR\r
+\r
+8C-3A-E3   (hex)               LG Electronics (Mobile Communications)\r
+8C3AE3     (base 16)           LG Electronics (Mobile Communications)\r
+                               60-39, Gasan-dong, Geumcheon-gu\r
+                               Seoul    153-801\r
+                               KR\r
+\r
+94-2A-3F   (hex)               Diversey Inc\r
+942A3F     (base 16)           Diversey Inc\r
+                               2415 Cascade Pointe Blvd\r
+                               Charlotte  NC  28208\r
+                               US\r
+\r
+78-F8-82   (hex)               LG Electronics (Mobile Communications)\r
+78F882     (base 16)           LG Electronics (Mobile Communications)\r
+                               60-39, Gasan-dong, Geumcheon-gu\r
+                               Seoul    153-801\r
+                               KR\r
+\r
+0C-61-11   (hex)               Anda Technologies SAC\r
+0C6111     (base 16)           Anda Technologies SAC\r
+                               Av. Santa Cruz 888, Miraflores\r
+                               Lima  Peru  Lima18\r
+                               PE\r
+\r
+B8-F7-4A   (hex)               RCNTEC\r
+B8F74A     (base 16)           RCNTEC\r
+                               Polkovaya street 3\r
+                               Moscow    127018\r
+                               RU\r
+\r
+C8-D1-2A   (hex)               Comtrend Corporation\r
+C8D12A     (base 16)           Comtrend Corporation\r
+                               3F-1, No. 10, Lane 609, Chung Hsin Road, Sec 5, San Chung Dist.\r
+                               New Taipei City  Taiwan  24159\r
+                               TW\r
+\r
+B4-F1-DA   (hex)               LG Electronics (Mobile Communications)\r
+B4F1DA     (base 16)           LG Electronics (Mobile Communications)\r
+                               60-39, Gasan-dong, Geumcheon-gu\r
+                               Seoul    153-801\r
+                               KR\r
+\r
+00-21-FB   (hex)               LG Electronics (Mobile Communications)\r
+0021FB     (base 16)           LG Electronics (Mobile Communications)\r
+                               60-39, Gasan-dong, Geumcheon-gu\r
+                               Seoul    153-801\r
+                               KR\r
+\r
+D0-13-FD   (hex)               LG Electronics (Mobile Communications)\r
+D013FD     (base 16)           LG Electronics (Mobile Communications)\r
+                               60-39, Gasan-dong, Geumcheon-gu\r
+                               Seoul    153-801\r
+                               KR\r
+\r
+A8-B8-6E   (hex)               LG Electronics (Mobile Communications)\r
+A8B86E     (base 16)           LG Electronics (Mobile Communications)\r
+                               60-39, Gasan-dong, Geumcheon-gu\r
+                               Seoul    153-801\r
+                               KR\r
+\r
+DC-4F-22   (hex)               Espressif Inc.\r
+DC4F22     (base 16)           Espressif Inc.\r
+                               Room 204, Building 2, 690 Bibo Road, Pudong New Area\r
+                               Shanghai  Shanghai  201203\r
+                               CN\r
+\r
+34-2A-F1   (hex)               Texas Instruments\r
+342AF1     (base 16)           Texas Instruments\r
+                               12500 TI Blvd\r
+                               Dallas  TX  75243\r
+                               US\r
+\r
+70-E5-6E   (hex)               Texas Instruments\r
+70E56E     (base 16)           Texas Instruments\r
+                               12500 TI Blvd\r
+                               Dallas  TX  75243\r
+                               US\r
+\r
+F0-85-C1   (hex)               SHENZHEN RF-LINK TECHNOLOGY CO.,LTD.\r
+F085C1     (base 16)           SHENZHEN RF-LINK TECHNOLOGY CO.,LTD.\r
+                               Bldg56A,6/F,Baotian Rd3,Xixiang Town,Baoan District,\r
+                               Shenzhen  Guangdong  518000\r
+                               CN\r
+\r
+C8-DE-C9   (hex)               Coriant\r
+C8DEC9     (base 16)           Coriant\r
+                               1415 W. Diehl Rd\r
+                               Naperville  IL  60563\r
+                               US\r
+\r
+38-0E-4D   (hex)               Cisco Systems, Inc\r
+380E4D     (base 16)           Cisco Systems, Inc\r
+                               80 West Tasman Drive\r
+                               San Jose  CA  94568\r
+                               US\r
+\r
+FC-9D-D8   (hex)               Beijing TongTongYiLian Science and Technology Ltd.\r
+FC9DD8     (base 16)           Beijing TongTongYiLian Science and Technology Ltd.\r
+                                Room 301,Zone 3,Building 9,No.8 Dongbeiwang West Road,Haidian District,Beijing\r
+                               BEIJING  BEIJING  100193\r
+                               CN\r
+\r
+04-B1-67   (hex)               Xiaomi Communications Co Ltd\r
+04B167     (base 16)           Xiaomi Communications Co Ltd\r
+                               The Rainbow City of China Resources\r
+                               NO.68, Qinghe Middle Street  Haidian District, Beijing  100085\r
+                               CN\r
+\r
+38-AD-BE   (hex)               New H3C Technologies Co., Ltd\r
+38ADBE     (base 16)           New H3C Technologies Co., Ltd\r
+                               466 Changhe Road, Binjiang District\r
+                               Hangzhou  Zhejiang  310052\r
+                               CN\r
+\r
+58-19-F8   (hex)               ARRIS Group, Inc.\r
+5819F8     (base 16)           ARRIS Group, Inc.\r
+                               6450 Sequence Drive\r
+                               San Diego  CA  92121\r
+                               US\r
+\r
+20-78-52   (hex)               Nokia\r
+207852     (base 16)           Nokia\r
+                               Karaportti 3\r
+                               Espoo  Finland  02610\r
+                               FI\r
+\r
+AC-64-17   (hex)               Siemens AG - Industrial Automation - EWA\r
+AC6417     (base 16)           Siemens AG - Industrial Automation - EWA\r
+                               Werner-von-Siemens Strasse 50\r
+                               Amberg    92224\r
+                               DE\r
+\r
+CC-5D-4E   (hex)               Zyxel Communications Corporation\r
+CC5D4E     (base 16)           Zyxel Communications Corporation\r
+                               No. 6 Innovation Road II, Science Park\r
+                               Hsichu  Taiwan  300\r
+                               TW\r
+\r
+40-4A-03   (hex)               Zyxel Communications Corporation\r
+404A03     (base 16)           Zyxel Communications Corporation\r
+                               No. 6 Innovation Road II, Science Park\r
+                               Hsichu  Taiwan  300\r
+                               TW\r
+\r
+00-13-49   (hex)               Zyxel Communications Corporation\r
+001349     (base 16)           Zyxel Communications Corporation\r
+                               No. 6 Innovation Road II, Science Park\r
+                               Hsichu  Taiwan  300\r
+                               TW\r
+\r
+1C-74-0D   (hex)               Zyxel Communications Corporation\r
+1C740D     (base 16)           Zyxel Communications Corporation\r
+                               No. 6 Innovation Road II, Science Park\r
+                               Hsichu  Taiwan  300\r
+                               TW\r
+\r
+A0-E4-CB   (hex)               Zyxel Communications Corporation\r
+A0E4CB     (base 16)           Zyxel Communications Corporation\r
+                               No. 6 Innovation Road II, Science Park\r
+                               Hsichu  Taiwan  300\r
+                               TW\r
+\r
+5C-6A-80   (hex)               Zyxel Communications Corporation\r
+5C6A80     (base 16)           Zyxel Communications Corporation\r
+                               No. 6 Innovation Road II, Science Park\r
+                               Hsichu  Taiwan  300\r
+                               TW\r
+\r
+5C-E2-8C   (hex)               Zyxel Communications Corporation\r
+5CE28C     (base 16)           Zyxel Communications Corporation\r
+                               No. 6 Innovation Road II, Science Park\r
+                               Hsichu  Taiwan  300\r
+                               TW\r
+\r
+A8-EE-C6   (hex)               Muuselabs NV/SA\r
+A8EEC6     (base 16)           Muuselabs NV/SA\r
+                               Rue du Tocsin 12\r
+                               Brussels    1000\r
+                               BE\r
+\r
+A0-9D-C1   (hex)               China Dragon Technology Limited\r
+A09DC1     (base 16)           China Dragon Technology Limited\r
+                               B4 Bldg.Haoshan 1st Industry Park,\r
+                               Shenzhen  Guangdong  518104\r
+                               CN\r
+\r
+38-43-7D   (hex)               Compal Broadband Networks, Inc.\r
+38437D     (base 16)           Compal Broadband Networks, Inc.\r
+                               13F., No.1, Taiyuan 1st St.\r
+                               Zhubei City  Hsinchu County  30265\r
+                               TW\r
+\r
+5C-86-C1   (hex)               DONGGUAN SOLUM ELECTRONICS CO.,LTD\r
+5C86C1     (base 16)           DONGGUAN SOLUM ELECTRONICS CO.,LTD\r
+                               NO.157,13 Coastal Way TPFTZ\r
+                               TIANJIN    300461\r
+                               CN\r
+\r
+6C-DD-30   (hex)               Cisco Systems, Inc\r
+6CDD30     (base 16)           Cisco Systems, Inc\r
+                               80 West Tasman Drive\r
+                               San Jose  CA  94568\r
+                               US\r
+\r
+00-80-6C   (hex)               Secure Systems & Services\r
+00806C     (base 16)           Secure Systems & Services\r
+                               24, Chemin de la Pouranque\r
+                               F-13752  LES PENNES MIRABEAU  CS30084\r
+                               FR\r
+\r
+00-02-61   (hex)               Tilgin AB\r
+000261     (base 16)           Tilgin AB\r
+                               Finlandsgatan 40\r
+                                   \r
+                               SE\r
+\r
+AC-E2-D3   (hex)               Hewlett Packard\r
+ACE2D3     (base 16)           Hewlett Packard\r
+                               11445 Compaq Center Drive\r
+                               Houston  TX  77070\r
+                               US\r
+\r
+28-2F-C2   (hex)               Automotive Data Solutions\r
+282FC2     (base 16)           Automotive Data Solutions\r
+                               8400 rue Bougainville\r
+                               Montreal  Quebec  H4P2G1\r
+                               CA\r
+\r
+00-1D-38   (hex)               Seagate Technology\r
+001D38     (base 16)           Seagate Technology\r
+                               M/S NW1F01\r
+                               Longmont  CO  80503\r
+                               US\r
+\r
+68-3E-02   (hex)               SIEMENS AG, Digital Factory, Motion Control System\r
+683E02     (base 16)           SIEMENS AG, Digital Factory, Motion Control System\r
+                               Varey Road\r
+                               Congleton  Cheshire  CW12 1PH\r
+                               GB\r
+\r
+34-E3-80   (hex)               Genexis B.V.\r
+34E380     (base 16)           Genexis B.V.\r
+                               Lodewijkstraat 1A\r
+                               Eindhoven    5652AC\r
+                               NL\r
+\r
+2C-B2-1A   (hex)               Phicomm (Shanghai) Co., Ltd.\r
+2CB21A     (base 16)           Phicomm (Shanghai) Co., Ltd.\r
+                               3666 SiXian Rd.,Songjiang District\r
+                               Shanghai  Shanghai  201616\r
+                               CN\r
+\r
+CC-81-DA   (hex)               Phicomm (Shanghai) Co., Ltd.\r
+CC81DA     (base 16)           Phicomm (Shanghai) Co., Ltd.\r
+                               3666 SiXian Rd.,Songjiang District\r
+                               Shanghai  Shanghai  201616\r
+                               CN\r
+\r
+B8-07-16   (hex)               vivo Mobile Communication Co., Ltd.\r
+B80716     (base 16)           vivo Mobile Communication Co., Ltd.\r
+                               #283,BBK Road\r
+                               Wusha,Chang'An  DongGuan City,Guangdong,  523860\r
+                               CN\r
+\r
+C8-DF-84   (hex)               Texas Instruments\r
+C8DF84     (base 16)           Texas Instruments\r
+                               12500 TI Blvd\r
+                               Dallas  TX  75243\r
+                               US\r
+\r
+5C-0E-8B   (hex)               Extreme Networks, Inc.\r
+5C0E8B     (base 16)           Extreme Networks, Inc.\r
+                               475 Half Day Road\r
+                               Lincolnshire  IL  60069\r
+                               US\r
+\r
+B4-C7-99   (hex)               Extreme Networks, Inc.\r
+B4C799     (base 16)           Extreme Networks, Inc.\r
+                               475 Half Day Road\r
+                               Lincolnshire  IL  60069\r
+                               US\r
+\r
+74-67-F7   (hex)               Extreme Networks, Inc.\r
+7467F7     (base 16)           Extreme Networks, Inc.\r
+                               1 Zebra Plaza\r
+                               Holtsville  NY  11742\r
+                               US\r
+\r
+98-00-74   (hex)               Raisecom Technology CO., LTD\r
+980074     (base 16)           Raisecom Technology CO., LTD\r
+                               No. 11, East Area, No. 10 Block, East Xibeiwang Road\r
+                               Beijing    100094\r
+                               CN\r
+\r
+18-C1-9D   (hex)               Integrated Device Technology (Malaysia) Sdn. Bhd.\r
+18C19D     (base 16)           Integrated Device Technology (Malaysia) Sdn. Bhd.\r
+                               Phase 3, Bayan Lepas FIZ\r
+                               Bayan Lepas  Penang  11900\r
+                               MY\r
+\r
+00-E0-2B   (hex)               Extreme Networks, Inc.\r
+00E02B     (base 16)           Extreme Networks, Inc.\r
+                               10460 BANDLEY DRIVE\r
+                               CUPERINT0  CA  95014\r
+                               US\r
+\r
+A4-86-AE   (hex)               Quectel Wireless Solutions\r
+A486AE     (base 16)           Quectel Wireless Solutions\r
+                               No.1801 Hongmei Road, Xuhui District\r
+                               Shanghai    200233\r
+                               CN\r
+\r
+70-26-05   (hex)               SONY Visual Products Inc.\r
+702605     (base 16)           SONY Visual Products Inc.\r
+                               2-10-1 Osaki\r
+                               Shinagawa-ku  Tokyo  141-8610\r
+                               JP\r
+\r
+5C-5F-67   (hex)               Intel Corporate\r
+5C5F67     (base 16)           Intel Corporate\r
+                               Lot 8, Jalan Hi-Tech 2/3\r
+                               Kulim  Kedah  09000\r
+                               MY\r
+\r
+7C-76-35   (hex)               Intel Corporate\r
+7C7635     (base 16)           Intel Corporate\r
+                               Lot 8, Jalan Hi-Tech 2/3\r
+                               Kulim  Kedah  09000\r
+                               MY\r
+\r
+DC-48-B2   (hex)               Baraja Pty. Ltd.\r
+DC48B2     (base 16)           Baraja Pty. Ltd.\r
+                               36 Bradfield Road\r
+                               West Lindfield  NSW  2070\r
+                               AU\r
+\r
+00-01-23   (hex)               Schneider Electric Japan Holdings Ltd.\r
+000123     (base 16)           Schneider Electric Japan Holdings Ltd.\r
+                               Schneider Electric Osaka Building\r
+                               4-4-9 Kitahama  Chuo-ku, Osaka  541-0041\r
+                               JP\r
+\r
+D8-63-75   (hex)               Xiaomi Communications Co Ltd\r
+D86375     (base 16)           Xiaomi Communications Co Ltd\r
+                               The Rainbow City of China Resources\r
+                               NO.68, Qinghe Middle Street  Haidian District, Beijing  100085\r
+                               CN\r
+\r
+DC-BF-E9   (hex)               Motorola Mobility LLC, a Lenovo Company\r
+DCBFE9     (base 16)           Motorola Mobility LLC, a Lenovo Company\r
+                               222 West Merchandise Mart Plaza\r
+                               Chicago  IL  60654\r
+                               US\r
+\r
+2C-37-C5   (hex)               Qingdao Haier Intelligent Home Appliance Technology Co.,Ltd\r
+2C37C5     (base 16)           Qingdao Haier Intelligent Home Appliance Technology Co.,Ltd\r
+                               ingdao high-tech park haier road 1\r
+                               Qingdao  Shandong  266101\r
+                               CN\r
+\r
+74-95-EC   (hex)               ALPS ELECTRIC CO.,LTD.\r
+7495EC     (base 16)           ALPS ELECTRIC CO.,LTD.\r
+                               6-1\r
+                               Kakuda  Miyagi-Pref  981-1595\r
+                               JP\r
+\r
+18-52-82   (hex)               Fiberhome Telecommunication Technologies Co.,LTD\r
+185282     (base 16)           Fiberhome Telecommunication Technologies Co.,LTD\r
+                               No.5 DongXin Road\r
+                               Wuhan  Hubei  430074\r
+                               CN\r
+\r
+18-D2-25   (hex)               Fiberhome Telecommunication Technologies Co.,LTD\r
+18D225     (base 16)           Fiberhome Telecommunication Technologies Co.,LTD\r
+                               No.5 DongXin Road\r
+                               Wuhan  Hubei  430074\r
+                               CN\r
+\r
+04-02-CA   (hex)               Shenzhen Vtsonic Co.,ltd\r
+0402CA     (base 16)           Shenzhen Vtsonic Co.,ltd\r
+                               No.35,the 2nd Industrial Zone,Tangxiayong Village,Songgang Town,Bao'an District,Shenzhen,China.\r
+                               Shenzhen  Guangdong  518102\r
+                               CN\r
+\r
+30-6A-85   (hex)               Samsung Electronics Co.,Ltd\r
+306A85     (base 16)           Samsung Electronics Co.,Ltd\r
+                               #94-1, Imsoo-Dong\r
+                               Gumi  Gyeongbuk  730-350\r
+                               KR\r
+\r
+E4-F1-4C   (hex)               Private\r
+E4F14C     (base 16)           Private\r
+\r
+34-1A-35   (hex)               Fiberhome Telecommunication Technologies Co.,LTD\r
+341A35     (base 16)           Fiberhome Telecommunication Technologies Co.,LTD\r
+                               No.5 DongXin Road\r
+                               Wuhan  Hubei  430074\r
+                               CN\r
+\r
+6C-A8-58   (hex)               Fiberhome Telecommunication Technologies Co.,LTD\r
+6CA858     (base 16)           Fiberhome Telecommunication Technologies Co.,LTD\r
+                               No.5 DongXin Road\r
+                               Wuhan  Hubei  430074\r
+                               CN\r
+\r
+74-CC-39   (hex)               Fiberhome Telecommunication Technologies Co.,LTD\r
+74CC39     (base 16)           Fiberhome Telecommunication Technologies Co.,LTD\r
+                               No.5 DongXin Road\r
+                               Wuhan  Hubei  430074\r
+                               CN\r
+\r
+FC-F6-47   (hex)               Fiberhome Telecommunication Technologies Co.,LTD\r
+FCF647     (base 16)           Fiberhome Telecommunication Technologies Co.,LTD\r
+                               No.5 DongXin Road\r
+                               Wuhan City  Hubei Province  430074\r
+                               CN\r
+\r
+10-88-CE   (hex)               Fiberhome Telecommunication Technologies Co.,LTD\r
+1088CE     (base 16)           Fiberhome Telecommunication Technologies Co.,LTD\r
+                               No.5 DongXin Road\r
+                               Wuhan City  Hubei Province  430074\r
+                               CN\r
+\r
+BC-98-89   (hex)               Fiberhome Telecommunication Technologies Co.,LTD\r
+BC9889     (base 16)           Fiberhome Telecommunication Technologies Co.,LTD\r
+                               No.5 DongXin Road\r
+                               Wuhan City  Hubei Province  430074\r
+                               CN\r
+\r
+E4-2F-26   (hex)               Fiberhome Telecommunication Technologies Co.,LTD\r
+E42F26     (base 16)           Fiberhome Telecommunication Technologies Co.,LTD\r
+                               No.5 DongXin Road\r
+                               Wuhan City  Hubei Province  430074\r
+                               CN\r
+\r
+34-4B-3D   (hex)               Fiberhome Telecommunication Technologies Co.,LTD\r
+344B3D     (base 16)           Fiberhome Telecommunication Technologies Co.,LTD\r
+                               No.5 DongXin Road\r
+                               Wuhan City  Hubei Province  430074\r
+                               CN\r
+\r
+70-B9-21   (hex)               Fiberhome Telecommunication Technologies Co.,LTD\r
+70B921     (base 16)           Fiberhome Telecommunication Technologies Co.,LTD\r
+                               No.5 DongXin Road\r
+                               Wuhan  Hubei  430074\r
+                               CN\r
+\r
+74-E1-9A   (hex)               Fiberhome Telecommunication Technologies Co.,LTD\r
+74E19A     (base 16)           Fiberhome Telecommunication Technologies Co.,LTD\r
+                               No.5 DongXin Road\r
+                               Wuhan  Hubei  430074\r
+                               CN\r
+\r
+94-8D-EF   (hex)               Oetiker Schweiz AG\r
+948DEF     (base 16)           Oetiker Schweiz AG\r
+                               Spätzstrasse 11\r
+                               Horgen    8810\r
+                               CH\r
+\r
+74-72-1E   (hex)               Edison Labs Inc.\r
+74721E     (base 16)           Edison Labs Inc.\r
+                               1122 Stanyan St\r
+                               San Francisco  CA  94117\r
+                               US\r
+\r
+A8-36-7A   (hex)               frogblue TECHNOLOGY GmbH\r
+A8367A     (base 16)           frogblue TECHNOLOGY GmbH\r
+                               Luxemburger Straße 6\r
+                               Kaiserslautern  Rheinland-Pfalz  67657\r
+                               DE\r
+\r
+14-4E-34   (hex)               Remote Solution\r
+144E34     (base 16)           Remote Solution\r
+                               92, Chogokri, Nammyun\r
+                               Kimcheon city  Kyungbuk  740-871\r
+                               KR\r
+\r
+EC-65-CC   (hex)               Panasonic Automotive Systems Company of America\r
+EC65CC     (base 16)           Panasonic Automotive Systems Company of America\r
+                               776 Highway 74 South\r
+                               Peachtree City    30269\r
+                               US\r
+\r
+DC-4E-F4   (hex)               Shenzhen MTN Electronics CO., Ltd\r
+DC4EF4     (base 16)           Shenzhen MTN Electronics CO., Ltd\r
+                               MTN Industrial Park, No. 5, 9 South Futai Road, Pingxi Community, Pingdi Street, Longgang District\r
+                               Shenzhen  Guangdong  518117\r
+                               CN\r
+\r
+AC-F8-5C   (hex)               Private\r
+ACF85C     (base 16)           Private\r
+\r
+D4-60-E3   (hex)               Sercomm Corporation.\r
+D460E3     (base 16)           Sercomm Corporation.\r
+                               violet_liu@sercomm.com\r
+                               Miao-Lih Hsuan    115\r
+                               TW\r
+\r
+D0-25-98   (hex)               Apple, Inc.\r
+D02598     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+A8-66-7F   (hex)               Apple, Inc.\r
+A8667F     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+70-14-A6   (hex)               Apple, Inc.\r
+7014A6     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+10-41-7F   (hex)               Apple, Inc.\r
+10417F     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+AC-29-3A   (hex)               Apple, Inc.\r
+AC293A     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+94-E9-6A   (hex)               Apple, Inc.\r
+94E96A     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+0C-4D-E9   (hex)               Apple, Inc.\r
+0C4DE9     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+90-72-40   (hex)               Apple, Inc.\r
+907240     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+A8-88-08   (hex)               Apple, Inc.\r
+A88808     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+C8-E0-EB   (hex)               Apple, Inc.\r
+C8E0EB     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+54-E4-3A   (hex)               Apple, Inc.\r
+54E43A     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+28-E1-4C   (hex)               Apple, Inc.\r
+28E14C     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+84-8E-0C   (hex)               Apple, Inc.\r
+848E0C     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+B0-34-95   (hex)               Apple, Inc.\r
+B03495     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+F0-F6-1C   (hex)               Apple, Inc.\r
+F0F61C     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+0C-30-21   (hex)               Apple, Inc.\r
+0C3021     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+D8-96-95   (hex)               Apple, Inc.\r
+D89695     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+64-9A-BE   (hex)               Apple, Inc.\r
+649ABE     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+5C-F5-DA   (hex)               Apple, Inc.\r
+5CF5DA     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+20-A2-E4   (hex)               Apple, Inc.\r
+20A2E4     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+F0-24-75   (hex)               Apple, Inc.\r
+F02475     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+24-A0-74   (hex)               Apple, Inc.\r
+24A074     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+88-63-DF   (hex)               Apple, Inc.\r
+8863DF     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+60-92-17   (hex)               Apple, Inc.\r
+609217     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+34-E2-FD   (hex)               Apple, Inc.\r
+34E2FD     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+0C-3E-9F   (hex)               Apple, Inc.\r
+0C3E9F     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+6C-70-9F   (hex)               Apple, Inc.\r
+6C709F     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+6C-40-08   (hex)               Apple, Inc.\r
+6C4008     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+5C-97-F3   (hex)               Apple, Inc.\r
+5C97F3     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+90-FD-61   (hex)               Apple, Inc.\r
+90FD61     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+00-61-71   (hex)               Apple, Inc.\r
+006171     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+80-E6-50   (hex)               Apple, Inc.\r
+80E650     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+DC-2B-2A   (hex)               Apple, Inc.\r
+DC2B2A     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+B8-44-D9   (hex)               Apple, Inc.\r
+B844D9     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+E0-F5-C6   (hex)               Apple, Inc.\r
+E0F5C6     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+94-94-26   (hex)               Apple, Inc.\r
+949426     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+CC-29-F5   (hex)               Apple, Inc.\r
+CC29F5     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+58-40-4E   (hex)               Apple, Inc.\r
+58404E     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+DC-0C-5C   (hex)               Apple, Inc.\r
+DC0C5C     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+2C-20-0B   (hex)               Apple, Inc.\r
+2C200B     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+DC-A4-CA   (hex)               Apple, Inc.\r
+DCA4CA     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+8C-8F-E9   (hex)               Apple, Inc.\r
+8C8FE9     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+98-10-E8   (hex)               Apple, Inc.\r
+9810E8     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+B4-9C-DF   (hex)               Apple, Inc.\r
+B49CDF     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+A4-E9-75   (hex)               Apple, Inc.\r
+A4E975     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+C0-A5-3E   (hex)               Apple, Inc.\r
+C0A53E     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+98-00-C6   (hex)               Apple, Inc.\r
+9800C6     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+78-7B-8A   (hex)               Apple, Inc.\r
+787B8A     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+38-66-F0   (hex)               Apple, Inc.\r
+3866F0     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+20-EE-28   (hex)               Apple, Inc.\r
+20EE28     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+08-F4-AB   (hex)               Apple, Inc.\r
+08F4AB     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+8C-85-90   (hex)               Apple, Inc.\r
+8C8590     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+B4-8B-19   (hex)               Apple, Inc.\r
+B48B19     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+E4-9A-79   (hex)               Apple, Inc.\r
+E49A79     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+28-A0-2B   (hex)               Apple, Inc.\r
+28A02B     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+B4-4B-D2   (hex)               Apple, Inc.\r
+B44BD2     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+2C-F0-A2   (hex)               Apple, Inc.\r
+2CF0A2     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+EC-AD-B8   (hex)               Apple, Inc.\r
+ECADB8     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+98-01-A7   (hex)               Apple, Inc.\r
+9801A7     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+60-9A-C1   (hex)               Apple, Inc.\r
+609AC1     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+F0-79-60   (hex)               Apple, Inc.\r
+F07960     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+9C-8B-A0   (hex)               Apple, Inc.\r
+9C8BA0     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+4C-32-75   (hex)               Apple, Inc.\r
+4C3275     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+E4-E4-AB   (hex)               Apple, Inc.\r
+E4E4AB     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+C8-33-4B   (hex)               Apple, Inc.\r
+C8334B     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+00-F4-B9   (hex)               Apple, Inc.\r
+00F4B9     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+0C-77-1A   (hex)               Apple, Inc.\r
+0C771A     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-00-1C-73   (hex)               Arista Networks\r
-001C73     (base 16)           Arista Networks\r
-                               5470 Great America Pkwy\r
-                               Santa Clara  California  95054\r
+74-E1-B6   (hex)               Apple, Inc.\r
+74E1B6     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-38-AD-8E   (hex)               New H3C Technologies Co., Ltd\r
-38AD8E     (base 16)           New H3C Technologies Co., Ltd\r
-                               466 Changhe Road, Binjiang District\r
-                               Hangzhou  Zhejiang  310052\r
-                               CN\r
+64-20-0C   (hex)               Apple, Inc.\r
+64200C     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-B0-CA-68   (hex)               Apple, Inc.\r
-B0CA68     (base 16)           Apple, Inc.\r
+C0-84-7A   (hex)               Apple, Inc.\r
+C0847A     (base 16)           Apple, Inc.\r
                                1 Infinite Loop\r
                                Cupertino  CA  95014\r
                                US\r
 \r
-00-12-48   (hex)               Dell EMC\r
-001248     (base 16)           Dell EMC\r
-                               176 South Street\r
-                               Hopkinton  MA  01748\r
+18-34-51   (hex)               Apple, Inc.\r
+183451     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-00-01-44   (hex)               Dell EMC\r
-000144     (base 16)           Dell EMC\r
-                               228 South St.\r
-                               Hopkinton  MA  01748\r
+FC-25-3F   (hex)               Apple, Inc.\r
+FC253F     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-00-BF-61   (hex)               Samsung Electronics Co.,Ltd\r
-00BF61     (base 16)           Samsung Electronics Co.,Ltd\r
-                               129, Samsung-ro, Youngtongl-Gu\r
-                               Suwon  Gyeonggi-Do  16677\r
-                               KR\r
+10-40-F3   (hex)               Apple, Inc.\r
+1040F3     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-30-9F-FB   (hex)               Ardomus Networks Corporation\r
-309FFB     (base 16)           Ardomus Networks Corporation\r
-                               4F,No. 6 Innovation Road II, Hsinchu Science Park  \r
-                               Hsinchu    300\r
-                               TW\r
+6C-C2-6B   (hex)               Apple, Inc.\r
+6CC26B     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-E4-BD-4B   (hex)               zte corporation\r
-E4BD4B     (base 16)           zte corporation\r
-                               12/F.,zte R&D building ,kejinan Road,Shenzhen,P.R.China\r
-                               shenzhen  guangdong  518057\r
-                               CN\r
+18-20-32   (hex)               Apple, Inc.\r
+182032     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-6C-56-97   (hex)               Amazon Technologies Inc.\r
-6C5697     (base 16)           Amazon Technologies Inc.\r
-                               P.O Box 8102\r
-                               Reno  NV  89507\r
+70-DE-E2   (hex)               Apple, Inc.\r
+70DEE2     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-3C-A5-81   (hex)               vivo Mobile Communication Co., Ltd.\r
-3CA581     (base 16)           vivo Mobile Communication Co., Ltd.\r
-                               #283,BBK Road\r
-                               Wusha,Chang'An  DongGuan City,Guangdong,  523860\r
-                               CN\r
+00-C6-10   (hex)               Apple, Inc.\r
+00C610     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-F4-EA-B5   (hex)               Aerohive Networks Inc.\r
-F4EAB5     (base 16)           Aerohive Networks Inc.\r
-                               1011 McCarthy Blvd\r
-                               Milpitas  CA  95035\r
+10-1C-0C   (hex)               Apple, Inc.\r
+101C0C     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-F8-20-55   (hex)               Green Information System\r
-F82055     (base 16)           Green Information System\r
-                               #202(Shopping center), Woldong-ro 28, Buk-gu\r
-                               Gwangju    61153\r
-                               KR\r
+7C-FA-DF   (hex)               Apple, Inc.\r
+7CFADF     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-78-5C-28   (hex)               Prime Motion Inc.\r
-785C28     (base 16)           Prime Motion Inc.\r
-                               Akaho 1134-12\r
-                               Komagane  Nagano  399-4117\r
-                               JP\r
+5C-F9-38   (hex)               Apple, Inc.\r
+5CF938     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-94-49-96   (hex)               WiSilica Inc\r
-944996     (base 16)           WiSilica Inc\r
-                               23282 Mill Creek Dr #340\r
-                               Laguna Hills  CA  92653\r
+38-71-DE   (hex)               Apple, Inc.\r
+3871DE     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-00-26-A8   (hex)               DAEHAP HYPER-TECH\r
-0026A8     (base 16)           DAEHAP HYPER-TECH\r
-                               Mega center #1108, SK Techno-Park, #190-1, Sangdaewon-Dong, Jungwon-Gu\r
-                               Seongnam  Gyeonggi-Do  462-807\r
-                               KR\r
+BC-54-36   (hex)               Apple, Inc.\r
+BC5436     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-F8-7B-20   (hex)               Cisco Systems, Inc\r
-F87B20     (base 16)           Cisco Systems, Inc\r
-                               80 West Tasman Drive\r
-                               San Jose  CA  94568\r
+9C-4F-DA   (hex)               Apple, Inc.\r
+9C4FDA     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-F8-1D-0F   (hex)               Hitron Technologies. Inc\r
-F81D0F     (base 16)           Hitron Technologies. Inc\r
-                               No. 1-8, Lising 1st Rd. Hsinchu Science Park, Hsinchu, 300, Taiwan, R.O.C\r
-                               Hsin-chu  Taiwan  300\r
-                               TW\r
+1C-5C-F2   (hex)               Apple, Inc.\r
+1C5CF2     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-30-FB-94   (hex)               Shanghai Fangzhiwei Information Technology CO.,Ltd.\r
-30FB94     (base 16)           Shanghai Fangzhiwei Information Technology CO.,Ltd.\r
-                               The 17th  Building A Unit,No. 1688 Lianhang Road,Minhang District,Shanghai City\r
-                               Shanghai    201100\r
-                               CN\r
+60-FB-42   (hex)               Apple, Inc.\r
+60FB42     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-08-BA-22   (hex)               Swaive Corporation\r
-08BA22     (base 16)           Swaive Corporation\r
-                               3565 Kettmann Road\r
-                               San Jose  CA  95121\r
+00-25-00   (hex)               Apple, Inc.\r
+002500     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-F8-0C-F3   (hex)               LG Electronics (Mobile Communications)\r
-F80CF3     (base 16)           LG Electronics (Mobile Communications)\r
-                               60-39, Gasan-dong, Geumcheon-gu\r
-                               Seoul    153-801\r
-                               KR\r
+00-23-6C   (hex)               Apple, Inc.\r
+00236C     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-30-76-6F   (hex)               LG Electronics (Mobile Communications)\r
-30766F     (base 16)           LG Electronics (Mobile Communications)\r
-                               60-39, Gasan-dong, Geumcheon-gu\r
-                               Seoul    153-801\r
-                               KR\r
+00-21-E9   (hex)               Apple, Inc.\r
+0021E9     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-8C-3A-E3   (hex)               LG Electronics (Mobile Communications)\r
-8C3AE3     (base 16)           LG Electronics (Mobile Communications)\r
-                               60-39, Gasan-dong, Geumcheon-gu\r
-                               Seoul    153-801\r
-                               KR\r
+00-1F-F3   (hex)               Apple, Inc.\r
+001FF3     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-94-2A-3F   (hex)               Diversey Inc\r
-942A3F     (base 16)           Diversey Inc\r
-                               2415 Cascade Pointe Blvd\r
-                               Charlotte  NC  28208\r
+00-1F-5B   (hex)               Apple, Inc.\r
+001F5B     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-78-F8-82   (hex)               LG Electronics (Mobile Communications)\r
-78F882     (base 16)           LG Electronics (Mobile Communications)\r
-                               60-39, Gasan-dong, Geumcheon-gu\r
-                               Seoul    153-801\r
-                               KR\r
+00-1E-52   (hex)               Apple, Inc.\r
+001E52     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-0C-61-11   (hex)               Anda Technologies SAC\r
-0C6111     (base 16)           Anda Technologies SAC\r
-                               Av. Santa Cruz 888, Miraflores\r
-                               Lima  Peru  Lima18\r
-                               PE\r
+00-1D-4F   (hex)               Apple, Inc.\r
+001D4F     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-B8-F7-4A   (hex)               RCNTEC\r
-B8F74A     (base 16)           RCNTEC\r
-                               Polkovaya street 3\r
-                               Moscow    127018\r
-                               RU\r
+00-11-24   (hex)               Apple, Inc.\r
+001124     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-C8-D1-2A   (hex)               Comtrend Corporation\r
-C8D12A     (base 16)           Comtrend Corporation\r
-                               3F-1, No. 10, Lane 609, Chung Hsin Road, Sec 5, San Chung Dist.\r
-                               New Taipei City  Taiwan  24159\r
-                               TW\r
+A8-FA-D8   (hex)               Apple, Inc.\r
+A8FAD8     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-B4-F1-DA   (hex)               LG Electronics (Mobile Communications)\r
-B4F1DA     (base 16)           LG Electronics (Mobile Communications)\r
-                               60-39, Gasan-dong, Geumcheon-gu\r
-                               Seoul    153-801\r
-                               KR\r
+5C-96-9D   (hex)               Apple, Inc.\r
+5C969D     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-00-21-FB   (hex)               LG Electronics (Mobile Communications)\r
-0021FB     (base 16)           LG Electronics (Mobile Communications)\r
-                               60-39, Gasan-dong, Geumcheon-gu\r
-                               Seoul    153-801\r
-                               KR\r
+E4-8B-7F   (hex)               Apple, Inc.\r
+E48B7F     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-D0-13-FD   (hex)               LG Electronics (Mobile Communications)\r
-D013FD     (base 16)           LG Electronics (Mobile Communications)\r
-                               60-39, Gasan-dong, Geumcheon-gu\r
-                               Seoul    153-801\r
-                               KR\r
+84-FC-FE   (hex)               Apple, Inc.\r
+84FCFE     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-A8-B8-6E   (hex)               LG Electronics (Mobile Communications)\r
-A8B86E     (base 16)           LG Electronics (Mobile Communications)\r
-                               60-39, Gasan-dong, Geumcheon-gu\r
-                               Seoul    153-801\r
-                               KR\r
+44-4C-0C   (hex)               Apple, Inc.\r
+444C0C     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-DC-4F-22   (hex)               Espressif Inc.\r
-DC4F22     (base 16)           Espressif Inc.\r
-                               Room 204, Building 2, 690 Bibo Road, Pudong New Area\r
-                               Shanghai  Shanghai  201203\r
-                               CN\r
+8C-2D-AA   (hex)               Apple, Inc.\r
+8C2DAA     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-34-2A-F1   (hex)               Texas Instruments\r
-342AF1     (base 16)           Texas Instruments\r
-                               12500 TI Blvd\r
-                               Dallas  TX  75243\r
+6C-3E-6D   (hex)               Apple, Inc.\r
+6C3E6D     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-70-E5-6E   (hex)               Texas Instruments\r
-70E56E     (base 16)           Texas Instruments\r
-                               12500 TI Blvd\r
-                               Dallas  TX  75243\r
+18-9E-FC   (hex)               Apple, Inc.\r
+189EFC     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-F0-85-C1   (hex)               SHENZHEN RF-LINK TECHNOLOGY CO.,LTD.\r
-F085C1     (base 16)           SHENZHEN RF-LINK TECHNOLOGY CO.,LTD.\r
-                               Bldg56A,6/F,Baotian Rd3,Xixiang Town,Baoan District,\r
-                               Shenzhen  Guangdong  518000\r
-                               CN\r
+C0-9F-42   (hex)               Apple, Inc.\r
+C09F42     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-C8-DE-C9   (hex)               Coriant\r
-C8DEC9     (base 16)           Coriant\r
-                               1415 W. Diehl Rd\r
-                               Naperville  IL  60563\r
+B8-F6-B1   (hex)               Apple, Inc.\r
+B8F6B1     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-38-0E-4D   (hex)               Cisco Systems, Inc\r
-380E4D     (base 16)           Cisco Systems, Inc\r
-                               80 West Tasman Drive\r
-                               San Jose  CA  94568\r
+40-6C-8F   (hex)               Apple, Inc.\r
+406C8F     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-FC-9D-D8   (hex)               Beijing TongTongYiLian Science and Technology Ltd.\r
-FC9DD8     (base 16)           Beijing TongTongYiLian Science and Technology Ltd.\r
-                                Room 301,Zone 3,Building 9,No.8 Dongbeiwang West Road,Haidian District,Beijing\r
-                               BEIJING  BEIJING  100193\r
-                               CN\r
+A4-D1-D2   (hex)               Apple, Inc.\r
+A4D1D2     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-04-B1-67   (hex)               Xiaomi Communications Co Ltd\r
-04B167     (base 16)           Xiaomi Communications Co Ltd\r
-                               The Rainbow City of China Resources\r
-                               NO.68, Qinghe Middle Street  Haidian District, Beijing  100085\r
-                               CN\r
+04-0C-CE   (hex)               Apple, Inc.\r
+040CCE     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-38-AD-BE   (hex)               New H3C Technologies Co., Ltd\r
-38ADBE     (base 16)           New H3C Technologies Co., Ltd\r
-                               466 Changhe Road, Binjiang District\r
-                               Hangzhou  Zhejiang  310052\r
-                               CN\r
+D8-9E-3F   (hex)               Apple, Inc.\r
+D89E3F     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-58-19-F8   (hex)               ARRIS Group, Inc.\r
-5819F8     (base 16)           ARRIS Group, Inc.\r
-                               6450 Sequence Drive\r
-                               San Diego  CA  92121\r
+28-E7-CF   (hex)               Apple, Inc.\r
+28E7CF     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
                                US\r
 \r
-20-78-52   (hex)               Nokia\r
-207852     (base 16)           Nokia\r
-                               Karaportti 3\r
-                               Espoo  Finland  02610\r
-                               FI\r
+C8-BC-C8   (hex)               Apple, Inc.\r
+C8BCC8     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-AC-64-17   (hex)               Siemens AG - Industrial Automation - EWA\r
-AC6417     (base 16)           Siemens AG - Industrial Automation - EWA\r
-                               Werner-von-Siemens Strasse 50\r
-                               Amberg    92224\r
-                               DE\r
+D8-A2-5E   (hex)               Apple, Inc.\r
+D8A25E     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-CC-5D-4E   (hex)               Zyxel Communications Corporation\r
-CC5D4E     (base 16)           Zyxel Communications Corporation\r
-                               No. 6 Innovation Road II, Science Park\r
-                               Hsichu  Taiwan  300\r
-                               TW\r
+90-84-0D   (hex)               Apple, Inc.\r
+90840D     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-40-4A-03   (hex)               Zyxel Communications Corporation\r
-404A03     (base 16)           Zyxel Communications Corporation\r
-                               No. 6 Innovation Road II, Science Park\r
-                               Hsichu  Taiwan  300\r
-                               TW\r
+F8-1E-DF   (hex)               Apple, Inc.\r
+F81EDF     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-00-13-49   (hex)               Zyxel Communications Corporation\r
-001349     (base 16)           Zyxel Communications Corporation\r
-                               No. 6 Innovation Road II, Science Park\r
-                               Hsichu  Taiwan  300\r
-                               TW\r
+B0-CA-68   (hex)               Apple, Inc.\r
+B0CA68     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-1C-74-0D   (hex)               Zyxel Communications Corporation\r
-1C740D     (base 16)           Zyxel Communications Corporation\r
-                               No. 6 Innovation Road II, Science Park\r
-                               Hsichu  Taiwan  300\r
-                               TW\r
+98-CA-33   (hex)               Apple, Inc.\r
+98CA33     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-A0-E4-CB   (hex)               Zyxel Communications Corporation\r
-A0E4CB     (base 16)           Zyxel Communications Corporation\r
-                               No. 6 Innovation Road II, Science Park\r
-                               Hsichu  Taiwan  300\r
-                               TW\r
+68-EF-43   (hex)               Apple, Inc.\r
+68EF43     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-5C-6A-80   (hex)               Zyxel Communications Corporation\r
-5C6A80     (base 16)           Zyxel Communications Corporation\r
-                               No. 6 Innovation Road II, Science Park\r
-                               Hsichu  Taiwan  300\r
-                               TW\r
+CC-2D-B7   (hex)               Apple, Inc.\r
+CC2DB7     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-5C-E2-8C   (hex)               Zyxel Communications Corporation\r
-5CE28C     (base 16)           Zyxel Communications Corporation\r
-                               No. 6 Innovation Road II, Science Park\r
-                               Hsichu  Taiwan  300\r
-                               TW\r
+D4-A3-3D   (hex)               Apple, Inc.\r
+D4A33D     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-A8-EE-C6   (hex)               Muuselabs NV/SA\r
-A8EEC6     (base 16)           Muuselabs NV/SA\r
-                               Rue du Tocsin 12\r
-                               Brussels    1000\r
-                               BE\r
+E4-E0-A6   (hex)               Apple, Inc.\r
+E4E0A6     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-A0-9D-C1   (hex)               China Dragon Technology Limited\r
-A09DC1     (base 16)           China Dragon Technology Limited\r
-                               B4 Bldg.Haoshan 1st Industry Park,\r
-                               Shenzhen  Guangdong  518104\r
-                               CN\r
+70-EF-00   (hex)               Apple, Inc.\r
+70EF00     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
 \r
-38-43-7D   (hex)               Compal Broadband Networks, Inc.\r
-38437D     (base 16)           Compal Broadband Networks, Inc.\r
-                               13F., No.1, Taiyuan 1st St.\r
-                               Zhubei City  Hsinchu County  30265\r
-                               TW\r
+A0-39-EE   (hex)               Sagemcom Broadband SAS\r
+A039EE     (base 16)           Sagemcom Broadband SAS\r
+                               250, route de l'Empereur\r
+                               Rueil Malmaison Cedex  hauts de seine  92848\r
+                               FR\r
 \r
-5C-86-C1   (hex)               DONGGUAN SOLUM ELECTRONICS CO.,LTD\r
-5C86C1     (base 16)           DONGGUAN SOLUM ELECTRONICS CO.,LTD\r
-                               NO.157,13 Coastal Way TPFTZ\r
-                               TIANJIN    300461\r
+A4-40-27   (hex)               zte corporation\r
+A44027     (base 16)           zte corporation\r
+                               12/F.,zte R&D building ,kejinan Road,Shenzhen,P.R.China\r
+                               shenzhen  guangdong  518057\r
                                CN\r
 \r
-6C-DD-30   (hex)               Cisco Systems, Inc\r
-6CDD30     (base 16)           Cisco Systems, Inc\r
-                               80 West Tasman Drive\r
-                               San Jose  CA  94568\r
+1C-11-61   (hex)               Ciena Corporation\r
+1C1161     (base 16)           Ciena Corporation\r
+                               7035 Ridge Road\r
+                               Hanover  MD  21076\r
                                US\r
 \r
-00-80-6C   (hex)               Secure Systems & Services\r
-00806C     (base 16)           Secure Systems & Services\r
-                               24, Chemin de la Pouranque\r
-                               F-13752  LES PENNES MIRABEAU  CS30084\r
-                               FR\r
+4C-82-CF   (hex)               Dish Technologies Corp\r
+4C82CF     (base 16)           Dish Technologies Corp\r
+                               94 Inverness Terrace E\r
+                               Englewood  CO  80112\r
+                               US\r
 \r
-00-02-61   (hex)               Tilgin AB\r
-000261     (base 16)           Tilgin AB\r
-                               Finlandsgatan 40\r
-                                   \r
-                               SE\r
+F0-C9-D1   (hex)               GD Midea Air-Conditioning Equipment Co.,Ltd.\r
+F0C9D1     (base 16)           GD Midea Air-Conditioning Equipment Co.,Ltd.\r
+                               Midea Global Innovation Center,Beijiao Town,Shunde\r
+                               Foshan  Guangdong  528311\r
+                               CN\r
 \r
-AC-E2-D3   (hex)               Hewlett Packard\r
-ACE2D3     (base 16)           Hewlett Packard\r
-                               11445 Compaq Center Drive\r
-                               Houston  TX  77070\r
+D4-9C-F4   (hex)               Palo Alto Networks\r
+D49CF4     (base 16)           Palo Alto Networks\r
+                               3000 Tannery Way\r
+                               Santa Clara  CA  95054\r
                                US\r
 \r
-28-2F-C2   (hex)               Automotive Data Solutions\r
-282FC2     (base 16)           Automotive Data Solutions\r
-                               8400 rue Bougainville\r
-                               Montreal  Quebec  H4P2G1\r
-                               CA\r
+3C-57-4F   (hex)               China Mobile Group Device Co.,Ltd.\r
+3C574F     (base 16)           China Mobile Group Device Co.,Ltd.\r
+                               32 Xuanwumen West Street,Xicheng District\r
+                               Beijing    100053\r
+                               CN\r
 \r
-00-1D-38   (hex)               Seagate Technology\r
-001D38     (base 16)           Seagate Technology\r
-                               M/S NW1F01\r
-                               Longmont  CO  80503\r
+50-6B-4B   (hex)               Mellanox Technologies, Inc.\r
+506B4B     (base 16)           Mellanox Technologies, Inc.\r
+                               350 Oakmead Parkway, Suite 100\r
+                               Sunnyvale  CA  94085\r
                                US\r
 \r
-68-3E-02   (hex)               SIEMENS AG, Digital Factory, Motion Control System\r
-683E02     (base 16)           SIEMENS AG, Digital Factory, Motion Control System\r
-                               Varey Road\r
-                               Congleton  Cheshire  CW12 1PH\r
-                               GB\r
+F8-C1-20   (hex)               Xi'an Link-Science Technology Co.,Ltd\r
+F8C120     (base 16)           Xi'an Link-Science Technology Co.,Ltd\r
+                               1/F,Block F,Building zhichao Weilai,No.999,10#Caotan Road,Xi'an\r
+                               xi'an    710016\r
+                               CN\r
 \r
-34-E3-80   (hex)               Genexis B.V.\r
-34E380     (base 16)           Genexis B.V.\r
-                               Lodewijkstraat 1A\r
-                               Eindhoven    5652AC\r
-                               NL\r
+90-3A-72   (hex)               Ruckus Wireless\r
+903A72     (base 16)           Ruckus Wireless\r
+                               350 West Java Drive\r
+                               Sunnyvale  CA  94089\r
+                               US\r
 \r
-2C-B2-1A   (hex)               Phicomm (Shanghai) Co., Ltd.\r
-2CB21A     (base 16)           Phicomm (Shanghai) Co., Ltd.\r
-                               3666 SiXian Rd.,Songjiang District\r
-                               Shanghai  Shanghai  201616\r
+3C-E8-24   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
+3CE824     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
+                               No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park\r
+                               Dongguan    523808\r
                                CN\r
 \r
-CC-81-DA   (hex)               Phicomm (Shanghai) Co., Ltd.\r
-CC81DA     (base 16)           Phicomm (Shanghai) Co., Ltd.\r
-                               3666 SiXian Rd.,Songjiang District\r
-                               Shanghai  Shanghai  201616\r
+E8-AB-F3   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
+E8ABF3     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
+                               No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park\r
+                               Dongguan    523808\r
                                CN\r
 \r
-B8-07-16   (hex)               vivo Mobile Communication Co., Ltd.\r
-B80716     (base 16)           vivo Mobile Communication Co., Ltd.\r
-                               #283,BBK Road\r
-                               Wusha,Chang'An  DongGuan City,Guangdong,  523860\r
+70-06-AC   (hex)               Eastcompeace Technology Co., Ltd\r
+7006AC     (base 16)           Eastcompeace Technology Co., Ltd\r
+                               Number 8 Pinggong Zhong Road,Nanping S&T Industry Community,Zhuhai,Guangdong,519060 China \r
+                               Zhuhai  Guangdong  519060\r
                                CN\r
 \r
-C8-DF-84   (hex)               Texas Instruments\r
-C8DF84     (base 16)           Texas Instruments\r
-                               12500 TI Blvd\r
-                               Dallas  TX  75243\r
-                               US\r
+50-6F-77   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
+506F77     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
+                               No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park\r
+                               Dongguan    523808\r
+                               CN\r
 \r
-5C-0E-8B   (hex)               Extreme Networks, Inc.\r
-5C0E8B     (base 16)           Extreme Networks, Inc.\r
-                               475 Half Day Road\r
-                               Lincolnshire  IL  60069\r
+2C-95-69   (hex)               ARRIS Group, Inc.\r
+2C9569     (base 16)           ARRIS Group, Inc.\r
+                               6450 Sequence Drive\r
+                               San Diego  CA  92121\r
                                US\r
 \r
-B4-C7-99   (hex)               Extreme Networks, Inc.\r
-B4C799     (base 16)           Extreme Networks, Inc.\r
-                               475 Half Day Road\r
-                               Lincolnshire  IL  60069\r
+50-95-51   (hex)               ARRIS Group, Inc.\r
+509551     (base 16)           ARRIS Group, Inc.\r
+                               6450 Sequence Drive\r
+                               San Diego  CA  92121\r
                                US\r
 \r
-74-67-F7   (hex)               Extreme Networks, Inc.\r
-7467F7     (base 16)           Extreme Networks, Inc.\r
-                               1 Zebra Plaza\r
-                               Holtsville  NY  11742\r
+60-98-13   (hex)               Shanghai Visking Digital Technology Co. LTD\r
+609813     (base 16)           Shanghai Visking Digital Technology Co. LTD\r
+                               Room 1301, Building A8, No.1688 Guoquan North Road, Yangpu District\r
+                               Shanghai    200082\r
+                               CN\r
+\r
+8C-4C-AD   (hex)               Evoluzn Inc.\r
+8C4CAD     (base 16)           Evoluzn Inc.\r
+                               34 Samoset Lane\r
+                               Schaumburg  IL  60193\r
                                US\r
 \r
-98-00-74   (hex)               Raisecom Technology CO., LTD\r
-980074     (base 16)           Raisecom Technology CO., LTD\r
-                               No. 11, East Area, No. 10 Block, East Xibeiwang Road\r
-                               Beijing    100094\r
+A4-D4-B2   (hex)               Shenzhen MeiG Smart Technology Co.,Ltd\r
+A4D4B2     (base 16)           Shenzhen MeiG Smart Technology Co.,Ltd\r
+                               #88 Qinjiang Road, Xuhui District\r
+                               Shanghai    200233\r
                                CN\r
 \r
-18-C1-9D   (hex)               Integrated Device Technology (Malaysia) Sdn. Bhd.\r
-18C19D     (base 16)           Integrated Device Technology (Malaysia) Sdn. Bhd.\r
-                               Phase 3, Bayan Lepas FIZ\r
-                               Bayan Lepas  Penang  11900\r
-                               MY\r
-\r
-00-E0-2B   (hex)               Extreme Networks, Inc.\r
-00E02B     (base 16)           Extreme Networks, Inc.\r
-                               10460 BANDLEY DRIVE\r
-                               CUPERINT0  CA  95014\r
+DC-E5-33   (hex)               IEEE Registration Authority\r
+DCE533     (base 16)           IEEE Registration Authority\r
+                               445 Hoes Lane\r
+                               Piscataway  NJ  08554\r
                                US\r
 \r
-A4-86-AE   (hex)               Quectel Wireless Solutions\r
-A486AE     (base 16)           Quectel Wireless Solutions\r
-                               No.1801 Hongmei Road, Xuhui District\r
-                               Shanghai    200233\r
+8C-F7-10   (hex)               AMPAK Technology, Inc.\r
+8CF710     (base 16)           AMPAK Technology, Inc.\r
+                               No.1,Jen Ai Road Hsinchu Industrial Park, Hukou\r
+                               Hsinchu  Taiwan ROC.  30352 \r
+                               TW\r
+\r
+38-E1-AA   (hex)               zte corporation\r
+38E1AA     (base 16)           zte corporation\r
+                               12/F.,zte R&D building ,kejinan Road,Shenzhen,P.R.China\r
+                               shenzhen  guangdong  518057\r
                                CN\r
 \r
-70-26-05   (hex)               SONY Visual Products Inc.\r
-702605     (base 16)           SONY Visual Products Inc.\r
-                               2-10-1 Osaki\r
-                               Shinagawa-ku  Tokyo  141-8610\r
-                               JP\r
+18-A2-8A   (hex)               Essel-T Co., Ltd\r
+18A28A     (base 16)           Essel-T Co., Ltd\r
+                               1211 kranztechno, 388 Dunchon-daero\r
+                               Seongnam-si  Jungwon-gu, Gyeonggi-do  13403\r
+                               KR\r
 \r
-5C-5F-67   (hex)               Intel Corporate\r
-5C5F67     (base 16)           Intel Corporate\r
+38-DE-AD   (hex)               Intel Corporate\r
+38DEAD     (base 16)           Intel Corporate\r
                                Lot 8, Jalan Hi-Tech 2/3\r
                                Kulim  Kedah  09000\r
                                MY\r
 \r
-7C-76-35   (hex)               Intel Corporate\r
-7C7635     (base 16)           Intel Corporate\r
-                               Lot 8, Jalan Hi-Tech 2/3\r
-                               Kulim  Kedah  09000\r
-                               MY\r
+74-E1-82   (hex)               Texas Instruments\r
+74E182     (base 16)           Texas Instruments\r
+                               12500 TI Blvd\r
+                               Dallas  TX  75243\r
+                               US\r
 \r
-DC-48-B2   (hex)               Baraja Pty. Ltd.\r
-DC48B2     (base 16)           Baraja Pty. Ltd.\r
-                               36 Bradfield Road\r
-                               West Lindfield  NSW  2070\r
-                               AU\r
+40-BD-32   (hex)               Texas Instruments\r
+40BD32     (base 16)           Texas Instruments\r
+                               12500 TI Blvd\r
+                               Dallas  TX  75243\r
+                               US\r
 \r
-00-01-23   (hex)               Schneider Electric Japan Holdings Ltd.\r
-000123     (base 16)           Schneider Electric Japan Holdings Ltd.\r
-                               Schneider Electric Osaka Building\r
-                               4-4-9 Kitahama  Chuo-ku, Osaka  541-0041\r
-                               JP\r
+3C-17-10   (hex)               Sagemcom Broadband SAS\r
+3C1710     (base 16)           Sagemcom Broadband SAS\r
+                               250, route de l'Empereur\r
+                               Rueil Malmaison Cedex  hauts de seine  92848\r
+                               FR\r
 \r
-D8-63-75   (hex)               Xiaomi Communications Co Ltd\r
-D86375     (base 16)           Xiaomi Communications Co Ltd\r
+C8-FA-E1   (hex)               ARQ Digital LLC\r
+C8FAE1     (base 16)           ARQ Digital LLC\r
+                               2430 Auto Park Way\r
+                               Escondido  CA  92029\r
+                               US\r
+\r
+80-AD-16   (hex)               Xiaomi Communications Co Ltd\r
+80AD16     (base 16)           Xiaomi Communications Co Ltd\r
                                The Rainbow City of China Resources\r
                                NO.68, Qinghe Middle Street  Haidian District, Beijing  100085\r
                                CN\r
 \r
-DC-BF-E9   (hex)               Motorola Mobility LLC, a Lenovo Company\r
-DCBFE9     (base 16)           Motorola Mobility LLC, a Lenovo Company\r
-                               222 West Merchandise Mart Plaza\r
-                               Chicago  IL  60654\r
-                               US\r
+04-4E-AF   (hex)               LG Innotek\r
+044EAF     (base 16)           LG Innotek\r
+                               26, Hanamsandan 5beon-ro\r
+                               Gwangju  Gwangsan-gu  506-731\r
+                               KR\r
 \r
-2C-37-C5   (hex)               Qingdao Haier Intelligent Home Appliance Technology Co.,Ltd\r
-2C37C5     (base 16)           Qingdao Haier Intelligent Home Appliance Technology Co.,Ltd\r
-                               ingdao high-tech park haier road 1\r
-                               Qingdao  Shandong  266101\r
+DC-A3-33   (hex)               Shenzhen YOUHUA Technology Co., Ltd\r
+DCA333     (base 16)           Shenzhen YOUHUA Technology Co., Ltd\r
+                               Room 407 Shenzhen University-town Business Park,Lishan Road,Taoyuan Street,Nanshan District\r
+                               Shenzhen  Guangdong  518055\r
                                CN\r
 \r
-74-95-EC   (hex)               ALPS ELECTRIC CO.,LTD.\r
-7495EC     (base 16)           ALPS ELECTRIC CO.,LTD.\r
-                               6-1\r
-                               Kakuda  Miyagi-Pref  981-1595\r
-                               JP\r
-\r
-18-52-82   (hex)               Fiberhome Telecommunication Technologies Co.,LTD\r
-185282     (base 16)           Fiberhome Telecommunication Technologies Co.,LTD\r
-                               No.5 DongXin Road\r
-                               Wuhan  Hubei  430074\r
+BC-DD-C2   (hex)               Espressif Inc.\r
+BCDDC2     (base 16)           Espressif Inc.\r
+                               Room 204, Building 2, 690 Bibo Road, Pudong New Area\r
+                               Shanghai  Shanghai  201203\r
                                CN\r
 \r
-18-D2-25   (hex)               Fiberhome Telecommunication Technologies Co.,LTD\r
-18D225     (base 16)           Fiberhome Telecommunication Technologies Co.,LTD\r
-                               No.5 DongXin Road\r
-                               Wuhan  Hubei  430074\r
+FC-7C-02   (hex)               Phicomm (Shanghai) Co., Ltd.\r
+FC7C02     (base 16)           Phicomm (Shanghai) Co., Ltd.\r
+                               3666 SiXian Rd.,Songjiang District\r
+                               Shanghai  Shanghai  201616\r
                                CN\r
 \r
-04-02-CA   (hex)               Shenzhen Vtsonic Co.,ltd\r
-0402CA     (base 16)           Shenzhen Vtsonic Co.,ltd\r
-                               No.35,the 2nd Industrial Zone,Tangxiayong Village,Songgang Town,Bao'an District,Shenzhen,China.\r
-                               Shenzhen  Guangdong  518102\r
-                               CN\r
+88-A9-A7   (hex)               IEEE Registration Authority\r
+88A9A7     (base 16)           IEEE Registration Authority\r
+                               445 Hoes Lane\r
+                               Piscataway  NJ  08554\r
+                               US\r
 \r
-30-6A-85   (hex)               Samsung Electronics Co.,Ltd\r
-306A85     (base 16)           Samsung Electronics Co.,Ltd\r
-                               #94-1, Imsoo-Dong\r
-                               Gumi  Gyeongbuk  730-350\r
-                               KR\r
+F0-E3-DC   (hex)               Tecon MT, LLC\r
+F0E3DC     (base 16)           Tecon MT, LLC\r
+                               3rd Khoroshevskaya st - 20\r
+                               Moscow    123298\r
+                               RU\r
 \r
-E4-F1-4C   (hex)               Private\r
-E4F14C     (base 16)           Private\r
+30-B2-16   (hex)               ABB AG - Power Grids - Grid Automation\r
+30B216     (base 16)           ABB AG - Power Grids - Grid Automation\r
+                               Kallstadter Strasse 1\r
+                               Mannheim    68309\r
+                               DE\r
 \r
-34-1A-35   (hex)               Fiberhome Telecommunication Technologies Co.,LTD\r
-341A35     (base 16)           Fiberhome Telecommunication Technologies Co.,LTD\r
-                               No.5 DongXin Road\r
-                               Wuhan  Hubei  430074\r
-                               CN\r
+00-D0-CE   (hex)               iSystem Labs \r
+00D0CE     (base 16)           iSystem Labs \r
+                               BRODISCE 7, 10C \r
+                               Trzin    1236\r
+                               SI\r
 \r
-6C-A8-58   (hex)               Fiberhome Telecommunication Technologies Co.,LTD\r
-6CA858     (base 16)           Fiberhome Telecommunication Technologies Co.,LTD\r
-                               No.5 DongXin Road\r
-                               Wuhan  Hubei  430074\r
-                               CN\r
+00-BE-75   (hex)               Cisco Systems, Inc\r
+00BE75     (base 16)           Cisco Systems, Inc\r
+                               80 West Tasman Drive\r
+                               San Jose  CA  94568\r
+                               US\r
 \r
-74-CC-39   (hex)               Fiberhome Telecommunication Technologies Co.,LTD\r
-74CC39     (base 16)           Fiberhome Telecommunication Technologies Co.,LTD\r
-                               No.5 DongXin Road\r
-                               Wuhan  Hubei  430074\r
-                               CN\r
+50-4E-DC   (hex)               Ping Communication\r
+504EDC     (base 16)           Ping Communication\r
+                               Brenden 18\r
+                               Appenzell Meistersrüte  AI  9050\r
+                               CH\r
 \r
-FC-F6-47   (hex)               Fiberhome Telecommunication Technologies Co.,LTD\r
-FCF647     (base 16)           Fiberhome Telecommunication Technologies Co.,LTD\r
-                               No.5 DongXin Road\r
-                               Wuhan City  Hubei Province  430074\r
-                               CN\r
+20-67-7C   (hex)               Hewlett Packard Enterprise\r
+20677C     (base 16)           Hewlett Packard Enterprise\r
+                               8000 Foothills Blvd.\r
+                               Roseville  CA  95747\r
+                               US\r
 \r
-10-88-CE   (hex)               Fiberhome Telecommunication Technologies Co.,LTD\r
-1088CE     (base 16)           Fiberhome Telecommunication Technologies Co.,LTD\r
-                               No.5 DongXin Road\r
-                               Wuhan City  Hubei Province  430074\r
+C4-2C-4F   (hex)               Qingdao Hisense Mobile Communication Technology Co,Ltd\r
+C42C4F     (base 16)           Qingdao Hisense Mobile Communication Technology Co,Ltd\r
+                               No.399, Song Ling Road\r
+                               Qingdao  Shandong  266100\r
                                CN\r
 \r
-BC-98-89   (hex)               Fiberhome Telecommunication Technologies Co.,LTD\r
-BC9889     (base 16)           Fiberhome Telecommunication Technologies Co.,LTD\r
+24-CA-CB   (hex)               Fiberhome Telecommunication Technologies Co.,LTD\r
+24CACB     (base 16)           Fiberhome Telecommunication Technologies Co.,LTD\r
                                No.5 DongXin Road\r
-                               Wuhan City  Hubei Province  430074\r
+                               Wuhan  Hubei  430074\r
                                CN\r
 \r
-E4-2F-26   (hex)               Fiberhome Telecommunication Technologies Co.,LTD\r
-E42F26     (base 16)           Fiberhome Telecommunication Technologies Co.,LTD\r
-                               No.5 DongXin Road\r
-                               Wuhan City  Hubei Province  430074\r
-                               CN\r
+24-0A-63   (hex)               ARRIS Group, Inc.\r
+240A63     (base 16)           ARRIS Group, Inc.\r
+                               6450 Sequence Drive\r
+                               San Diego  CA  92121\r
+                               US\r
 \r
-34-4B-3D   (hex)               Fiberhome Telecommunication Technologies Co.,LTD\r
-344B3D     (base 16)           Fiberhome Telecommunication Technologies Co.,LTD\r
-                               No.5 DongXin Road\r
-                               Wuhan City  Hubei Province  430074\r
+44-FF-BA   (hex)               zte corporation\r
+44FFBA     (base 16)           zte corporation\r
+                               12/F.,zte R&D building ,kejinan Road,Shenzhen,P.R.China\r
+                               shenzhen  guangdong  518057\r
                                CN\r
 \r
-70-B9-21   (hex)               Fiberhome Telecommunication Technologies Co.,LTD\r
-70B921     (base 16)           Fiberhome Telecommunication Technologies Co.,LTD\r
-                               No.5 DongXin Road\r
-                               Wuhan  Hubei  430074\r
-                               CN\r
+00-23-A8   (hex)               Marshall Electronics\r
+0023A8     (base 16)           Marshall Electronics\r
+                               20608 Madrona Ave\r
+                               Torrance  CA  90503\r
+                               US\r
 \r
-74-E1-9A   (hex)               Fiberhome Telecommunication Technologies Co.,LTD\r
-74E19A     (base 16)           Fiberhome Telecommunication Technologies Co.,LTD\r
-                               No.5 DongXin Road\r
-                               Wuhan  Hubei  430074\r
-                               CN\r
+B4-81-BF   (hex)               Meta-Networks, LLC\r
+B481BF     (base 16)           Meta-Networks, LLC\r
+                               Office 106C, 5/2, Varshavskaya street\r
+                               Saint-Petersburg  Saint-Petersburg  196128\r
+                               RU\r
 \r
-AC-F8-5C   (hex)               Private\r
-ACF85C     (base 16)           Private\r
+10-1D-51   (hex)               8Mesh Networks\r
+101D51     (base 16)           8Mesh Networks\r
+                               Unit 607, 6/F, Yen Sheng Centre,\r
+                               64 Hoi Yuen Road  Kwun Tong  000\r
+                               HK\r
+\r
+0C-AE-7D   (hex)               Texas Instruments\r
+0CAE7D     (base 16)           Texas Instruments\r
+                               12500 TI Blvd\r
+                               Dallas  TX  75243\r
+                               US\r
 \r
 D8-6C-E9   (hex)               Sagemcom Broadband SAS\r
 D86CE9     (base 16)           Sagemcom Broadband SAS\r
@@ -85901,18 +86933,6 @@ D86CE9     (base 16)           Sagemcom Broadband SAS
                                Irvine  CA  92612\r
                                US\r
 \r
-6C-8D-C1   (hex)               Apple, Inc.\r
-6C8DC1     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-38-CA-DA   (hex)               Apple, Inc.\r
-38CADA     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 8C-57-9B   (hex)               Wistron Neweb Corporation\r
 8C579B     (base 16)           Wistron Neweb Corporation\r
                                No.20,Park Avenue II,Hsinchu Science Park\r
@@ -85943,18 +86963,6 @@ B436A9     (base 16)           Fibocom Wireless Inc.
                                Dongguan  Guangdong  523808 \r
                                CN\r
 \r
-68-DB-CA   (hex)               Apple, Inc.\r
-68DBCA     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-04-4B-ED   (hex)               Apple, Inc.\r
-044BED     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 3C-BB-73   (hex)               Shenzhen Xinguodu Technology Co., Ltd.\r
 3CBB73     (base 16)           Shenzhen Xinguodu Technology Co., Ltd.\r
                                F17A, JinSong Building, Tairan Industrial & Trade Park, Chegongmiao, Shennan Road,Futian District\r
@@ -86339,18 +87347,6 @@ EC52DC     (base 16)           WORLD MEDIA AND TECHNOLOGY Corp.
                                Miami    33132\r
                                US\r
 \r
-A4-D1-8C   (hex)               Apple, Inc.\r
-A4D18C     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-CC-25-EF   (hex)               Apple, Inc.\r
-CC25EF     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 24-09-95   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
 240995     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
                                No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park\r
@@ -86897,78 +87893,6 @@ FC9947     (base 16)           Cisco Systems, Inc
                                San Jose  CA  95134\r
                                US\r
 \r
-7C-C5-37   (hex)               Apple, Inc.\r
-7CC537     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-70-CD-60   (hex)               Apple, Inc.\r
-70CD60     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-24-AB-81   (hex)               Apple, Inc.\r
-24AB81     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-58-1F-AA   (hex)               Apple, Inc.\r
-581FAA     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-A4-67-06   (hex)               Apple, Inc.\r
-A46706     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-3C-07-54   (hex)               Apple, Inc.\r
-3C0754     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-E4-CE-8F   (hex)               Apple, Inc.\r
-E4CE8F     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-E8-04-0B   (hex)               Apple, Inc.\r
-E8040B     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-B8-C7-5D   (hex)               Apple, Inc.\r
-B8C75D     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-40-3C-FC   (hex)               Apple, Inc.\r
-403CFC     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-28-6A-B8   (hex)               Apple, Inc.\r
-286AB8     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-7C-C3-A1   (hex)               Apple, Inc.\r
-7CC3A1     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
 00-E1-6D   (hex)               Cisco Systems, Inc\r
 00E16D     (base 16)           Cisco Systems, Inc\r
                                170 West Tasman Drive\r
@@ -87029,84 +87953,6 @@ E0D173     (base 16)           Cisco Systems, Inc
                                San Jose  CA  95134\r
                                US\r
 \r
-B8-78-2E   (hex)               Apple, Inc.\r
-B8782E     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-00-05-02   (hex)               Apple, Inc.\r
-000502     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-00-10-FA   (hex)               Apple, Inc.\r
-0010FA     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-00-03-93   (hex)               Apple, Inc.\r
-000393     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-00-16-CB   (hex)               Apple, Inc.\r
-0016CB     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-00-17-F2   (hex)               Apple, Inc.\r
-0017F2     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-00-1B-63   (hex)               Apple, Inc.\r
-001B63     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-00-1E-C2   (hex)               Apple, Inc.\r
-001EC2     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-00-26-08   (hex)               Apple, Inc.\r
-002608     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-7C-6D-62   (hex)               Apple, Inc.\r
-7C6D62     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-40-D3-2D   (hex)               Apple, Inc.\r
-40D32D     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-D8-30-62   (hex)               Apple, Inc.\r
-D83062     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-C4-2C-03   (hex)               Apple, Inc.\r
-C42C03     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
 6C-20-56   (hex)               Cisco Systems, Inc\r
 6C2056     (base 16)           Cisco Systems, Inc\r
                                170 West Tasman Drive\r
@@ -87149,54 +87995,6 @@ F872EA     (base 16)           Cisco Systems, Inc
                                San Jose  CA  95134\r
                                US\r
 \r
-78-9F-70   (hex)               Apple, Inc.\r
-789F70     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-DC-37-14   (hex)               Apple, Inc.\r
-DC3714     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-40-33-1A   (hex)               Apple, Inc.\r
-40331A     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-94-F6-A3   (hex)               Apple, Inc.\r
-94F6A3     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-D8-1D-72   (hex)               Apple, Inc.\r
-D81D72     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-70-EC-E4   (hex)               Apple, Inc.\r
-70ECE4     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-38-C9-86   (hex)               Apple, Inc.\r
-38C986     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-FC-FC-48   (hex)               Apple, Inc.\r
-FCFC48     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 28-57-BE   (hex)               Hangzhou Hikvision Digital Technology Co.,Ltd.\r
 2857BE     (base 16)           Hangzhou Hikvision Digital Technology Co.,Ltd.\r
                                No.469,Jianghui Road\r
@@ -87221,258 +88019,6 @@ F0F249     (base 16)          Hitron Technologies. Inc
                                Hsin-chu  Taiwan  300\r
                                TW\r
 \r
-A4-C3-61   (hex)               Apple, Inc.\r
-A4C361     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-AC-7F-3E   (hex)               Apple, Inc.\r
-AC7F3E     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-28-0B-5C   (hex)               Apple, Inc.\r
-280B5C     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-90-B9-31   (hex)               Apple, Inc.\r
-90B931     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-24-A2-E1   (hex)               Apple, Inc.\r
-24A2E1     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-80-EA-96   (hex)               Apple, Inc.\r
-80EA96     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-60-03-08   (hex)               Apple, Inc.\r
-600308     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-04-F1-3E   (hex)               Apple, Inc.\r
-04F13E     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-54-72-4F   (hex)               Apple, Inc.\r
-54724F     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-48-74-6E   (hex)               Apple, Inc.\r
-48746E     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-3C-AB-8E   (hex)               Apple, Inc.\r
-3CAB8E     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-7C-6D-F8   (hex)               Apple, Inc.\r
-7C6DF8     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-48-D7-05   (hex)               Apple, Inc.\r
-48D705     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-3C-D0-F8   (hex)               Apple, Inc.\r
-3CD0F8     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-98-D6-BB   (hex)               Apple, Inc.\r
-98D6BB     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-4C-B1-99   (hex)               Apple, Inc.\r
-4CB199     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-64-E6-82   (hex)               Apple, Inc.\r
-64E682     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-80-49-71   (hex)               Apple, Inc.\r
-804971     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-98-FE-94   (hex)               Apple, Inc.\r
-98FE94     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-D8-00-4D   (hex)               Apple, Inc.\r
-D8004D     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-98-B8-E3   (hex)               Apple, Inc.\r
-98B8E3     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-80-92-9F   (hex)               Apple, Inc.\r
-80929F     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-88-53-95   (hex)               Apple, Inc.\r
-885395     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-9C-04-EB   (hex)               Apple, Inc.\r
-9C04EB     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-78-FD-94   (hex)               Apple, Inc.\r
-78FD94     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-C8-85-50   (hex)               Apple, Inc.\r
-C88550     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-D4-F4-6F   (hex)               Apple, Inc.\r
-D4F46F     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-78-7E-61   (hex)               Apple, Inc.\r
-787E61     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-60-F8-1D   (hex)               Apple, Inc.\r
-60F81D     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-4C-7C-5F   (hex)               Apple, Inc.\r
-4C7C5F     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-48-E9-F1   (hex)               Apple, Inc.\r
-48E9F1     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-FC-E9-98   (hex)               Apple, Inc.\r
-FCE998     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-F0-99-BF   (hex)               Apple, Inc.\r
-F099BF     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-68-64-4B   (hex)               Apple, Inc.\r
-68644B     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-A8-96-8A   (hex)               Apple, Inc.\r
-A8968A     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-4C-8D-79   (hex)               Apple, Inc.\r
-4C8D79     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-20-7D-74   (hex)               Apple, Inc.\r
-207D74     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-F4-F1-5A   (hex)               Apple, Inc.\r
-F4F15A     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-04-26-65   (hex)               Apple, Inc.\r
-042665     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-2C-B4-3A   (hex)               Apple, Inc.\r
-2CB43A     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-68-9C-70   (hex)               Apple, Inc.\r
-689C70     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-08-70-45   (hex)               Apple, Inc.\r
-087045     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
 CC-E0-C3   (hex)               Mangstor, Inc.\r
 CCE0C3     (base 16)           Mangstor, Inc.\r
                                108 Wild Basin Rd\r
@@ -87635,24 +88181,6 @@ D0C193     (base 16)           SKYBELL, INC
                                IRVINE  CA  92618\r
                                US\r
 \r
-20-9B-CD   (hex)               Apple, Inc.\r
-209BCD     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-F0-B0-E7   (hex)               Apple, Inc.\r
-F0B0E7     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-CC-20-E8   (hex)               Apple, Inc.\r
-CC20E8     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 E4-35-C8   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
 E435C8     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
                                No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park\r
@@ -89003,12 +89531,6 @@ B0D7C5     (base 16)           Logipix Ltd
                                Budapest  -  1158\r
                                HU\r
 \r
-38-C9-A9   (hex)               SMART High Reliability Solutions, Inc.\r
-38C9A9     (base 16)           SMART High Reliability Solutions, Inc.\r
-                               2600 W. Geronimo Place\r
-                               Chandler  AZ  85224\r
-                               US\r
-\r
 BC-1A-67   (hex)               YF Technology Co., Ltd\r
 BC1A67     (base 16)           YF Technology Co., Ltd\r
                                No.62,South Fumin Road,\r
@@ -90650,12 +91172,6 @@ CC262D     (base 16)           Verifi, LLC
                                Hangzhou  Zhejiang  310013\r
                                CN\r
 \r
-7C-B2-32   (hex)               Hui Zhou Gaoshengda Technology Co.,LTD\r
-7CB232     (base 16)           Hui Zhou Gaoshengda Technology Co.,LTD\r
-                               No.75,Zhongkai High-Tech Development District,Huizhou\r
-                               Hui Zhou  Guangdong  516006\r
-                               CN\r
-\r
 54-DF-63   (hex)               Intrakey technologies GmbH\r
 54DF63     (base 16)           Intrakey technologies GmbH\r
                                Wiener Strasse 114-116\r
@@ -93251,12 +93767,6 @@ A04041     (base 16)           SAMWONFA Co.,Ltd.
                                Busan    608-042\r
                                KR\r
 \r
-78-8C-54   (hex)               Eltek Technologies LTD\r
-788C54     (base 16)           Eltek Technologies LTD\r
-                               Glatt Tower\r
-                                 8301 Glattzentrum ZH  \r
-                               CH\r
-\r
 94-11-DA   (hex)               ITF Fröschl GmbH\r
 9411DA     (base 16)           ITF Fröschl GmbH\r
                                Hauserbachstraße 9\r
@@ -93353,12 +93863,6 @@ AC6123     (base 16)           Drivven, Inc.
                                Seoul    153-793\r
                                KR\r
 \r
-D4-66-A8   (hex)               Riedo Networks GmbH\r
-D466A8     (base 16)           Riedo Networks GmbH\r
-                               Warpelstrasse 10\r
-                               Duedingen  FR  3186\r
-                               CH\r
-\r
 98-E1-65   (hex)               Accutome\r
 98E165     (base 16)           Accutome\r
                                3222 Phoenixville Pike\r
@@ -97142,12 +97646,6 @@ EC3091     (base 16)           Cisco Systems, Inc
                                Aalen  Baden-Württemberg  73434\r
                                DE\r
 \r
-00-1B-D9   (hex)               Edgewater Computer Systems\r
-001BD9     (base 16)           Edgewater Computer Systems\r
-                               1125 Innovation Drive\r
-                               Ottawa  Ontario  K2K-3G6\r
-                               CA\r
-\r
 00-1B-DB   (hex)               Valeo VECS\r
 001BDB     (base 16)           Valeo VECS\r
                                2 Avenue Fernand Pouillon\r
@@ -109082,12 +109580,6 @@ DC0077     (base 16)         TP-LINK TECHNOLOGIES CO.,LTD.
                                Yokohama, Kanagawa    231-0021\r
                                JP\r
 \r
-F4-5C-89   (hex)               Apple, Inc.\r
-F45C89     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 00-21-FD   (hex)               LACROIX TRAFFIC S.A.U\r
 0021FD     (base 16)           LACROIX TRAFFIC S.A.U\r
                                Majada 4\r
@@ -109124,24 +109616,6 @@ F45C89     (base 16)         Apple, Inc.
                                Sydney  NSW  2000\r
                                AU\r
 \r
-BC-EC-5D   (hex)               Apple, Inc.\r
-BCEC5D     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-DC-41-5F   (hex)               Apple, Inc.\r
-DC415F     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-30-63-6B   (hex)               Apple, Inc.\r
-30636B     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 84-68-3E   (hex)               Intel Corporate\r
 84683E     (base 16)           Intel Corporate\r
                                Lot 8, Jalan Hi-Tech 2/3\r
@@ -109622,12 +110096,6 @@ BC7574     (base 16)         HUAWEI TECHNOLOGIES CO.,LTD
                                Gyeonggi-Do    14523\r
                                KR\r
 \r
-A0-67-BE   (hex)               Sicon srl\r
-A067BE     (base 16)           Sicon srl\r
-                               Via Sila 1/3\r
-                               Isola Vicentina  Vicenza  36033\r
-                               IT\r
-\r
 C4-CA-D9   (hex)               Hangzhou H3C Technologies Co., Limited\r
 C4CAD9     (base 16)           Hangzhou H3C Technologies Co., Limited\r
                                310 Liuhe Road, Zhijiang Science Park\r
@@ -109700,24 +110168,6 @@ C02FF1     (base 16)         Volta Networks
                                Heuchelheim  Hessen  35452\r
                                DE\r
 \r
-0C-51-01   (hex)               Apple, Inc.\r
-0C5101     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-08-6D-41   (hex)               Apple, Inc.\r
-086D41     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-04-D3-CF   (hex)               Apple, Inc.\r
-04D3CF     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 30-C8-2A   (hex)               WI-BIZ srl\r
 30C82A     (base 16)           WI-BIZ srl\r
                                Via Carlo Ferrero 10\r
@@ -110696,30 +111146,12 @@ CCA260     (base 16)                SICHUAN TIANYI COMHEART TELECOMCO.,LTD
                                Chengdu  Sichuan  610000\r
                                CN\r
 \r
-20-3C-AE   (hex)               Apple, Inc.\r
-203CAE     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-74-8D-08   (hex)               Apple, Inc.\r
-748D08     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 00-D7-8F   (hex)               Cisco Systems, Inc\r
 00D78F     (base 16)           Cisco Systems, Inc\r
                                80 West Tasman Drive\r
                                San Jose  CA  94568\r
                                US\r
 \r
-A0-3B-E3   (hex)               Apple, Inc.\r
-A03BE3     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 88-6B-0F   (hex)               Bluegiga Technologies OY\r
 886B0F     (base 16)           Bluegiga Technologies OY\r
                                P.O. BOX 120\r
@@ -111812,36 +112244,6 @@ CCA219     (base 16)         SHENZHEN ALONG INVESTMENT CO.,LTD
                                Vienna    1030\r
                                AT\r
 \r
-64-B0-A6   (hex)               Apple, Inc.\r
-64B0A6     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-84-FC-AC   (hex)               Apple, Inc.\r
-84FCAC     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-6C-19-C0   (hex)               Apple, Inc.\r
-6C19C0     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-20-AB-37   (hex)               Apple, Inc.\r
-20AB37     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-18-65-90   (hex)               Apple, Inc.\r
-186590     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 2C-0B-E9   (hex)               Cisco Systems, Inc\r
 2C0BE9     (base 16)           Cisco Systems, Inc\r
                                80 West Tasman Drive\r
@@ -112298,36 +112700,6 @@ A8A198     (base 16)         TCT mobile ltd
                                Round Rock  TX  78682\r
                                US\r
 \r
-C0-D0-12   (hex)               Apple, Inc.\r
-C0D012     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-D4-DC-CD   (hex)               Apple, Inc.\r
-D4DCCD     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-48-4B-AA   (hex)               Apple, Inc.\r
-484BAA     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-F8-03-77   (hex)               Apple, Inc.\r
-F80377     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-14-BD-61   (hex)               Apple, Inc.\r
-14BD61     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 08-27-CE   (hex)               NAGANO KEIKI CO., LTD.\r
 0827CE     (base 16)           NAGANO KEIKI CO., LTD.\r
                                2150 IKUTA\r
@@ -113644,40 +114016,22 @@ B0350B     (base 16)                MOBIWIRE MOBILES (NINGBO) CO.,LTD
 \r
 E0-48-D3   (hex)               MOBIWIRE MOBILES (NINGBO) CO.,LTD\r
 E048D3     (base 16)           MOBIWIRE MOBILES (NINGBO) CO.,LTD\r
-                               No.999,Dacheng East Road,\r
-                               Fenghua  Zhejiang  315500\r
-                               CN\r
-\r
-24-C4-2F   (hex)               Philips Lifeline\r
-24C42F     (base 16)           Philips Lifeline\r
-                               111 Lawrence st\r
-                               Framingham  MA  01702\r
-                               US\r
-\r
-B8-EE-0E   (hex)               Sagemcom Broadband SAS\r
-B8EE0E     (base 16)           Sagemcom Broadband SAS\r
-                               250, route de l'Empereur\r
-                               Rueil Malmaison Cedex  hauts de seine  92848\r
-                               FR\r
-\r
-78-88-6D   (hex)               Apple, Inc.\r
-78886D     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-A8-5C-2C   (hex)               Apple, Inc.\r
-A85C2C     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
+                               No.999,Dacheng East Road,\r
+                               Fenghua  Zhejiang  315500\r
+                               CN\r
 \r
-00-DB-70   (hex)               Apple, Inc.\r
-00DB70     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
+24-C4-2F   (hex)               Philips Lifeline\r
+24C42F     (base 16)           Philips Lifeline\r
+                               111 Lawrence st\r
+                               Framingham  MA  01702\r
                                US\r
 \r
+B8-EE-0E   (hex)               Sagemcom Broadband SAS\r
+B8EE0E     (base 16)           Sagemcom Broadband SAS\r
+                               250, route de l'Empereur\r
+                               Rueil Malmaison Cedex  hauts de seine  92848\r
+                               FR\r
+\r
 38-6E-A2   (hex)               vivo Mobile Communication Co., Ltd.\r
 386EA2     (base 16)           vivo Mobile Communication Co., Ltd.\r
                                #283,BBK Road\r
@@ -114011,30 +114365,6 @@ F06E0B     (base 16)         Microsoft Corporation
                                 Zhubei City   Hsinchu County  302\r
                                TW\r
 \r
-80-B0-3D   (hex)               Apple, Inc.\r
-80B03D     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-C8-3C-85   (hex)               Apple, Inc.\r
-C83C85     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-A0-4E-A7   (hex)               Apple, Inc.\r
-A04EA7     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-40-9C-28   (hex)               Apple, Inc.\r
-409C28     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 50-C9-A0   (hex)               SKIPPER AS\r
 50C9A0     (base 16)           SKIPPER AS\r
                                Enebakkvn 150\r
@@ -114194,6 +114524,222 @@ D4AD2D     (base 16)                Fiberhome Telecommunication Technologies Co.,LTD
                                Wuhan  Hubei  430074\r
                                CN\r
 \r
+68-57-2D   (hex)               HANGZHOU AIXIANGJI TECHNOLOGY CO., LTD\r
+68572D     (base 16)           HANGZHOU AIXIANGJI TECHNOLOGY CO., LTD\r
+                               7 Floor, 3 Blvd., More Centre, 87 Gudun Rd., Xihu District\r
+                               Hangzhou  Zhejiang  310012\r
+                               CN\r
+\r
+F0-B0-E7   (hex)               Apple, Inc.\r
+F0B0E7     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+20-9B-CD   (hex)               Apple, Inc.\r
+209BCD     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+CC-20-E8   (hex)               Apple, Inc.\r
+CC20E8     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+10-C2-5A   (hex)               Technicolor CH USA Inc.\r
+10C25A     (base 16)           Technicolor CH USA Inc.\r
+                               101 West 103rd St.\r
+                               Indianapolis  IN  46290\r
+                               US\r
+\r
+8C-59-73   (hex)               Zyxel Communications Corporation\r
+8C5973     (base 16)           Zyxel Communications Corporation\r
+                               No. 6 Innovation Road II, Science Park\r
+                               Hsichu  Taiwan  300\r
+                               TW\r
+\r
+94-FE-9D   (hex)               SHENZHEN GONGJIN ELECTRONICS CO.,LT\r
+94FE9D     (base 16)           SHENZHEN GONGJIN ELECTRONICS CO.,LT\r
+                               SONGGANG\r
+                               SHENZHEN  GUANGDONG  518105\r
+                               CN\r
+\r
+04-D1-3A   (hex)               Xiaomi Communications Co Ltd\r
+04D13A     (base 16)           Xiaomi Communications Co Ltd\r
+                               The Rainbow City of China Resources\r
+                               NO.68, Qinghe Middle Street  Haidian District, Beijing  100085\r
+                               CN\r
+\r
+24-7E-12   (hex)               Cisco Systems, Inc\r
+247E12     (base 16)           Cisco Systems, Inc\r
+                               80 West Tasman Drive\r
+                               San Jose  CA  94568\r
+                               US\r
+\r
+E4-2D-7B   (hex)               China Mobile IOT Company Limited\r
+E42D7B     (base 16)           China Mobile IOT Company Limited\r
+                               NO.8 Yu Ma Road, NanAn Area Chongqing,China\r
+                               Chongqing  Chongqing  401336\r
+                               CN\r
+\r
+04-EC-BB   (hex)               Fiberhome Telecommunication Technologies Co.,LTD\r
+04ECBB     (base 16)           Fiberhome Telecommunication Technologies Co.,LTD\r
+                               No.5 DongXin Road\r
+                               Wuhan  Hubei  430074\r
+                               CN\r
+\r
+0C-54-15   (hex)               Intel Corporate\r
+0C5415     (base 16)           Intel Corporate\r
+                               Lot 8, Jalan Hi-Tech 2/3\r
+                               Kulim  Kedah  09000\r
+                               MY\r
+\r
+84-DB-9E   (hex)               Aifloo AB\r
+84DB9E     (base 16)           Aifloo AB\r
+                               Postbox 2005\r
+                               Stockholm    10311\r
+                               SE\r
+\r
+B0-B3-AD   (hex)               HUMAX Co., Ltd.\r
+B0B3AD     (base 16)           HUMAX Co., Ltd.\r
+                               HUMAX Village, 216, Hwangsaeul-ro, Bu\r
+                               Seongnam-si  Gyeonggi-do  463-875\r
+                               KR\r
+\r
+38-78-62   (hex)               Sony Mobile Communications AB\r
+387862     (base 16)           Sony Mobile Communications AB\r
+                               Nya Vattentornet\r
+                               Lund  SE  22128\r
+                               SE\r
+\r
+18-31-BF   (hex)               ASUSTek COMPUTER INC.\r
+1831BF     (base 16)           ASUSTek COMPUTER INC.\r
+                               15,Li-Te Rd., Peitou, Taipei 112, Taiwan\r
+                               Taipei  Taiwan  112\r
+                               TW\r
+\r
+7C-25-86   (hex)               Juniper Networks\r
+7C2586     (base 16)           Juniper Networks\r
+                               1133 Innovation Way\r
+                               Sunnyvale  CA  94089\r
+                               US\r
+\r
+00-1B-D9   (hex)               Edgewater Wireless Systems Inc\r
+001BD9     (base 16)           Edgewater Wireless Systems Inc\r
+                               50 HInes Road Suite 200\r
+                               Ottawa  Ontario  K2K-2M5\r
+                               CA\r
+\r
+54-3E-64   (hex)               Fiberhome Telecommunication Technologies Co.,LTD\r
+543E64     (base 16)           Fiberhome Telecommunication Technologies Co.,LTD\r
+                               No.5 DongXin Road\r
+                               Wuhan  Hubei  430074\r
+                               CN\r
+\r
+D4-F7-86   (hex)               Fiberhome Telecommunication Technologies Co.,LTD\r
+D4F786     (base 16)           Fiberhome Telecommunication Technologies Co.,LTD\r
+                               No.5 DongXin Road\r
+                               Wuhan  Hubei  430074\r
+                               CN\r
+\r
+64-02-CB   (hex)               ARRIS Group, Inc.\r
+6402CB     (base 16)           ARRIS Group, Inc.\r
+                               6450 Sequence Drive\r
+                               San Diego  CA  92121\r
+                               US\r
+\r
+F0-FC-C8   (hex)               ARRIS Group, Inc.\r
+F0FCC8     (base 16)           ARRIS Group, Inc.\r
+                               6450 Sequence Drive\r
+                               San Diego  CA  92121\r
+                               US\r
+\r
+EC-7F-C6   (hex)               ECCEL CORPORATION SAS\r
+EC7FC6     (base 16)           ECCEL CORPORATION SAS\r
+                               CRA 106 15A 25 LT 88 MZ 17 BG 1, ZONA FRANCA BOGOTA\r
+                               BOGOTA  D.C.  110921\r
+                               CO\r
+\r
+A4-33-D7   (hex)               MitraStar Technology Corp.\r
+A433D7     (base 16)           MitraStar Technology Corp.\r
+                               No. 6, Innovation Road II,\r
+                               Hsinchu    300\r
+                               TW\r
+\r
+B0-AC-D2   (hex)               zte corporation\r
+B0ACD2     (base 16)           zte corporation\r
+                               12/F.,zte R&D building ,kejinan Road,Shenzhen,P.R.China\r
+                               shenzhen  guangdong  518057\r
+                               CN\r
+\r
+7C-2A-31   (hex)               Intel Corporate\r
+7C2A31     (base 16)           Intel Corporate\r
+                               Lot 8, Jalan Hi-Tech 2/3\r
+                               Kulim  Kedah  09000\r
+                               MY\r
+\r
+0C-F3-46   (hex)               Xiaomi Communications Co Ltd\r
+0CF346     (base 16)           Xiaomi Communications Co Ltd\r
+                               The Rainbow City of China Resources\r
+                               NO.68, Qinghe Middle Street  Haidian District, Beijing  100085\r
+                               CN\r
+\r
+20-2D-23   (hex)               Collinear Networks Inc.\r
+202D23     (base 16)           Collinear Networks Inc.\r
+                               2901 Tasman Drive\r
+                               Santa Clara  CA  95054\r
+                               US\r
+\r
+48-18-FA   (hex)               Nocsys\r
+4818FA     (base 16)           Nocsys\r
+                               1F, No. 63 Building, No. 421 Hong Cao Road, Xuhui District\r
+                               Shanghai  Shanghai  200233\r
+                               CN\r
+\r
+78-0F-77   (hex)               HangZhou Gubei Electronics Technology Co.,Ltd\r
+780F77     (base 16)           HangZhou Gubei Electronics Technology Co.,Ltd\r
+                               HangZhou City, Zhejiang province Binjiang District Jiang Hong Road 611 Building 1 room 106\r
+                               Hangzhou  ZheJiang  310052\r
+                               CN\r
+\r
+0C-08-B4   (hex)               HUMAX Co., Ltd.\r
+0C08B4     (base 16)           HUMAX Co., Ltd.\r
+                               HUMAX Village, 216, Hwangsaeul-ro, Bu\r
+                               Seongnam-si  Gyeonggi-do  463-875\r
+                               KR\r
+\r
+00-BF-77   (hex)               Cisco Systems, Inc\r
+00BF77     (base 16)           Cisco Systems, Inc\r
+                               80 West Tasman Drive\r
+                               San Jose  CA  94568\r
+                               US\r
+\r
+00-3D-E8   (hex)               LG Electronics (Mobile Communications)\r
+003DE8     (base 16)           LG Electronics (Mobile Communications)\r
+                               60-39, Gasan-dong, Geumcheon-gu\r
+                               Seoul    153-801\r
+                               KR\r
+\r
+00-2F-D9   (hex)               Fiberhome Telecommunication Technologies Co.,LTD\r
+002FD9     (base 16)           Fiberhome Telecommunication Technologies Co.,LTD\r
+                               No.5 DongXin Road\r
+                               Wuhan  Hubei  430074\r
+                               CN\r
+\r
+88-5F-E8   (hex)               IEEE Registration Authority\r
+885FE8     (base 16)           IEEE Registration Authority\r
+                               445 Hoes Lane\r
+                               Piscataway  NJ  08554\r
+                               US\r
+\r
+A0-67-BE   (hex)               Sicon srl\r
+A067BE     (base 16)           Sicon srl\r
+                               Via Sila 1/3\r
+                               Isola Vicentina  Vicenza  36033\r
+                               IT\r
+\r
 54-C5-7A   (hex)               Sunnovo International Limited\r
 54C57A     (base 16)           Sunnovo International Limited\r
                                1717 Haitai Building\r
@@ -114533,6 +115079,888 @@ B42D56     (base 16)                Extreme Networks, Inc.
                                Seongnam-si  Gyeonggi-do  463-875\r
                                KR\r
 \r
+48-74-6E   (hex)               Apple, Inc.\r
+48746E     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+54-72-4F   (hex)               Apple, Inc.\r
+54724F     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+04-F1-3E   (hex)               Apple, Inc.\r
+04F13E     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+60-03-08   (hex)               Apple, Inc.\r
+600308     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+80-EA-96   (hex)               Apple, Inc.\r
+80EA96     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+24-A2-E1   (hex)               Apple, Inc.\r
+24A2E1     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+90-B9-31   (hex)               Apple, Inc.\r
+90B931     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+28-0B-5C   (hex)               Apple, Inc.\r
+280B5C     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+A8-96-8A   (hex)               Apple, Inc.\r
+A8968A     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+9C-04-EB   (hex)               Apple, Inc.\r
+9C04EB     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+88-53-95   (hex)               Apple, Inc.\r
+885395     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+80-92-9F   (hex)               Apple, Inc.\r
+80929F     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+98-B8-E3   (hex)               Apple, Inc.\r
+98B8E3     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+D8-00-4D   (hex)               Apple, Inc.\r
+D8004D     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+98-FE-94   (hex)               Apple, Inc.\r
+98FE94     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+68-64-4B   (hex)               Apple, Inc.\r
+68644B     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+F0-99-BF   (hex)               Apple, Inc.\r
+F099BF     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+FC-E9-98   (hex)               Apple, Inc.\r
+FCE998     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+48-E9-F1   (hex)               Apple, Inc.\r
+48E9F1     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+4C-7C-5F   (hex)               Apple, Inc.\r
+4C7C5F     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+60-F8-1D   (hex)               Apple, Inc.\r
+60F81D     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+68-9C-70   (hex)               Apple, Inc.\r
+689C70     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+2C-B4-3A   (hex)               Apple, Inc.\r
+2CB43A     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+04-26-65   (hex)               Apple, Inc.\r
+042665     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+F4-F1-5A   (hex)               Apple, Inc.\r
+F4F15A     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+20-7D-74   (hex)               Apple, Inc.\r
+207D74     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+4C-8D-79   (hex)               Apple, Inc.\r
+4C8D79     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+FC-FC-48   (hex)               Apple, Inc.\r
+FCFC48     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+38-C9-86   (hex)               Apple, Inc.\r
+38C986     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+70-EC-E4   (hex)               Apple, Inc.\r
+70ECE4     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+D8-1D-72   (hex)               Apple, Inc.\r
+D81D72     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+94-F6-A3   (hex)               Apple, Inc.\r
+94F6A3     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+78-FD-94   (hex)               Apple, Inc.\r
+78FD94     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+48-D7-05   (hex)               Apple, Inc.\r
+48D705     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+7C-6D-F8   (hex)               Apple, Inc.\r
+7C6DF8     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+3C-AB-8E   (hex)               Apple, Inc.\r
+3CAB8E     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+78-7E-61   (hex)               Apple, Inc.\r
+787E61     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+D4-F4-6F   (hex)               Apple, Inc.\r
+D4F46F     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+C8-85-50   (hex)               Apple, Inc.\r
+C88550     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+AC-7F-3E   (hex)               Apple, Inc.\r
+AC7F3E     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+A4-C3-61   (hex)               Apple, Inc.\r
+A4C361     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+08-70-45   (hex)               Apple, Inc.\r
+087045     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+40-33-1A   (hex)               Apple, Inc.\r
+40331A     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+DC-37-14   (hex)               Apple, Inc.\r
+DC3714     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+78-9F-70   (hex)               Apple, Inc.\r
+789F70     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+64-B0-A6   (hex)               Apple, Inc.\r
+64B0A6     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+84-FC-AC   (hex)               Apple, Inc.\r
+84FCAC     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+6C-19-C0   (hex)               Apple, Inc.\r
+6C19C0     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+20-AB-37   (hex)               Apple, Inc.\r
+20AB37     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+C0-D0-12   (hex)               Apple, Inc.\r
+C0D012     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+D4-DC-CD   (hex)               Apple, Inc.\r
+D4DCCD     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+48-4B-AA   (hex)               Apple, Inc.\r
+484BAA     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+F8-03-77   (hex)               Apple, Inc.\r
+F80377     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+14-BD-61   (hex)               Apple, Inc.\r
+14BD61     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+78-88-6D   (hex)               Apple, Inc.\r
+78886D     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+A8-5C-2C   (hex)               Apple, Inc.\r
+A85C2C     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+00-DB-70   (hex)               Apple, Inc.\r
+00DB70     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+BC-EC-5D   (hex)               Apple, Inc.\r
+BCEC5D     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+DC-41-5F   (hex)               Apple, Inc.\r
+DC415F     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+30-63-6B   (hex)               Apple, Inc.\r
+30636B     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+0C-51-01   (hex)               Apple, Inc.\r
+0C5101     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+08-6D-41   (hex)               Apple, Inc.\r
+086D41     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+04-D3-CF   (hex)               Apple, Inc.\r
+04D3CF     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+20-3C-AE   (hex)               Apple, Inc.\r
+203CAE     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+74-8D-08   (hex)               Apple, Inc.\r
+748D08     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+A0-3B-E3   (hex)               Apple, Inc.\r
+A03BE3     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+18-65-90   (hex)               Apple, Inc.\r
+186590     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+00-10-FA   (hex)               Apple, Inc.\r
+0010FA     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+00-05-02   (hex)               Apple, Inc.\r
+000502     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+B8-78-2E   (hex)               Apple, Inc.\r
+B8782E     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+A4-D1-8C   (hex)               Apple, Inc.\r
+A4D18C     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+CC-25-EF   (hex)               Apple, Inc.\r
+CC25EF     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+68-DB-CA   (hex)               Apple, Inc.\r
+68DBCA     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+04-4B-ED   (hex)               Apple, Inc.\r
+044BED     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+6C-8D-C1   (hex)               Apple, Inc.\r
+6C8DC1     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+38-CA-DA   (hex)               Apple, Inc.\r
+38CADA     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+F4-5C-89   (hex)               Apple, Inc.\r
+F45C89     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+58-1F-AA   (hex)               Apple, Inc.\r
+581FAA     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+24-AB-81   (hex)               Apple, Inc.\r
+24AB81     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+70-CD-60   (hex)               Apple, Inc.\r
+70CD60     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+7C-C5-37   (hex)               Apple, Inc.\r
+7CC537     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+C4-2C-03   (hex)               Apple, Inc.\r
+C42C03     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+D8-30-62   (hex)               Apple, Inc.\r
+D83062     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+40-D3-2D   (hex)               Apple, Inc.\r
+40D32D     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+7C-6D-62   (hex)               Apple, Inc.\r
+7C6D62     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+28-6A-B8   (hex)               Apple, Inc.\r
+286AB8     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+40-3C-FC   (hex)               Apple, Inc.\r
+403CFC     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+B8-C7-5D   (hex)               Apple, Inc.\r
+B8C75D     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+E8-04-0B   (hex)               Apple, Inc.\r
+E8040B     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+E4-CE-8F   (hex)               Apple, Inc.\r
+E4CE8F     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+3C-07-54   (hex)               Apple, Inc.\r
+3C0754     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+A4-67-06   (hex)               Apple, Inc.\r
+A46706     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+80-B0-3D   (hex)               Apple, Inc.\r
+80B03D     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+C8-3C-85   (hex)               Apple, Inc.\r
+C83C85     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+A0-4E-A7   (hex)               Apple, Inc.\r
+A04EA7     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+40-9C-28   (hex)               Apple, Inc.\r
+409C28     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+08-E6-89   (hex)               Apple, Inc.\r
+08E689     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+4C-B1-99   (hex)               Apple, Inc.\r
+4CB199     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+98-D6-BB   (hex)               Apple, Inc.\r
+98D6BB     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+3C-D0-F8   (hex)               Apple, Inc.\r
+3CD0F8     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+7C-C3-A1   (hex)               Apple, Inc.\r
+7CC3A1     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+00-26-08   (hex)               Apple, Inc.\r
+002608     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+00-1E-C2   (hex)               Apple, Inc.\r
+001EC2     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+00-1B-63   (hex)               Apple, Inc.\r
+001B63     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+00-17-F2   (hex)               Apple, Inc.\r
+0017F2     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+00-16-CB   (hex)               Apple, Inc.\r
+0016CB     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+00-03-93   (hex)               Apple, Inc.\r
+000393     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+80-49-71   (hex)               Apple, Inc.\r
+804971     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+64-E6-82   (hex)               Apple, Inc.\r
+64E682     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+B4-F7-A1   (hex)               LG Electronics (Mobile Communications)\r
+B4F7A1     (base 16)           LG Electronics (Mobile Communications)\r
+                               60-39, Gasan-dong, Geumcheon-gu\r
+                               Seoul    153-801\r
+                               KR\r
+\r
+C0-A8-F0   (hex)               Adamson Systems Engineering\r
+C0A8F0     (base 16)           Adamson Systems Engineering\r
+                               1401 Scugog Line 6\r
+                               Port Perry  Ontario  L9L 1B2\r
+                               CA\r
+\r
+38-C9-A9   (hex)               SMART High Reliability Solutions, Inc.\r
+38C9A9     (base 16)           SMART High Reliability Solutions, Inc.\r
+                               1325 N Fiesta Blvd., #101\r
+                               Gilbert  AZ  85233\r
+                               US\r
+\r
+28-3B-82   (hex)               D-Link International\r
+283B82     (base 16)           D-Link International\r
+                               1 Internal Business Park, #03-12,The Synergy, Singapore\r
+                               Singapore  Singapore  609917\r
+                               SG\r
+\r
+C4-00-AD   (hex)               Advantech Technology (CHINA) Co., Ltd.\r
+C400AD     (base 16)           Advantech Technology (CHINA) Co., Ltd.\r
+                               No.666, Han-Pu Rd. Yu-Shan\r
+                               Kun-Shan  Jiang Su  215316\r
+                               CN\r
+\r
+34-5A-06   (hex)               SHARP Corporation\r
+345A06     (base 16)           SHARP Corporation\r
+                               1 Takumi-cho, Sakai-ku\r
+                               Sakai City  Osaka  590-8522\r
+                               JP\r
+\r
+0C-8B-D3   (hex)               ITEL MOBILE LIMITED\r
+0C8BD3     (base 16)           ITEL MOBILE LIMITED\r
+                               RM B3 & B4 BLOCK B, KO FAI INDUSTRIAL BUILDING  NO.7 KO FAI ROAD, YAU TONG, KLN, H.K\r
+                               Hong Kong  KOWLOON  999077\r
+                               HK\r
+\r
+04-AC-44   (hex)               Holtek Semiconductor Inc.\r
+04AC44     (base 16)           Holtek Semiconductor Inc.\r
+                               No.3, Creation Rd. II, Science Park\r
+                               Hsinchu    300\r
+                               TW\r
+\r
+F4-DC-A5   (hex)               DAWON DNS\r
+F4DCA5     (base 16)           DAWON DNS\r
+                               217ho, Sauphwajiwon-dong, KETI, 226, Cheomdangwagi-ro, Buk-gu\r
+                               Gwangju    61011\r
+                               KR\r
+\r
+50-1C-B0   (hex)               Cisco Systems, Inc\r
+501CB0     (base 16)           Cisco Systems, Inc\r
+                               80 West Tasman Drive\r
+                               San Jose  CA  94568\r
+                               US\r
+\r
+C4-FF-BC   (hex)               IEEE Registration Authority\r
+C4FFBC     (base 16)           IEEE Registration Authority\r
+                               445 Hoes Lane\r
+                               Piscataway  NJ  08554\r
+                               US\r
+\r
+78-58-60   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
+785860     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
+                               No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park\r
+                               Dongguan    523808\r
+                               CN\r
+\r
+F8-90-66   (hex)               Nain Inc.\r
+F89066     (base 16)           Nain Inc.\r
+                               Aoyamadai building 902, Shibuya 2-9-10, Shibuya-ku\r
+                               Tokyo    150-0002\r
+                               JP\r
+\r
+B4-FB-F9   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
+B4FBF9     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
+                               No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park\r
+                               Dongguan    523808\r
+                               CN\r
+\r
+B4-2E-F8   (hex)               Eline Technology co.Ltd\r
+B42EF8     (base 16)           Eline Technology co.Ltd\r
+                               kangcheng Road, Pharmaceutical Industrical Park, Yuanzhou District\r
+                               Yichun  Jiangxi  336000\r
+                               CN\r
+\r
+D8-44-5C   (hex)               DEV Tecnologia Ind Com Man Eq LTDA\r
+D8445C     (base 16)           DEV Tecnologia Ind Com Man Eq LTDA\r
+                               Av Prof Lineu Prestes 2242 SL 23\r
+                               Sao Paulo  SP  05508000\r
+                               BR\r
+\r
+78-5D-C8   (hex)               LG Electronics\r
+785DC8     (base 16)           LG Electronics\r
+                               222 LG-ro, JINWI-MYEON\r
+                               Pyeongtaek-si  Gyeonggi-do  451-713\r
+                               KR\r
+\r
+7C-39-53   (hex)               zte corporation\r
+7C3953     (base 16)           zte corporation\r
+                               12/F.,zte R&D building ,kejinan Road,Shenzhen,P.R.China\r
+                               shenzhen  guangdong  518057\r
+                               CN\r
+\r
+48-C7-96   (hex)               Samsung Electronics Co.,Ltd\r
+48C796     (base 16)           Samsung Electronics Co.,Ltd\r
+                               #94-1, Imsoo-Dong\r
+                               Gumi  Gyeongbuk  730-350\r
+                               KR\r
+\r
+80-4E-70   (hex)               Samsung Electronics Co.,Ltd\r
+804E70     (base 16)           Samsung Electronics Co.,Ltd\r
+                               #94-1, Imsoo-Dong\r
+                               Gumi  Gyeongbuk  730-350\r
+                               KR\r
+\r
+4C-EF-C0   (hex)               Amazon Technologies Inc.\r
+4CEFC0     (base 16)           Amazon Technologies Inc.\r
+                               P.O Box 8102\r
+                               Reno  NV  89507\r
+                               US\r
+\r
+D4-6D-6D   (hex)               Intel Corporate\r
+D46D6D     (base 16)           Intel Corporate\r
+                               Lot 8, Jalan Hi-Tech 2/3\r
+                               Kulim  Kedah  09000\r
+                               MY\r
+\r
+CC-8E-71   (hex)               Cisco Systems, Inc\r
+CC8E71     (base 16)           Cisco Systems, Inc\r
+                               80 West Tasman Drive\r
+                               San Jose  CA  94568\r
+                               US\r
+\r
+CC-3B-58   (hex)               Curiouser Products Inc\r
+CC3B58     (base 16)           Curiouser Products Inc\r
+                               712 Broadway #4\r
+                               New York  NY  10003\r
+                               US\r
+\r
+38-F5-54   (hex)               HISENSE ELECTRIC CO.,LTD\r
+38F554     (base 16)           HISENSE ELECTRIC CO.,LTD\r
+                               No. 218, Qianwangang Rd\r
+                               Qingdao  Shandong  266555\r
+                               CN\r
+\r
+18-94-C6   (hex)               ShenZhen Chenyee Technology Co., Ltd.\r
+1894C6     (base 16)           ShenZhen Chenyee Technology Co., Ltd.\r
+                               32F, Tower A, East Pacific International Center, No.7888, Shennan Avenue, Futian District\r
+                               Shenzhen    518040\r
+                               CN\r
+\r
+14-A7-2B   (hex)               currentoptronics Pvt.Ltd\r
+14A72B     (base 16)           currentoptronics Pvt.Ltd\r
+                               CRT Building, Jupitor Jn , Near Time kids Koothattukulam - Piravom Rd\r
+                               ERNAKULAM  Time Kids day care  686662\r
+                               IN\r
+\r
+AC-07-5F   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
+AC075F     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
+                               No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park\r
+                               Dongguan    523808\r
+                               CN\r
+\r
+88-17-A3   (hex)               Integrated Device Technology (Malaysia) Sdn. Bhd.\r
+8817A3     (base 16)           Integrated Device Technology (Malaysia) Sdn. Bhd.\r
+                               Phase 3, Bayan Lepas FIZ\r
+                               Bayan Lepas  Penang  11900\r
+                               MY\r
+\r
+00-71-47   (hex)               Amazon Technologies Inc.\r
+007147     (base 16)           Amazon Technologies Inc.\r
+                               P.O Box 8102\r
+                               Reno  NV  89507\r
+                               US\r
+\r
+78-8C-54   (hex)               Ping Communication\r
+788C54     (base 16)           Ping Communication\r
+                               Brenden 18\r
+                               Appenzell Meistersrüte  AI  9050\r
+                               CH\r
+\r
+D4-66-A8   (hex)               Riedo Networks Ltd\r
+D466A8     (base 16)           Riedo Networks Ltd\r
+                               Route de la Fonderie 6\r
+                               Fribourg    1700\r
+                               CH\r
+\r
+30-B7-D4   (hex)               Hitron Technologies. Inc\r
+30B7D4     (base 16)           Hitron Technologies. Inc\r
+                               No. 1-8, Lising 1st Rd. Hsinchu Science Park, Hsinchu, 300, Taiwan, R.O.C\r
+                               Hsin-chu  Taiwan  300\r
+                               TW\r
+\r
+38-80-DF   (hex)               Motorola Mobility LLC, a Lenovo Company\r
+3880DF     (base 16)           Motorola Mobility LLC, a Lenovo Company\r
+                               222 West Merchandise Mart Plaza\r
+                               Chicago  IL  60654\r
+                               US\r
+\r
+7C-B2-32   (hex)               Hui Zhou Gaoshengda Technology Co.,LTD\r
+7CB232     (base 16)           Hui Zhou Gaoshengda Technology Co.,LTD\r
+                               No.75,Zhongkai High-Tech Development District,Huizhou\r
+                               Hui Zhou  Guangdong  516006\r
+                               CN\r
+\r
+2C-D9-74   (hex)               Hui Zhou Gaoshengda Technology Co.,LTD\r
+2CD974     (base 16)           Hui Zhou Gaoshengda Technology Co.,LTD\r
+                               No.75,Zhongkai High-Tech Development District,Huizhou\r
+                               Hui Zhou  Guangdong  516006\r
+                               CN\r
+\r
+58-B3-FC   (hex)               SHENZHEN RF-LINK TECHNOLOGY CO.,LTD.\r
+58B3FC     (base 16)           SHENZHEN RF-LINK TECHNOLOGY CO.,LTD.\r
+                               Bldg56A,6/F,Baotian Rd3,Xixiang Town,Baoan District,\r
+                               Shenzhen  Guangdong  518000\r
+                               CN\r
+\r
+BC-AB-7C   (hex)               TRnP KOREA Co Ltd\r
+BCAB7C     (base 16)           TRnP KOREA Co Ltd\r
+                               room1308,239 SoHyungRo,WonMiGu,\r
+                               BuChunCity  KyungKiDo  1135\r
+                               KR\r
+\r
 2C-39-96   (hex)               Sagemcom Broadband SAS\r
 2C3996     (base 16)           Sagemcom Broadband SAS\r
                                250 route de l'Empereur\r
@@ -114575,42 +116003,6 @@ A0F895     (base 16)         Shenzhen TINNO Mobile Technology Corp.
                                San Jose    95110\r
                                US\r
 \r
-28-ED-6A   (hex)               Apple, Inc.\r
-28ED6A     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-34-AB-37   (hex)               Apple, Inc.\r
-34AB37     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-60-A3-7D   (hex)               Apple, Inc.\r
-60A37D     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-00-56-CD   (hex)               Apple, Inc.\r
-0056CD     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-70-81-EB   (hex)               Apple, Inc.\r
-7081EB     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-08-66-98   (hex)               Apple, Inc.\r
-086698     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 2C-FD-37   (hex)               Blue Calypso, Inc.\r
 2CFD37     (base 16)           Blue Calypso, Inc.\r
                                101 West Renner RD Suite 280\r
@@ -115055,12 +116447,6 @@ A4516F     (base 16)         Microsoft Mobile Oy
                                Shanghai  Shanghai  201616\r
                                CN\r
 \r
-90-60-F1   (hex)               Apple, Inc.\r
-9060F1     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 EC-26-CA   (hex)               TP-LINK TECHNOLOGIES CO.,LTD.\r
 EC26CA     (base 16)           TP-LINK TECHNOLOGIES CO.,LTD.\r
                                Building 24 (floors 1,3,4,5) and 28 (floors1-4) \r
@@ -115283,12 +116669,6 @@ A49947     (base 16)         HUAWEI TECHNOLOGIES CO.,LTD
                                Shenzhen  Guangdong  518108\r
                                CN\r
 \r
-74-1B-B2   (hex)               Apple, Inc.\r
-741BB2     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 00-25-86   (hex)               TP-LINK TECHNOLOGIES CO.,LTD.\r
 002586     (base 16)           TP-LINK TECHNOLOGIES CO.,LTD.\r
                                Building 7, Second Part, Honghualing Industrial Zone\r
@@ -115355,12 +116735,6 @@ AC7E8A     (base 16)         Cisco Systems, Inc
                                San Jose  CA  95134\r
                                US\r
 \r
-28-CF-E9   (hex)               Apple, Inc.\r
-28CFE9     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 00-50-2A   (hex)               Cisco Systems, Inc\r
 00502A     (base 16)           Cisco Systems, Inc\r
                                170 W. TASMAN DR.\r
@@ -115751,480 +117125,12 @@ E8EDF3     (base 16)               Cisco Systems, Inc
                                San Jose  CA  95134\r
                                US\r
 \r
-E4-25-E7   (hex)               Apple, Inc.\r
-E425E7     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-08-00-07   (hex)               Apple, Inc.\r
-080007     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-00-0A-95   (hex)               Apple, Inc.\r
-000A95     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-00-22-41   (hex)               Apple, Inc.\r
-002241     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-00-23-DF   (hex)               Apple, Inc.\r
-0023DF     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-00-25-BC   (hex)               Apple, Inc.\r
-0025BC     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-00-26-4A   (hex)               Apple, Inc.\r
-00264A     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-00-26-B0   (hex)               Apple, Inc.\r
-0026B0     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-04-1E-64   (hex)               Apple, Inc.\r
-041E64     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-D4-9A-20   (hex)               Apple, Inc.\r
-D49A20     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-90-27-E4   (hex)               Apple, Inc.\r
-9027E4     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-60-33-4B   (hex)               Apple, Inc.\r
-60334B     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-A4-31-35   (hex)               Apple, Inc.\r
-A43135     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-9C-35-EB   (hex)               Apple, Inc.\r
-9C35EB     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-50-7A-55   (hex)               Apple, Inc.\r
-507A55     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-A0-99-9B   (hex)               Apple, Inc.\r
-A0999B     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-24-24-0E   (hex)               Apple, Inc.\r
-24240E     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-90-3C-92   (hex)               Apple, Inc.\r
-903C92     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-34-12-98   (hex)               Apple, Inc.\r
-341298     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-9C-29-3F   (hex)               Apple, Inc.\r
-9C293F     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 48-8A-D2   (hex)               SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD.\r
 488AD2     (base 16)           SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD.\r
                                Mid-Fourth Flr.,Building 28,Cui Xi Fourth Road,Ke Yuan West,Nanshan\r
                                Shenzhen  Guangdong  518057\r
                                CN\r
 \r
-A8-8E-24   (hex)               Apple, Inc.\r
-A88E24     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-E8-80-2E   (hex)               Apple, Inc.\r
-E8802E     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-68-AE-20   (hex)               Apple, Inc.\r
-68AE20     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-E0-B5-2D   (hex)               Apple, Inc.\r
-E0B52D     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-80-BE-05   (hex)               Apple, Inc.\r
-80BE05     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-D8-BB-2C   (hex)               Apple, Inc.\r
-D8BB2C     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-D0-4F-7E   (hex)               Apple, Inc.\r
-D04F7E     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-2C-1F-23   (hex)               Apple, Inc.\r
-2C1F23     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-54-9F-13   (hex)               Apple, Inc.\r
-549F13     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-B8-09-8A   (hex)               Apple, Inc.\r
-B8098A     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-F0-DB-E2   (hex)               Apple, Inc.\r
-F0DBE2     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-18-EE-69   (hex)               Apple, Inc.\r
-18EE69     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-74-81-14   (hex)               Apple, Inc.\r
-748114     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-18-F6-43   (hex)               Apple, Inc.\r
-18F643     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-D0-A6-37   (hex)               Apple, Inc.\r
-D0A637     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-A0-18-28   (hex)               Apple, Inc.\r
-A01828     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-D0-03-4B   (hex)               Apple, Inc.\r
-D0034B     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-5C-59-48   (hex)               Apple, Inc.\r
-5C5948     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-78-CA-39   (hex)               Apple, Inc.\r
-78CA39     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-18-E7-F4   (hex)               Apple, Inc.\r
-18E7F4     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-B8-FF-61   (hex)               Apple, Inc.\r
-B8FF61     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-DC-2B-61   (hex)               Apple, Inc.\r
-DC2B61     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-10-93-E9   (hex)               Apple, Inc.\r
-1093E9     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-44-2A-60   (hex)               Apple, Inc.\r
-442A60     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-E0-F8-47   (hex)               Apple, Inc.\r
-E0F847     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-14-5A-05   (hex)               Apple, Inc.\r
-145A05     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-28-CF-DA   (hex)               Apple, Inc.\r
-28CFDA     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-14-8F-C6   (hex)               Apple, Inc.\r
-148FC6     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-28-37-37   (hex)               Apple, Inc.\r
-283737     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-04-54-53   (hex)               Apple, Inc.\r
-045453     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-F0-CB-A1   (hex)               Apple, Inc.\r
-F0CBA1     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-C0-63-94   (hex)               Apple, Inc.\r
-C06394     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-8C-00-6D   (hex)               Apple, Inc.\r
-8C006D     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-B0-9F-BA   (hex)               Apple, Inc.\r
-B09FBA     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-DC-86-D8   (hex)               Apple, Inc.\r
-DC86D8     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-8C-29-37   (hex)               Apple, Inc.\r
-8C2937     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-DC-9B-9C   (hex)               Apple, Inc.\r
-DC9B9C     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-98-F0-AB   (hex)               Apple, Inc.\r
-98F0AB     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-F0-DB-F8   (hex)               Apple, Inc.\r
-F0DBF8     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-AC-CF-5C   (hex)               Apple, Inc.\r
-ACCF5C     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-3C-15-C2   (hex)               Apple, Inc.\r
-3C15C2     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-04-48-9A   (hex)               Apple, Inc.\r
-04489A     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-D8-CF-9C   (hex)               Apple, Inc.\r
-D8CF9C     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-30-F7-C5   (hex)               Apple, Inc.\r
-30F7C5     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-00-88-65   (hex)               Apple, Inc.\r
-008865     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-40-B3-95   (hex)               Apple, Inc.\r
-40B395     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-30-90-AB   (hex)               Apple, Inc.\r
-3090AB     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-1C-E6-2B   (hex)               Apple, Inc.\r
-1CE62B     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-A0-ED-CD   (hex)               Apple, Inc.\r
-A0EDCD     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-A8-86-DD   (hex)               Apple, Inc.\r
-A886DD     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-54-EA-A8   (hex)               Apple, Inc.\r
-54EAA8     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-E4-C6-3D   (hex)               Apple, Inc.\r
-E4C63D     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-84-38-35   (hex)               Apple, Inc.\r
-843835     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-70-73-CB   (hex)               Apple, Inc.\r
-7073CB     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-9C-20-7B   (hex)               Apple, Inc.\r
-9C207B     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-84-29-99   (hex)               Apple, Inc.\r
-842999     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-74-E2-F5   (hex)               Apple, Inc.\r
-74E2F5     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
-20-C9-D0   (hex)               Apple, Inc.\r
-20C9D0     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               CUPERTINO  CA  95014\r
-                               US\r
-\r
 14-02-EC   (hex)               Hewlett Packard Enterprise\r
 1402EC     (base 16)           Hewlett Packard Enterprise\r
                                8000 Foothills Blvd.\r
@@ -116351,36 +117257,6 @@ B813E9     (base 16)         Trace Live Network
                                Wuxi  Jiangsu  214131\r
                                CN\r
 \r
-7C-01-91   (hex)               Apple, Inc.\r
-7C0191     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-70-48-0F   (hex)               Apple, Inc.\r
-70480F     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-A4-B8-05   (hex)               Apple, Inc.\r
-A4B805     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-58-7F-57   (hex)               Apple, Inc.\r
-587F57     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-80-D6-05   (hex)               Apple, Inc.\r
-80D605     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 68-A8-28   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
 68A828     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
                                No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park\r
@@ -116393,18 +117269,6 @@ A4B805     (base 16)         Apple, Inc.
                                WUXI  Jiangsu  214128\r
                                CN\r
 \r
-C8-69-CD   (hex)               Apple, Inc.\r
-C869CD     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-BC-6C-21   (hex)               Apple, Inc.\r
-BC6C21     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 9C-8D-D3   (hex)               Leonton Technologies\r
 9C8DD3     (base 16)           Leonton Technologies\r
                                3F, No.501-16, Zhongzheng Rd., Xindian Dist.\r
@@ -116489,12 +117353,6 @@ A4DEC9     (base 16)         QLove Mobile Intelligence Information Technology (W.H.) Co
 A4-A6-A9   (hex)               Private\r
 A4A6A9     (base 16)           Private\r
 \r
-04-69-F8   (hex)               Apple, Inc.\r
-0469F8     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 9C-7A-03   (hex)               Ciena Corporation\r
 9C7A03     (base 16)           Ciena Corporation\r
                                7035 Ridge Road\r
@@ -116621,12 +117479,6 @@ D47BB0     (base 16)         ASKEY COMPUTER CORP
                                London  Greater London  W1F 7NT\r
                                GB\r
 \r
-94-9F-3E   (hex)               Sonos, Inc.\r
-949F3E     (base 16)           Sonos, Inc.\r
-                               223 E. De La Guerra Street\r
-                               Santa Barbara  CA  93101\r
-                               US\r
-\r
 78-8E-33   (hex)               Jiangsu SEUIC Technology Co.,Ltd\r
 788E33     (base 16)           Jiangsu SEUIC Technology Co.,Ltd\r
                                NO23.Wenzhu Road.Yuhuatai Distrct.\r
@@ -138113,12 +138965,6 @@ C4E510     (base 16)         Mechatro, Inc.
                                Sunnyvale  CA  94085\r
                                US\r
 \r
-20-76-8F   (hex)               Apple, Inc.\r
-20768F     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 9C-5C-F9   (hex)               Sony Mobile Communications AB\r
 9C5CF9     (base 16)           Sony Mobile Communications AB\r
                                Nya Vattentornet\r
@@ -138167,36 +139013,12 @@ BC44B0     (base 16)                Elastifile
                                shanghai  shanghai  20233\r
                                CN\r
 \r
-C0-CC-F8   (hex)               Apple, Inc.\r
-C0CCF8     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-80-ED-2C   (hex)               Apple, Inc.\r
-80ED2C     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-E8-B2-AC   (hex)               Apple, Inc.\r
-E8B2AC     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 00-80-B8   (hex)               DMG MORI B.U.G. CO., LTD.\r
 0080B8     (base 16)           DMG MORI B.U.G. CO., LTD.\r
                                1-1-14 Techno park,\r
                                Shimonopporo, Atsubetsuku, Sapporo  Hokkaido  004-0015\r
                                JP\r
 \r
-84-89-AD   (hex)               Apple, Inc.\r
-8489AD     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 40-B6-88   (hex)               LEGIC Identsystems AG\r
 40B688     (base 16)           LEGIC Identsystems AG\r
                                Binzackerstrasse 41\r
@@ -138755,18 +139577,6 @@ D09DAB     (base 16)         TCT mobile ltd
                                Hui Zhou  Guang Dong  516006\r
                                CN\r
 \r
-8C-8E-F2   (hex)               Apple, Inc.\r
-8C8EF2     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-F4-0F-24   (hex)               Apple, Inc.\r
-F40F24     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 A0-D3-85   (hex)               AUMA Riester GmbH & Co. KG\r
 A0D385     (base 16)           AUMA Riester GmbH & Co. KG\r
                                Aumastr. 1\r
@@ -138779,18 +139589,6 @@ A0D385     (base 16)         AUMA Riester GmbH & Co. KG
                                ningbo  zhejiang  315048\r
                                CN\r
 \r
-84-A1-34   (hex)               Apple, Inc.\r
-84A134     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-1C-91-48   (hex)               Apple, Inc.\r
-1C9148     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 CC-16-7E   (hex)               Cisco Systems, Inc\r
 CC167E     (base 16)           Cisco Systems, Inc\r
                                80 West Tasman Drive\r
@@ -139871,18 +140669,6 @@ B4D135     (base 16)         Cloudistics
                                Mianyang City  Sichuan Province  621000\r
                                CN\r
 \r
-78-28-CA   (hex)               Sonos, Inc.\r
-7828CA     (base 16)           Sonos, Inc.\r
-                               614 Chapala Street\r
-                               Santa Barbara  CA  93101\r
-                               US\r
-\r
-B8-E9-37   (hex)               Sonos, Inc.\r
-B8E937     (base 16)           Sonos, Inc.\r
-                               223 East De La Guerra Street\r
-                               Santa Barbara  CA  93101\r
-                               US\r
-\r
 B0-52-16   (hex)               Hon Hai Precision Ind. Co.,Ltd.\r
 B05216     (base 16)           Hon Hai Precision Ind. Co.,Ltd.\r
                                Building D21,No.1, East Zone 1st Road\r
@@ -140651,24 +141437,6 @@ C8028F     (base 16)         Nova Electronics (Shanghai) Co., Ltd.
                                Gumi  Gyeongbuk  730-350\r
                                KR\r
 \r
-5C-F7-E6   (hex)               Apple, Inc.\r
-5CF7E6     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-A0-D7-95   (hex)               Apple, Inc.\r
-A0D795     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-CC-08-8D   (hex)               Apple, Inc.\r
-CC088D     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 00-80-FB   (hex)               BVM LIMITED\r
 0080FB     (base 16)           BVM LIMITED\r
                                Lakeside House, Brickyard Road,\r
@@ -140867,36 +141635,6 @@ E8EADA     (base 16)         Denkovi Assembly Electronics LTD
                                Maebashi-shi  Gunma  379-2105\r
                                JP\r
 \r
-B0-70-2D   (hex)               Apple, Inc.\r
-B0702D     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-D0-C5-F3   (hex)               Apple, Inc.\r
-D0C5F3     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-60-F4-45   (hex)               Apple, Inc.\r
-60F445     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-00-B3-62   (hex)               Apple, Inc.\r
-00B362     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-F8-62-14   (hex)               Apple, Inc.\r
-F86214     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 C0-E5-4E   (hex)               ARIES Embedded GmbH\r
 C0E54E     (base 16)           ARIES Embedded GmbH\r
                                Schöngeisinger Str. 84\r
@@ -141071,18 +141809,6 @@ CC82EB     (base 16)         KYOCERA CORPORATION
                                Yokohama-shi  Kanagawa  224-8502\r
                                JP\r
 \r
-50-82-D5   (hex)               Apple, Inc.\r
-5082D5     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-9C-84-BF   (hex)               Apple, Inc.\r
-9C84BF     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 78-94-B4   (hex)               Sercomm Corporation.\r
 7894B4     (base 16)           Sercomm Corporation.\r
                                violet_liu@sercomm.com\r
@@ -141161,24 +141887,6 @@ E0C0D1     (base 16)         CK Telecom (Shenzhen) Limited
                                shenzhen  guangdong  518057\r
                                CN\r
 \r
-48-BF-6B   (hex)               Apple, Inc.\r
-48BF6B     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-24-5B-A7   (hex)               Apple, Inc.\r
-245BA7     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-BC-A9-20   (hex)               Apple, Inc.\r
-BCA920     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 D0-55-B2   (hex)               Integrated Device Technology (Malaysia) Sdn. Bhd.\r
 D055B2     (base 16)           Integrated Device Technology (Malaysia) Sdn. Bhd.\r
                                Phase 3, Bayan Lepas FIZ\r
@@ -142455,34 +143163,16 @@ C06D1A     (base 16)                Tianjin Henxinhuifeng Technology Co.,Ltd.
                                DE\r
 \r
 40-A3-CC   (hex)               Intel Corporate\r
-40A3CC     (base 16)           Intel Corporate\r
-                               Lot 8, Jalan Hi-Tech 2/3\r
-                               Kulim  Kedah  09000\r
-                               MY\r
-\r
-E4-70-B8   (hex)               Intel Corporate\r
-E470B8     (base 16)           Intel Corporate\r
-                               Lot 8, Jalan Hi-Tech 2/3\r
-                               Kulim  Kedah  09000\r
-                               MY\r
-\r
-B0-19-C6   (hex)               Apple, Inc.\r
-B019C6     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-58-E2-8F   (hex)               Apple, Inc.\r
-58E28F     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
+40A3CC     (base 16)           Intel Corporate\r
+                               Lot 8, Jalan Hi-Tech 2/3\r
+                               Kulim  Kedah  09000\r
+                               MY\r
 \r
-AC-1F-74   (hex)               Apple, Inc.\r
-AC1F74     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
+E4-70-B8   (hex)               Intel Corporate\r
+E470B8     (base 16)           Intel Corporate\r
+                               Lot 8, Jalan Hi-Tech 2/3\r
+                               Kulim  Kedah  09000\r
+                               MY\r
 \r
 30-38-55   (hex)               Nokia Corporation\r
 303855     (base 16)           Nokia Corporation\r
@@ -142907,42 +143597,6 @@ F8F21E     (base 16)         Intel Corporate
                                Swindon    SN5 7XP\r
                                GB\r
 \r
-24-F6-77   (hex)               Apple, Inc.\r
-24F677     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-78-67-D7   (hex)               Apple, Inc.\r
-7867D7     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-54-33-CB   (hex)               Apple, Inc.\r
-5433CB     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-D0-D2-B0   (hex)               Apple, Inc.\r
-D0D2B0     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-D8-8F-76   (hex)               Apple, Inc.\r
-D88F76     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
-3C-2E-F9   (hex)               Apple, Inc.\r
-3C2EF9     (base 16)           Apple, Inc.\r
-                               1 Infinite Loop\r
-                               Cupertino  CA  95014\r
-                               US\r
-\r
 8C-83-9D   (hex)               SHENZHEN XINYUPENG ELECTRONIC TECHNOLOGY CO., LTD\r
 8C839D     (base 16)           SHENZHEN XINYUPENG ELECTRONIC TECHNOLOGY CO., LTD\r
                                ROOM 1505,BIT INNOVATION BUILDING,SCIENCE AND TECHNOLOGY PARK,NANSHAN DISTRICT\r
@@ -143473,3 +144127,1119 @@ BCC00F     (base 16)               Fiberhome Telecommunication Technologies Co.,LTD
                                Via Aosta 23\r
                                Venaria Reale   Torino  10078\r
                                IT\r
+\r
+04-69-F8   (hex)               Apple, Inc.\r
+0469F8     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+BC-6C-21   (hex)               Apple, Inc.\r
+BC6C21     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+C8-69-CD   (hex)               Apple, Inc.\r
+C869CD     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+80-D6-05   (hex)               Apple, Inc.\r
+80D605     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+58-7F-57   (hex)               Apple, Inc.\r
+587F57     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+A4-B8-05   (hex)               Apple, Inc.\r
+A4B805     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+70-48-0F   (hex)               Apple, Inc.\r
+70480F     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+7C-01-91   (hex)               Apple, Inc.\r
+7C0191     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+9C-29-3F   (hex)               Apple, Inc.\r
+9C293F     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+34-12-98   (hex)               Apple, Inc.\r
+341298     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+90-3C-92   (hex)               Apple, Inc.\r
+903C92     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+24-24-0E   (hex)               Apple, Inc.\r
+24240E     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+A0-99-9B   (hex)               Apple, Inc.\r
+A0999B     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+D0-A6-37   (hex)               Apple, Inc.\r
+D0A637     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+18-F6-43   (hex)               Apple, Inc.\r
+18F643     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+74-81-14   (hex)               Apple, Inc.\r
+748114     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+18-EE-69   (hex)               Apple, Inc.\r
+18EE69     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+F0-DB-E2   (hex)               Apple, Inc.\r
+F0DBE2     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+B8-09-8A   (hex)               Apple, Inc.\r
+B8098A     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+54-9F-13   (hex)               Apple, Inc.\r
+549F13     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+2C-1F-23   (hex)               Apple, Inc.\r
+2C1F23     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+E4-CB-59   (hex)               Beijing Loveair Science and Technology Co. Ltd.\r
+E4CB59     (base 16)           Beijing Loveair Science and Technology Co. Ltd.\r
+                               103,Block B, Kelin Building, No.107, Dongsi North Street, Dongcheng District,\r
+                                Beijing    100000\r
+                               CN\r
+\r
+C8-77-65   (hex)               Tiesse SpA\r
+C87765     (base 16)           Tiesse SpA\r
+                               Via Asti\r
+                               Ivrea  TO  10015\r
+                               IT\r
+\r
+50-7A-55   (hex)               Apple, Inc.\r
+507A55     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+9C-35-EB   (hex)               Apple, Inc.\r
+9C35EB     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+A4-31-35   (hex)               Apple, Inc.\r
+A43135     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+D0-03-4B   (hex)               Apple, Inc.\r
+D0034B     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+A0-18-28   (hex)               Apple, Inc.\r
+A01828     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+3C-15-C2   (hex)               Apple, Inc.\r
+3C15C2     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+AC-CF-5C   (hex)               Apple, Inc.\r
+ACCF5C     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+F0-DB-F8   (hex)               Apple, Inc.\r
+F0DBF8     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+98-F0-AB   (hex)               Apple, Inc.\r
+98F0AB     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+DC-9B-9C   (hex)               Apple, Inc.\r
+DC9B9C     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+8C-29-37   (hex)               Apple, Inc.\r
+8C2937     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+DC-86-D8   (hex)               Apple, Inc.\r
+DC86D8     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+E4-C6-3D   (hex)               Apple, Inc.\r
+E4C63D     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+54-EA-A8   (hex)               Apple, Inc.\r
+54EAA8     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+A8-86-DD   (hex)               Apple, Inc.\r
+A886DD     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+A0-ED-CD   (hex)               Apple, Inc.\r
+A0EDCD     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+1C-E6-2B   (hex)               Apple, Inc.\r
+1CE62B     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+30-90-AB   (hex)               Apple, Inc.\r
+3090AB     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+F0-CB-A1   (hex)               Apple, Inc.\r
+F0CBA1     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+04-54-53   (hex)               Apple, Inc.\r
+045453     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+28-37-37   (hex)               Apple, Inc.\r
+283737     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+14-8F-C6   (hex)               Apple, Inc.\r
+148FC6     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+28-CF-DA   (hex)               Apple, Inc.\r
+28CFDA     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+14-5A-05   (hex)               Apple, Inc.\r
+145A05     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+D0-4F-7E   (hex)               Apple, Inc.\r
+D04F7E     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+D8-BB-2C   (hex)               Apple, Inc.\r
+D8BB2C     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+80-BE-05   (hex)               Apple, Inc.\r
+80BE05     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+E0-B5-2D   (hex)               Apple, Inc.\r
+E0B52D     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+68-AE-20   (hex)               Apple, Inc.\r
+68AE20     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+E8-80-2E   (hex)               Apple, Inc.\r
+E8802E     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+A8-8E-24   (hex)               Apple, Inc.\r
+A88E24     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+D8-CF-9C   (hex)               Apple, Inc.\r
+D8CF9C     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+04-48-9A   (hex)               Apple, Inc.\r
+04489A     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+B0-9F-BA   (hex)               Apple, Inc.\r
+B09FBA     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+8C-00-6D   (hex)               Apple, Inc.\r
+8C006D     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+C0-63-94   (hex)               Apple, Inc.\r
+C06394     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+84-38-35   (hex)               Apple, Inc.\r
+843835     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+20-C9-D0   (hex)               Apple, Inc.\r
+20C9D0     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+74-E2-F5   (hex)               Apple, Inc.\r
+74E2F5     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+84-29-99   (hex)               Apple, Inc.\r
+842999     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+9C-20-7B   (hex)               Apple, Inc.\r
+9C207B     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+40-B3-95   (hex)               Apple, Inc.\r
+40B395     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+00-88-65   (hex)               Apple, Inc.\r
+008865     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+30-F7-C5   (hex)               Apple, Inc.\r
+30F7C5     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+70-73-CB   (hex)               Apple, Inc.\r
+7073CB     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+00-B3-62   (hex)               Apple, Inc.\r
+00B362     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+F8-62-14   (hex)               Apple, Inc.\r
+F86214     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+B0-70-2D   (hex)               Apple, Inc.\r
+B0702D     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+D0-C5-F3   (hex)               Apple, Inc.\r
+D0C5F3     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+60-F4-45   (hex)               Apple, Inc.\r
+60F445     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+50-82-D5   (hex)               Apple, Inc.\r
+5082D5     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+9C-84-BF   (hex)               Apple, Inc.\r
+9C84BF     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+48-BF-6B   (hex)               Apple, Inc.\r
+48BF6B     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+24-5B-A7   (hex)               Apple, Inc.\r
+245BA7     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+BC-A9-20   (hex)               Apple, Inc.\r
+BCA920     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+B0-19-C6   (hex)               Apple, Inc.\r
+B019C6     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+58-E2-8F   (hex)               Apple, Inc.\r
+58E28F     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+AC-1F-74   (hex)               Apple, Inc.\r
+AC1F74     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+20-76-8F   (hex)               Apple, Inc.\r
+20768F     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+C0-CC-F8   (hex)               Apple, Inc.\r
+C0CCF8     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+80-ED-2C   (hex)               Apple, Inc.\r
+80ED2C     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+E8-B2-AC   (hex)               Apple, Inc.\r
+E8B2AC     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+84-89-AD   (hex)               Apple, Inc.\r
+8489AD     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+8C-8E-F2   (hex)               Apple, Inc.\r
+8C8EF2     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+F4-0F-24   (hex)               Apple, Inc.\r
+F40F24     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+84-A1-34   (hex)               Apple, Inc.\r
+84A134     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+1C-91-48   (hex)               Apple, Inc.\r
+1C9148     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+5C-F7-E6   (hex)               Apple, Inc.\r
+5CF7E6     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+A0-D7-95   (hex)               Apple, Inc.\r
+A0D795     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+CC-08-8D   (hex)               Apple, Inc.\r
+CC088D     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+08-00-07   (hex)               Apple, Inc.\r
+080007     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+E4-25-E7   (hex)               Apple, Inc.\r
+E425E7     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+28-CF-E9   (hex)               Apple, Inc.\r
+28CFE9     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+90-60-F1   (hex)               Apple, Inc.\r
+9060F1     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+74-1B-B2   (hex)               Apple, Inc.\r
+741BB2     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+28-ED-6A   (hex)               Apple, Inc.\r
+28ED6A     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+34-AB-37   (hex)               Apple, Inc.\r
+34AB37     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+60-A3-7D   (hex)               Apple, Inc.\r
+60A37D     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+00-56-CD   (hex)               Apple, Inc.\r
+0056CD     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+70-81-EB   (hex)               Apple, Inc.\r
+7081EB     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+08-66-98   (hex)               Apple, Inc.\r
+086698     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+E0-F8-47   (hex)               Apple, Inc.\r
+E0F847     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+44-2A-60   (hex)               Apple, Inc.\r
+442A60     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+10-93-E9   (hex)               Apple, Inc.\r
+1093E9     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+DC-2B-61   (hex)               Apple, Inc.\r
+DC2B61     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+B8-FF-61   (hex)               Apple, Inc.\r
+B8FF61     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+18-E7-F4   (hex)               Apple, Inc.\r
+18E7F4     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+78-CA-39   (hex)               Apple, Inc.\r
+78CA39     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+5C-59-48   (hex)               Apple, Inc.\r
+5C5948     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+60-33-4B   (hex)               Apple, Inc.\r
+60334B     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+90-27-E4   (hex)               Apple, Inc.\r
+9027E4     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+24-F6-77   (hex)               Apple, Inc.\r
+24F677     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+78-67-D7   (hex)               Apple, Inc.\r
+7867D7     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+54-33-CB   (hex)               Apple, Inc.\r
+5433CB     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+D0-D2-B0   (hex)               Apple, Inc.\r
+D0D2B0     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+D8-8F-76   (hex)               Apple, Inc.\r
+D88F76     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+3C-2E-F9   (hex)               Apple, Inc.\r
+3C2EF9     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+DC-56-E7   (hex)               Apple, Inc.\r
+DC56E7     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+34-7C-25   (hex)               Apple, Inc.\r
+347C25     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+D4-90-9C   (hex)               Apple, Inc.\r
+D4909C     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+D4-9A-20   (hex)               Apple, Inc.\r
+D49A20     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+04-1E-64   (hex)               Apple, Inc.\r
+041E64     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+00-26-B0   (hex)               Apple, Inc.\r
+0026B0     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+00-26-4A   (hex)               Apple, Inc.\r
+00264A     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+00-25-BC   (hex)               Apple, Inc.\r
+0025BC     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+00-23-DF   (hex)               Apple, Inc.\r
+0023DF     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+00-22-41   (hex)               Apple, Inc.\r
+002241     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+00-0A-95   (hex)               Apple, Inc.\r
+000A95     (base 16)           Apple, Inc.\r
+                               1 Infinite Loop\r
+                               Cupertino  CA  95014\r
+                               US\r
+\r
+60-5F-8D   (hex)               eero inc.\r
+605F8D     (base 16)           eero inc.\r
+                               500 Howard Street, Suite 900\r
+                               SAN FRANCISCO  CA  94105\r
+                               US\r
+\r
+B4-DE-DF   (hex)               zte corporation\r
+B4DEDF     (base 16)           zte corporation\r
+                               12/F.,zte R&D building ,kejinan Road,Shenzhen,P.R.China\r
+                               shenzhen  guangdong  518057\r
+                               CN\r
+\r
+84-74-60   (hex)               zte corporation\r
+847460     (base 16)           zte corporation\r
+                               12/F.,zte R&D building ,kejinan Road,Shenzhen,P.R.China\r
+                               shenzhen  guangdong  518057\r
+                               CN\r
+\r
+B4-A8-B9   (hex)               Cisco Systems, Inc\r
+B4A8B9     (base 16)           Cisco Systems, Inc\r
+                               80 West Tasman Drive\r
+                               San Jose  CA  94568\r
+                               US\r
+\r
+88-B6-EE   (hex)               Dish Technologies Corp\r
+88B6EE     (base 16)           Dish Technologies Corp\r
+                               94 Inverness Terrace E\r
+                               Englewood  CO  80112\r
+                               US\r
+\r
+38-E6-0A   (hex)               Xiaomi Communications Co Ltd\r
+38E60A     (base 16)           Xiaomi Communications Co Ltd\r
+                               The Rainbow City of China Resources\r
+                               NO.68, Qinghe Middle Street  Haidian District, Beijing  100085\r
+                               CN\r
+\r
+C0-42-D0   (hex)               Juniper Networks\r
+C042D0     (base 16)           Juniper Networks\r
+                               1133 Innovation Way\r
+                               Sunnyvale  CA  94089\r
+                               US\r
+\r
+E8-33-0D   (hex)               Xaptec GmbH\r
+E8330D     (base 16)           Xaptec GmbH\r
+                               Neidenburger Str. 10\r
+                               Gelsenkirchen    45897\r
+                               DE\r
+\r
+D8-D7-75   (hex)               Sagemcom Broadband SAS\r
+D8D775     (base 16)           Sagemcom Broadband SAS\r
+                               250, route de l'Empereur\r
+                               Rueil Malmaison Cedex  hauts de seine  92848\r
+                               FR\r
+\r
+78-53-64   (hex)               SHIFT GmbH\r
+785364     (base 16)           SHIFT GmbH\r
+                               Am Gänsemarkt 6\r
+                               Wabern Falkenberg  Hessen  34590\r
+                               DE\r
+\r
+24-18-1D   (hex)               SAMSUNG ELECTRO-MECHANICS(THAILAND)\r
+24181D     (base 16)           SAMSUNG ELECTRO-MECHANICS(THAILAND)\r
+                               93Moo5T. Bangsamak SEMTHAI, WELLGROW INDUSTRIAL ESTATE\r
+                               Bangpakong  Chachoengsao  24180\r
+                               TH\r
+\r
+54-B7-E5   (hex)               Rayson Technology Co., Ltd.\r
+54B7E5     (base 16)           Rayson Technology Co., Ltd.\r
+                               1F No.9 R&D Rd.II, Science-Based Industrial Park\r
+                               Hsin-Chu    300\r
+                               TW\r
+\r
+BC-0F-A7   (hex)               Ouster\r
+BC0FA7     (base 16)           Ouster\r
+                               350 Treat Ave\r
+                               San Francisco  CA  94110\r
+                               US\r
+\r
+AC-F9-70   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
+ACF970     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
+                               No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park\r
+                               Dongguan    523808\r
+                               CN\r
+\r
+0C-41-E9   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
+0C41E9     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
+                               No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park\r
+                               Dongguan    523808\r
+                               CN\r
+\r
+58-D7-59   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
+58D759     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
+                               No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park\r
+                               Dongguan    523808\r
+                               CN\r
+\r
+B4-1C-30   (hex)               zte corporation\r
+B41C30     (base 16)           zte corporation\r
+                               12/F.,zte R&D building ,kejinan Road,Shenzhen,P.R.China\r
+                               shenzhen  guangdong  518057\r
+                               CN\r
+\r
+F4-C2-48   (hex)               Samsung Electronics Co.,Ltd\r
+F4C248     (base 16)           Samsung Electronics Co.,Ltd\r
+                               #94-1, Imsoo-Dong\r
+                               Gumi  Gyeongbuk  730-350\r
+                               KR\r
+\r
+A8-51-5B   (hex)               Samsung Electronics Co.,Ltd\r
+A8515B     (base 16)           Samsung Electronics Co.,Ltd\r
+                               #94-1, Imsoo-Dong\r
+                               Gumi  Gyeongbuk  730-350\r
+                               KR\r
+\r
+60-6B-FF   (hex)               Nintendo Co.,Ltd\r
+606BFF     (base 16)           Nintendo Co.,Ltd\r
+                               11-1 HOKOTATE-CHO KAMITOBA,MINAMI-KU\r
+                               KYOTO  KYOTO  601-8501\r
+                               JP\r
+\r
+AC-17-C8   (hex)               Cisco Meraki\r
+AC17C8     (base 16)           Cisco Meraki\r
+                               500 Terry A. Francois Blvd\r
+                               San Francisco    94158\r
+                               US\r
+\r
+EC-9B-8B   (hex)               Hewlett Packard Enterprise\r
+EC9B8B     (base 16)           Hewlett Packard Enterprise\r
+                               8000 Foothills Blvd.\r
+                               Roseville  CA  95747\r
+                               US\r
+\r
+70-C9-4E   (hex)               Liteon Technology Corporation\r
+70C94E     (base 16)           Liteon Technology Corporation\r
+                               4F, 90, Chien 1 Road\r
+                               New Taipei City  Taiwan  23585\r
+                               TW\r
+\r
+70-D0-81   (hex)               Beijing Netpower Technologies Inc.\r
+70D081     (base 16)           Beijing Netpower Technologies Inc.\r
+                               Room 201, Block B, NO. 15 Building, EastZone\r
+                               Courtyard10, Xibeiwang East Road  Haidian District, Beijing  100094\r
+                               CN\r
+\r
+70-3A-73   (hex)               Shenzhen Sundray Technologies Company Limited\r
+703A73     (base 16)           Shenzhen Sundray Technologies Company Limited\r
+                               6th Floor,Block A1, Nanshan iPark, No.1001 XueYuan Road, Nanshan District\r
+                               Shenzhen  Guangdong  518057\r
+                               CN\r
+\r
+18-0F-76   (hex)               D-Link International\r
+180F76     (base 16)           D-Link International\r
+                               1 Internal Business Park, #03-12,The Synergy, Singapore\r
+                               Singapore  Singapore  609917\r
+                               SG\r
+\r
+18-4C-08   (hex)               Rockwell Automation\r
+184C08     (base 16)           Rockwell Automation\r
+                               1 Allen-Bradley Dr.\r
+                               Mayfield Heights  OH  44124-6118\r
+                               US\r
+\r
+88-E9-0F   (hex)               innomdlelab\r
+88E90F     (base 16)           innomdlelab\r
+                               Unnam 1 gil, 3 \r
+                               Seocho-gu  Seoul  06778\r
+                               KR\r
+\r
+C0-98-DA   (hex)               China Mobile IOT Company Limited\r
+C098DA     (base 16)           China Mobile IOT Company Limited\r
+                               NO.8 Yu Ma Road, NanAn Area Chongqing,China\r
+                               Chongqing  Chongqing  401336\r
+                               CN\r
+\r
+98-D8-63   (hex)               Shanghai High-Flying Electronics Technology Co., Ltd\r
+98D863     (base 16)           Shanghai High-Flying Electronics Technology Co., Ltd\r
+                               Room 1002 ,#1Building,No.3000 Longdong Avenue,Pudong District,Shanghai,China\r
+                               shanghai  shanghai  201203\r
+                               CN\r
+\r
+F0-0F-EC   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
+F00FEC     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
+                               No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park\r
+                               Dongguan    523808\r
+                               CN\r
+\r
+0C-70-4A   (hex)               HUAWEI TECHNOLOGIES CO.,LTD\r
+0C704A     (base 16)           HUAWEI TECHNOLOGIES CO.,LTD\r
+                               No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park\r
+                               Dongguan    523808\r
+                               CN\r
+\r
+54-A6-5C   (hex)               Technicolor CH USA Inc.\r
+54A65C     (base 16)           Technicolor CH USA Inc.\r
+                               101 West 103rd St.\r
+                               Indianapolis  IN  46290\r
+                               US\r
+\r
+94-9F-3E   (hex)               Sonos, Inc.\r
+949F3E     (base 16)           Sonos, Inc.\r
+                               614 Chapala St\r
+                               Santa Barbara  CA  93101\r
+                               US\r
+\r
+B8-E9-37   (hex)               Sonos, Inc.\r
+B8E937     (base 16)           Sonos, Inc.\r
+                               614 Chapala St\r
+                               Santa Barbara  CA  93101\r
+                               US\r
+\r
+78-28-CA   (hex)               Sonos, Inc.\r
+7828CA     (base 16)           Sonos, Inc.\r
+                               614 Chapala St\r
+                               Santa Barbara  CA  93101\r
+                               US\r
+\r
+34-7E-5C   (hex)               Sonos, Inc.\r
+347E5C     (base 16)           Sonos, Inc.\r
+                               614 Chapala St\r
+                               Santa Barbara  CA  93101\r
+                               US\r
+\r
+C0-48-E6   (hex)               Samsung Electronics Co.,Ltd\r
+C048E6     (base 16)           Samsung Electronics Co.,Ltd\r
+                               129, Samsung-ro, Youngtongl-Gu\r
+                               Suwon  Gyeonggi-Do  16677\r
+                               KR\r
+\r
+6C-E4-DA   (hex)               NEC Platforms, Ltd.\r
+6CE4DA     (base 16)           NEC Platforms, Ltd.\r
+                               2-3 Kandatsukasamachi\r
+                               Chiyodaku  Tokyo  101-8532\r
+                               JP\r
+\r
+C8-8F-26   (hex)               Skyworth Digital Technology(Shenzhen) Co.,Ltd\r
+C88F26     (base 16)           Skyworth Digital Technology(Shenzhen) Co.,Ltd\r
+                               7F,Block A,Skyworth Building,\r
+                               Shenzhen  Guangdong  518057\r
+                               CN\r
+\r
+B0-26-80   (hex)               Cisco Systems, Inc\r
+B02680     (base 16)           Cisco Systems, Inc\r
+                               80 West Tasman Drive\r
+                               San Jose  CA  94568\r
+                               US\r
+\r
+00-3C-10   (hex)               Cisco Systems, Inc\r
+003C10     (base 16)           Cisco Systems, Inc\r
+                               80 West Tasman Drive\r
+                               San Jose  CA  94568\r
+                               US\r
+\r
+90-83-4B   (hex)               BEIJING YUNYI TIMES TECHNOLOGY CO,.LTD\r
+90834B     (base 16)           BEIJING YUNYI TIMES TECHNOLOGY CO,.LTD\r
+                               1-411Room 19#Building No.26 Xihuan South Rd. BDA Daxing District,\r
+                               BEIJING    100176\r
+                               CN\r
+\r
+48-BD-3D   (hex)               New H3C Technologies Co., Ltd\r
+48BD3D     (base 16)           New H3C Technologies Co., Ltd\r
+                               466 Changhe Road, Binjiang District\r
+                               Hangzhou  Zhejiang  310052\r
+                               CN\r
+\r
+4C-AB-FC   (hex)               zte corporation\r
+4CABFC     (base 16)           zte corporation\r
+                               12/F.,zte R&D building ,kejinan Road,Shenzhen,P.R.China\r
+                               shenzhen  guangdong  518057\r
+                               CN\r
+\r
+20-0F-70   (hex)               FOXTECH\r
+200F70     (base 16)           FOXTECH\r
+                               152-160 City Road\r
+                               LONDON  KEMP HOUSE  EC1V 2NX\r
+                               GB\r
+\r
+E8-1A-AC   (hex)               ORFEO SOUNDWORKS Inc.\r
+E81AAC     (base 16)           ORFEO SOUNDWORKS Inc.\r
+                               612, 11-41, Simin-daero 327beon-gil, Dongan-gu\r
+                               Anyang    14055\r
+                               KR\r
+\r
+A0-38-F8   (hex)               OURA Health Oy\r
+A038F8     (base 16)           OURA Health Oy\r
+                               Elektroniikkatie 3\r
+                               Oulu    90590\r
+                               FI\r
+\r
+14-6B-9C   (hex)               SHENZHEN BILIAN ELECTRONIC CO.,LTD\r
+146B9C     (base 16)           SHENZHEN BILIAN ELECTRONIC CO.,LTD\r
+                               NO.268, Fuqian Rd, Jutang community, Guanlan Town, Longhua New district\r
+                               shenzhen  guangdong  518000\r
+                               CN\r
+\r
+D0-77-14   (hex)               Motorola Mobility LLC, a Lenovo Company\r
+D07714     (base 16)           Motorola Mobility LLC, a Lenovo Company\r
+                               222 West Merchandise Mart Plaza\r
+                               Chicago  IL  60654\r
+                               US\r
+\r
+34-D7-12   (hex)               Smartisan Digital Co., Ltd\r
+34D712     (base 16)           Smartisan Digital Co., Ltd\r
+                               4F, China Digital Kingdom, No.1 Wangjing North Road, Chaoyang District\r
+                               Beijing  Beijing  100012\r
+                               CN\r
+\r
+98-45-62   (hex)               Shanghai Baud Data Communication Co.,Ltd.\r
+984562     (base 16)           Shanghai Baud Data Communication Co.,Ltd.\r
+                               NO.123 JULI RD\r
+                               PUDONG ZHANGJIANG HIGH-TECH PARK  SHANGHAI  201203\r
+                               CN\r
+\r
+E8-98-6D   (hex)               Palo Alto Networks\r
+E8986D     (base 16)           Palo Alto Networks\r
+                               3000 Tannery Way\r
+                               Santa Clara  CA  95054\r
+                               US\r
+\r
+F0-81-73   (hex)               Amazon Technologies Inc.\r
+F08173     (base 16)           Amazon Technologies Inc.\r
+                               P.O Box 8102\r
+                               Reno    89507\r
+                               US\r
+\r
+24-29-FE   (hex)               KYOCERA Corporation \r
+2429FE     (base 16)           KYOCERA Corporation \r
+                               30 Hoji\r
+                               Kitami,  Hokkaido  099-1595\r
+                               JP\r
index 30505fa..89577b9 100644 (file)
@@ -1718,9 +1718,6 @@ F00000-FFFFFF     (base 16)               Private
 90-C6-82   (hex)               Private\r
 F00000-FFFFFF     (base 16)            Private\r
 \r
-98-02-D8   (hex)               Private\r
-F00000-FFFFFF     (base 16)            Private\r
-\r
 D0-76-50   (hex)               Private\r
 F00000-FFFFFF     (base 16)            Private\r
 \r
@@ -2003,6 +2000,105 @@ F00000-FFFFFF     (base 16)             Private
                                NishiTokyo-city  Tokyo  202-0022\r
                                JP\r
 \r
+9C-43-1E   (hex)               HK ELEPHONE Communication Tech Co.,Limited\r
+D00000-DFFFFF     (base 16)            HK ELEPHONE Communication Tech Co.,Limited\r
+                               Unit 04, 7/F Bright Way Tower No.33 Mong Kok Rd KL\r
+                               Hong Kong     999077\r
+                               HK\r
+\r
+9C-43-1E   (hex)               Wireless Environment, LLC\r
+400000-4FFFFF     (base 16)            Wireless Environment, LLC\r
+                               600 Beta Drive Unit 100 Mayfield Village, OH 44143,US\r
+                               Mayfield Village  OH  44143\r
+                               US\r
+\r
+28-2C-02   (hex)               ThirdReality, Inc\r
+B00000-BFFFFF     (base 16)            ThirdReality, Inc\r
+                               647 East Longhua Road, Huangpu District\r
+                               Shanghai  Shanghai  200023\r
+                               CN\r
+\r
+9C-43-1E   (hex)               HAESUNG DS\r
+200000-2FFFFF     (base 16)            HAESUNG DS\r
+                               8F, Haesung 2 Building, 508, Teheran-ro, Gangnam-gu\r
+                               Seoul    06178\r
+                               KR\r
+\r
+28-2C-02   (hex)               Tokin Limited\r
+A00000-AFFFFF     (base 16)            Tokin Limited\r
+                               Unit 513-4, Block A, Focal Industrial Centre, 21 Man Lok Street, Hung Hom\r
+                               Kowloon    0000\r
+                               HK\r
+\r
+F0-41-C8   (hex)               Shenzhen Medica Technology Development Co., Ltd.\r
+200000-2FFFFF     (base 16)            Shenzhen Medica Technology Development Co., Ltd.\r
+                               2F Building A, Tongfang Information Harbor, No.11, East Langshan Road, Nanshan District\r
+                               Shenzhen    518000\r
+                               CN\r
+\r
+C4-FF-BC   (hex)               Danego BV\r
+000000-0FFFFF     (base 16)            Danego BV\r
+                               Protonenlaan 24\r
+                               Uden  NB  5405 NE\r
+                               NL\r
+\r
+C4-FF-BC   (hex)               Critical Link\r
+700000-7FFFFF     (base 16)            Critical Link\r
+                               6712 Brooklawn  Parkway\r
+                               Syracuse    13211\r
+                               US\r
+\r
+A4-DA-22   (hex)               Klashwerks Inc.\r
+B00000-BFFFFF     (base 16)            Klashwerks Inc.\r
+                               441 Maclaren Street, Suite 408\r
+                               Ottawa  ON  K2P2H3\r
+                               CA\r
+\r
+88-A9-A7   (hex)               Sieper Lüdenscheid GmbH & Co. KG\r
+600000-6FFFFF     (base 16)            Sieper Lüdenscheid GmbH & Co. KG\r
+                               Schlittenbacher Straße 60\r
+                               Lüdenscheid    58511\r
+                               DE\r
+\r
+98-02-D8   (hex)               Private\r
+F00000-FFFFFF     (base 16)            Private\r
+\r
+C4-FF-BC   (hex)               KyongBo Electric Co., Ltd.\r
+C00000-CFFFFF     (base 16)            KyongBo Electric Co., Ltd.\r
+                               5, Seongsuil-ro 12-gagil Seongdong-gu\r
+                               Seoul    04792\r
+                               KR\r
+\r
+C4-FF-BC   (hex)               ShenZhen ZYT Technology co., Ltd\r
+800000-8FFFFF     (base 16)            ShenZhen ZYT Technology co., Ltd\r
+                               Floor four,Build C,FuSen Industrial park, HangCheng Avenue,Baoan District\r
+                               Shenzhen  GuangDong  518000\r
+                               CN\r
+\r
+DC-E5-33   (hex)               SAN Engineering\r
+700000-7FFFFF     (base 16)            SAN Engineering\r
+                               434-31 UTO Korea BD. 4F\r
+                               Seongnam-si Jungwon-gu  Gyunggi-do  13230\r
+                               KR\r
+\r
+DC-E5-33   (hex)               Suzhou ATES electronic technology co.LTD\r
+D00000-DFFFFF     (base 16)            Suzhou ATES electronic technology co.LTD\r
+                               NO.2 aimin road,Xiangcheng district\r
+                                Suzhou city  Jiangsu Province  215002\r
+                               CN\r
+\r
+88-A9-A7   (hex)               Zhejiang Haoteng Electronic Technology Co.,Ltd.\r
+A00000-AFFFFF     (base 16)            Zhejiang Haoteng Electronic Technology Co.,Ltd.\r
+                               Zhejiang Lishui city streets Nanming mountain Shek road Liandu District No. 268 Building 2 block B\r
+                               Lishui  Zhejiang  323000\r
+                               CN\r
+\r
+F0-41-C8   (hex)               LINPA ACOUSTIC TECHNOLOGY CO.,LTD \r
+000000-0FFFFF     (base 16)            LINPA ACOUSTIC TECHNOLOGY CO.,LTD \r
+                               2A,No60 , Lizhong Road,DaliQingxi Town\r
+                               Dongguan  Guandong  523648\r
+                               CN\r
+\r
 1C-87-76   (hex)               Strone Technology\r
 C00000-CFFFFF     (base 16)            Strone Technology\r
                                13 Ellis Street\r
@@ -3944,6 +4040,123 @@ F8-B5-68   (hex)                CloudMinds (Shenzhen) Holdings Co., Ltd
 10-07-23   (hex)               Private\r
 F00000-FFFFFF     (base 16)            Private\r
 \r
+28-2C-02   (hex)               LLC MICROTEH\r
+500000-5FFFFF     (base 16)            LLC MICROTEH\r
+                               pl.5 bldg.2/3 Akademika Anokhina str. \r
+                               Moscow    119602\r
+                               RU\r
+\r
+9C-43-1E   (hex)               Wunda Group plc\r
+800000-8FFFFF     (base 16)            Wunda Group plc\r
+                               Unit 1-5, Hawthorn, Crick\r
+                               Caldicot  Monmouthshire  NP26 5UT\r
+                               GB\r
+\r
+9C-43-1E   (hex)               Advanced Logic Technology (ALT) sa\r
+300000-3FFFFF     (base 16)            Advanced Logic Technology (ALT) sa\r
+                               Route de Niederpallen, 30H\r
+                               Redange-sur-Attert  Luxembourg  8506\r
+                               LU\r
+\r
+C4-FF-BC   (hex)               GSM Innovations Pty Ltd\r
+900000-9FFFFF     (base 16)            GSM Innovations Pty Ltd\r
+                               142-144 Fullarton Road\r
+                               Rose Park  SA  5067\r
+                               AU\r
+\r
+C4-FF-BC   (hex)               SHENZHEN KALIF ELECTRONICS CO.,LTD\r
+300000-3FFFFF     (base 16)            SHENZHEN KALIF ELECTRONICS CO.,LTD\r
+                               1、2 and 3 Floor, No.114, Haochong No.2 Industry Area, Hongxing Community, Songgang, Baoan, Shenzhen \r
+                               SHENZHEN  GuangDong  518105\r
+                               CN\r
+\r
+C4-FF-BC   (hex)               Beijing  KDF information technology co. LTD.\r
+D00000-DFFFFF     (base 16)            Beijing  KDF information technology co. LTD.\r
+                               Room14C,TowerA,,LindaBuilding,No.8,Dongtucheng Road,Chaoyang District, Beijing.\r
+                               Beijing    100013\r
+                               CN\r
+\r
+9C-43-1E   (hex)               Optris GmbH\r
+700000-7FFFFF     (base 16)            Optris GmbH\r
+                               Ferdinand-Buisson-Str. 14\r
+                               Berlin    13127\r
+                               DE\r
+\r
+C4-FF-BC   (hex)               viRaTec GmbH\r
+E00000-EFFFFF     (base 16)            viRaTec GmbH\r
+                               Phorusgasse 8/1\r
+                               Wien    1040\r
+                               AT\r
+\r
+DC-E5-33   (hex)               Controls Inc\r
+500000-5FFFFF     (base 16)            Controls Inc\r
+                               5204 Portside Drive\r
+                               Medina  OH  44256\r
+                               US\r
+\r
+C4-FF-BC   (hex)               Shenzhen C & D Electronics Co., Ltd.\r
+600000-6FFFFF     (base 16)            Shenzhen C & D Electronics Co., Ltd.\r
+                               9th FIoor, Building 9, No.1 Qingxiang road, BaoNeng Science and TechnoIogy Industrial Park, Longhua New District\r
+                               ShenZhen  GuangDong  518000\r
+                               CN\r
+\r
+DC-E5-33   (hex)               FLYHT Aerospace\r
+000000-0FFFFF     (base 16)            FLYHT Aerospace\r
+                               300E 1144 - 29th St. N.E.\r
+                               Calgary  AB  T2E7P1\r
+                               CA\r
+\r
+DC-E5-33   (hex)               Private\r
+A00000-AFFFFF     (base 16)            Private\r
+\r
+A4-DA-22   (hex)               Shen Zhen City YaKun Electronics Co., Ltd\r
+D00000-DFFFFF     (base 16)            Shen Zhen City YaKun Electronics Co., Ltd\r
+                               SOUTHERN BUILDING 5388 Shang Bu  Industrial Zone Huaqiang North Road Futian District\r
+                               shen zhen city  Guang Dong Province  518000\r
+                               CN\r
+\r
+A4-DA-22   (hex)               Abetechs GmbH\r
+A00000-AFFFFF     (base 16)            Abetechs GmbH\r
+                               Niermannsweg 11\r
+                               Erkrath   North Rhine-Westphalia  40699\r
+                               DE\r
+\r
+A4-DA-22   (hex)               T2T System\r
+100000-1FFFFF     (base 16)            T2T System\r
+                               #316, HYUNDAI Knowledge Industry Center, 70, Dusan-ro\r
+                               Geumcheon-gu  Seoul  08584\r
+                               KR\r
+\r
+A4-DA-22   (hex)               Quuppa Oy\r
+E00000-EFFFFF     (base 16)            Quuppa Oy\r
+                               Keilaranta 1\r
+                               Espoo    02150\r
+                               FI\r
+\r
+88-A9-A7   (hex)               AndroVideo Inc.\r
+C00000-CFFFFF     (base 16)            AndroVideo Inc.\r
+                               2f-4, 17, Lane 91, Nei Hu Rd., Sec. 1\r
+                               Taipei    11441\r
+                               TW\r
+\r
+F0-41-C8   (hex)               Shenzhen  Nufilo Electronic Technology Co., Ltd.\r
+900000-9FFFFF     (base 16)            Shenzhen  Nufilo Electronic Technology Co., Ltd.\r
+                               Tianliao Building West Unit F1315, (New Materials Industrial Park),  Xueyuan Road,  Nanshan District\r
+                               Shenzhen   Guangdong  518055\r
+                               CN\r
+\r
+F0-41-C8   (hex)               SHENZHEN WISEWING INTERNET TECHNOLOGY CO.,LTD\r
+300000-3FFFFF     (base 16)            SHENZHEN WISEWING INTERNET TECHNOLOGY CO.,LTD\r
+                               No.826,Zone 1,Block B,Famous industrial product display purchasing center,Baoyuan Road,Xixiang,Bao'an Dis., Shenzhen,P.R.China\r
+                               shenzhen  China  518102\r
+                               CN\r
+\r
+F0-41-C8   (hex)                Shanghai Think-Force Electronic Technology Co. Ltd\r
+C00000-CFFFFF     (base 16)             Shanghai Think-Force Electronic Technology Co. Ltd\r
+                               North ZhongShan Road, No. 3000, Room 2608\r
+                               Shanghai    200000\r
+                               CN\r
+\r
 1C-87-76   (hex)               Zhuhai MYZR Technology Co.,Ltd\r
 500000-5FFFFF     (base 16)            Zhuhai MYZR Technology Co.,Ltd\r
                                Room 302,Area D2,National Hi-tech Zone,NO.1,Software Park Road\r
@@ -6005,6 +6218,156 @@ F8-B5-68   (hex)                Combiwins Technology Co.,Limited
                                Chennai  Tamilnadu  600035\r
                                IN\r
 \r
+28-2C-02   (hex)               SHENZHEN DOMENOR TECHNOLOGY LLC\r
+D00000-DFFFFF     (base 16)            SHENZHEN DOMENOR TECHNOLOGY LLC\r
+                               F4, BUILDING A3, SILICON VALLEY POWER TECHNOLOGY PARK, SILI ROAD, KUKENG COMMUNITY, GUANLAN TOWN,LONGHUA DISTRICT\r
+                               SHENZHEN  GUANGDONG  518110\r
+                               CN\r
+\r
+9C-43-1E   (hex)               Symfun Telecom Ltd\r
+100000-1FFFFF     (base 16)            Symfun Telecom Ltd\r
+                               Floor 4 Building 11 Xi Qi Dian Jia Yuan\r
+                               Beijing    100083\r
+                               CN\r
+\r
+9C-43-1E   (hex)               Antailiye Technology Co.,Ltd\r
+000000-0FFFFF     (base 16)            Antailiye Technology Co.,Ltd\r
+                               7/F,Zhengjiyuan Buiding,2 Road,Qianjing, Xixiang, Baoan District,Shenzhen\r
+                               SHEN ZHEN  GUANGDONG  518000\r
+                               CN\r
+\r
+9C-43-1E   (hex)               ST Access Control System Corp.\r
+A00000-AFFFFF     (base 16)            ST Access Control System Corp.\r
+                               3F., No. 111 Zhongzheng Rd., Banciao Dist., New Taipei City\r
+                               New Taipei City    22054\r
+                               TW\r
+\r
+C4-FF-BC   (hex)               Mobiletron Electronics Co., Ltd\r
+200000-2FFFFF     (base 16)            Mobiletron Electronics Co., Ltd\r
+                               85, Sec.4, Chung-Ching Rd., Ta-Ya District\r
+                               Taichung    428\r
+                               TW\r
+\r
+C4-FF-BC   (hex)               iMageTech CO.,LTD.\r
+400000-4FFFFF     (base 16)            iMageTech CO.,LTD.\r
+                               5F., No.16, Lane 15, Sec. 6, Mincyuan E. Rd., Neihu District,\r
+                               TAIPEI    114\r
+                               TW\r
+\r
+C4-FF-BC   (hex)               KAGA ELECTRONICS CO.,LTD.\r
+B00000-BFFFFF     (base 16)            KAGA ELECTRONICS CO.,LTD.\r
+                               20 Kandamatsunaga-cho\r
+                               Chiyoda-ku  TOKYO  101-8627\r
+                               JP\r
+\r
+C4-FF-BC   (hex)               comtime GmbH\r
+500000-5FFFFF     (base 16)            comtime GmbH\r
+                               Gutenbergring 22\r
+                               Norderstedt    22848\r
+                               US\r
+\r
+DC-E5-33   (hex)               Tintel Hongkong Co.Ltd\r
+B00000-BFFFFF     (base 16)            Tintel Hongkong Co.Ltd\r
+                               FLAT C,23/F,LUCKY PLAZA,315-321 LOCKHART ROAD,WANCHAI,HONGKONG\r
+                               HONGKONG  GUANG DONG PROVINCE  999077\r
+                               HK\r
+\r
+DC-E5-33   (hex)               JB-Lighting Lichtanlagen GmbH\r
+800000-8FFFFF     (base 16)            JB-Lighting Lichtanlagen GmbH\r
+                               Sallersteig 15\r
+                               89134    89134\r
+                               DE\r
+\r
+DC-E5-33   (hex)               Giant Power Technology Biomedical Corporation\r
+E00000-EFFFFF     (base 16)            Giant Power Technology Biomedical Corporation\r
+                               Rm201, 2nd Educational Building, No. 84, Gongzhuan Rd, Taishan Dist\r
+                               New Taipei City    24301\r
+                               TW\r
+\r
+DC-E5-33   (hex)               shenzhen bangying electronics co,.ltd\r
+400000-4FFFFF     (base 16)            shenzhen bangying electronics co,.ltd\r
+                               3/F Building 16,Hongfa industrialPark,Tangtou Shiyan Town\r
+                               shenzhen  guangdong  518000\r
+                               CN\r
+\r
+A4-DA-22   (hex)               AURANEXT\r
+600000-6FFFFF     (base 16)            AURANEXT\r
+                               202 quai de clichy\r
+                               CLICHY    92110\r
+                               FR\r
+\r
+A4-DA-22   (hex)               Wyze Labs Inc\r
+200000-2FFFFF     (base 16)            Wyze Labs Inc\r
+                                22522 29TH DR SE L101\r
+                               BOTHELL  WA  98021\r
+                               US\r
+\r
+A4-DA-22   (hex)               LORIOT AG\r
+400000-4FFFFF     (base 16)            LORIOT AG\r
+                               Zuercherstrasse 68\r
+                               Thalwil  Zürich  8800\r
+                               CH\r
+\r
+A4-DA-22   (hex)               DURATECH Enterprise,LLC\r
+300000-3FFFFF     (base 16)            DURATECH Enterprise,LLC\r
+                               NO.1013,184,Gasan digital 2-ro,Geumcheon-gu,Seoul\r
+                               Seoul    08501\r
+                               KR\r
+\r
+A4-DA-22   (hex)               EHO.LINK\r
+C00000-CFFFFF     (base 16)            EHO.LINK\r
+                               5 Avenue de Saint Menet, Imm. Axiome, Bat. B\r
+                               Marseille    13011\r
+                               FR\r
+\r
+A4-DA-22   (hex)               General Electric Company\r
+000000-0FFFFF     (base 16)            General Electric Company\r
+                               Valle del Cedro #1551\r
+                               Ciudad Juarez  Chih  32575\r
+                               MX\r
+\r
+88-A9-A7   (hex)               Mikroelektronika\r
+300000-3FFFFF     (base 16)            Mikroelektronika\r
+                               Batajnicki drum 23\r
+                               Belgrade    11186\r
+                               RS\r
+\r
+88-A9-A7   (hex)               kimura giken corporation\r
+700000-7FFFFF     (base 16)            kimura giken corporation\r
+                               4-9-19 kamiyoga\r
+                               Setagaya-ku  Tokyo  158-0098\r
+                               JP\r
+\r
+88-A9-A7   (hex)               FlashForge Corporation\r
+900000-9FFFFF     (base 16)            FlashForge Corporation\r
+                                No.518, Xianyuan Road\r
+                               Jinhua  Zhejiang  321000\r
+                               CN\r
+\r
+88-A9-A7   (hex)               Thomas & Darden, Inc\r
+400000-4FFFFF     (base 16)            Thomas & Darden, Inc\r
+                               916 Springdale Rd Bldg 4 #104\r
+                               Austin    78702\r
+                               US\r
+\r
+88-A9-A7   (hex)               Impact Distribution\r
+E00000-EFFFFF     (base 16)            Impact Distribution\r
+                               Ter Heidelaan 50a\r
+                               Aarschot    3200\r
+                               BE\r
+\r
+88-A9-A7   (hex)               Honeywell spol. s.r.o. HTS CZ o.z. \r
+200000-2FFFFF     (base 16)            Honeywell spol. s.r.o. HTS CZ o.z. \r
+                               Turanka 100/1387 \r
+                               Brno    62700\r
+                               CZ\r
+\r
+88-A9-A7   (hex)               Solaredge LTD.\r
+100000-1FFFFF     (base 16)            Solaredge LTD.\r
+                               Hamada 1\r
+                               Herzelia    4673335\r
+                               IL\r
+\r
 1C-87-76   (hex)               Hekatron Vertriebs GmbH\r
 B00000-BFFFFF     (base 16)            Hekatron Vertriebs GmbH\r
                                Brühlmatten 9\r
@@ -7889,21 +8252,12 @@ F00000-FFFFFF     (base 16)             Private
 58-FC-DB   (hex)               Private\r
 F00000-FFFFFF     (base 16)            Private\r
 \r
-2C-26-5F   (hex)               Private\r
-F00000-FFFFFF     (base 16)            Private\r
-\r
-28-FD-80   (hex)               Private\r
-F00000-FFFFFF     (base 16)            Private\r
-\r
 2C-D1-41   (hex)               Private\r
 F00000-FFFFFF     (base 16)            Private\r
 \r
 2C-6A-6F   (hex)               Private\r
 F00000-FFFFFF     (base 16)            Private\r
 \r
-A0-BB-3E   (hex)               Private\r
-F00000-FFFFFF     (base 16)            Private\r
-\r
 BC-66-41   (hex)               Private\r
 F00000-FFFFFF     (base 16)            Private\r
 \r
@@ -8075,6 +8429,57 @@ D00000-DFFFFF     (base 16)              NOX Systems AG
                                Moscow    107258\r
                                RU\r
 \r
+28-2C-02   (hex)               Shenzhen Neoway Technology Co.,Ltd.\r
+800000-8FFFFF     (base 16)            Shenzhen Neoway Technology Co.,Ltd.\r
+                               4F-2#,Lian Jian Science & Industry Park,Huarong Road,Dalang Street,Longhua District\r
+                               Shenzhen  Guangdong  518000\r
+                               CN\r
+\r
+C4-FF-BC   (hex)               VISATECH C0., LTD.\r
+100000-1FFFFF     (base 16)            VISATECH C0., LTD.\r
+                               C-312 168, Gasan digital 1-ro\r
+                                Geumcheon-gu   Seoul  08507\r
+                               KR\r
+\r
+DC-E5-33   (hex)               Tiertime Corporation\r
+900000-9FFFFF     (base 16)            Tiertime Corporation\r
+                               2398 Walsh Avenue\r
+                               Santa Clara  CA  95051\r
+                               US\r
+\r
+A4-DA-22   (hex)               Hydro Electronic Devices, Inc.\r
+700000-7FFFFF     (base 16)            Hydro Electronic Devices, Inc.\r
+                               2120 Constitution Ave\r
+                               Hartford  WI  53027\r
+                               US\r
+\r
+2C-26-5F   (hex)               Private\r
+F00000-FFFFFF     (base 16)            Private\r
+\r
+28-FD-80   (hex)               Private\r
+F00000-FFFFFF     (base 16)            Private\r
+\r
+A0-BB-3E   (hex)               Private\r
+F00000-FFFFFF     (base 16)            Private\r
+\r
+F0-41-C8   (hex)               ATN Media Group FZ LLC\r
+D00000-DFFFFF     (base 16)            ATN Media Group FZ LLC\r
+                               Business Bay-alabrj st Business Towar By Damac.office-807\r
+                               Dubai    25051\r
+                               AE\r
+\r
+F0-41-C8   (hex)               XI'AN MEI SHANG MEI WIRELESS TECHNOLOGY.Co., Ltd.\r
+500000-5FFFFF     (base 16)            XI'AN MEI SHANG MEI WIRELESS TECHNOLOGY.Co., Ltd.\r
+                               Xi'an Beilin District Yanta Middle Road No. 17A XIN QING YA YUAN 2-5C\r
+                               XI'AN  shanxi  710000\r
+                               CN\r
+\r
+F0-41-C8   (hex)               AED Engineering GmbH\r
+600000-6FFFFF     (base 16)            AED Engineering GmbH\r
+                               Taunusstr. 51\r
+                               Munich  Bavaria  80807\r
+                               DE\r
+\r
 34-D0-B8   (hex)               Kongqiguanjia (Beijing)Technology co.,ltd\r
 E00000-EFFFFF     (base 16)            Kongqiguanjia (Beijing)Technology co.,ltd\r
                                Room 1201,Block A,Building of Fesco,Xidawang Road,Chaoyang district\r
@@ -8147,6 +8552,66 @@ F8-B5-68   (hex)         Beijing Wanji Techonology Co., Ltd.
                                beijing  beijing  100193\r
                                CN\r
 \r
+28-2C-02   (hex)               Dexin Digital Technology Corp. Ltd.\r
+300000-3FFFFF     (base 16)            Dexin Digital Technology Corp. Ltd.\r
+                               No.10 and 12, Wuxing Fourth Road,Wuhou District Chengdu 610045 Sichuan, PR China\r
+                               chengdu  Sichuan  610045\r
+                               CN\r
+\r
+9C-43-1E   (hex)               ProMOS Technologies Inc.\r
+500000-5FFFFF     (base 16)            ProMOS Technologies Inc.\r
+                               3A3, No.1, Lixing 1st Rd., East Dist.,\r
+                               Hsinchu City  Taiwan  300\r
+                               TW\r
+\r
+DC-E5-33   (hex)               Ambi Labs Limited\r
+100000-1FFFFF     (base 16)            Ambi Labs Limited\r
+                               1903, 19/F, Loon Lee Building, 267-275 Des Voeux Road Central., Sheung Wan, Hong Kong\r
+                               Hong Kong  Hong Kong  00000\r
+                               HK\r
+\r
+DC-E5-33   (hex)               Remko GmbH & Co. KG\r
+200000-2FFFFF     (base 16)            Remko GmbH & Co. KG\r
+                               Im Seelenkamp 12\r
+                               Lage    32791\r
+                               DE\r
+\r
+A4-DA-22   (hex)               SolidPro Technology Corporation\r
+800000-8FFFFF     (base 16)            SolidPro Technology Corporation\r
+                               10F.-1, No.150, Jian 1st Rd.\r
+                               Zhonghe Dist.  New Taipei City  23511\r
+                               TW\r
+\r
+A4-DA-22   (hex)               Original Products Pvt. Ltd.\r
+500000-5FFFFF     (base 16)            Original Products Pvt. Ltd.\r
+                               B-19, Shiv Park, School Road, Khanpur \r
+                               New Delhi  New Delhi  110062\r
+                               IN\r
+\r
+88-A9-A7   (hex)               Shenzhenshi kechuangzhixian technology Co.LTD\r
+000000-0FFFFF     (base 16)            Shenzhenshi kechuangzhixian technology Co.LTD\r
+                               Room 14G,14th Floor, Langshi Building , keji South Road 12 , High-tech Industrial Park , Nanshan District\r
+                               Shenzhen    518000\r
+                               CN\r
+\r
+88-A9-A7   (hex)               TWK-ELEKTRONIK\r
+B00000-BFFFFF     (base 16)            TWK-ELEKTRONIK\r
+                               Heinrichstr. 85\r
+                               Duesseldorf    40239\r
+                               DE\r
+\r
+88-A9-A7   (hex)               psb intralogistics GmbH\r
+800000-8FFFFF     (base 16)            psb intralogistics GmbH\r
+                               Blocksbergstrasse 145\r
+                               Pirmasens    66955\r
+                               DE\r
+\r
+F0-41-C8   (hex)               Nanchang BlackShark Co.,Ltd.\r
+700000-7FFFFF     (base 16)            Nanchang BlackShark Co.,Ltd.\r
+                               Room 319, Jiaoqiao Town Office Building, Economic and Technical development zone, Nanchang City, Jiangxi Province.\r
+                               Nanchang    330013\r
+                               CN\r
+\r
 1C-87-74   (hex)               Philips Personal Health Solutions\r
 000000-0FFFFF     (base 16)            Philips Personal Health Solutions\r
                                High Tech Campus, HTC37 floor 0\r
@@ -10150,3 +10615,93 @@ F00000-FFFFFF     (base 16)            Private
 \r
 0C-EF-AF   (hex)               Private\r
 F00000-FFFFFF     (base 16)            Private\r
+\r
+28-2C-02   (hex)               EFENTO T P SZYDŁOWSKI K ZARĘBA SPÓŁKA JAWNA\r
+400000-4FFFFF     (base 16)            EFENTO T P SZYDŁOWSKI K ZARĘBA SPÓŁKA JAWNA\r
+                               Dietla 93/6\r
+                               Kraków    31-031\r
+                               PL\r
+\r
+28-2C-02   (hex)               Capintec, Inc.\r
+E00000-EFFFFF     (base 16)            Capintec, Inc.\r
+                               7 Vreeland Road\r
+                               Florham Park  NJ  07932\r
+                               US\r
+\r
+9C-43-1E   (hex)               R-S-I Elektrotechnik GmbH  CO KG\r
+600000-6FFFFF     (base 16)            R-S-I Elektrotechnik GmbH  CO KG\r
+                               Woelkestrasse 11\r
+                               Schweitenkirchen    85276\r
+                               DE\r
+\r
+9C-43-1E   (hex)               CONTINENT Co. Ltd\r
+900000-9FFFFF     (base 16)            CONTINENT Co. Ltd\r
+                               Bumazhnaya st., 16/3 lit B, of. 414\r
+                               Saint-Petersburg    190020\r
+                               RU\r
+\r
+9C-43-1E   (hex)               SuZhou Jinruiyang Information Technology CO.,LTD\r
+C00000-CFFFFF     (base 16)            SuZhou Jinruiyang Information Technology CO.,LTD\r
+                               NO.1003 Room A1 Buliding Tengfei Business Park in Suzhou Industrial Park.\r
+                               Suzhou  Jiangsu  215123\r
+                               CN\r
+\r
+9C-43-1E   (hex)               JNL Technologies Inc\r
+B00000-BFFFFF     (base 16)            JNL Technologies Inc\r
+                               W1205 Industrial Dr\r
+                               Ixonia  WI  53036\r
+                               US\r
+\r
+9C-43-1E   (hex)               Midas Technology DBA Phoenix Audio Technologies\r
+E00000-EFFFFF     (base 16)            Midas Technology DBA Phoenix Audio Technologies\r
+                               16 Goodyear #120\r
+                               Irvine  CA  92618\r
+                               US\r
+\r
+C4-FF-BC   (hex)               Advanced Navigation\r
+A00000-AFFFFF     (base 16)            Advanced Navigation\r
+                               Level 8, 37 Pitt Street\r
+                               Sydney  NSW  2000\r
+                               AU\r
+\r
+DC-E5-33   (hex)               ShenZhen C&D Electronics CO.Ltd.\r
+300000-3FFFFF     (base 16)            ShenZhen C&D Electronics CO.Ltd.\r
+                               9th FIoor, Building 9, No.1 Qingxiang road, BaoNeng Science and TechnoIogy Industrial Park,  Longhua New District\r
+                               ShenZhen  GuangDong  518000\r
+                               CN\r
+\r
+DC-E5-33   (hex)               WECAN Solution Inc.\r
+600000-6FFFFF     (base 16)            WECAN Solution Inc.\r
+                               71, Yulhadong-ro 8-gil, Dong-gu, Daegu, Republic of Korea\r
+                               Daegu    41102\r
+                               KR\r
+\r
+DC-E5-33   (hex)               BRCK\r
+C00000-CFFFFF     (base 16)            BRCK\r
+                               PO Box 58275-00200, 2nd Floor Bishop Magua Center, George Padmore Lane, 2nd Floor Bishop Magua Center, George Padmore Lane\r
+                               Nairobi  Nairobi  00200\r
+                               KE\r
+\r
+A4-DA-22   (hex)               Malldon Technology Limited\r
+900000-9FFFFF     (base 16)            Malldon Technology Limited\r
+                               607 Longsheng Technology Building, Longhua Dist\r
+                               Shenzhen  Guangdong  518000\r
+                               CN\r
+\r
+88-A9-A7   (hex)               AVLINK INDUSTRIAL CO., LTD\r
+D00000-DFFFFF     (base 16)            AVLINK INDUSTRIAL CO., LTD\r
+                               7/F, A1 Bldg, 1st Shuichanjingwan Industrial Park, Nanchang Village, Gushu, Bao'an Dist \r
+                               Shenzhen  Guangdong  518126\r
+                               CN\r
+\r
+88-A9-A7   (hex)               Volterman Inc.\r
+500000-5FFFFF     (base 16)            Volterman Inc.\r
+                               Suite B2, Sunset Lake Road\r
+                               Newark  DE  19702\r
+                               US\r
+\r
+F0-41-C8   (hex)               Powervault Ltd\r
+B00000-BFFFFF     (base 16)            Powervault Ltd\r
+                               29 Shand Street, London Bridge\r
+                               London    SE1 2ES\r
+                               GB\r
index 5a7b6e7..79b2cc6 100644 (file)
@@ -620,12 +620,6 @@ F78000-F78FFF     (base 16)                Manvish eTech Pvt. Ltd.
                                SUMIDA-KU  TOKYO  1300026\r
                                JP\r
 \r
-70-B3-D5   (hex)               Vtron Pty Ltd\r
-341000-341FFF     (base 16)            Vtron Pty Ltd\r
-                               Unit 6, 59 Township Drive\r
-                               West Burleigh  Queensland  4219\r
-                               AU\r
-\r
 70-B3-D5   (hex)               Peek Traffic\r
 875000-875FFF     (base 16)            Peek Traffic\r
                                2906 Corporate Way\r
@@ -2777,6 +2771,150 @@ B6C000-B6CFFF     (base 16)             GHM-Messtechnik GmbH (Standort IMTRON)
                                Kraków    31-031\r
                                PL\r
 \r
+70-B3-D5   (hex)               KST technology\r
+351000-351FFF     (base 16)            KST technology\r
+                               KST B/D 4-5, Wiryeseong-daero 12-gil\r
+                               Songpa-gu  Seoul  05636\r
+                               KR\r
+\r
+70-B3-D5   (hex)               Vtron Pty Ltd\r
+15D000-15DFFF     (base 16)            Vtron Pty Ltd\r
+                               Unit 2, 62 Township Drive West\r
+                               West Burleigh  Queensland  4219\r
+                               AU\r
+\r
+70-B3-D5   (hex)               Vtron Pty Ltd\r
+341000-341FFF     (base 16)            Vtron Pty Ltd\r
+                               Unit 2, 62 Township Drive West\r
+                               West Burleigh  Queensland  4219\r
+                               AU\r
+\r
+70-B3-D5   (hex)               Kunshan excellent Intelligent Technology Co., Ltd.\r
+BE4000-BE4FFF     (base 16)            Kunshan excellent Intelligent Technology Co., Ltd.\r
+                               Room 2002 Site B Modern Square No 8 Wei yi Road \r
+                               kunshan  Jiangsu Province   215301\r
+                               CN\r
+\r
+70-B3-D5   (hex)               YUYAMA MFG Co.,Ltd\r
+E86000-E86FFF     (base 16)            YUYAMA MFG Co.,Ltd\r
+                               3-3-1\r
+                               TOYONAKASHI  OSAKA  561-0841\r
+                               JP\r
+\r
+70-B3-D5   (hex)               QUANTAFLOW\r
+6EB000-6EBFFF     (base 16)            QUANTAFLOW\r
+                               AVENUE DU CANADA\r
+                               HONFLEUR    14600\r
+                               FR\r
+\r
+70-B3-D5   (hex)               FLUDIA\r
+4A0000-4A0FFF     (base 16)            FLUDIA\r
+                               4T rue honoré d'estienne d'orves\r
+                               Suresnes    92150\r
+                               FR\r
+\r
+70-B3-D5   (hex)               OLEDCOMM\r
+A43000-A43FFF     (base 16)            OLEDCOMM\r
+                               10-12 avenue de l'Europe\r
+                               Vélizy Villacoublay  Ile de France  78140\r
+                               FR\r
+\r
+70-B3-D5   (hex)               Peter Huber Kaeltemaschinenbau AG\r
+D7B000-D7BFFF     (base 16)            Peter Huber Kaeltemaschinenbau AG\r
+                               Werner-von-Siemens-Str. 1\r
+                               Offenburg  Ba-Wue  77656\r
+                               DE\r
+\r
+70-B3-D5   (hex)               TORGOVYY DOM  TEHNOLOGIY LLC\r
+7C0000-7C0FFF     (base 16)            TORGOVYY DOM  TEHNOLOGIY LLC\r
+                               The village of Rumyantsevo,  Build.1\r
+                               Moscow  Moscow  142784\r
+                               RU\r
+\r
+70-B3-D5   (hex)               Cardinal Health\r
+75E000-75EFFF     (base 16)            Cardinal Health\r
+                               444 McDonnell Blvd.\r
+                               Hazelwood  MO  63042\r
+                               US\r
+\r
+70-B3-D5   (hex)               Matrix Orbital Corporation\r
+2B7000-2B7FFF     (base 16)            Matrix Orbital Corporation\r
+                               Suite 602, 4774 Westwinds Dr NE\r
+                               Calgary  Alberta  T3J 0L7\r
+                               CA\r
+\r
+70-B3-D5   (hex)               Stone Three\r
+7BF000-7BFFFF     (base 16)            Stone Three\r
+                               24 Gardner Williams Ave\r
+                               Somerset West  Western Cape  7130\r
+                               ZA\r
+\r
+70-B3-D5   (hex)               Transas Marine Limited\r
+304000-304FFF     (base 16)            Transas Marine Limited\r
+                               10 Eastgate Avenue, Eastgate Business Park\r
+                               Little Island, Cork    0\r
+                               IE\r
+\r
+70-B3-D5   (hex)               MonsoonRF, Inc.\r
+0F3000-0F3FFF     (base 16)            MonsoonRF, Inc.\r
+                               7740 Garvey Ave, Unit D\r
+                               Rosemead  CA  91770\r
+                               US\r
+\r
+70-B3-D5   (hex)               SHINWA INDUSTRIES, INC.\r
+F87000-F87FFF     (base 16)            SHINWA INDUSTRIES, INC.\r
+                               Daisan Nishi-Aoyama Bldg. 6F 1-8-1 Shibuya\r
+                               Shibuya-ku  Tokyo  150-0002\r
+                               JP\r
+\r
+70-B3-D5   (hex)               AmTote Australasia\r
+DAA000-DAAFFF     (base 16)            AmTote Australasia\r
+                               Unit3, 28 LeightonPlace.\r
+                               HORNSBY  NSW  2077\r
+                               AU\r
+\r
+70-B3-D5   (hex)               EA Elektroautomatik GmbH & Co. KG\r
+743000-743FFF     (base 16)            EA Elektroautomatik GmbH & Co. KG\r
+                               Helmholtzstraße 31-33\r
+                               Viersen  NRW  41747\r
+                               DE\r
+\r
+70-B3-D5   (hex)               MB connect line GmbH Fernwartungssysteme\r
+08A000-08AFFF     (base 16)            MB connect line GmbH Fernwartungssysteme\r
+                               Winnettener Straße 6\r
+                               Dinkelsbuehl  Bavaria  91550\r
+                               DE\r
+\r
+70-B3-D5   (hex)               Prisma Telecom Testing Srl\r
+689000-689FFF     (base 16)            Prisma Telecom Testing Srl\r
+                               Via Petrocchi, 4\r
+                               Milano  MI  20127\r
+                               IT\r
+\r
+70-B3-D5   (hex)               Plantiga Technologies Inc\r
+525000-525FFF     (base 16)            Plantiga Technologies Inc\r
+                               324-611 Alexander Street\r
+                               Vancouver  British Columbia  V6A 1E1\r
+                               CA\r
+\r
+70-B3-D5   (hex)               Krontech\r
+6E9000-6E9FFF     (base 16)            Krontech\r
+                               I.T.U ARI 3 Teknokent Kron Telekomunikasyon, Maslak\r
+                               Istanbul    34467\r
+                               TR\r
+\r
+70-B3-D5   (hex)               TRIDENT INFOSOL PVT LTD\r
+C8F000-C8FFFF     (base 16)            TRIDENT INFOSOL PVT LTD\r
+                               NO1A , KUSHAL GARDEN , PEENYA INDUSTRIAL AREA\r
+                               BANGALORE    560058\r
+                               IN\r
+\r
+70-B3-D5   (hex)               Zamir Recognition Systems Ltd.\r
+981000-981FFF     (base 16)            Zamir Recognition Systems Ltd.\r
+                               Manachat Tech Park 1/22\r
+                               Jerusalem    96951\r
+                               IL\r
+\r
 70-B3-D5   (hex)               Flintab AB\r
 D60000-D60FFF     (base 16)            Flintab AB\r
                                Kabelvägen 4\r
@@ -5582,6 +5720,171 @@ FF9000-FF9FFF     (base 16)             InOut Communication Systems
                                Udiner  UD  33100\r
                                IT\r
 \r
+70-B3-D5   (hex)               Neuron GmbH\r
+E1B000-E1BFFF     (base 16)            Neuron GmbH\r
+                               Badenerstrasse 9\r
+                               Brugg    5200\r
+                               CH\r
+\r
+70-B3-D5   (hex)               HAVELSAN A.Ş.\r
+096000-096FFF     (base 16)            HAVELSAN A.Ş.\r
+                               Mustafa Kemal Mah. 2120.Cad. No.39                   \r
+                               ANKARA    06510 \r
+                               TR\r
+\r
+70-B3-D5   (hex)               YG COMPANY CO., LTD\r
+63F000-63FFFF     (base 16)            YG COMPANY CO., LTD\r
+                               65, Techno 3-ro\r
+                               Daejeon  Yuseong-gu  34016\r
+                               KR\r
+\r
+70-B3-D5   (hex)               Selex ES Inc.\r
+F5E000-F5EFFF     (base 16)            Selex ES Inc.\r
+                               4221 Tudor Lane\r
+                               Greensboro  NC  27410\r
+                               US\r
+\r
+70-B3-D5   (hex)               DIMASTEC GESTAO DE PONTO E ACESSO EIRELI-ME\r
+F8F000-F8FFFF     (base 16)            DIMASTEC GESTAO DE PONTO E ACESSO EIRELI-ME\r
+                               Praça Rotary Club, 355\r
+                               Ribeirão Preto  São Paulo  14021-355\r
+                               BR\r
+\r
+70-B3-D5   (hex)               Savari Inc\r
+207000-207FFF     (base 16)            Savari Inc\r
+                               2005 De la cruz blvd, st 111,\r
+                               santa clara  CA  95050\r
+                               US\r
+\r
+70-B3-D5   (hex)               QIAGEN Instruments AG\r
+A29000-A29FFF     (base 16)            QIAGEN Instruments AG\r
+                               Garstligweg 8\r
+                               Hombrechtikon  Zurich  8634\r
+                               CH\r
+\r
+70-B3-D5   (hex)               ONDEMAND LABORATORY Co., Ltd.\r
+069000-069FFF     (base 16)            ONDEMAND LABORATORY Co., Ltd.\r
+                               Daiba 449 Space 369 Building 2F\r
+                               Mishima  Shizuoka  411-0803\r
+                               JP\r
+\r
+70-B3-D5   (hex)               EPSOFT Co., Ltd\r
+A3A000-A3AFFF     (base 16)            EPSOFT Co., Ltd\r
+                               301, Bupyeong-daero, Bupyeong-gu\r
+                               Incheon    21315\r
+                               KR\r
+\r
+70-B3-D5   (hex)               Emergency Lighting Products Limited\r
+480000-480FFF     (base 16)            Emergency Lighting Products Limited\r
+                               Gillmans Industrial Estate, Natts Lane\r
+                               Billingshurst    RH14 9EZ\r
+                               GB\r
+\r
+70-B3-D5   (hex)               CSM MACHINERY srl\r
+FE3000-FE3FFF     (base 16)            CSM MACHINERY srl\r
+                               Via Cadore Mare, 25\r
+                               Cimetta di Codognè  Treviso  31013\r
+                               IT\r
+\r
+70-B3-D5   (hex)               X-Laser LLC\r
+711000-711FFF     (base 16)            X-Laser LLC\r
+                               9125 Whiskey Bottom Rd Ste A\r
+                               Laurel  MD  20723\r
+                               US\r
+\r
+70-B3-D5   (hex)               GS Elektromedizinsiche Geräte G. Stemple GmbH\r
+144000-144FFF     (base 16)            GS Elektromedizinsiche Geräte G. Stemple GmbH\r
+                               Hauswiesenstr. 26\r
+                               Kaufering  Bayern  86916\r
+                               DE\r
+\r
+70-B3-D5   (hex)               NESA SRL\r
+BFA000-BFAFFF     (base 16)            NESA SRL\r
+                               Via Sartori, 6/8\r
+                               Vidor  Treviso  31020\r
+                               IT\r
+\r
+70-B3-D5   (hex)               Renesas Electronics\r
+340000-340FFF     (base 16)            Renesas Electronics\r
+                               2801 Scott Blvd\r
+                               Santa Clara  CA  95050\r
+                               US\r
+\r
+70-B3-D5   (hex)               AEM Singapore Pte. Ltd.\r
+AC1000-AC1FFF     (base 16)            AEM Singapore Pte. Ltd.\r
+                               52 Serangoon North Ave 4\r
+                               Singapore  Singapore  555853\r
+                               SG\r
+\r
+70-B3-D5   (hex)               Planewave Instruments\r
+CB4000-CB4FFF     (base 16)            Planewave Instruments\r
+                               1819 Kona Dr.\r
+                               Compton  CA  90220\r
+                               US\r
+\r
+70-B3-D5   (hex)               Avionica \r
+611000-611FFF     (base 16)            Avionica \r
+                               9941 West Jessamine St\r
+                               Miami   FL  33157 \r
+                               US\r
+\r
+70-B3-D5   (hex)               ELDES\r
+9A0000-9A0FFF     (base 16)            ELDES\r
+                               Ukmerges 283B\r
+                               Vilnius    06313\r
+                               LT\r
+\r
+70-B3-D5   (hex)               Intesens\r
+B17000-B17FFF     (base 16)            Intesens\r
+                               425 rue Jean Rostand\r
+                               labege    31670\r
+                               FR\r
+\r
+70-B3-D5   (hex)               Avant Technologies, Inc\r
+410000-410FFF     (base 16)            Avant Technologies, Inc\r
+                               Road 156 Caguas West Ind. Park bldg 39\r
+                               Caguas  PR  00726\r
+                               US\r
+\r
+70-B3-D5   (hex)               Lab241 Co.,Ltd.\r
+21B000-21BFFF     (base 16)            Lab241 Co.,Ltd.\r
+                               25Dong 241Ho, 97, Siheung-daero, Geumcheon-gu\r
+                               Seoul  Seoul  08639\r
+                               KR\r
+\r
+70-B3-D5   (hex)               HEITEC AG\r
+228000-228FFF     (base 16)            HEITEC AG\r
+                               Dr.-Otto-Leich-Str. 16\r
+                               Eckental  Bavaria  90542\r
+                               DE\r
+\r
+70-B3-D5   (hex)               Alere Technologies AS\r
+2AE000-2AEFFF     (base 16)            Alere Technologies AS\r
+                               Kjelsaasveien 161\r
+                               Oslo  Oslo  0382\r
+                               NO\r
+\r
+70-B3-D5   (hex)               Insitu, Inc\r
+B3B000-B3BFFF     (base 16)            Insitu, Inc\r
+                               118 E Columbia River Way\r
+                               Bingen  WA  98605\r
+                               US\r
+\r
+70-B3-D5   (hex)               MatchX GmbH\r
+1CB000-1CBFFF     (base 16)            MatchX GmbH\r
+                               Adalbert Str.8\r
+                               Berlin    10999\r
+                               DE\r
+\r
+70-B3-D5   (hex)               Metrum Sweden AB\r
+F98000-F98FFF     (base 16)            Metrum Sweden AB\r
+                               Anders Personsgatan 16\r
+                               Goteborg    41664\r
+                               SE\r
+\r
+70-B3-D5   (hex)               Private\r
+DE9000-DE9FFF     (base 16)            Private\r
+\r
 70-B3-D5   (hex)               Schildknecht AG\r
 494000-494FFF     (base 16)            Schildknecht AG\r
                                Haugweg 26\r
@@ -7328,18 +7631,6 @@ AE7000-AE7FFF     (base 16)              E-T-A Elektrotechnische Apparate GmbH
                                Altdorf    90518\r
                                DE\r
 \r
-70-B3-D5   (hex)               Vtron Pty Ltd\r
-400000-400FFF     (base 16)            Vtron Pty Ltd\r
-                               Unit 2, 62 Township Drive\r
-                               Australia  Queensland  4219\r
-                               AU\r
-\r
-70-B3-D5   (hex)               Vtron Pty Ltd\r
-E0F000-E0FFFF     (base 16)            Vtron Pty Ltd\r
-                               Unit 6, 59 Township Drive\r
-                               West Burleigh  Queensland  4219\r
-                               AU\r
-\r
 70-B3-D5   (hex)               DSP4YOU LTd\r
 12F000-12FFFF     (base 16)            DSP4YOU LTd\r
                                Unit 1204, 106 How Ming Street\r
@@ -7784,12 +8075,6 @@ FFC000-FFCFFF     (base 16)              Symetrics Industries d.b.a. Extant Aerospace
                                Montoire sur le Loir  Loir et Cher  41800\r
                                FR\r
 \r
-70-B3-D5   (hex)               Vtron Pty Ltd\r
-B2B000-B2BFFF     (base 16)            Vtron Pty Ltd\r
-                               Unit 2, 62 Township Drive\r
-                               West Burleigh  Queensland  4219\r
-                               AU\r
-\r
 70-B3-D5   (hex)               RJ45 Technologies\r
 9D0000-9D0FFF     (base 16)            RJ45 Technologies\r
                                7, rue Roland Martin\r
@@ -8039,12 +8324,6 @@ C14000-C14FFF     (base 16)              Grupo Epelsa S.L.
                                Alcala de Henares  Madrid  28805\r
                                ES\r
 \r
-70-B3-D5   (hex)               SENSO2ME bvba\r
-631000-631FFF     (base 16)            SENSO2ME bvba\r
-                               Zandhoef  16\r
-                               KASTERLEE  België  2460\r
-                               BE\r
-\r
 70-B3-D5   (hex)               S Labs sp. z o.o.\r
 C53000-C53FFF     (base 16)            S Labs sp. z o.o.\r
                                Jasnogórska, 44\r
@@ -8294,6 +8573,120 @@ CFE000-CFEFFF     (base 16)             Secturion Systems
                                Centerville  UT  84014\r
                                US\r
 \r
+70-B3-D5   (hex)               Shenzhen INVT Electric Co.,Ltd\r
+1D0000-1D0FFF     (base 16)            Shenzhen INVT Electric Co.,Ltd\r
+                                INVT Bldg., GaoFa Scientific Park, Longjing, Nanshan, Shenzhen.\r
+                               Shenzhen  Guangdong  518055\r
+                               CN\r
+\r
+70-B3-D5   (hex)               Vtron Pty Ltd\r
+400000-400FFF     (base 16)            Vtron Pty Ltd\r
+                               Unit 2, 62 Township Drive West\r
+                               West Burleigh  Queensland  4219\r
+                               AU\r
+\r
+70-B3-D5   (hex)               Vtron Pty Ltd\r
+B2B000-B2BFFF     (base 16)            Vtron Pty Ltd\r
+                               Unit 2, 62 Township Drive West\r
+                               West Burleigh  Queensland  4219\r
+                               AU\r
+\r
+70-B3-D5   (hex)               Vtron Pty Ltd\r
+E0F000-E0FFFF     (base 16)            Vtron Pty Ltd\r
+                               Unit 2, 62 Township Drive West\r
+                               West Burleigh  Queensland  4219\r
+                               AU\r
+\r
+70-B3-D5   (hex)               KRONOTECH SRL\r
+8C8000-8C8FFF     (base 16)            KRONOTECH SRL\r
+                               VIALE UNGHERIA 125\r
+                               UDINE  ITALY/UDINE  33100\r
+                               IT\r
+\r
+70-B3-D5   (hex)               Particle sizing systems\r
+670000-670FFF     (base 16)            Particle sizing systems\r
+                               8203 Kristel Cir\r
+                               New Port Richey  FL  34652\r
+                               US\r
+\r
+70-B3-D5   (hex)               Grupo Epelsa S.L.\r
+4E1000-4E1FFF     (base 16)            Grupo Epelsa S.L.\r
+                               C/ Punto Net,3\r
+                               Alcala de Henares  Madrid  28805\r
+                               ES\r
+\r
+70-B3-D5   (hex)               Waterkotte GmbH\r
+7EA000-7EAFFF     (base 16)            Waterkotte GmbH\r
+                               Gewerkenstr. 15\r
+                               Herne    44628\r
+                               DE\r
+\r
+70-B3-D5   (hex)               Imecon Engineering SrL\r
+5E3000-5E3FFF     (base 16)            Imecon Engineering SrL\r
+                               via Gerola 13/15\r
+                               Fiesco  CR  26010\r
+                               IT\r
+\r
+70-B3-D5   (hex)               ELBIT SYSTEMS BMD AND LAND EW - ELISRA LTD\r
+24F000-24FFFF     (base 16)            ELBIT SYSTEMS BMD AND LAND EW - ELISRA LTD\r
+                               Hamerchava 29\r
+                               holon    58101\r
+                               IL\r
+\r
+70-B3-D5   (hex)               HiDes, Inc.\r
+837000-837FFF     (base 16)            HiDes, Inc.\r
+                               6F, No.86, Baozhong Rd., Xindian Dist.,\r
+                               New Taipei City  New Taipei City  23144\r
+                               TW\r
+\r
+70-B3-D5   (hex)               OptoPrecision GmbH\r
+4F9000-4F9FFF     (base 16)            OptoPrecision GmbH\r
+                               Auf der Höhe 15\r
+                               Bremen  Bremen  28357\r
+                               DE\r
+\r
+70-B3-D5   (hex)               OSUNG LST CO.,LTD.\r
+B64000-B64FFF     (base 16)            OSUNG LST CO.,LTD.\r
+                               #433-31, Sandong-ro, Eumbong-myeon\r
+                               Asan-si  Chungcheongnam-do  31418\r
+                               KR\r
+\r
+70-B3-D5   (hex)               Impulse Automation\r
+7A3000-7A3FFF     (base 16)            Impulse Automation\r
+                               Obuhovskoy Oborony 120-B\r
+                               Saint Petersburg  Saint Petersburg  192012\r
+                               RU\r
+\r
+70-B3-D5   (hex)               SENSO2ME \r
+631000-631FFF     (base 16)            SENSO2ME \r
+                               Zandhoef  16\r
+                               KASTERLEE  België  2460\r
+                               BE\r
+\r
+70-B3-D5   (hex)               Infodev Electronic Designers Intl.\r
+DBF000-DBFFFF     (base 16)            Infodev Electronic Designers Intl.\r
+                               1995 rue Frank-Carrel Suite 202\r
+                               Quebec  Quebec  G1N4H9\r
+                               CA\r
+\r
+70-B3-D5   (hex)               SENSO2ME \r
+F7A000-F7AFFF     (base 16)            SENSO2ME \r
+                               Zandhoef  16\r
+                               KASTERLEE  België  2460\r
+                               BE\r
+\r
+70-B3-D5   (hex)               KOSMEK.Ltd\r
+BB9000-BB9FFF     (base 16)            KOSMEK.Ltd\r
+                               Murodani 2-1-5, Nishi-ku\r
+                               Kobe-City  Hyogo Pref.  6512241\r
+                               JP\r
+\r
+70-B3-D5   (hex)               Quantum Opus, LLC\r
+602000-602FFF     (base 16)            Quantum Opus, LLC\r
+                               45211 Helm St\r
+                               Plymouth  MI  48170\r
+                               US\r
+\r
 70-B3-D5   (hex)               Innitive B.V.\r
 66B000-66BFFF     (base 16)            Innitive B.V.\r
                                Brouwerijstraat 20\r
@@ -9902,12 +10295,6 @@ B44000-B44FFF     (base 16)             ENTEC Electric & Electronic Co., LTD.
                                London     NW1 5QP \r
                                GB\r
 \r
-70-B3-D5   (hex)               Vtron Pty Ltd\r
-3EF000-3EFFFF     (base 16)            Vtron Pty Ltd\r
-                               Unit 6, 59 Township Drive\r
-                               West Burleigh  Queensland  4219\r
-                               AU\r
-\r
 70-B3-D5   (hex)               Morgan Schaffer Inc.\r
 7C2000-7C2FFF     (base 16)            Morgan Schaffer Inc.\r
                                8300 rue St-Patrick bureau 150\r
@@ -10925,6 +11312,54 @@ BA2000-BA2FFF     (base 16)            MAMAC Systems, Inc.
                                Chanhassen    55317-8002\r
                                US\r
 \r
+70-B3-D5   (hex)               Vtron Pty Ltd\r
+3EF000-3EFFFF     (base 16)            Vtron Pty Ltd\r
+                               Unit 2, 62 Township Drive West\r
+                               West Burleigh  Queensland  4219\r
+                               AU\r
+\r
+70-B3-D5   (hex)               ELVA-1 MICROWAVE HANDELSBOLAG\r
+FA3000-FA3FFF     (base 16)            ELVA-1 MICROWAVE HANDELSBOLAG\r
+                               c/o Hornlund, Kungsgatan 54\r
+                               Furulund    244 62\r
+                               SE\r
+\r
+70-B3-D5   (hex)               Collini Dienstleistungs GmbH\r
+C67000-C67FFF     (base 16)            Collini Dienstleistungs GmbH\r
+                               Schweizerstr. 59\r
+                               Hohenems    A 6845\r
+                               AT\r
+\r
+70-B3-D5   (hex)               Richard Paul Russell Ltd\r
+98B000-98BFFF     (base 16)            Richard Paul Russell Ltd\r
+                               The Lodge, Unit 1 Barnes Farm Business Park\r
+                               Milford on Sea  Hampshire  SO41 0AP\r
+                               GB\r
+\r
+70-B3-D5   (hex)               Association Romandix\r
+AEB000-AEBFFF     (base 16)            Association Romandix\r
+                               rue de Sebeillon 9b\r
+                               Lausanne  Vaud  1004\r
+                               CH\r
+\r
+70-B3-D5   (hex)               Special Services Group, LLC\r
+0F8000-0F8FFF     (base 16)            Special Services Group, LLC\r
+                               PO Box 825\r
+                               Denair  CA  95316\r
+                               US\r
+\r
+70-B3-D5   (hex)               Divigraph (Pty) LTD\r
+A86000-A86FFF     (base 16)            Divigraph (Pty) LTD\r
+                                Postnet Suite 72, Private Bag X7\r
+                               Chempet    7442\r
+                               ZA\r
+\r
+70-B3-D5   (hex)               Tunstall A/S\r
+A17000-A17FFF     (base 16)            Tunstall A/S\r
+                               Niels Bohrs vej 42\r
+                               Stilling  Skanderborg  8660\r
+                               DK\r
+\r
 70-B3-D5   (hex)               Saline Lectronics, Inc.\r
 246000-246FFF     (base 16)            Saline Lectronics, Inc.\r
                                710 N Maple Rd\r
@@ -11009,6 +11444,84 @@ FD6000-FD6FFF     (base 16)            Visual Fan
                                Anyang-si  Gyeonggi-do  14067\r
                                KR\r
 \r
+70-B3-D5   (hex)               FactoryLab B.V.\r
+5DC000-5DCFFF     (base 16)            FactoryLab B.V.\r
+                               Lindtsedijk 54\r
+                               Zwijndrecht  Zuid Holland  3336LE\r
+                               NL\r
+\r
+70-B3-D5   (hex)               True Networks Ltd.\r
+AF2000-AF2FFF     (base 16)            True Networks Ltd.\r
+                               #401 51 Seongnam-Daero Bundang-gu\r
+                               SEONGNAM-si  GYEONGGI-do  13636\r
+                               KR\r
+\r
+70-B3-D5   (hex)               Storbyte, Inc.\r
+63D000-63DFFF     (base 16)            Storbyte, Inc.\r
+                               1800 Washington Blvd Suite 412\r
+                               Baltimore  MD  21230\r
+                               US\r
+\r
+70-B3-D5   (hex)               HGH SYSTEMES INFRAROUGES\r
+853000-853FFF     (base 16)            HGH SYSTEMES INFRAROUGES\r
+                               10 Rue Maryse Bastié\r
+                               Igny  IDF  91430\r
+                               FR\r
+\r
+70-B3-D5   (hex)               Shenzhen bayue software co. LTD\r
+784000-784FFF     (base 16)            Shenzhen bayue software co. LTD\r
+                               B301, second phase of China merchants street technology building, nanshan district\r
+                               ShenZhen    518000\r
+                               CN\r
+\r
+70-B3-D5   (hex)               Preston Industries dba PolyScience\r
+3B5000-3B5FFF     (base 16)            Preston Industries dba PolyScience\r
+                               6600 W. Touhy Ave\r
+                               Niles  IL  60714-4588\r
+                               US\r
+\r
+70-B3-D5   (hex)               KMtronic ltd\r
+0AF000-0AFFFF     (base 16)            KMtronic ltd\r
+                               Dobri Czintulov 28A str.\r
+                                Gorna Oryahovica  VT  5100\r
+                               BG\r
+\r
+70-B3-D5   (hex)               BLOCKSI LLC\r
+9E6000-9E6FFF     (base 16)            BLOCKSI LLC\r
+                               228 Hamilton avenue 3rd floor\r
+                               Palo Alto    94301\r
+                               US\r
+\r
+70-B3-D5   (hex)               Fire4 Systems UK Ltd\r
+E69000-E69FFF     (base 16)            Fire4 Systems UK Ltd\r
+                               8 Regent Street\r
+                               Leeds  West Yorkshire  LS7 4PE\r
+                               GB\r
+\r
+70-B3-D5   (hex)               RealD\r
+CCB000-CCBFFF     (base 16)            RealD\r
+                               5700 Flatiron Parkway\r
+                               Boulder  CO  80301\r
+                               US\r
+\r
+70-B3-D5   (hex)               Melecs EWS GmbH\r
+704000-704FFF     (base 16)            Melecs EWS GmbH\r
+                               GZO-Technologiestrasse 1\r
+                               Siegendorf     7011\r
+                               AT\r
+\r
+70-B3-D5   (hex)               Raft Technologies\r
+8D0000-8D0FFF     (base 16)            Raft Technologies\r
+                               Habarzel 25\r
+                               Tel aviv    6971035\r
+                               IL\r
+\r
+70-B3-D5   (hex)               Jacarta Ltd\r
+09B000-09BFFF     (base 16)            Jacarta Ltd\r
+                               Wagon Yard, London Road\r
+                               Marlborough    SN8 1LH\r
+                               GB\r
+\r
 70-B3-D5   (hex)               EMAC, Inc.\r
 8AB000-8ABFFF     (base 16)            EMAC, Inc.\r
                                2390 EMAC Way\r
@@ -11378,12 +11891,6 @@ A27000-A27FFF     (base 16)            HDL da Amazônia Industria Eletrônica Ltda
                                Manaus  MN  69075-010\r
                                BR\r
 \r
-70-B3-D5   (hex)               Insitu Inc\r
-7AD000-7ADFFF     (base 16)            Insitu Inc\r
-                               118 E. Columbia River Way\r
-                               Bingen  Washington  98605\r
-                               US\r
-\r
 70-B3-D5   (hex)               LLVISION TECHNOLOGY CO.,LTD\r
 E21000-E21FFF     (base 16)            LLVISION TECHNOLOGY CO.,LTD\r
                                Room302,Building A Fuxing,No.30 He Tao Yuan,Guan Dong Dian Bei Jie\r
@@ -13699,3 +14206,123 @@ EF9000-EF9FFF     (base 16)           Critical Link LLC
                                Av. Onze de Setembre 19\r
                                Reus  Tarragona  43203\r
                                ES\r
+\r
+70-B3-D5   (hex)               Triax A/S\r
+963000-963FFF     (base 16)            Triax A/S\r
+                               Bjornkaervej 3\r
+                               Hornsyld  Denmark  8783\r
+                               DK\r
+\r
+70-B3-D5   (hex)               White Matter LLC\r
+368000-368FFF     (base 16)            White Matter LLC\r
+                               999 3rd Ave 700\r
+                               Seattle    98104\r
+                               US\r
+\r
+70-B3-D5   (hex)               iFreecomm Technology Co., Ltd\r
+032000-032FFF     (base 16)            iFreecomm Technology Co., Ltd\r
+                               D401, NO.16 Langshan Road, Nanshan District\r
+                               Shenzhen  Guangdong  518057\r
+                               CN\r
+\r
+70-B3-D5   (hex)               RELISTE Ges.m.b.H.\r
+1B9000-1B9FFF     (base 16)            RELISTE Ges.m.b.H.\r
+                               Enzersdorfer Strasse 8-10\r
+                               Brunn am Gebirge    2345\r
+                               AT\r
+\r
+70-B3-D5   (hex)               JUSTEK INC\r
+EB5000-EB5FFF     (base 16)            JUSTEK INC\r
+                               613-9, DONGCHUN-RI, JINWI-MYEON\r
+                               PYEONGTAEK-SI  GYEONGGI-DO  17711\r
+                               KR\r
+\r
+70-B3-D5   (hex)               SHENZHEN WISEWING INTERNET TECHNOLOGY CO.,LTD\r
+94A000-94AFFF     (base 16)            SHENZHEN WISEWING INTERNET TECHNOLOGY CO.,LTD\r
+                               No.826,Zone 1,Block B,Famous industrial product display purchasing center,Baoyuan Road,Xixiang,Bao'an Dis., Shenzhen,P.R.China\r
+                               shenzhen  China  518102\r
+                               CN\r
+\r
+70-B3-D5   (hex)               Mo-Sys Engineering Ltd\r
+075000-075FFF     (base 16)            Mo-Sys Engineering Ltd\r
+                               Thames Bank House, Tunnel Avenue\r
+                               London    SE100PA\r
+                               GB\r
+\r
+70-B3-D5   (hex)               Abbas, a.s.\r
+B18000-B18FFF     (base 16)            Abbas, a.s.\r
+                               Edisonova 5\r
+                               Brno  CZ  61200\r
+                               CZ\r
+\r
+70-B3-D5   (hex)               Shanghai Holystar Information Technology Co.,Ltd\r
+6E1000-6E1FFF     (base 16)            Shanghai Holystar Information Technology Co.,Ltd\r
+                               8F Building A3 NO.1528 Gumei Rd Shanghai China PR\r
+                               shanghai    200233\r
+                               CN\r
+\r
+70-B3-D5   (hex)               Mimo Networks\r
+25D000-25DFFF     (base 16)            Mimo Networks\r
+                               701 E Middlefield Road Mountain View, \r
+                               Mountain View  CA  94043\r
+                               US\r
+\r
+70-B3-D5   (hex)               ATBiS Co.,Ltd\r
+C2F000-C2FFFF     (base 16)            ATBiS Co.,Ltd\r
+                               #1603 5th. Ace High-end Tower, 226 Gasan Digital 1-ro, Geumcheon-gu\r
+                               Seoul    08502\r
+                               KR\r
+\r
+70-B3-D5   (hex)               Cyanview\r
+E3A000-E3AFFF     (base 16)            Cyanview\r
+                               26, Rue de la Foire\r
+                               Papignies    7861\r
+                               BE\r
+\r
+70-B3-D5   (hex)               AdInte, inc.\r
+BAC000-BACFFF     (base 16)            AdInte, inc.\r
+                               347-1, Shijo-cho, Shimogyo-ku, 7F CUBE Nishikarasuma BLDG.\r
+                               Kyoto-shi  Kyoto  6008441\r
+                               JP\r
+\r
+70-B3-D5   (hex)               Valk Welding B.V.\r
+5DA000-5DAFFF     (base 16)            Valk Welding B.V.\r
+                               Staalindustrieweg 15\r
+                               Alblasserdam  Zuid Holland  2952 AT\r
+                               NL\r
+\r
+70-B3-D5   (hex)               VITEC\r
+CDA000-CDAFFF     (base 16)            VITEC\r
+                               99 rue pierre sémard\r
+                               Chatillon  France  92320\r
+                               FR\r
+\r
+70-B3-D5   (hex)               Nortek Global HVAC\r
+4D4000-4D4FFF     (base 16)            Nortek Global HVAC\r
+                               Fens Pool Ave\r
+                               Brierley Hill  West Midlands  DY5 1QA\r
+                               GB\r
+\r
+70-B3-D5   (hex)               Insitu, Inc\r
+7AD000-7ADFFF     (base 16)            Insitu, Inc\r
+                               118 E Columbia River Way\r
+                               Bingen  WA  98605\r
+                               US\r
+\r
+70-B3-D5   (hex)               KWS-Electronic GmbH\r
+EB3000-EB3FFF     (base 16)            KWS-Electronic GmbH\r
+                               Sportplatzstrasse 1\r
+                               Grosskarolinenfeld    D-83109\r
+                               DE\r
+\r
+70-B3-D5   (hex)               University Of Groningen\r
+700000-700FFF     (base 16)            University Of Groningen\r
+                               Broerstraat 5\r
+                               Groningen  Groningen  9712 CP\r
+                               NL\r
+\r
+70-B3-D5   (hex)               Globalcom Engineering SPA\r
+A0D000-A0DFFF     (base 16)            Globalcom Engineering SPA\r
+                               Via Volta 39\r
+                               CARDANO AL CAMPO  VA  21010\r
+                               IT\r
index a517503..d333ee6 100644 (file)
@@ -1,3 +1,20 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
+# Copyright 2017 Zbigniew Jędrzejewski-Szmek
+#
+# 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.
+#
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
 hwdb_files = files('''
         20-pci-vendor-model.hwdb
         20-pci-classes.hwdb
index a25ac8d..f4cc9c6 100755 (executable)
@@ -1,5 +1,6 @@
 #!/usr/bin/env python3
 # -*- Mode: python; coding: utf-8; indent-tabs-mode: nil -*- */
+#  SPDX-License-Identifier: MIT
 #
 # This file is part of systemd. It is distrubuted under the MIT license, see
 # below.
@@ -65,6 +66,7 @@ UDEV_TAG = Word(string.ascii_uppercase, alphanums + '_')
 
 TYPES = {'mouse':    ('usb', 'bluetooth', 'ps2', '*'),
          'evdev':    ('name', 'atkbd', 'input'),
+         'id-input': ('modalias'),
          'touchpad': ('i8042', 'rmi', 'bluetooth', 'usb'),
          'joystick': ('i8042', 'rmi', 'bluetooth', 'usb'),
          'keyboard': ('name', ),
@@ -105,6 +107,18 @@ def property_grammar():
              ('MOUSE_WHEEL_CLICK_ANGLE_HORIZONTAL', INTEGER),
              ('MOUSE_WHEEL_CLICK_COUNT', INTEGER),
              ('MOUSE_WHEEL_CLICK_COUNT_HORIZONTAL', INTEGER),
+             ('ID_INPUT', Literal('1')),
+             ('ID_INPUT_ACCELEROMETER', Literal('1')),
+             ('ID_INPUT_JOYSTICK', Literal('1')),
+             ('ID_INPUT_KEY', Literal('1')),
+             ('ID_INPUT_KEYBOARD', Literal('1')),
+             ('ID_INPUT_MOUSE', Literal('1')),
+             ('ID_INPUT_POINTINGSTICK', Literal('1')),
+             ('ID_INPUT_SWITCH', Literal('1')),
+             ('ID_INPUT_TABLET', Literal('1')),
+             ('ID_INPUT_TABLET_PAD', Literal('1')),
+             ('ID_INPUT_TOUCHPAD', Literal('1')),
+             ('ID_INPUT_TOUCHSCREEN', Literal('1')),
              ('ID_INPUT_TRACKBALL', Literal('1')),
              ('MOUSE_WHEEL_TILT_HORIZONTAL', Literal('1')),
              ('MOUSE_WHEEL_TILT_VERTICAL', Literal('1')),
index be21887..f749ba4 100644 (file)
@@ -1,8 +1,8 @@
 #
 #      List of PCI ID's
 #
-#      Version: 2017.09.26
-#      Date:    2017-09-26 03:15:02
+#      Version: 2017.12.06
+#      Date:    2017-12-06 03:15:02
 #
 #      Maintained by Albert Pool, Martin Mares, and other volunteers from
 #      the PCI ID Project at http://pci-ids.ucw.cz/.
 0b0b  Rhino Equipment Corp.
        0105  R1T1
        0205  R4FXO
-       0206  RCB4FXO 4-channel FXO analog telphony card
+       0206  RCB4FXO 4-channel FXO analog telephony card
        0305  R4T1
        0405  R8FXX
-       0406  RCB8FXX 8-channel modular analog telphony card
+       0406  RCB8FXX 8-channel modular analog telephony card
        0505  R24FXX
-       0506  RCB24FXS 24-Channel FXS analog telphony card
+       0506  RCB24FXS 24-Channel FXS analog telephony card
        0605  R2T1
        0705  R24FXS
-       0706  RCB24FXO 24-Channel FXO analog telphony card
+       0706  RCB24FXO 24-Channel FXO analog telephony card
        0905  R1T3 Single T3 Digital Telephony Card
-       0906  RCB24FXX 24-channel modular analog telphony card
-       0a06  RCB672FXX 672-channel modular analog telphony card
+       0906  RCB24FXX 24-channel modular analog telephony card
+       0a06  RCB672FXX 672-channel modular analog telephony card
 0e11  Compaq Computer Corporation
        0001  PCI to EISA Bridge
        0002  PCI to ISA Bridge
                1028 1fd4  PERC H745P MX
                1d49 0602  ThinkSystem RAID 930-16i 4GB Flash PCIe 12Gb Adapter
                1d49 0604  ThinkSystem RAID 930-8e 4GB Flash PCIe 12Gb Adapter
+               8086 352d  Integrated RAID Module RMSP3AD160F
+               8086 9460  RAID Controller RSP3TD160F
+               8086 9480  RAID Controller RSP3MD088F
        0015  MegaRAID Tri-Mode SAS3416
        0016  MegaRAID Tri-Mode SAS3508
                1028 1fc9  PERC H840 Adapter
                1d49 0601  ThinkSystem RAID 930-8i 2GB Flash PCIe 12Gb Adapter
                1d49 0603  ThinkSystem RAID 930-24i 4GB Flash PCIe 12Gb Adapter
                1d49 0604  ThinkSystem RAID 930-8e 4GB Flash PCIe 12Gb Adapter
+               8086 352e  Integrated RAID Module RMSP3CD080F
+               8086 352f  Integrated RAID Module RMSP3HD080E
+               8086 9461  RAID Controller RSP3DD080F
        0017  MegaRAID Tri-Mode SAS3408
                1d49 0500  ThinkSystem RAID 530-8i PCIe 12Gb Adapter
                1d49 0502  ThinkSystem RAID 530-8i Dense Adapter
+               8086 3528  Integrated RAID RMSP3LD060
+               8086 3529  Integrated RAID RMSP3LD060
+               8086 9441  RAID Controller RSP3WD080E
        001b  MegaRAID Tri-Mode SAS3504
                1d49 0605  ThinkSystem RAID 930-4i 2GB Flash Flex Adapter
        001c  MegaRAID Tri-Mode SAS3404
                1028 1fd3  HBA330 MMZ
                1bd4 0011  Inspur 12Gb 8i-3008 IT SAS HBA
        00ab  SAS3516 Fusion-MPT Tri-Mode RAID On Chip (ROC)
+               8086 3530  Integrated RAID Module RMSP3JD160J
        00ac  SAS3416 Fusion-MPT Tri-Mode I/O Controller Chip (IOC)
                1d49 0201  ThinkSystem 430-16i SAS/SATA 12Gb HBA
                1d49 0203  ThinkSystem 430-16e SAS/SATA 12Gb HBA
+               8086 3000  RAID Controller RSP3QD160J
+               8086 3020  RAID Controller RSP3GD016J
        00ae  SAS3508 Fusion-MPT Tri-Mode RAID On Chip (ROC)
        00af  SAS3408 Fusion-MPT Tri-Mode I/O Controller Chip (IOC)
                1d49 0200  ThinkSystem 430-8i SAS/SATA 12Gb HBA
        131b  Kaveri [Radeon R4 Graphics]
        131c  Kaveri [Radeon R7 Graphics]
        131d  Kaveri [Radeon R6 Graphics]
+       15dd  Radeon Vega 8 Mobile
        1714  BeaverCreek HDMI Audio [Radeon HD 6500D and 6400G-6600G series]
                103c 168b  ProBook 4535s
        3150  RV380/M24 [Mobility Radeon X600]
                1043 836c  M4A785TD Motherboard
                1043 8410  M4A89GTD PRO/USB3 Motherboard
                1043 841b  M5A88-V EVO
+               105b 0e13  N15235/A74MX mainboard / AMD SB700
                1179 ff50  Satellite P305D-S8995E
                1458 a022  GA-MA770-DS3rev2.0 Motherboard
                17f2 5000  KI690-AM2 Motherboard
                103c 280a  DC5750 Microtower
                1043 82ef  M3A78-EH Motherboard
                1043 8389  M4A785TD Motherboard
+               105b 0e13  N15235/A74MX mainboard / AMD SB700
                1179 ff50  Satellite P305D-S8995E
                1458 4385  GA-MA770-DS3rev2.0 Motherboard
                1462 7368  K9AG Neo2
        4390  SB7x0/SB8x0/SB9x0 SATA Controller [IDE mode]
                1043 82ef  M3A78-EH Motherboard
                1043 8389  M4A785TD Motherboard
+               105b 0e13  N15235/A74MX mainboard / AMD SB700
                1458 b002  GA-MA770-DS3rev2.0 Motherboard
                1849 4390  Motherboard (one of many)
        4391  SB7x0/SB8x0/SB9x0 SATA Controller [AHCI mode]
                103c 1611  Pavilion DM1Z-3000
                1043 82ef  M3A78-EH Motherboard
                1043 8443  M5A88-V EVO
+               105b 0e13  N15235/A74MX mainboard / AMD SB700
                174b 1001  PURE Fusion Mini
        4392  SB7x0/SB8x0/SB9x0 SATA Controller [Non-RAID5 mode]
+               105b 0e13  N15235/A74MX mainboard / AMD SB700
        4393  SB7x0/SB8x0/SB9x0 SATA Controller [RAID5 mode]
        4394  SB7x0/SB8x0/SB9x0 SATA Controller [AHCI mode]
        4395  SB8x0/SB9x0 SATA Controller [Storage mode]
                103c 1611  Pavilion DM1Z-3000
                1043 82ef  M3A78-EH Motherboard
                1043 8443  M5A88-V EVO
+               105b 0e13  N15235/A74MX mainboard / AMD SB700
                15d9 a811  H8DGU
                174b 1001  PURE Fusion Mini
        4397  SB7x0/SB8x0/SB9x0 USB OHCI0 Controller
                103c 1611  Pavilion DM1Z-3000
                1043 82ef  M3A78-EH Motherboard
                1043 8443  M5A88-V EVO
+               105b 0e13  N15235/A74MX mainboard / AMD SB700
                15d9 a811  H8DGU
                174b 1001  PURE Fusion Mini
        4398  SB7x0 USB OHCI1 Controller
                1019 2120  A785GM-M
                1043 82ef  M3A78-EH Motherboard
+               105b 0e13  N15235/A74MX mainboard / AMD SB700
                15d9 a811  H8DGU
        4399  SB7x0/SB8x0/SB9x0 USB OHCI2 Controller
                1019 2120  A785GM-M
                1043 82ef  M3A78-EH Motherboard
                1043 8443  M5A88-V EVO
+               105b 0e13  N15235/A74MX mainboard / AMD SB700
                174b 1001  PURE Fusion Mini
        439c  SB7x0/SB8x0/SB9x0 IDE Controller
                1019 2120  A785GM-M
                1043 82ef  M3A78-EH Motherboard
+               105b 0e13  N15235/A74MX mainboard / AMD SB700
        439d  SB7x0/SB8x0/SB9x0 LPC host controller
                1019 2120  A785GM-M
                103c 1611  Pavilion DM1Z-3000
                1043 82ef  M3A78-EH Motherboard
                1043 8443  M5A88-V EVO
+               105b 0e13  N15235/A74MX mainboard / AMD SB700
                174b 1001  PURE Fusion Mini
        43a0  SB700/SB800/SB900 PCI to PCI bridge (PCIE port 0)
        43a1  SB700/SB800/SB900 PCI to PCI bridge (PCIE port 1)
                103c 8006  FirePro M4170
                17aa 3643  Radeon R7 A360
        6605  Opal PRO [Radeon R7 M260]
+               103c 2259  FirePro M4150
        6606  Mars XTX [Radeon HD 8790M]
                1028 0684  FirePro W4170M
        6607  Mars LE [Radeon HD 8530M / R5 M240]
        6623  Mars
        6631  Oland
        6640  Saturn XT [FirePro M6100]
+               106b 014b  Tropo XT [Radeon R9 M380 Mac Edition]
        6641  Saturn PRO [Radeon HD 8930M]
        6646  Bonaire XT [Radeon R9 M280X]
        6647  Bonaire PRO [Radeon R9 M270X]
        6828  Cape Verde PRO [FirePro W600]
        6829  Cape Verde
        682a  Venus PRO
-       682b  Venus LE [Radeon HD 8830M]
+       682b  Venus LE / Tropo PRO-L [Radeon HD 8830M / R7 M465X]
+               0128 079c  Radeon R7 465X
        682c  Cape Verde GL [FirePro W4100]
        682d  Chelsea XT GL [FirePro M4000]
        682f  Chelsea LP [Radeon HD 7730M]
                144d c0c7  Radeon HD 7550M
        6842  Thames LE [Radeon HD 7000M Series]
        6843  Thames [Radeon HD 7670M]
+       6861  Vega 10 XT [Radeon PRO WX 9100]
        6863  Vega 10 XTX [Radeon Vega Frontier Edition]
        687f  Vega 10 XT [Radeon RX Vega 64]
        6888  Cypress XT [FirePro V8800]
        7910  RS690 Host Bridge
                1179 ff50  Satellite P305D-S8995E
                17f2 5000  KI690-AM2 Motherboard
-       7911  RS690 Host Bridge
-       7912  RS690 PCI to PCI Bridge (Internal gfx)
+       7911  RS690/RS740 Host Bridge
+               1002 7910  RS690/RS740 Host Bridge
+       7912  RS690/RS740 PCI to PCI Bridge (Internal gfx)
        7913  RS690 PCI to PCI Bridge (PCI Express Graphics Port 0)
        7915  RS690 PCI to PCI Bridge (PCI Express Port 1)
        7916  RS690 PCI to PCI Bridge (PCI Express Port 2)
        7941  RS600 [Radeon Xpress 1250]
        7942  RS600M [Radeon Xpress 1250]
        796e  RS740 [Radeon 2100]
+               105b 0e13  N15235/A74MX mainboard
        9400  R600 [Radeon HD 2900 PRO/XT]
                1002 2552  Radeon HD 2900 XT
                1002 3000  Radeon HD 2900 PRO
        9840  Kabini HDMI/DP Audio
        9850  Mullins [Radeon R3 Graphics]
        9851  Mullins [Radeon R4/R5 Graphics]
+               1179 f928  Beema [Radeon R5 Graphics]
        9852  Mullins [Radeon R2 Graphics]
        9853  Mullins [Radeon R2 Graphics]
        9854  Mullins [Radeon R3E Graphics]
        141f  Family 15h (Models 30h-3fh) Processor Function 5
        1422  Family 15h (Models 30h-3fh) Processor Root Complex
        1423  Family 15h (Models 30h-3fh) I/O Memory Management Unit
+       1424  Family 15h (Models 30h-3fh) Processor Root Port
        1426  Family 15h (Models 30h-3fh) Processor Root Port
        1436  Liverpool Processor Root Complex
        1437  Liverpool I/O Memory Management Unit
        1438  Liverpool Processor Root Port
        1439  Family 16h Processor Functions 5:1
        1450  Family 17h (Models 00h-0fh) Root Complex
+       1451  Family 17h (Models 00h-0fh) I/O Memory Management Unit
        1452  Family 17h (Models 00h-0fh) PCIe Dummy Host Bridge
+       1453  Family 17h (Models 00h-0fh) PCIe GPP Bridge
        1454  Family 17h (Models 00h-0fh) Internal PCIe GPP Bridge 0 to Bus B
+       1456  Family 17h (Models 00h-0fh) Platform Security Processor
+       1457  Family 17h (Models 00h-0fh) HD Audio Controller
        145b  Zeppelin Non-Transparent Bridge
-       145c  USB3 Host Controller
+       145c  Family 17h (Models 00h-0fh) USB 3.0 Host Controller
        145f  USB 3.0 Host controller
        1460  Family 17h (Models 00h-0fh) Data Fabric: Device 18h; Function 0
        1461  Family 17h (Models 00h-0fh) Data Fabric: Device 18h; Function 1
        43a1  Hudson PCI to PCI bridge (PCIE port 1)
        43a2  Hudson PCI to PCI bridge (PCIE port 2)
        43a3  Hudson PCI to PCI bridge (PCIE port 3)
-       43bb  USB 3.1 XHCI Controller
+       43b4  300 Series Chipset PCIe Port
+       43b7  300 Series Chipset SATA Controller
+       43bb  300 Series Chipset USB 3.1 xHCI Controller
        7006  AMD-751 [Irongate] System Controller
        7007  AMD-751 [Irongate] AGP Bridge
        700a  AMD-IGR4 AGP Host to PCI Bridge
                102b 0f84  Millennium G550 Dual Head DDR 32Mb
                102b 1e41  Millennium G550
                102b 2300  Millennium G550 LP PCIE
-       2537  Millenium P650/P750
+       2537  Millennium P650/P750
                102b 1820  Millennium P750 64MB
                102b 1830  Millennium P650 64MB
                102b 1850  RAD2mp
                102b 1880  Sono S10
                102b 1c10  QID 128MB
                102b 2811  Millennium P650 Low-profile PCI 64MB
-               102b 2821  Millenium P650 Low-profile PCI
+               102b 2821  Millennium P650 Low-profile PCI
                102b 2841  RAD PCI
                102b 2851  Spectrum PCI
                102b 2871  EpicA TC2
                102b 3051  RG-400SL
                102b 3061  Extio F1420
                102b 3081  Extio F1240
-       2538  Millenium P650 PCIe
+       2538  Millennium P650 PCIe
                102b 0847  RAD PCIe
                102b 08c7  Millennium P650 PCIe 128MB
                102b 0907  Millennium P650 PCIe 64MB
                102b 0987  ATC PCIe 4MP
                102b 1047  Millennium P650 LP PCIe 128MB
                102b 1087  Millennium P650 LP PCIe 64MB
-               102b 1801  Millenium P650 PCIe x1
+               102b 1801  Millennium P650 PCIe x1
                102b 2538  Parhelia APVe
                102b 3007  QID Low-profile PCIe
                102b 3087  Aurora VX3mp
                102b 30c7  QID LP PCIe
        2539  Millennium P690
-               102b 0040  Millenium P690 PCIe x16
+               102b 0040  Millennium P690 PCIe x16
                102b 0042  ONYX
                102b 0043  SPECTRA
-               102b 0080  Millenium P690 Plus LP PCIe x16
-               102b 0081  Millenium P690 LP PCIe x16
+               102b 0080  Millennium P690 Plus LP PCIe x16
+               102b 0081  Millennium P690 LP PCIe x16
                102b 0082  RAD LPX PCIe x16
-               102b 00c0  Millenium P690 Plus LP PCI
-               102b 00c2  Millenium P690 LP PCI
+               102b 00c0  Millennium P690 Plus LP PCI
+               102b 00c2  Millennium P690 LP PCI
                102b 00c3  RAD LPX PCI
-               102b 0101  Millenium P690 PCI
-               102b 0140  Millenium P690 LP PCIe x1
+               102b 0101  Millennium P690 PCI
+               102b 0140  Millennium P690 LP PCIe x1
                102b 0180  Display Wall IP Decode 128 MB
        4164  Morphis QxT frame grabber
        43b4  Morphis Qxt encoding engine
        3308  Integrated Lights-Out Standard MS Watchdog Timer
                103c 330e  iLO3
                103c 3381  iLO4
-       402f  PCIe Root Port
        4030  zx2 System Bus Adapter
        4031  zx2 I/O Controller
        4037  PCIe Local Bus Adapter
-       403b  PCIe Root Port
 103e  Solliday Engineering
 103f  Synopsys/Logic Modeling Group
 1040  Accelgraphics Inc.
        3020  Samurai_IDE
 1043  ASUSTeK Computer Inc.
        0464  Radeon R9 270x GPU
+       0521  RX580 [RX 580 Dual O8G]
        0675  ISDNLink P-IN100-ST-D
                0675 1704  ISDN Adapter (PCI Bus, D, C)
                0675 1707  ISDN Adapter (PCI Bus, DV, W)
                10cf 105e  ISDN Adapter (PCI Bus, DV, W)
-       13a0  Transformer Book T101HA-GR030R
 # Should be 1022:9602
        9602  AMD RS780/RS880 PCI to PCI bridge (int gfx)
                1043 83a2  M4A785TD Motherboard
                103c 12dd  4Gb Fibre Channel [AB429A]
        2432  ISP2432-based 4Gb Fibre Channel to PCI Express HBA
                103c 7040  FC1142SR 4Gb 1-port PCIe Fibre Channel Host Bus Adapter [HPAE311A]
+               1077 0137  QLE2460 4 GB PCI-X Host-Bus-Adapter
        2532  ISP2532-based 8Gb Fibre Channel to PCI Express HBA
                1014 041e  FC EN0Y/EN12 PCIe2 LP 8 Gb 4-port Fibre Channel Adapter for POWER
                103c 3262  StorageWorks 81Q
                1077 015e  QLE2564 PCI Express to 8Gb FC Quad Channel
                1077 0167  QME2572 Dual Port FC8 HBA Mezzanine
                1590 00fc  StoreFabric 84Q 8Gb Quad Port Fibre Channel Host Bus Adapter
+       2971  ISP2684
        3022  ISP4022-based Ethernet NIC
        3032  ISP4032-based Ethernet IPv6 NIC
        4010  ISP4010-based iSCSI TOE HBA
                1077 000b  25GE 2P QL41262HxCU-DE Adapter
                1077 0011  FastLinQ QL41212H 25GbE Adapter
                1077 0012  FastLinQ QL41112H 10GbE Adapter
+               1590 021d  10/25GbE 2P QL41222HLCU-HP Adapter
+               1590 021e  10/25GbE 2P QL41162HMRJ-HP Adapter
+               1590 021f  10/25GbE 2P QL41262HMCU-HP Adapter
+               1590 0220  10/25GbE 2P QL41122HLRJ-HP Adapter
        8080  FastLinQ QL41000 Series 10/25/40/50GbE Controller (FCoE)
                1077 0001  10GE 2P QL41162HxRJ-DE Adapter
                1077 0002  10GE 2P QL41112HxCU-DE Adapter
                1077 000e  FastLinQ QL41162H 10GbE iSCSI Adapter (SR-IOV VF)
                1077 0011  FastLinQ QL41212H 25GbE Adapter (SR-IOV VF)
                1077 0012  FastLinQ QL41112H 10GbE Adapter (SR-IOV VF)
+               1590 021e  10/25GbE 2P QL41162HMRJ-HP Adapter
+               1590 021f  10/25GbE 2P QL41262HMCU-HP Adapter
        8430  ISP8324 1/10GbE Converged Network Controller (NIC VF)
        8431  8300 Series 10GbE Converged Network Adapter (FCoE VF)
        8432  ISP2432M-based 10GbE Converged Network Adapter (CNA)
        0533  C67 [GeForce 7000M / nForce 610M]
        053a  C68 [GeForce 7050 PV / nForce 630a]
        053b  C68 [GeForce 7050 PV / nForce 630a]
-               1043 8308  M2N68-AM Motherbord
+               1043 8308  M2N68-AM Motherboard
        053e  C68 [GeForce 7025 / nForce 630a]
        0541  MCP67 Memory Controller
        0542  MCP67 SMBus
-               1043 8308  M2N68-AM Motherbord
+               1043 8308  M2N68-AM Motherboard
        0543  MCP67 Co-processor
        0547  MCP67 Memory Controller
-               1043 8308  M2N68-AM Motherbord
+               1043 8308  M2N68-AM Motherboard
                1849 0547  ALiveNF7G-HDready
        0548  MCP67 ISA Bridge
                1043 8308  M2N68-AM Motherboard
        054c  MCP67 Ethernet
-               1043 8308  M2N68-AM Motherbord
+               1043 8308  M2N68-AM Motherboard
                1849 054c  ALiveNF7G-HDready, MCP67 Gigabit Ethernet
        054d  MCP67 Ethernet
        054e  MCP67 Ethernet
        1282  GK208 [GeForce GT 640 Rev. 2]
        1284  GK208 [GeForce GT 630 Rev. 2]
        1286  GK208 [GeForce GT 720]
-       1287  GK208 [GeForce GT 730]
-       1288  GK208 [GeForce GT 720]
+       1287  GK208B [GeForce GT 730]
+       1288  GK208B [GeForce GT 720]
        1289  GK208 [GeForce GT 710]
-       128b  GK208 [GeForce GT 710B]
+       128b  GK208B [GeForce GT 710]
        1290  GK208M [GeForce GT 730M]
                103c 2afa  GeForce GT 730A
                103c 2b04  GeForce GT 730A
                17aa 367c  GeForce 710A
        1296  GK208M [GeForce 825M]
        1298  GK208M [GeForce GT 720M]
-       1299  GK208M [GeForce 920M]
+       1299  GK208BM [GeForce 920M]
                17aa 30bb  GeForce 920A
+               17aa 30df  GeForce 920A
                17aa 36a7  GeForce 920A
                17aa 36af  GeForce 920M
-       129a  GK208M [GeForce 910M]
+       129a  GK208BM [GeForce 910M]
        12a0  GK208
        12b9  GK208GLM [Quadro K610M]
        12ba  GK208GLM [Quadro K510M]
        13fb  GM204GLM [Quadro M5500]
        1401  GM206 [GeForce GTX 960]
        1402  GM206 [GeForce GTX 950]
-       1406  GM206 [GeForce GTX 960]
+       1406  GM206 [GeForce GTX 960 OEM]
        1407  GM206 [GeForce GTX 750 v2]
        1427  GM206M [GeForce GTX 965M]
        1430  GM206GL [Quadro M2000]
        15f1  GP100GL
        15f7  GP100GL [Tesla P100 PCIe 12GB]
        15f8  GP100GL [Tesla P100 PCIe 16GB]
-       15f9  GP100GL [Tesla P100 SMX2 16GB]
+       15f9  GP100GL [Tesla P100 SXM2 16GB]
        1617  GM204M [GeForce GTX 980M]
        1618  GM204M [GeForce GTX 970M]
        1619  GM204M [GeForce GTX 965M]
        1725  GP100
        172e  GP100
        172f  GP100
+       174d  GM108M [GeForce MX130]
+       174e  GM108M [GeForce MX110]
        17c2  GM200 [GeForce GTX TITAN X]
        17c8  GM200 [GeForce GTX 980 Ti]
        17f0  GM200GL [Quadro M6000]
        1b78  GP102GL
        1b80  GP104 [GeForce GTX 1080]
        1b81  GP104 [GeForce GTX 1070]
-       1b82  GP104
+       1b82  GP104 [GeForce GTX 1070 Ti]
        1b83  GP104
        1b84  GP104 [GeForce GTX 1060 3GB]
        1b87  GP104 [P104-100]
                1462 11e8  GeForce GTX 1070 Max-Q
                1462 11e9  GeForce GTX 1070 Max-Q
                1558 9501  GeForce GTX 1070 Max-Q
+       1bad  GP104 [GeForce GTX 1070 Engineering Sample]
        1bb0  GP104GL [Quadro P5000]
        1bb1  GP104GL [Quadro P4000]
        1bb3  GP104GL [Tesla P4]
-       1bb4  GP104GL
+       1bb4  GP104GL [Tesla P6]
+       1bb5  GP104GLM [Quadro P5200 Mobile]
        1bb6  GP104GLM [Quadro P5000 Mobile]
        1bb7  GP104GLM [Quadro P4000 Mobile]
                1462 11e9  Quadro P4000 Max-Q
        1c03  GP106 [GeForce GTX 1060 6GB]
        1c07  GP106 [P106-100]
        1c09  GP106 [P106-090]
-       1c20  GP106M [GeForce GTX 1060 Mobile 3GB]
+       1c20  GP106M [GeForce GTX 1060 Mobile]
                17aa 39b9  GeForce GTX 1060 Max-Q 3GB
        1c21  GP106M [GeForce GTX 1050 Ti Mobile]
        1c22  GP106M [GeForce GTX 1050 Mobile]
        1d01  GP108 [GeForce GT 1030]
        1d10  GP108M [GeForce MX150]
        1d81  GV100
+       1db1  GV100 [Tesla V100 SXM2]
+       1db4  GV100 [Tesla V100 PCIe]
 10df  Emulex Corporation
        0720  OneConnect NIC (Skyhawk)
                103c 1934  FlexFabric 20Gb 2-port 650M Adapter
                103c 21d4  StoreFabric CN1200E 10Gb Converged Network Adapter
                103c 220a  FlexFabric 10Gb 2-port 556FLR-SFP+ Adapter
                103c 803f  Ethernet 10Gb 2-port 557SFP+ Adapter
+               103c 8144  FlexFabric 10GB 2-port 556FLR-T Adapter
                17aa 1056  ThinkServer OCm14102-UX-L AnyFabric
                17aa 1057  ThinkServer OCm14104-UX-L AnyFabric
                17aa 1059  ThinkServer OCm14104-UT-L AnyFabric
        f111  Saturn-X LightPulse Fibre Channel Host Adapter
        f112  Saturn-X LightPulse Fibre Channel Host Adapter
        f180  LPSe12002 EmulexSecure Fibre Channel Adapter
+       f400  LPe36000 Fibre Channel Host Adapter [Prism]
+               10df f401  LPe35000 Fibre Channel Host Adapter [Prism]
+               10df f402  LPe35000 Fibre Channel Host Adapter [Prism]
        f700  LP7000 Fibre Channel Host Adapter
        f701  LP7000 Fibre Channel Host Adapter Alternate ID (JX1:2-3, JX2:1-2)
        f800  LP8000 Fibre Channel Host Adapter
        8129  RTL-8129
                10ec 8129  RT8129 Fast Ethernet Adapter
                11ec 8129  RTL8111/8168 PCIe Gigabit Ethernet (misconfigured)
-       8136  RTL8101/2/6E PCI Express Fast/Gigabit Ethernet controller
-               103c 1985  Pavilion 17-e163sg Notebook PC
+       8136  RTL8101/2/6E PCI Express Fast Ethernet controller
+               103c 1985  RTL8106E on Pavilion 17-e163sg Notebook PC
                103c 2a8c  Compaq 500B Microtower
                103c 2ab1  Pavilion p6774
                103c 30cc  Pavilion dv6700
                8e2e 7100  KF-230TX/2
                a0a0 0007  ALN-325C
        8167  RTL-8110SC/8169SC Gigabit Ethernet
+               105b 0e10  RTL-8110SC-GR on a N15235/A74MX mainboard
                1458 e000  GA-MA69G-S3H Motherboard
                1462 235c  P965 Neo MS-7235 mainboard
                1462 236c  945P Neo3-F motherboard
        8821  RTL8821AE 802.11ac PCIe Wireless Network Adapter
        b723  RTL8723BE PCIe Wireless Network Adapter
                10ec 8739  Dell Wireless 1801
+       c821  RTL8821CE 802.11ac PCIe Wireless Network Adapter
 10ed  Ascii Corporation
        7310  V7310
 10ee  Xilinx Corporation
                1131 4f61  Activy DVB-S Budget Rev GR
                1131 5f61  Activy DVB-T Budget
                114b 2003  DVRaptor Video Edit/Capture Card
+               1159 0040  MuTech M-Vision 500 (MV-500 rev. E)
+               1159 0050  MuTech M-Vision 500 (MV-500 rev. F)
                11bd 0006  DV500 Overlay
                11bd 000a  DV500 Overlay
                11bd 000f  DV500 Overlay
        3011  Tokenet/vg 1001/10m anylan
        9050  Lanfleet/Truevalue
        9051  Lanfleet/Truevalue
-1159  Mutech Corp
+1159  MuTech Corporation
        0001  MV-1000
        0002  MV-1500
 115a  Harlequin Ltd
 12d7  Biotronic SRL
 12d8  Pericom Semiconductor
        01a7  7C21P100 2-port PCI-X to PCI-X Bridge
+       2608  PI7C9X2G608GP PCIe2 6-Port/8-Lane Packet Switch
        400a  PI7C9X442SL PCI Express Bridge Port
        400e  PI7C9X442SL USB OHCI Controller
        400f  PI7C9X442SL USB EHCI Controller
        0040  QSC-200/300
        0050  ESC-100D
        0060  ESC-100M
-       00f0  MPAC-100 Syncronous Serial Card (Zilog 85230)
+       00f0  MPAC-100 Synchronous Serial Card (Zilog 85230)
        0170  QSCLP-100
        0180  DSCLP-100
        0190  SSCLP-100
 1392  Medialight Inc
 1393  Moxa Technologies Co Ltd
        0001  UC7000 Serial
-       1020  CP102 (2-port RS-232 PCI)
-       1021  CP102UL (2-port RS-232 Universal PCI)
-       1022  CP102U (2-port RS-232 Universal PCI)
+       1020  CP-102 (2-port RS-232 PCI)
+       1021  CP-102UL (2-port RS-232 Universal PCI)
+       1022  CP-102U (2-port RS-232 Universal PCI)
        1023  CP-102UF
        1024  CP-102E (2-port RS-232 Smart PCI Express Serial Board)
        1025  CP-102EL (2-port RS-232 Smart PCI Express Serial Board)
        1380  CP138U (8-port RS-232/422/485 Smart Universal PCI)
        1680  Smartio C168H/PCI
        1681  CP-168U V2 Smart Serial Board (8-port RS-232)
-       1682  CP168EL (8-port RS-232 Smart PCI Express)
+       1682  CP-168EL (8-port RS-232 Smart PCI Express)
        1683  CP-168EL-A (8-port RS-232 PCI Express Serial Board)
        2040  Intellio CP-204J
        2180  Intellio C218 Turbo PCI
                1043 838e  Virtuoso 66 (Xonar DS)
                1043 8428  Virtuoso 100 (Xonar Xense)
                1043 8467  CMI8786 (Xonar DG)
+               1043 8521  CMI8786 (Xonar DGX)
                1043 85f4  Virtuoso 100 (Xonar Essence STX II)
                13f6 8782  PCI 2.0 HD Audio
                13f6 ffff  CMI8787-HG2PCI
        50a7  T580-50A7 Unified Wire Ethernet Controller
        50a8  T580-50A8 Unified Wire Ethernet Controller
        50a9  T580-50A9 Unified Wire Ethernet Controller
+       50aa  T580-50AA Unified Wire Ethernet Controller
+       50ab  T520-50AB Unified Wire Ethernet Controller
        5401  T520-CR Unified Wire Ethernet Controller
        5402  T522-CR Unified Wire Ethernet Controller
        5403  T540-CR Unified Wire Ethernet Controller
        54a7  T580-50A7 Unified Wire Ethernet Controller
        54a8  T580-50A8 Unified Wire Ethernet Controller
        54a9  T580-50A9 Unified Wire Ethernet Controller
+       54aa  T580-50AA Unified Wire Ethernet Controller
+       54ab  T520-50AB Unified Wire Ethernet Controller
        5501  T520-CR Unified Wire Storage Controller
        5502  T522-CR Unified Wire Storage Controller
        5503  T540-CR Unified Wire Storage Controller
        56a7  T580-50A7 Unified Wire Storage Controller
        56a8  T580-50A8 Unified Wire Storage Controller
        56a9  T580-50A9 Unified Wire Storage Controller
+       56aa  T580-50AA Unified Wire Storage Controller
+       56ab  T520-50AB Unified Wire Storage Controller
        5701  T520-CR Unified Wire Ethernet Controller
        5702  T522-CR Unified Wire Ethernet Controller
        5703  T540-CR Unified Wire Ethernet Controller
        58a7  T580-50A7 Unified Wire Ethernet Controller [VF]
        58a8  T580-50A8 Unified Wire Ethernet Controller [VF]
        58a9  T580-50A9 Unified Wire Ethernet Controller [VF]
+       58aa  T580-50AA Unified Wire Ethernet Controller [VF]
+       58ab  T520-50AB Unified Wire Ethernet Controller [VF]
        6001  T6225-CR Unified Wire Ethernet Controller
        6002  T6225-SO-CR Unified Wire Ethernet Controller
        6003  T6425-CR Unified Wire Ethernet Controller
        6082  T6225-6082 Unified Wire Ethernet Controller
        6083  T62100-6083 Unified Wire Ethernet Controller
        6084  T64100-6084 Unified Wire Ethernet Controller
+       6085  T6240-6085 Unified Wire Ethernet Controller
+       6086  T6225-6086 Unified Wire Ethernet Controller
        6401  T6225-CR Unified Wire Ethernet Controller
        6402  T6225-SO-CR Unified Wire Ethernet Controller
        6403  T6425-CR Unified Wire Ethernet Controller
        6482  T6225-6082 Unified Wire Ethernet Controller
        6483  T62100-6083 Unified Wire Ethernet Controller
        6484  T64100-6084 Unified Wire Ethernet Controller
+       6485  T6240-6085 Unified Wire Ethernet Controller
+       6486  T6225-6086 Unified Wire Ethernet Controller
        6501  T6225-CR Unified Wire Storage Controller
        6502  T6225-SO-CR Unified Wire Storage Controller
        6503  T6425-CR Unified Wire Storage Controller
        6582  T6225-6082 Unified Wire Storage Controller
        6583  T62100-6083 Unified Wire Storage Controller
        6584  T64100-6084 Unified Wire Storage Controller
+       6585  T6240-6085 Unified Wire Storage Controller
+       6586  T6225-6086 Unified Wire Storage Controller
        6601  T6225-CR Unified Wire Storage Controller
        6602  T6225-SO-CR Unified Wire Storage Controller
        6603  T6425-CR Unified Wire Storage Controller
        6682  T6225-6082 Unified Wire Storage Controller
        6683  T62100-6083 Unified Wire Storage Controller
        6684  T64100-6084 Unified Wire Storage Controller
+       6685  T6240-6085 Unified Wire Storage Controller
+       6686  T6225-6086 Unified Wire Storage Controller
        6801  T6225-CR Unified Wire Ethernet Controller [VF]
        6802  T6225-SO-CR Unified Wire Ethernet Controller [VF]
        6803  T6425-CR Unified Wire Ethernet Controller [VF]
        6882  T6225-6082 Unified Wire Ethernet Controller [VF]
        6883  T62100-6083 Unified Wire Ethernet Controller [VF]
        6884  T64100-6084 Unified Wire Ethernet Controller [VF]
+       6885  T6240-6085 Unified Wire Ethernet Controller [VF]
+       6886  T6225-6086 Unified Wire Ethernet Controller [VF]
        a000  PE10K Unified Wire Ethernet Controller
 1426  Storage Technology Corp.
 1427  Better On-Line Solutions
        169d  NetLink BCM5789 Gigabit Ethernet PCI Express
        16a0  NetLink BCM5785 Fast Ethernet
        16a1  BCM57840 NetXtreme II 10 Gigabit Ethernet
+               1043 866e  PEB-10G/57840-2T 10GBase-T Network Adapter
        16a2  BCM57840 NetXtreme II 10/20-Gigabit Ethernet
                103c 1916  FlexFabric 20Gb 2-port 630FLB Adapter
                103c 1917  FlexFabric 20Gb 2-port 630M Adapter
                14e4 1404  BCM957414M4142 OCP 2x25G Type1 wRoCE
                1590 020e  Ethernet 25Gb 2-port 631SFP28 Adapter
                1590 0211  Ethernet 25Gb 2-port 631FLR-SFP28 Adapter
-       16d8  BCM57416 NetXtreme-E 10GBase-T RDMA Ethernet Controller
+       16d8  BCM57416 NetXtreme-E Dual-Media 10G RDMA Ethernet Controller
+               1028 1feb  NetXtreme-E 10Gb SFP+ Adapter
                1590 020c  Ethernet 10Gb 2-port 535T Adapter
                1590 0212  Ethernet 10Gb 2-port 535FLR-T Adapter
        16d9  BCM57417 NetXtreme-E 10GBASE-T RDMA Ethernet Controller
        7016  AP470 48-Channel TTL Level Digital Input/Output Module
        7017  AP323 16-bit, 20 or 40 Channel Analog Input Module
        7018  AP408: 32-Channel Digital I/O Module
+       7019  AP341 14-bit, 16-Channel Simultaneous Conversion Analog Input Module
        701a  AP220-16 12-Bit, 16-Channel Analog Output Module
        701b  AP231-16 16-Bit, 16-Channel Analog Output Module
        7021  APA7-201 Reconfigurable Artix-7 FPGA module 48 TTL channels
        7022  APA7-202 Reconfigurable Artix-7 FPGA module 24 RS485 channels
        7023  APA7-203 Reconfigurable Artix-7 FPGA module 24 TTL & 12 RS485 channels
        7024  APA7-204 Reconfigurable Artix-7 FPGA module 24 LVDS channels
+       7027  AP418 16-Channel High Voltage Digital Input/Output Module
        7042  AP482 Counter Timer Module with TTL Level Input/Output
        7043  AP483 Counter Timer Module with TTL Level and RS422 Input/Output
        7044  AP484 Counter Timer Module with RS422 Input/Output
 1803  ProdaSafe GmbH
 1805  Euresys S.A.
 1809  Lumanate, Inc.
+180c  IEI Integration Corp
 1813  Ambient Technologies Inc
        4000  HaM controllerless modem
                16be 0001  V9x HAM Data Fax Modem
                1924 8018  SFN8042-R2 8000 Series 10/40G Adapter
                1924 8019  SFN8542-R2 8000 Series 10/40G Adapter
                1924 801a  SFN8722-R1 8000 Series OCP 10G Adapter
+               1924 801b  SFN8522-R3 8000 Series 10G Adapter
        1803  SFC9020 10G Ethernet Controller (Virtual Function)
        1813  SFL9021 10GBASE-T Ethernet Controller (Virtual Function)
        1903  SFC9120 10G Ethernet Controller (Virtual Function)
 # E2200, E2201, E2205
        e091  Killer E220x Gigabit Ethernet Controller
        e0a1  Killer E2400 Gigabit Ethernet Controller
+       e0b1  Killer E2500 Gigabit Ethernet Controller
 196a  Sensory Networks Inc.
        0101  NodalCore C-1000 Content Classification Accelerator
        0102  NodalCore C-2000 Content Classification Accelerator
 1cc7  Radian Memory Systems Inc.
        0200  RMS-200
        0250  RMS-250
+1ccf  Zoom Corporation
+       0001  TAC-2 Thunderbolt Audio Converter
 1cd2  SesKion GmbH
        0301  Simulyzer-RT CompactPCI Serial DIO-1 card
        0302  Simulyzer-RT CompactPCI Serial PSI5-ECU-1 card
        2020  DC-390
        690c  690c
        dc29  DC290
+1de5  Eideticom, Inc
+       1000  IO Memory Controller
+       2000  NoLoad Hardware Development Kit
 # nee Tumsan Oy
 1fc0  Ascom (Finland) Oy
        0300  E2200 Dual E1/Rawpipe Card
                0000 3014  10-Giga TOE Dual Port CX4 Low Profile SmartNIC
        4010  TN4010 Clean SROM
        4020  TN9030 10GbE CX4 Ethernet Adapter
+               180c 2040  Mustang-200 10GbE Ethernet Adapter
        4022  TN9310 10GbE SFP+ Ethernet Adapter
                1043 8709  XG-C100F 10GbE SFP+ Ethernet Adapter
                1186 4d00  DXE-810S 10GbE SFP+ Ethernet Adapter
                17aa 21cf  ThinkPad T520
        0150  Xeon E3-1200 v2/3rd Gen Core processor DRAM Controller
                1043 84ca  P8 series motherboard
+               1458 d000  Ivy Bridge GT1 [HD Graphics]
                15d9 0624  X9SCM-F Motherboard
                1849 0150  Motherboard
        0151  Xeon E3-1200 v2/3rd Gen Core processor PCI Express Root Port
        0897  Centrino Wireless-N 130
                8086 5015  Centrino Wireless-N 130 BGN
                8086 5017  Centrino Wireless-N 130 BG
+       08a7  Quark SoC X1000 SDIO / eMMC Controller
        08ae  Centrino Wireless-N 100
                8086 1005  Centrino Wireless-N 100 BGN
                8086 1007  Centrino Wireless-N 100 BG
                8086 8370  Dual Band Wireless AC 3160
 # PowerVR SGX 545
        08cf  Atom Processor Z2760 Integrated Graphics Controller
+       0934  Quark SoC X1000 I2C Controller and GPIO Controller
+       0935  Quark SoC X1000 SPI Controller
+       0936  Quark SoC X1000 HS-UART
+       0937  Quark SoC X1000 10/100 Ethernet MAC
+       0939  Quark SoC X1000 USB EHCI Host Controller / USB 2.0 Device
+       093a  Quark SoC X1000 USB OHCI Host Controller
        0953  PCIe Data Center SSD
                8086 3702  DC P3700 SSD
                8086 3703  DC P3700 SSD [2.5" SFF]
                8086 370a  DC P3600 SSD [2.5" SFF]
                8086 370d  SSD 750 Series [Add-in Card]
                8086 370e  SSD 750 Series [2.5" SFF]
+       0958  Quark SoC X1000 Host Bridge
        095a  Wireless 7265
 # Stone Peak 2 AC
                8086 1010  Dual Band Wireless-AC 7265
                8086 5310  Dual Band Wireless-AC 7265
 # Stone Peak 2 AGN
                8086 9200  Dual Band Wireless-AC 7265
+       095e  Quark SoC X1000 Legacy Bridge
        0960  80960RP (i960RP) Microprocessor/Bridge
        0962  80960RM (i960RM) Bridge
        0964  80960RP (i960RP) Microprocessor/Bridge
+       0a03  Haswell-ULT Thermal Subsystem
        0a04  Haswell-ULT DRAM Controller
                17aa 2214  ThinkPad X240
        0a06  Haswell-ULT Integrated Graphics Controller
        0a2e  Haswell-ULT Integrated Graphics Controller
        0a53  DC P3520 SSD
        0a54  Express Flash NVMe P4500
+               1028 1fe1  Express Flash NVMe 1TB 2.5" U.2 (P4500)
+               1028 1fe2  Express Flash NVMe 2TB 2.5" U.2 (P4500)
+               1028 1fe3  Express Flash NVMe 4TB 2.5" U.2 (P4500)
+               1028 1fe4  Express Flash NVMe 4TB HHHL AIC (P4500)
        0a55  Express Flash NVMe P4600
+               1028 1fe5  Express Flash NVMe 1.6TB 2.5" U.2 (P4600)
+               1028 1fe6  Express Flash NVMe 2TB 2.5" U.2 (P4600)
+               1028 1fe7  Express Flash NVMe 3.2TB 2.5" U.2 (P4600)
+               1028 1fe8  Express Flash NVMe 2.0TB HHHL AIC (P4600)
+               1028 1fe9  Express Flash NVMe 4.0TB HHHL AIC (P4600)
        0be0  Atom Processor D2xxx/N2xxx Integrated Graphics Controller
        0be1  Atom Processor D2xxx/N2xxx Integrated Graphics Controller
                105b 0d7c  D270S/D250S Motherboard
        11a1  Merrifield Power Management Unit
        11a2  Merrifield Serial IO DMA Controller
        11a5  Merrifield Serial IO PWM Controller
+       11c3  Quark SoC X1000 PCIe Root Port 0
+       11c4  Quark SoC X1000 PCIe Root Port 1
        1200  IXP1200 Network Processor
                172a 0000  AEP SSL Accelerator
        1209  8255xER/82551IT Fast Ethernet Controller
                108e 7b14  Sun Dual Port 10 GbE PCIe 2.0 ExpressModule, Base-T
                108e 7b15  Sun Dual Port 10 GbE PCIe 2.0 Low Profile Adapter, Base-T
                1137 00bf  Ethernet Converged Network Adapter X540-T2
+               1170 0052  Ethernet Controller 10-Gigabit X540-AT2
                17aa 1073  ThinkServer X540-T2 AnyFabric
                17aa 4006  Ethernet Controller 10-Gigabit X540-AT2
                1bd4 001a  10G base-T DP ER102Ti3 Rack Adapter
                8086 000b  Ethernet Server Adapter X710-DA2 for OCP
                8086 000d  Ethernet Controller X710 for 10GbE SFP+
                8086 000e  Ethernet Server Adapter OCP X710-2
+               8086 000f  Ethernet Server Adapter OCP X710-2
                8086 0010  Ethernet Converged Network Adapter X710
                8086 4005  Ethernet Controller X710 for 10GbE SFP+
                8086 4006  Ethernet Controller X710 for 10GbE SFP+
        15c8  Ethernet Connection X553/X557-AT 10GBASE-T
        15ce  Ethernet Connection X553 10 GbE SFP+
        15d0  Ethernet SDI Adapter FM10420-100GbE-QDA2
+               8086 0001  Ethernet SDI Adapter FM10420-100GbE-QDA2
        15d1  Ethernet Controller 10G X550T
                8086 0002  Ethernet Converged Network Adapter X550-T1
                8086 001b  Ethernet Server Adapter X550-T1 for OCP
                17aa 2247  ThinkPad T570
                17aa 224f  ThinkPad X1 Carbon 5th Gen
        1912  HD Graphics 530
-       1916  HD Graphics 520
+       1916  Skylake GT2 [HD Graphics 520]
                1028 06f3  Latitude 3570
        1918  Xeon E3-1200 v5/E3-1500 v5/6th Gen Core Processor Host Bridge/DRAM Registers
        1919  Xeon E3-1200 v5/E3-1500 v5/6th Gen Core Processor Imaging Unit
                8086 a000  D865PERL mainboard
                8086 e000  D865PERL mainboard
                8086 e001  Desktop Board D865GBF
-               8086 e002  SoundMax Intergrated Digital Audio
+               8086 e002  SoundMax Integrated Digital Audio
        24d6  82801EB/ER (ICH5/ICH5R) AC'97 Modem Controller
                103c 006a  NX9500
        24d7  82801EB/ER (ICH5/ICH5R) USB UHCI Controller #3
        2822  SATA Controller [RAID mode]
                1028 020d  Inspiron 530
                103c 2a6f  Asus IPIBL-LB Motherboard
-               1043 8277  P5K PRO Motherboard
+               1043 8277  P5K PRO Motherboard: 82801IR [ICH9R]
        2823  C610/X99 series chipset sSATA Controller [RAID mode]
        2824  82801HB (ICH8) 4 port SATA Controller [AHCI mode]
                1043 81ec  P5B
        284b  82801H (ICH8 Family) HD Audio Controller
                1025 011f  Realtek ALC268 audio codec
                1025 0121  Aspire 5920G
-               1025 0145  Realtek ALC889 (Aspire 8920G w. Dolby Theather)
+               1025 0145  Realtek ALC889 (Aspire 8920G w. Dolby Theater)
                1028 01da  OptiPlex 745
                1028 01f3  Inspiron 1420
                1028 01f9  Latitude D630
                1028 0210  PowerEdge T300 onboard SATA Controller
                1028 0211  Optiplex 755
                1028 023c  PowerEdge R200 onboard SATA Controller
-               1043 8277  P5K PRO Motherboard
+               1043 8277  P5K PRO Motherboard: 82801IR [ICH9R]
        2921  82801IB (ICH9) 2 port SATA Controller [IDE mode]
                1028 0235  PowerEdge R710 SATA IDE Controller
                1028 0236  PowerEdge R610 SATA IDE Controller
                1028 0237  PowerEdge T610 SATA IDE Controller
                1462 7360  G33/P35 Neo
        2922  82801IR/IO/IH (ICH9R/DO/DH) 6 port SATA Controller [AHCI mode]
-               1043 8277  P5K PRO Motherboard
+               1043 8277  P5K PRO Motherboard: 82801IR [ICH9R]
                1af4 1100  QEMU Virtual Machine
                8086 5044  Desktop Board DP35DP
        2923  82801IB (ICH9) 4 port SATA Controller [AHCI mode]
                1028 020f  PowerEdge R300 onboard SATA Controller
                1028 0210  PowerEdge T300 onboard SATA Controller
                1028 0211  Optiplex 755
-               1043 8277  P5K PRO Motherboard
+               1043 8277  P5K PRO Motherboard: 82801IR [ICH9R]
                1462 7360  G33/P35 Neo
        2928  82801IBM/IEM (ICH9M/ICH9M-E) 2 port SATA Controller [IDE mode]
        2929  82801IBM/IEM (ICH9M/ICH9M-E) 4 port SATA Controller [AHCI mode]
                1028 0211  Optiplex 755
                103c 2a6f  Asus IPIBL-LB Motherboard
                103c 3628  dv6-1190en
-               1043 8277  P5K PRO Motherboard
+               1043 8277  P5K PRO Motherboard: 82801IR [ICH9R]
                1462 7360  G33/P35 Neo
                1af4 1100  QEMU Virtual Machine
                8086 5044  Desktop Board DP35DP
                1028 029c  PowerEdge M710 USB UHCI Controller
                1028 2011  Optiplex 755
                103c 2a6f  Asus IPIBL-LB Motherboard
-               1043 8277  P5K PRO Motherboard
+               1043 8277  P5K PRO Motherboard: 82801IR [ICH9R]
                1462 7360  G33/P35 Neo
                1af4 1100  QEMU Virtual Machine
                8086 5044  Desktop Board DP35DP
                1028 0287  PowerEdge M610 onboard UHCI
                1028 029c  PowerEdge M710 USB UHCI Controller
                103c 2a6f  Asus IPIBL-LB Motherboard
-               1043 8277  P5K PRO Motherboard
+               1043 8277  P5K PRO Motherboard: 82801IR [ICH9R]
                1462 7360  G33/P35 Neo
                1af4 1100  QEMU Virtual Machine
                8086 5044  Desktop Board DP35DP
                1028 0287  PowerEdge M610 onboard UHCI
                1028 029c  PowerEdge M710 USB UHCI Controller
                103c 2a6f  Asus IPIBL-LB Motherboard
-               1043 8277  P5K PRO Motherboard
+               1043 8277  P5K PRO Motherboard: 82801IR [ICH9R]
                1462 7360  G33/P35 Neo
                1af4 1100  QEMU Virtual Machine
                8086 5044  Desktop Board DP35DP
                1028 029c  PowerEdge M710 USB UHCI Controller
                1028 2011  Optiplex 755
                103c 2a6f  Asus IPIBL-LB Motherboard
-               1043 8277  P5K PRO Motherboard
+               1043 8277  P5K PRO Motherboard: 82801IR [ICH9R]
                1462 7360  G33/P35 Neo
                1af4 1100  QEMU Virtual Machine
                8086 2937  Optiplex 755
                1028 0287  PowerEdge M610 onboard UHCI
                1028 029c  PowerEdge M710 USB UHCI Controller
                103c 2a6f  Asus IPIBL-LB Motherboard
-               1043 8277  P5K PRO Motherboard
+               1043 8277  P5K PRO Motherboard: 82801IR [ICH9R]
                1462 7360  G33/P35 Neo
                1af4 1100  QEMU Virtual Machine
                8086 2938  Optiplex 755
                1028 0210  PowerEdge T300 onboard UHCI
                1028 0237  PowerEdge T610 USB UHCI Controller
                103c 2a6f  Asus IPIBL-LB Motherboard
-               1043 8277  P5K PRO Motherboard
+               1043 8277  P5K PRO Motherboard: 82801IR [ICH9R]
                1462 7360  G33/P35 Neo
                1af4 1100  QEMU Virtual Machine
                8086 5044  Desktop Board DP35DP
                1028 0287  PowerEdge M610 onboard EHCI
                1028 029c  PowerEdge M710 USB EHCI Controller
                103c 2a6f  Asus IPIBL-LB Motherboard
-               1043 8277  P5K PRO Motherboard
+               1043 8277  P5K PRO Motherboard: 82801IR [ICH9R]
                1462 7360  G33/P35 Neo
                1af4 1100  QEMU Virtual Machine
                8086 5044  Desktop Board DP35DP
                1028 0287  PowerEdge M610 onboard EHCI
                1028 029c  PowerEdge M710 USB EHCI Controller
                103c 2a6f  Asus IPIBL-LB Motherboard
-               1043 8277  P5K PRO Motherboard
+               1043 8277  P5K PRO Motherboard: 82801IR [ICH9R]
                1462 7360  G33/P35 Neo
                1af4 1100  QEMU Virtual Machine
                8086 293c  Optiplex 755
                1028 0211  Optiplex 755
                103c 2a6f  Asus IPIBL-LB Motherboard
                103c 3628  dv6-1190en
-               1043 829f  P5K PRO Motherboard
+               1043 829f  P5K PRO Motherboard: 82801IR [ICH9R]
                1462 7360  G33/P35 Neo
                1af4 1100  QEMU Virtual Machine
                8086 293e  Optiplex 755
                1028 020d  Inspiron 530
                1028 0211  Optiplex 755
                103c 2a6f  Asus IPIBL-LB Motherboard
-# same ID possibly also on other ASUS boards
-               1043 8277  P5K PRO Motherboard
+               1043 8277  P5K PRO Motherboard: 82801IR [ICH9R]
                8086 2940  Optiplex 755
        2942  82801I (ICH9 Family) PCI Express Port 2
                1028 020d  Inspiron 530
                1028 020d  Inspiron 530
        2948  82801I (ICH9 Family) PCI Express Port 5
                1028 020d  Inspiron 530
-# same ID possibly also on other ASUS boards
-               1043 8277  P5K PRO Motherboard
+               1043 8277  P5K PRO Motherboard: 82801IR [ICH9R]
        294a  82801I (ICH9 Family) PCI Express Port 6
                1028 020d  Inspiron 530
-# same ID possibly also on other ASUS boards
-               1043 8277  P5K PRO Motherboard
+               1043 8277  P5K PRO Motherboard: 82801IR [ICH9R]
        294c  82566DC-2 Gigabit Network Connection
                17aa 302e  82566DM-2 Gigabit Network Connection
        2970  82946GZ/PL/GL Memory Controller Hub
        29c0  82G33/G31/P35/P31 Express DRAM Controller
                1028 020d  Inspiron 530
                103c 2a6f  Asus IPIBL-LB Motherboard
-# same ID possibly also on other ASUS boards
-               1043 8276  P5K PRO Motherboard
+               1043 8276  P5K PRO Motherboard: Intel 82P35 Northbridge
                1043 82b0  P5KPL-VM Motherboard
                1462 7360  G33/P35 Neo
                1af4 1100  QEMU Virtual Machine
                8086 5044  Desktop Board DP35DP
        29c1  82G33/G31/P35/P31 Express PCI Express Root Port
                1028 020d  Inspiron 530
-# same ID possibly also on other ASUS boards
-               1043 8276  P5K PRO Motherboard
+               1043 8276  P5K PRO Motherboard: Intel 82P35 Northbridge
        29c2  82G33/G31 Express Integrated Graphics Controller
                1028 020d  Inspiron 530
                1043 82b0  P5KPL-VM Motherboard
                103c 0701  Smart Array P204i-b SR Gen10
                103c 1100  Smart Array P816i-a SR Gen10
                103c 1101  Smart Array P416ie-m SR G10
+               9005 0800  SmartRAID 3154-8i
+               9005 0801  SmartRAID 3152-8i
+               9005 0802  SmartRAID 3151-4i
+               9005 0803  SmartRAID 3101-4i
+               9005 0804  SmartRAID 3154-8e
+               9005 0805  SmartRAID 3102-8i
+               9005 0806  SmartRAID 3100
+               9005 0807  SmartRAID 3162-8i
+               9005 0900  SmartHBA 2100-8i
+               9005 0901  SmartHBA 2100-4i
+               9005 0902  HBA 1100-8i
+               9005 0903  HBA 1100-4i
+               9005 0904  SmartHBA 2100-8e
+               9005 0905  HBA 1100-8e
+               9005 0906  SmartHBA 2100-4i4e
+               9005 0907  HBA 1100
+               9005 0908  SmartHBA 2100
+               9005 090a  SmartHBA 2100A-8i
+               9005 1200  SmartRAID 3154-24i
+               9005 1201  SmartRAID 3154-8i16e
+               9005 1202  SmartRAID 3154-8i8e
+               9005 1280  HBA 1100-16i
+               9005 1281  HBA 1100-16e
+               9005 1300  HBA 1100-8i8e
+               9005 1301  HBA 1100-24i
+               9005 1302  SmartHBA 2100-8i8e
+               9005 1303  SmartHBA 2100-24i
+               9005 1380  SmartRAID 3154-16i
        0410  AIC-9410W SAS (Razor HBA RAID)
                9005 0410  ASC-48300(Spirit RAID)
                9005 0411  ASC-58300 (Oakmont RAID)
index 3b00f5b..a2752e2 100644 (file)
  <tr class="odd"><td>Digital Audio Labs Inc</td><td>DAL</td><td>11/29/1996</td> </tr>
  <tr class="even"><td>Digital Communications Association</td><td>DCA</td><td>11/29/1996</td> </tr>
  <tr class="odd"><td>Digital Discovery</td><td>SHR</td><td>09/24/1997</td> </tr>
- <tr class="even"><td>Digital Electronics Corporation</td><td>PRF</td><td>01/02/2003</td> </tr>
+ <tr class="even"><td>Schneider Electric Japan Holdings, Ltd.</td><td>PRF</td><td>01/02/2003</td> </tr>
  <tr class="odd"><td>Digital Equipment Corporation</td><td>DEC</td><td>11/29/1996</td> </tr>
  <tr class="even"><td>Digital Processing Systems</td><td>DPS</td><td>11/29/1996</td> </tr>
  <tr class="odd"><td>Digital Projection Limited</td><td>DPL</td><td>07/09/2002</td> </tr>
  <tr class="even"><td>Televic Conference  </td><td>TCF</td><td>02/28/2017</td> </tr>
  <tr class="odd"><td>Shanghai Chai Ming Huang Info&amp;Tech Co, Ltd  </td><td>HYL</td><td>02/28/2017</td> </tr>
  <tr class="even"><td>Techlogix Networx</td><td>TLN</td><td>02/28/2017</td> </tr>
+ <tr class="odd"><td>G2TOUCH KOREA</td><td>GGT</td><td>05/25/2017</td> </tr>
+ <tr class="even"><td>MediCapture, Inc.</td><td>MVR</td><td>05/25/2017</td> </tr>
+ <tr class="odd"><td>HOYA Corporation PENTAX Lifecare Division</td><td>PNT</td><td>05/25/2017</td> </tr>
+ <tr class="even"><td>christmann informationstechnik + medien GmbH &amp; Co. KG</td><td>CHR</td><td>05/25/2017</td> </tr>
+ <tr class="odd"><td>Tencent</td><td>TEN</td><td>06/20/2017</td> </tr>
+ <tr class="even"><td>VRstudios, Inc.</td><td>VRS</td><td>06/22/2017</td> </tr>
+ <tr class="odd"><td>Extreme Engineering Solutions, Inc.</td><td>XES</td><td>06/22/2017</td> </tr>
+ <tr class="even"><td>NewTek</td><td>NTK</td><td>06/22/2017</td> </tr>
+ <tr class="odd"><td>BlueBox Video Limited</td><td>BBV</td><td>06/22/2017</td> </tr>
+ <tr class="even"><td>Televés, S.A.</td><td>TEV</td><td>06/22/2017</td> </tr>
+ <tr class="odd"><td>Avatron Software Inc.</td><td>AVS</td><td>08/23/2017</td> </tr>
+ <tr class="even"><td>Positivo Tecnologia S.A.</td><td>POS</td><td>09/01/2017</td> </tr>
+ <tr class="odd"><td>VRgineers, Inc.</td><td>VRG</td><td>09/07/2017</td> </tr>
+ <tr class="even"><td>Noritake Itron Corporation</td><td>NRI</td><td>11/13/2017</td> </tr>
+ <tr class="odd"><td>Matrix Orbital Corporation</td><td>MOC</td><td>11/13/2017</td> </tr>
       </tbody>
     </table>
   </body>
index dae1bf3..ec20b2f 100644 (file)
@@ -9,8 +9,8 @@
 #      The latest version can be obtained from
 #              http://www.linux-usb.org/usb.ids
 #
-# Version: 2017.09.10
-# Date:    2017-09-10 20:34:07
+# Version: 2017.11.27
+# Date:    2017-11-27 20:34:05
 #
 
 # Vendors, devices and interfaces. Please keep sorted.
@@ -61,6 +61,8 @@
        0499  SE340D PC Remote Control
 03da  Bernd Walter Computer Technology
        0002  HD44780 LCD interface
+03e7  Intel
+       2150  Myriad VPU [Movidius Neural Compute Stick]
 03e8  EndPoints, Inc.
        0004  SE401 Webcam
        0008  101 Ethernet [klsi]
        2106  STK600 development board
        2107  AVR Dragon
        2109  STK541 ZigBee Development Board
+       210a  AT86RF230 [RZUSBSTICK] transceiver
        210d  XPLAIN evaluation kit (CDC ACM)
        2110  AVR JTAGICE3 Debugger and Programmer
        2111  Xplained Pro board debugger and programmer
        0217  LaserJet 2200
        0218  APOLLO P2500/2600
        0221  StreamSmart 400 [F2235AA]
+       0223  Digital Drive Flash Reader
        022a  Laserjet CP1525nw
        0241  Link-5 micro dongle
        0304  DeskJet 810c/812c
        0611  OfficeJet K60xi
        0612  business inkjet 3000
        0624  Bluetooth Dongle
+       0641  X1200 Optical Mouse
        0701  ScanJet 5300c/5370c
        0704  DeskJet 825c
        0705  ScanJet 4400c
        1524  Smart Card Keyboard - KR
        1539  Mini Magnetic Stripe Reader
        1541  Prime [G8X92AA]
+       154a  Laser Mouse
        1602  PhotoSmart 330 series
        1604  DeskJet 940c
        1605  ScanJet 5530C PhotoSmart
        5307  v165w Stick
        5311  OfficeJet 6300
        5312  Officejet Pro 8500A
+       5317  Color LaserJet CP2025 series
        5411  OfficeJet 4300
        5511  DeskJet F300 series
        5611  PhotoSmart C3180
        9c02  PhotoSmart M440 series
        a004  DeskJet 5850c
        a011  Deskjet 3050A
+       a407  Wireless Optical Comfort Mouse
        b002  PhotoSmart 7200 series
        b102  PhotoSmart 7200 series
        b107  v255w/c310w Flash Drive
        a951  HCP HIT GSM/GPRS modem [Cinterion MC55i]
        a9a0  FT2232D - Dual UART/FIFO IC - FTDI
        abb8  Lego Mindstorms NXTCam
+       b0c2  iID contactless RFID device
+       b0c3  iID contactless RFID device
        b810  US Interface Navigator (CAT and 2nd PTT lines)
        b811  US Interface Navigator (WKEY and FSK lines)
        b812  US Interface Navigator (RS232 and CONFIG lines)
        602a  i900
 040b  Weltrend Semiconductor
        0a68  Func MS-3 gaming mouse [WT6573F MCU]
+       2367  Human Interface Device [HP CalcPad 200 Calculator and Numeric Keypad]
        6510  Weltrend Bar Code Reader
        6520  XBOX Xploder
        6533  Speed-Link Competition Pro
        0104  ADL Re-Flashing Engine Parent
        0105  Nokia Firmware Upgrade Mode
        0106  ROM Parent
+       010d  E75 (Storage Mode)
+       010e  E75 (PC Suite mode)
+       010f  E75 (Media transfer mode)
+       0110  E75 (Imaging Mode)
        0154  5800 XpressMusic (PC Suite mode)
        0155  5800 XpressMusic (Multimedia mode)
        0156  5800 XpressMusic (Storage mode)
        0736  Sidewinder X5 Mouse
        0737  Compact Optical Mouse 500
        0745  Nano Transceiver v1.0 for Bluetooth
+       074a  LifeCam VX-500 [1357]
        0750  Wired Keyboard 600
        0752  Wired Keyboard 400
        075d  LifeCam Cinema
        0768  Sidewinder X4
        076c  Comfort Mouse 4500
        076d  LifeCam HD-5000
+       0770  LifeCam VX-700
        0772  LifeCam Studio
        0779  LifeCam HD-3000
        077f  LifeChat LX-6000 Headset
        0780  Comfort Curve Keyboard 3000
        0797  Optical Mouse 200
+       0799  Surface Pro embedded keyboard
        07a5  Wireless Receiver 1461C
        07b9  Wired Keyboard 200
        07ca  Surface Pro 3 Docking Station Audio Device
        081c  Elitegroup ECS-C11 Camera
        081d  Elitegroup ECS-C11 Storage
        0a00  Micro Innovations Web Cam 320
-       4d01  Comfort Keyboard
+       4d01  Comfort Keyboard / Kensington Orbit Elite
        4d02  Mouse-in-a-Box
        4d03  Kensington Mouse-in-a-box
        4d04  Mouse
        4d75  Rocketfish RF-FLBTAD Bluetooth Adapter
        4d81  Dell N889 Optical Mouse
        4de7  webcam
+       4e04  Lenovo Keyboard KB1021
 0463  MGE UPS Systems
        0001  UPS
        ffff  UPS
        0a45  960 Headset
        0a4d  G430 Surround Sound Gaming Headset
        0a5b  G933 Wireless Headset Dongle
+       0a66  [G533 Wireless Headset Dongle]
        0b02  C-UV35 [Bluetooth Mini-Receiver] (HID proxy mode)
        8801  Video Camera
        b014  Bluetooth Mouse M336/M337/M535
        c31c  Keyboard K120
        c31d  Media Keyboard K200
        c31f  Comfort Keyboard K290
+       c328  Corded Keyboard K280e
        c332  G502 Proteus Spectrum Optical Mouse
        c335  G910 Orion Spectrum Mechanical Keyboard
        c401  TrackMan Marble Wheel
        0203  AH-K3001V
        0204  iBurst Terminal
        0408  FS-1320D Printer
+       069b  ECOSYS M2635dn
 0483  STMicroelectronics
        0137  BeWAN ADSL USB ST (blue or green)
        0138  Unicorn II (ST70138B + MTC-20174TQ chipset)
        1054  S90XS Keyboard/Music Synthesizer
        160f  P-105
        1613  Clavinova CLP535
+       1704  Steinberg UR44
        2000  DGP-7
        2001  DGP-5
        3001  YST-MS55D USB Speaker
        2229  CanoScan 8600F
        2602  MultiPASS C555
        2603  MultiPASS C755
-       260a  CAPT Printer
+       260a  LBP810
        260e  LBP-2000
        2610  MPC600F
        2611  SmartBase MPC400
        2612  MultiPASS C855
-       2617  CAPT Printer
+       2617  LBP1210
        261a  iR1600
        261b  iR1610
        261c  iC2300
        2671  iR5570/iR6570
        2672  iR C3170
        2673  iR 3170C EUR
-       2674  L120
+       2674  FAX-L120
        2675  iR2830
-       2676  CAPT Device
+       2676  LBP2900
        2677  iR C2570
        2678  iR 2570C EUR
        2679  CAPT Device
        2686  MF6500 series
        2687  iR4530
        2688  LBP3460
+       2689  FAX-L180/L380S/L398S
        268c  iR C6870
        268d  iR 6870C EUR
        268e  iR C5870
        26b5  MF4200 series
        26da  LBP3010B printer
        26e6  iR1024
+       271a  LBP6000
        2736  I-SENSYS MF4550d
        2737  MF4410
        3041  PowerShot S10
        32ad  PowerShot SX410 IS
        32b1  SELPHY CP1200
        32b2  PowerShot G9 X
+       32b4  EOS Rebel T6
        32bb  EOS M5
        32bf  PowerShot SX420 IS
        32c1  PowerShot ELPH 180 / IXUS 175
        10fe  S500
        1150  fi-6230
        125a  PalmSecure Sensor Device - MP
+       200f  Sigma DP2 (Mass Storage)
+       2010  Sigma DP2 (PictBridge)
        201d  SATA 3.0 6Gbit/s Adaptor [GROOVY]
 04c6  Toshiba America Electronic Components
 04c7  Micro Macro Technologies
        01bf  FinePix F6000fd/S6500fd Zoom (PTP)
        01c0  FinePix F20 (PTP)
        01c1  FinePix F31fd (PTP)
+       01c3  FinePix S5 Pro
        01c4  FinePix S5700 Zoom (PTP)
        01c5  FinePix F40fd (PTP)
        01c6  FinePix A820 Zoom (PTP)
        0240  FinePix S2950 Digital Camera
        0241  FinePix S3200 Digital Camera
        0278  FinePix JV300
+       02c5  FinePix S9900W Digital Camera (PTP)
+       5006  ASK-300
 04cc  ST-Ericsson
        1122  Hub
        1520  USB 2.0 Hub (Avocent KVM)
        a01c  wireless multimedia keyboard with trackball [Trust ADURA 17911]
        a050  Chatman V1
        a055  Keyboard
+       a096  Keyboard
        a09f  E-Signal LUOM G10 Mechanical Gaming Mouse
        a100  Mouse [HV-MS735]
        a11b  Mouse [MX-3200]
+       e002  MCU
 04da  Panasonic (Matsushita)
        0901  LS-120 Camera
        0912  SDR-S10
        b104  CNF7069 Webcam
        b107  CNF7070 Webcam
        b14c  CNF8050 Webcam
+       b159  CNF8243 Webcam
        b15c  Sony Vaio Integrated Camera
        b175  4-Port Hub
        b1aa  Webcam-101
 04f3  Elan Microelectronics Corp.
        000a  Touchscreen
        0103  ActiveJet K-2024 Multimedia Keyboard
+       016f  Touchscreen
        01a4  Wireless Keyboard
        0201  Touchscreen
        0210  Optical Mouse
        002c  Printer
        002d  Printer
        0039  HL-5340 series
+       0041  HL-2250DN Laser Printer
        0042  HL-2270DW Laser Printer
        0100  MFC8600/9650 series
        0101  MFC9600/9870 series
        021c  MFC-9320CW
        021d  MFC-9120CN
        021e  DCP-9010CN
+       021f  DCP-8085DN
        0220  MFC-9010CN
        0222  DCP-195C
        0223  DCP-365CN
        023f  MFC-8680DN
        0240  MFC-J950DN
        0248  DCP-7055 scanner/printer
+       024e  MFC-7460DN
        0253  DCP-J125
        0254  DCP-J315W
        0255  DCP-J515W
        026d  MFC-J805D
        026e  MFC-J855DN
        026f  MFC-J270W
+       0270  MFC-7360N
        0273  DCP-7057 scanner/printer
        0276  MFC-5895CW
        0278  MFC-J410W
        2027  QL-560 P-touch Label Printer
        2028  QL-570 P-touch Label Printer
        202b  PT-7600 P-touch Label Printer
+       2041  PT-2730 P-touch Label Printer
        2061  PT-P700 P-touch Label Printer
        2064  PT-P700 P-touch Label Printer RemovableDisk
        2100  Card Reader Writer
        2727  Xircom PGUNET USB-USB Bridge
        2750  EZ-Link (EZLNKUSB.SYS)
        2810  Cypress ATAPI Bridge
+       4018  AmScope MU1803
        4d90  AmScope MD1900 camera
        6010  AmScope MU1000 camera
        6510  Touptek UCMOS05100KPA
        06bb  WALKMAN NWZ-F805
        06c3  RC-S380
        07c4  ILCE-6000 (aka Alpha-6000) in Mass Storage mode
+       0847  WG-C10 Portable Wireless Server
        088c  Portable Headphone Amplifier
        08b7  ILCE-6000 (aka Alpha-6000) in MTP mode
        094e  ILCE-6000 (aka Alpha-6000) in PC Remote mode
        0354  DTH-1620 [Cintiq Pro 16] touchscreen
        0357  PTH-660 [Intuos Pro (M)]
        0358  PTH-860 [Intuos Pro (L)]
+       035a  DTH-1152 tablet
+       0368  DTH-1152 touchscreen
        0400  PenPartner 4x5
        4001  TPC4001
        4004  TPC4004
        0003  Device Bay Controller
 056e  Elecom Co., Ltd
        0002  29UO Mouse
+       0057  M-PGDL Mouse
        0072  Mouse
        200c  LD-USB/TX
        4002  Laneed 100Mbps Ethernet LD-USB/TX [pegasus]
 0656  Glory Mark Electronic, Ltd
 0657  Tekcon Electronics Corp.
 0658  Sigma Designs, Inc.
+       0200  Aeotec Z-Stick Gen5 (ZW090) - UZB
 0659  Aethra
 065a  Optoelectronics Co., Ltd
        0001  Opticon OPR-2001 / NLV-1001 (keyboard mode)
@@ -19915,7 +19961,7 @@ HUT 07  Keyboard
        031  \ and | (Backslash and Bar)
        032  # and ~ (Hash and Tilde, Non-US Keyboard near right shift)
        033  ; and : (Semicolon and Colon)
-       034  Â´ and " (Accent Acute and Double Quotes)
+       034  ´ and " (Accent Acute and Double Quotes)
        035  ` and ~ (Accent Grace and Tilde)
        036  , and < (Comma and Less)
        037  . and > (Period and Greater)
index 5b63cfb..5f55cb4 100644 (file)
@@ -2,6 +2,8 @@
 <!--*-nxml-*-->
 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2011 Lennart Poettering
index 675e017..7662593 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   systemd is free software; you can redistribute it and/or modify it
@@ -50,6 +52,9 @@
       <command>bootctl <arg choice="opt" rep="repeat">OPTIONS</arg> status</command>
     </cmdsynopsis>
     <cmdsynopsis>
+      <command>bootctl <arg choice="opt" rep="repeat">OPTIONS</arg> list</command>
+    </cmdsynopsis>
+    <cmdsynopsis>
       <command>bootctl <arg choice="opt" rep="repeat">OPTIONS</arg> update</command>
     </cmdsynopsis>
     <cmdsynopsis>
@@ -71,6 +76,9 @@
     currently installed versions of the boot loader binaries and
     all current EFI boot variables.</para>
 
+    <para><command>bootctl list</command> displays all configured boot loader entries.
+    </para>
+
     <para><command>bootctl update</command> updates all installed versions of systemd-boot, if the current version is
     newer than the version installed in the EFI system partition. This also includes the EFI default/fallback loader at
     <filename>/EFI/BOOT/BOOT*.EFI</filename>. A systemd-boot entry in the EFI boot variables is created if there is no
       </varlistentry>
 
       <varlistentry>
+        <term><option>-p</option></term>
+        <term><option>--print-path</option></term>
+        <listitem><para>This option modifies the behaviour of <command>status</command>.
+        Just print the path to the EFI System Partition (ESP) to standard output and
+        exit.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
         <term><option>--no-variables</option></term>
         <listitem><para>Do not touch the EFI boot variables.</para></listitem>
       </varlistentry>
     <title>See Also</title>
     <para>
       <ulink url="https://www.freedesktop.org/wiki/Specifications/BootLoaderSpec">Boot loader specification</ulink>
-      <ulink url="https://www.freedesktop.org/wiki/Software/systemd/BootLoaderInterface">Systemd boot loader interface</ulink>
+      <ulink url="https://www.freedesktop.org/wiki/Software/systemd/BootLoaderInterface">systemd boot loader interface</ulink>
     </para>
   </refsect1>
 </refentry>
index b92c60f..56f4f57 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2012 Lennart Poettering
index 28b36f0..0c0d28b 100644 (file)
@@ -3,6 +3,8 @@
 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2014 Zbigniew Jędrzejewski-Szmek
       </varlistentry>
 
       <varlistentry>
+        <term><option>-q</option></term>
         <term><option>--quiet</option></term>
 
         <listitem>
index 5f61e05..0972960 100644 (file)
@@ -3,6 +3,8 @@
         "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2014 Zbigniew Jędrzejewski-Szmek
index 5bbd522..72191d1 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2012 Zbigniew Jędrzejewski-Szmek
         <term><option>-q</option></term>
         <term><option>--quiet</option></term>
 
-        <listitem><para>Suppresses info messages about lack
+        <listitem><para>Suppresses informational messages about lack
         of access to journal files and possible in-flight coredumps.
         </para></listitem>
       </varlistentry>
index ac7d552..474d3d8 100644 (file)
@@ -2,6 +2,8 @@
 <!--*-nxml-*-->
 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2012 Lennart Poettering
         started after the network is available, similarly to
         <citerefentry><refentrytitle>systemd.mount</refentrytitle><manvolnum>5</manvolnum></citerefentry>
         units marked with <option>_netdev</option>. The service unit to set up this device
-        will be ordered between <filename>remote-cryptsetup-pre.target</filename> and
+        will be ordered between <filename>remote-fs-pre.target</filename> and
         <filename>remote-cryptsetup.target</filename>, instead of
         <filename>cryptsetup-pre.target</filename> and
-        <filename>cryptsetup.target</filename>.</para></listitem>
+        <filename>cryptsetup.target</filename>.</para>
+
+        <para>Hint: if this device is used for a mount point that is specified in
+        <citerefentry project='man-pages'><refentrytitle>fstab</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+        the <option>_netdev</option> option should also be used for the mount
+        point. Otherwise, a dependency loop might be created where the mount point
+        will be pulled in by <filename>local-fs.target</filename>, while the
+        service to configure the network is usually only started <emphasis>after</emphasis>
+        the local file system has been mounted.</para>
+        </listitem>
       </varlistentry>
 
       <varlistentry>
@@ -433,6 +444,7 @@ hidden     /mnt/tc_hidden  /dev/null    tcrypt-hidden,tcrypt-keyfile=/etc/keyfil
       <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
       <citerefentry><refentrytitle>systemd-cryptsetup@.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
       <citerefentry><refentrytitle>systemd-cryptsetup-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+      <citerefentry project='man-pages'><refentrytitle>fstab</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
       <citerefentry project='die-net'><refentrytitle>cryptsetup</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
       <citerefentry project='man-pages'><refentrytitle>mkswap</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
       <citerefentry project='man-pages'><refentrytitle>mke2fs</refentrytitle><manvolnum>8</manvolnum></citerefentry>
index 0257c2a..9ea9238 100644 (file)
@@ -5,3 +5,4 @@
 <!ENTITY usergeneratordir @USER_GENERATOR_PATH@>
 <!ENTITY systemenvgeneratordir @SYSTEM_ENV_GENERATOR_PATH@>
 <!ENTITY userenvgeneratordir @USER_ENV_GENERATOR_PATH@>
+<!ENTITY CERTIFICATE_ROOT @CERTIFICATE_ROOT@>
index e89d73e..47ce6ab 100644 (file)
@@ -1,6 +1,8 @@
 <?xml version='1.0'?> <!--*-nxml-*-->
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2011 Lennart Poettering
index e1b8d36..3307fd3 100644 (file)
@@ -1,6 +1,8 @@
 <?xml version='1.0'?> <!--*-nxml-*-->
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2013 Zbigniew Jędrzejewski-Szmek
index 485c662..18337da 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2010 Lennart Poettering
 
   </refsect1>
   <refsect1>
-    <title>Integration with Systemd</title>
+    <title>Integration with systemd</title>
 
     <refsect2>
-      <title>Writing Systemd Unit Files</title>
+      <title>Writing systemd Unit Files</title>
 
       <para>When writing systemd unit files, it is recommended to
       consider the following suggestions:</para>
     </refsect2>
 
     <refsect2>
-      <title>Installing Systemd Service Files</title>
+      <title>Installing systemd Service Files</title>
 
       <para>At the build installation time (e.g. <command>make
       install</command> during package build), packages are
index 6e90e6a..d6e4880 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2016 Lennart Poettering
index ad9db16..7dedfa4 100644 (file)
@@ -2,6 +2,8 @@
 <!--*-nxml-*-->
 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2016 Red Hat, Inc.
@@ -90,7 +92,7 @@
     <literal>${<replaceable>FOO</replaceable>}</literal> would have expanded to a non-empty value.
     No other elements of shell syntax are supported.</para>
 
-    <para>Each<replaceable>KEY</replaceable> must be a valid variable name. Empty lines
+    <para>Each <replaceable>KEY</replaceable> must be a valid variable name. Empty lines
     and lines beginning with the comment character <literal>#</literal> are ignored.</para>
 
     <refsect2>
index ab52ccf..b1442dd 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2014 Lennart Poettering
index 8f3168d..32d8e92 100644 (file)
@@ -1,4 +1,6 @@
 /***
+  SPDX-License-Identifier: MIT
+
   Copyright 2014 Tom Gundersen
 
   Permission is hereby granted, free of charge, to any person
index e3fa60a..0abcdb4 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2010 Lennart Poettering
         <term><option>-f</option></term>
         <term><option>--force</option></term>
 
-        <listitem><para>Force immediate halt, power-off, reboot. Do
-        not contact the init system.</para></listitem>
+        <listitem><para>Force immediate halt, power-off, or reboot. When
+        specified once, this results in an immediate but clean shutdown
+        by the system manager. When specified twice, this results in an
+        immediate shutdown without contacting the system manager. See the
+        description of <option>--force</option> in
+        <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+        for more details.</para></listitem>
       </varlistentry>
 
       <varlistentry>
index 8a4c0d5..7b0fd29 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2010 Lennart Poettering
index 81bce2d..fa70d5c 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2012 Lennart Poettering
index ae5ddb1..bf89819 100644 (file)
@@ -2,6 +2,28 @@
 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
+<!--
+  SPDX-License-Identifier: LGPL-2.1+
+
+  This file is part of systemd.
+
+  Copyright 2014 Tom Gundersen
+  Copyright 2016 Zbigniew Jędrzejewski-Szmek
+
+  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.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
 <refentry id="hwdb" conditional="ENABLE_HWDB">
   <refentryinfo>
     <title>hwdb</title>
index f7ac8c4..ed49c39 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2015 Chris Morgan
index e3be62d..bbb6df5 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2016 Zbigniew Jędrzejewski-Szmek
index 444b916..257ff5a 100644 (file)
@@ -3,6 +3,8 @@
         "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2012 Lennart Poettering
       </varlistentry>
 
       <varlistentry>
+        <term><option>--output-fields=</option></term>
+
+        <listitem><para>A comma separated list of the fields which should
+        be included in the output. This only has an effect for the output modes
+        which would normally show all fields (<option>verbose</option>,
+        <option>export</option>, <option>json</option>,
+        <option>json-pretty</option>, and <option>json-sse</option>). The
+        <literal>__CURSOR</literal>, <literal>__REALTIME_TIMESTAMP</literal>,
+        <literal>__MONOTONIC_TIMESTAMP</literal>, and
+        <literal>_BOOT_ID</literal> fields are always
+        printed.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
         <term><option>--utc</option></term>
 
         <listitem><para>Express time in Coordinated Universal Time
         <term><option>-q</option></term>
         <term><option>--quiet</option></term>
 
-        <listitem><para>Suppresses all info messages
+        <listitem><para>Suppresses all informational messages
         (i.e. "-- Logs begin at …", "-- Reboot --"),
         any warning messages regarding
         inaccessible system journals when run as a normal
index 8974f8f..844228e 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2010 Lennart Poettering
         <listitem><para>The maximum line length to permit when converting stream logs into record logs. When a systemd
         unit's standard output/error are connected to the journal via a stream socket, the data read is split into
         individual log records at newline (<literal>\n</literal>, ASCII 10) and NUL characters. If no such delimiter is
-        read for the specified number of bytes a hard log record boundary is artifically inserted, breaking up overly
+        read for the specified number of bytes a hard log record boundary is artificially inserted, breaking up overly
         long lines into multiple log records. Selecting overly large values increases the possible memory usage of the
         Journal daemon for each stream client, as in the worst case the journal daemon needs to buffer the specified
         number of bytes in memory before it can flush a new log record to disk. Also note that permitting overly large
index 4ab7648..422c060 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2012 Lennart Poettering
       </varlistentry>
 
       <varlistentry>
+        <term><varname>systemd.watchdog_device=</varname></term>
+
+        <listitem>
+          <para>Overwrites 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>modules_load=</varname></term>
         <term><varname>rd.modules_load=</varname></term>
 
index 94b6b11..fa86a3a 100644 (file)
@@ -3,6 +3,8 @@
 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2013 Harald Hoyer
index 396481c..750815e 100644 (file)
@@ -2,6 +2,27 @@
 <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
                  "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
 
+<!--
+  SPDX-License-Identifier: LGPL-2.1+
+
+  This file is part of systemd.
+
+  Copyright 2016 Lennart Poettering
+
+  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.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
 <refsect1>
   <title>Environment</title>
 
index 272da64..b98f609 100644 (file)
@@ -2,6 +2,27 @@
 <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
           "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
 
+<!--
+  SPDX-License-Identifier: LGPL-2.1+
+
+  This file is part of systemd.
+
+  Copyright 2014 Zbigniew Jędrzejewski-Szmek
+
+  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.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
 <refsect1>
   <title>Notes</title>
 
index 53b68dc..e92db55 100644 (file)
@@ -6,6 +6,8 @@
 ]>
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2015 David Herrmann <dh.herrmann@gmail.com>
index 1405dda..cd349ac 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2010 Lennart Poettering
index 7da12c2..89a7ab2 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2012 Lennart Poettering
       </varlistentry>
 
       <xi:include href="user-system-options.xml" xpointer="host" />
+      <xi:include href="user-system-options.xml" xpointer="machine" />
 
       <xi:include href="standard-options.xml" xpointer="help" />
       <xi:include href="standard-options.xml" xpointer="version" />
index 2827da6..0341c61 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2010 Lennart Poettering
index 534a0d9..65c5227 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2010 Lennart Poettering
         one or more logged in users, followed by the most recent log
         data from the journal. Takes one or more user names or numeric
         user IDs as parameters. If no parameters are passed, the status
-        of the caller's user is shown. This function is intended to
-        generate human-readable output. If you are looking for
-        computer-parsable output, use <command>show-user</command>
-        instead. Users may be specified by their usernames or numeric
-        user IDs. </para></listitem>
+        is shown for the user of the session of the caller. This
+        function is intended to generate human-readable output. If you
+        are looking for computer-parsable output, use
+        <command>show-user</command> instead.</para></listitem>
       </varlistentry>
 
       <varlistentry>
index 16f51af..8d2bfc5 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2010 Lennart Poettering
index 3c261bf..3d82a3e 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2010 Lennart Poettering
   <refsect1>
     <title>Description</title>
 
-    <para>The <filename>/etc/machine-id</filename> file contains the unique machine ID of the local
-    system that is set during installation. The machine ID is a single newline-terminated,
-    hexadecimal, 32-character, lowercase ID. When decoded from hexadecimal, this corresponds to a
-    16-byte/128-bit value.</para>
-
-    <para>The machine ID is usually generated from a random source
-    during system installation and stays constant for all subsequent
-    boots. Optionally, for stateless systems, it is generated during
-    runtime at early boot if it is found to be empty.</para>
+    <para>The <filename>/etc/machine-id</filename> file contains the unique machine ID of
+    the local system that is set during installation or boot. The machine ID is a single
+    newline-terminated, hexadecimal, 32-character, lowercase ID. When decoded from
+    hexadecimal, this corresponds to a 16-byte/128-bit value. This ID may not be all
+    zeros.</para>
+
+    <para>The machine ID is usually generated from a random source during system
+    installation or first boot and stays constant for all subsequent boots. Optionally,
+    for stateless systems, it is generated during runtime during early boot if necessary.
+    </para>
+
+    <para>The machine ID may be set, for example when network booting, with the
+    <varname>systemd.machine_id=</varname> kernel command line parameter or by passing the
+    option <option>--machine-id=</option> to systemd. An ID is specified in this manner
+    has higher priority and will be used instead of the ID stored in
+    <filename>/etc/machine-id</filename>.</para>
 
-    <para>The machine ID does not change based on local or network configuration or when hardware is
-    replaced. Due to this and its greater length, it is a more useful replacement for the
+    <para>The machine ID does not change based on local or network configuration or when
+    hardware is replaced. Due to this and its greater length, it is a more useful
+    replacement for the
     <citerefentry project='man-pages'><refentrytitle>gethostid</refentrytitle><manvolnum>3</manvolnum></citerefentry>
     call that POSIX specifies.</para>
 
     the original machine ID from the application-specific one. The
     <citerefentry><refentrytitle>sd_id128_get_machine_app_specific</refentrytitle><manvolnum>3</manvolnum></citerefentry>
     API provides an implementation of such an algorithm.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>Initialization</title>
+
+    <para>Each machine should have a non-empty ID in normal operation. The ID of each
+    machine should be unique. To achive those objectives,
+    <filename>/etc/machine-id</filename> can be initialized in a few different ways.
+    </para>
+
+    <para>For normal operating system installations, where a custom image is created for a
+    specific machine, <filename>/etc/machine-id</filename> should be populated during
+    installation.</para>
 
-    <para>The
+    <para>
     <citerefentry><refentrytitle>systemd-machine-id-setup</refentrytitle><manvolnum>1</manvolnum></citerefentry>
-    tool may be used by installer tools to initialize the machine ID
-    at install time. Use
-    <citerefentry><refentrytitle>systemd-firstboot</refentrytitle><manvolnum>1</manvolnum></citerefentry>
-    to initialize it on mounted (but not booted) system images.</para>
-
-    <para>The machine-id may also be set, for example when network
-    booting, by setting the <varname>systemd.machine_id=</varname>
-    kernel command line parameter or passing the option
-    <option>--machine-id=</option> to systemd. A machine-id may not
-    be set to all zeros.</para>
+    may be used by installer tools to initialize the machine ID at install time, but
+    <filename>/etc/machine-id</filename> may also be written using any other means.
+    </para>
+
+    <para>For operating system images which are created once and used on multiple
+    machines, for example for containers or in the cloud,
+    <filename>/etc/machine-id</filename> should be an empty file in the generic file
+    system image. An ID will be generated during boot and saved to this file if
+    possible. Having an empty file in place is useful because it allows a temporary file
+    to be bind-mounted over the real file, in case the image is used read-only.</para>
+
+    <para><citerefentry><refentrytitle>systemd-firstboot</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+    may be used to to initialize <filename>/etc/machine-id</filename> on mounted (but not
+    booted) system images.</para>
+
+    <para>When a machine is booted with
+    <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+    the ID of the machine will be established. If <varname>systemd.machine_id=</varname>
+    or <option>--machine-id=</option> options (see first section) are specified, this
+    value will be used. Otherwise, the value in <filename>/etc/machine-id</filename> will
+    be used. If this file is empty or missing, <filename>systemd</filename> will attempt
+    to use the D-Bus machine ID from <filename>/var/lib/dbus/machine-id</filename>, the
+    value of the kernel command line option <varname>container_uuid</varname>, the KVM DMI
+    <filename>product_uuid</filename> (on KVM systems), and finally a randomly generated
+    UUID.</para>
+
+    <para>After the machine ID is established,
+    <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+    will attempt to save it to <filename>/etc/machine-id</filename>. If this fails, it
+    will attempt to bind-mount a temporary file over <filename>/etc/machine-id</filename>.
+    It is an error if the file system is read-only and does not contain a (possibly empty)
+    <filename>/etc/machine-id</filename> file.</para>
+
+    <para><citerefentry><refentrytitle>systemd-machine-id-commit.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+    will attempt to write the machine ID to the file system if
+    <filename>/etc/machine-id</filename> or <filename>/etc</filename> are read-only during
+    early boot but become writable later on.</para>
   </refsect1>
 
   <refsect1>
index cd5997d..b9f4fa8 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2010 Lennart Poettering
index cf46fe8..43f4d12 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2013 Zbigniew Jędrzejewski-Szmek
       <varlistentry>
         <term><option>--mkdir</option></term>
 
-        <listitem><para>When used with <command>bind</command>, creates
-        the destination directory before applying the bind
-        mount.</para></listitem>
+        <listitem><para>When used with <command>bind</command>, creates the destination file or directory before
+        applying the bind mount. Note that even though the name of this option suggests that it is suitable only for
+        directories, this option also creates the destination file node to mount over if the the object to mount is not
+        a directory, but a regular file, device node, socket or FIFO.</para></listitem>
       </varlistentry>
 
       <varlistentry>
         <term><option>--read-only</option></term>
 
-        <listitem><para>When used with <command>bind</command>, applies
-        a read-only bind mount.</para>
+        <listitem><para>When used with <command>bind</command>, creates a read-only bind mount.</para>
 
         <para>When used with <command>clone</command>, <command>import-raw</command> or <command>import-tar</command> a
         read-only container or VM image is created.</para></listitem>
         <literal>,</literal> if another address will be output afterwards. </para></listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><option>-q</option></term>
+        <term><option>--quiet</option></term>
+
+        <listitem><para>Suppresses additional informational output while running.</para></listitem>
+      </varlistentry>
+
       <xi:include href="user-system-options.xml" xpointer="host" />
 
       <varlistentry>
       <varlistentry>
         <term><command>bind</command> <replaceable>NAME</replaceable> <replaceable>PATH</replaceable> [<replaceable>PATH</replaceable>]</term>
 
-        <listitem><para>Bind mounts a directory from the host into the specified container. The first directory
-        argument is the source directory on the host, the second directory argument is the destination directory in the
-        container. When the latter is omitted, the destination path in the container is the same as the source path on
-        the host. When combined with the <option>--read-only</option> switch, a ready-only bind mount is created. When
-        combined with the <option>--mkdir</option> switch, the destination path is first created before the mount is
-        applied. Note that this option is currently only supported for
+        <listitem><para>Bind mounts a file or directory from the host into the specified container. The first path
+        argument is the source file or directory on the host, the second path argument is the destination file or
+        directory in the container. When the latter is omitted, the destination path in the container is the same as
+        the source path on the host. When combined with the <option>--read-only</option> switch, a ready-only bind
+        mount is created. When combined with the <option>--mkdir</option> switch, the destination path is first created
+        before the mount is applied. Note that this option is currently only supported for
         <citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry> containers,
-        and only if user namespacing (<option>--private-users</option>) is not used.</para></listitem>
+        and only if user namespacing (<option>--private-users</option>) is not used. This command supports bind
+        mounting directories, regular files, device nodes, <constant>AF_UNIX</constant> socket nodes, as well as
+        FIFOs.</para></listitem>
       </varlistentry>
 
       <varlistentry>
index f276d94..3a68410 100644 (file)
@@ -1,3 +1,20 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
+# Copyright 2017 Zbigniew Jędrzejewski-Szmek
+#
+# 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.
+#
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
 # This is lame, I know, but meson has no other include mechanism
 subdir('rules')
 
@@ -115,8 +132,8 @@ systemd_index_xml = custom_target(
         output : 'systemd.index.xml',
         command : [make_man_index_py, '@OUTPUT@'] + nonindex_xml_files)
 
-foreach tuple : xsltproc.found() ? [['systemd.directives', '7', systemd_directives_xml],
-                                    ['systemd.index',      '7', systemd_index_xml]] : []
+foreach tuple : want_man or want_html ? [['systemd.directives', '7', systemd_directives_xml],
+                                         ['systemd.index',      '7', systemd_index_xml]] : []
         stem = tuple[0]
         section = tuple[1]
         xml = tuple[2]
index 4b722aa..0dd0c3c 100644 (file)
@@ -2,6 +2,8 @@
 <!--*-nxml-*-->
 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2011 Lennart Poettering
index d4fa5e9..33e0629 100644 (file)
@@ -3,6 +3,8 @@
 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2015 Zbigniew Jędrzejewski-Szmek
index 57e647a..8a16058 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2014 Vinay Kulkarni
index 6e05cb1..bf3ea40 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2011 Lennart Poettering
@@ -75,7 +77,7 @@
       ending in <literal>.localhost</literal> or <literal>.localhost.localdomain</literal>)
       are resolved to the IP addresses 127.0.0.1 and ::1.</para></listitem>
 
-      <listitem><para>The hostname <literal>gateway</literal> is
+      <listitem><para>The hostname <literal>_gateway</literal> is
       resolved to all current default routing gateway addresses,
       ordered by their metric. This assigns a stable hostname to the
       current gateway, useful for referencing it independently of the
index 00bcc53..dc3076a 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2014 Lennart Poettering
index f88c25c..edd4e9d 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2011 Lennart Poettering
index 34811f0..0114a6f 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2016 Lennart Poettering
index 99bbb61..b0468c1 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2010 Lennart Poettering
index cef5445..f456316 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2010 Lennart Poettering
index 1846df7..451b9cd 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2014 Tom Gundersen
index ae05560..499fe6d 100644 (file)
@@ -441,7 +441,7 @@ manpages = [
   '3',
   ['sd_notifyf', 'sd_pid_notify', 'sd_pid_notify_with_fds', 'sd_pid_notifyf'],
   ''],
- ['sd_pid_get_session',
+ ['sd_pid_get_owner_uid',
   '3',
   ['sd_peer_get_cgroup',
    'sd_peer_get_machine_name',
@@ -453,7 +453,7 @@ manpages = [
    'sd_peer_get_user_unit',
    'sd_pid_get_cgroup',
    'sd_pid_get_machine_name',
-   'sd_pid_get_owner_uid',
+   'sd_pid_get_session',
    'sd_pid_get_slice',
    'sd_pid_get_unit',
    'sd_pid_get_user_slice',
@@ -569,6 +569,13 @@ manpages = [
  ['systemd-machine-id-commit.service', '8', [], ''],
  ['systemd-machine-id-setup', '1', [], ''],
  ['systemd-machined.service', '8', ['systemd-machined'], 'ENABLE_MACHINED'],
+ ['systemd-makefs@.service',
+  '8',
+  ['systemd-growfs',
+   'systemd-growfs@.service',
+   'systemd-makefs',
+   'systemd-makeswap@.service'],
+  ''],
  ['systemd-modules-load.service', '8', ['systemd-modules-load'], 'HAVE_KMOD'],
  ['systemd-mount', '1', ['systemd-umount'], ''],
  ['systemd-networkd-wait-online.service',
@@ -655,6 +662,7 @@ manpages = [
  ['systemd.link', '5', [], ''],
  ['systemd.mount', '5', [], ''],
  ['systemd.netdev', '5', [], 'ENABLE_NETWORKD'],
+ ['systemd.dnssd', '5', [], 'ENABLE_RESOLVE'],
  ['systemd.network', '5', [], 'ENABLE_NETWORKD'],
  ['systemd.nspawn', '5', [], ''],
  ['systemd.offline-updates', '7', [], ''],
index 50fdacd..b3d90d8 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2010 Lennart Poettering
index 055af7a..a655ab1 100644 (file)
@@ -3,6 +3,8 @@
 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2015 Lennart Poettering
index 6439395..48d62d4 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2016 Zbigniew Jędrzejewski-Szmek
index b06d99f..151d89e 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2010 Lennart Poettering
index 24a69bb..2518050 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2015 Lennart Poettering
index bc74e3f..bd27237 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2012 Lennart Poettering
index 0f4b3e8..52f99c7 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2012 Lennart Poettering
index b2131a9..148dd19 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2010 Lennart Poettering
index 4dd674b..54a9de8 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2010 Lennart Poettering
index 2014141..4772c73 100644 (file)
@@ -3,6 +3,8 @@
 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2016 Julian Orth
index 0407a96..8306fd3 100644 (file)
@@ -3,6 +3,8 @@
 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2014 Zbigniew Jędrzejewski-Szmek
 
     <para><function>sd_bus_creds_get_session()</function> will
     retrieve the identifier of the login session that the process is
-    a part of. See
-    <citerefentry><refentrytitle>systemd-logind.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>. For
-    processes that are not part of a session, returns -ENXIO.
-    </para>
+    a part of. Please note the login session may be limited to a stub
+    process or two.  User processes may instead be started from their
+    systemd user manager, e.g. GUI applications started using DBus
+    activation, as well as service processes which are shared between
+    multiple logins of the same user. For processes that are not part
+    of a session, returns -ENXIO.</para>
 
     <para><function>sd_bus_creds_get_owner_uid()</function> will
     retrieve the numeric UID (user identifier) of the user who owns
-    the login session that the process is a part of. See
+    the user unit or login session that the process is a part of. See
     <citerefentry><refentrytitle>systemd-logind.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
-    For processes that are not part of a session, returns -ENXIO.
+    For processes that are not part of a user unit or session, returns
+    -ENXIO.
     </para>
 
     <para><function>sd_bus_creds_has_effective_cap()</function> will
 
         <listitem><para>The given field is not specified for the described
         process or peer. This will be returned by
-        <function>sd_bus_get_unit()</function>,
-        <function>sd_bus_get_slice()</function>,
-        <function>sd_bus_get_user_unit()</function>,
-        <function>sd_bus_get_user_slice()</function>,
-        <function>sd_bus_get_session()</function>, and
-        <function>sd_bus_get_owner_uid()</function> if the process is
+        <function>sd_bus_creds_get_unit()</function>,
+        <function>sd_bus_creds_get_slice()</function>,
+        <function>sd_bus_creds_get_user_unit()</function>,
+        <function>sd_bus_creds_get_user_slice()</function>, and
+        <function>sd_bus_creds_get_session()</function> if the process is
         not part of a systemd system unit, systemd user unit, systemd
-        slice, or logind session. It will also be returned by
-        <function>sd_bus_creds_get_exe()</function> and
+        slice, or logind session. It will be returned by
+        <function>sd_bus_creds_get_owner_uid()</function> if the process is
+        not part of a systemd user unit or logind session. It will also be
+        returned by <function>sd_bus_creds_get_exe()</function> and
         <function>sd_bus_creds_get_cmdline()</function> for kernel
         threads (since these are not started from an executable binary,
         nor have a command line), and by
index b4d7d61..5cdff07 100644 (file)
@@ -3,6 +3,8 @@
 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2014 Zbigniew Jędrzejewski-Szmek
index d9102a3..62520ff 100644 (file)
@@ -3,6 +3,8 @@
 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2014 Zbigniew Jędrzejewski-Szmek
index 4970ce3..ef40178 100644 (file)
@@ -3,6 +3,8 @@
 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2014 Zbigniew Jędrzejewski-Szmek
index a1eda21..b79381f 100644 (file)
@@ -3,6 +3,8 @@
 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2015 Lennart Poettering
index 9f70190..2e867b0 100644 (file)
@@ -3,6 +3,8 @@
 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2016 Julian Orth
index 2c28ee7..3fba212 100644 (file)
@@ -3,6 +3,8 @@
 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2014 Zbigniew Jędrzejewski-Szmek
index 27db2a9..2b9f3d1 100644 (file)
@@ -3,6 +3,8 @@
 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2014 Zbigniew Jędrzejewski-Szmek
index 276953a..bec1268 100644 (file)
@@ -3,6 +3,8 @@
 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2014 Zbigniew Jędrzejewski-Szmek
index 9e99999..470c62d 100644 (file)
@@ -3,6 +3,8 @@
 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2014 Zbigniew Jędrzejewski-Szmek
index 0f77adc..21feafd 100644 (file)
@@ -3,6 +3,8 @@
 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2014 Zbigniew Jędrzejewski-Szmek
index 3328eea..d87d361 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2013 Lennart Poettering
index 2c0a8a5..9d619e5 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2013 Lennart Poettering
index 6a46403..eb1750b 100644 (file)
@@ -3,6 +3,8 @@
 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2016 Julian Orth
index e91269b..5841c2d 100644 (file)
@@ -3,6 +3,8 @@
 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2014 Lennart Poettering
index d281b5d..57e9f4a 100644 (file)
@@ -3,6 +3,8 @@
 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2014 Zbigniew Jędrzejewski-Szmek
index 986eccc..1c898b4 100644 (file)
@@ -3,6 +3,8 @@
 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2014 Zbigniew Jędrzejewski-Szmek
index 4b9f52e..d9731f3 100644 (file)
@@ -3,6 +3,8 @@
 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2016 Julian Orth
index f07ae09..f44cfdb 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2013 Lennart Poettering
index 6a5e344..19d0115 100644 (file)
@@ -3,6 +3,8 @@
 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2016 Lennart Poettering
index 60e2e77..4f92a55 100644 (file)
@@ -3,6 +3,8 @@
 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2016 Lennart Poettering
index bc732db..15ea5de 100644 (file)
@@ -3,6 +3,8 @@
 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2014 Zbigniew Jędrzejewski-Szmek
index ab28b33..9064e63 100644 (file)
@@ -3,6 +3,8 @@
 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2014 Zbigniew Jędrzejewski-Szmek
index c374916..d7b26f7 100644 (file)
@@ -3,6 +3,8 @@
 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2015 Lennart Poettering
index e98f1d2..192ba95 100644 (file)
@@ -3,6 +3,8 @@
 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2014 Zbigniew Jędrzejewski-Szmek
index 5496b71..56abac1 100644 (file)
@@ -3,6 +3,8 @@
 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2014 Lennart Poettering
index 9846a3e..a798a1c 100644 (file)
@@ -3,6 +3,8 @@
 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2015 Lennart Poettering
index f68752d..ed648c2 100644 (file)
@@ -3,6 +3,8 @@
 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2014 Zbigniew Jędrzejewski-Szmek
index c0a5e98..35f91cd 100644 (file)
@@ -3,6 +3,8 @@
 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2014 Lennart Poettering
index 2c83b0b..a17e208 100644 (file)
@@ -3,6 +3,8 @@
 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2015 Lennart Poettering
index 5b68959..fb2687f 100644 (file)
@@ -3,6 +3,8 @@
 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2015 Zbigniew Jędrzejewski-Szmek
index cbc5bc0..ee28caf 100644 (file)
@@ -3,6 +3,8 @@
 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2015 Lennart Poettering
index 2fdbd41..219956d 100644 (file)
@@ -3,6 +3,8 @@
 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2015 Lennart Poettering
index 7f88bd1..dff6952 100644 (file)
@@ -3,6 +3,8 @@
 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2015 Lennart Poettering
index b9488a6..ad855e6 100644 (file)
@@ -3,6 +3,8 @@
 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2014 Zbigniew Jędrzejewski-Szmek
index 6844f29..0628c3e 100644 (file)
@@ -3,6 +3,8 @@
 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2015 Lennart Poettering
index ee61d23..148cab1 100644 (file)
@@ -3,6 +3,8 @@
 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2015 Lennart Poettering
index b6bab6d..43edd76 100644 (file)
@@ -3,6 +3,8 @@
 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2015 Lennart Poettering
index 533d491..cb317ad 100644 (file)
@@ -3,6 +3,8 @@
 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2015 Lennart Poettering
index 2c4d450..ec9e7c0 100644 (file)
@@ -3,6 +3,8 @@
 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2015 Lennart Poettering
index 26327dc..89de31d 100644 (file)
@@ -3,6 +3,8 @@
 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2015 Zbigniew Jędrzejewski-Szmek
index c053144..b4b133f 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2010 Lennart Poettering
index 3938c6d..a97beeb 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2012 Lennart Poettering
index 852a9fd..bdce3b1 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2012 Lennart Poettering
index 927d1ad..b82b141 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2012 Lennart Poettering
index 3bd388d..2af17df 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2010 Lennart Poettering
index 2294b43..b41d618 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2012 Lennart Poettering
index bc2c21e..2000556 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2016 Lennart Poettering
index 92ed0de..95f3e3b 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2012 Lennart Poettering
index b7aa05f..ead150e 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2012 Lennart Poettering
index 0950e11..8fd9674 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2012 Lennart Poettering
index 01e436e..831ed0b 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2012 Lennart Poettering
index 2e686ca..b162b2b 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2012 Lennart Poettering
index 607d746..49800c3 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2012 Lennart Poettering
index 06b0ff5..63d073e 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2012 Lennart Poettering
index 3f6d56c..7431190 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2016 Jan Synáček
index 7c385de..18b0da0 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2012 Lennart Poettering
index 25b3048..5e7ae45 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2012 Lennart Poettering
index a741abe..f771ba3 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2012 Lennart Poettering
index d7a41a0..fb08400 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2012 Lennart Poettering
index 9850734..7e866e8 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2012 Lennart Poettering
index db88eba..29d64f9 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2012 Lennart Poettering
index c1c2423..8563a06 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2010 Lennart Poettering
index 129c99f..935fca5 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2010 Lennart Poettering
index ef60413..989fa2d 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2014 Lennart Poettering
index 7d7b007..c28f303 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2010 Lennart Poettering
       <varlistentry>
         <term>READY=1</term>
 
-        <listitem><para>Tells the service manager that service startup
-        is finished. This is only used by systemd if the service
-        definition file has Type=notify set. Since there is little
-        value in signaling non-readiness, the only value services
-        should send is <literal>READY=1</literal> (i.e.
-        <literal>READY=0</literal> is not defined).</para></listitem>
+        <listitem><para>Tells the service manager that service startup is finished, or the service finished loading its
+        configuration. This is only used by systemd if the service definition file has <varname>Type=notify</varname>
+        set. Since there is little value in signaling non-readiness, the only value services should send is
+        <literal>READY=1</literal> (i.e.  <literal>READY=0</literal> is not defined).</para></listitem>
       </varlistentry>
 
       <varlistentry>
         watchdog is enabled. </para></listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term>WATCHDOG_USEC=…</term>
+
+        <listitem><para>Reset <varname>watchdog_usec</varname> value during runtime.
+        Notice that this is not available when using <function>sd_event_set_watchdog()</function>
+        or <function>sd_watchdog_enabled()</function>.
+        Example : <literal>WATCHDOG_USEC=20000000</literal></para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>EXTEND_TIMEOUT_USEC=…</term>
+
+        <listitem><para>Tells the service manager to extend the startup, runtime or shutdown service timeout
+        corresponding the current state. The value specified is a time in microseconds during which the service must
+        send a new message. A service timeout will occur if the message isn't received, but only if the runtime of the
+        current state is beyond the original maximium times of <varname>TimeoutStartSec=</varname>, <varname>RuntimeMaxSec=</varname>,
+        and <varname>TimeoutStopSec=</varname>.
+        See <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+        for effects on the service timeouts.</para></listitem>
+      </varlistentry>
 
       <varlistentry>
         <term>FDSTORE=1</term>
       </varlistentry>
 
       <varlistentry>
-        <term>FDNAME=…</term>
+        <term>FDSTOREREMOVE=1</term>
 
-        <listitem><para>When used in combination with
-        <varname>FDSTORE=1</varname>, specifies a name for the
-        submitted file descriptors. This name is passed to the service
-        during activation, and may be queried using
-        <citerefentry><refentrytitle>sd_listen_fds_with_names</refentrytitle><manvolnum>3</manvolnum></citerefentry>. File
-        descriptors submitted without this field set, will implicitly
-        get the name <literal>stored</literal> assigned. Note that, if
-        multiple file descriptors are submitted at once, the specified
-        name will be assigned to all of them. In order to assign
-        different names to submitted file descriptors, submit them in
-        separate invocations of
-        <function>sd_pid_notify_with_fds()</function>. The name may
-        consist of any ASCII character, but must not contain control
-        characters or <literal>:</literal>. It may not be longer than
-        255 characters. If a submitted name does not follow these
-        restrictions, it is ignored.</para></listitem>
+        <listitem><para>Removes file descriptors from the file descriptor store. This field needs to be combined with
+        <varname>FDNAME=</varname> to specify the name of the file descriptors to remove.</para></listitem>
       </varlistentry>
 
       <varlistentry>
-        <term>WATCHDOG_USEC=…</term>
+        <term>FDNAME=…</term>
 
-        <listitem><para>Reset <varname>watchdog_usec</varname> value during runtime.
-        Notice that this is not available when using <function>sd_event_set_watchdog()</function>
-        or <function>sd_watchdog_enabled()</function>.
-        Example : <literal>WATCHDOG_USEC=20000000</literal></para></listitem>
+        <listitem><para>When used in combination with <varname>FDSTORE=1</varname>, specifies a name for the submitted
+        file descriptors. When used with <varname>FDSTOREREMOVE=1</varname>, specifies the name for the file
+        descriptors to remove. This name is passed to the service during activation, and may be queried using
+        <citerefentry><refentrytitle>sd_listen_fds_with_names</refentrytitle><manvolnum>3</manvolnum></citerefentry>. File
+        descriptors submitted without this field set, will implicitly get the name <literal>stored</literal>
+        assigned. Note that, if multiple file descriptors are submitted at once, the specified name will be assigned to
+        all of them. In order to assign different names to submitted file descriptors, submit them in separate
+        invocations of <function>sd_pid_notify_with_fds()</function>. The name may consist of arbitrary ASCII
+        characters except control characters or <literal>:</literal>. It may not be longer than 255 characters. If a
+        submitted name does not follow these restrictions, it is ignored.</para></listitem>
       </varlistentry>
 
     </variablelist>
similarity index 85%
rename from man/sd_pid_get_session.xml
rename to man/sd_pid_get_owner_uid.xml
index 14ebd53..fcedcfc 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2010 Lennart Poettering
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 -->
 
-<refentry id="sd_pid_get_session" conditional='HAVE_PAM'>
+<refentry id="sd_pid_get_owner_uid" conditional='HAVE_PAM'>
 
   <refentryinfo>
-    <title>sd_pid_get_session</title>
+    <title>sd_pid_get_owner_uid</title>
     <productname>systemd</productname>
 
     <authorgroup>
   </refentryinfo>
 
   <refmeta>
-    <refentrytitle>sd_pid_get_session</refentrytitle>
+    <refentrytitle>sd_pid_get_owner_uid</refentrytitle>
     <manvolnum>3</manvolnum>
   </refmeta>
 
   <refnamediv>
+    <refname>sd_pid_get_owner_uid</refname>
     <refname>sd_pid_get_session</refname>
-    <refname>sd_pid_get_unit</refname>
     <refname>sd_pid_get_user_unit</refname>
-    <refname>sd_pid_get_owner_uid</refname>
+    <refname>sd_pid_get_unit</refname>
     <refname>sd_pid_get_machine_name</refname>
     <refname>sd_pid_get_slice</refname>
     <refname>sd_pid_get_user_slice</refname>
     <refname>sd_pid_get_cgroup</refname>
+    <refname>sd_peer_get_owner_uid</refname>
     <refname>sd_peer_get_session</refname>
-    <refname>sd_peer_get_unit</refname>
     <refname>sd_peer_get_user_unit</refname>
-    <refname>sd_peer_get_owner_uid</refname>
+    <refname>sd_peer_get_unit</refname>
     <refname>sd_peer_get_machine_name</refname>
     <refname>sd_peer_get_slice</refname>
     <refname>sd_peer_get_user_slice</refname>
     <refname>sd_peer_get_cgroup</refname>
-    <refpurpose>Determine session, unit, owner of a session,
-    container/VM or slice of a specific PID or socket
-    peer</refpurpose>
+    <refpurpose>Determine the owner uid of the user unit or session,
+    or the session, user unit, system unit, container/VM or slice that
+    a specific PID or socket peer belongs to.</refpurpose>
   </refnamediv>
 
   <refsynopsisdiv>
       <funcsynopsisinfo>#include &lt;systemd/sd-login.h&gt;</funcsynopsisinfo>
 
       <funcprototype>
-        <funcdef>int <function>sd_pid_get_session</function></funcdef>
+        <funcdef>int <function>sd_pid_get_owner_uid</function></funcdef>
         <paramdef>pid_t <parameter>pid</parameter></paramdef>
-        <paramdef>char **<parameter>session</parameter></paramdef>
+        <paramdef>uid_t *<parameter>uid</parameter></paramdef>
       </funcprototype>
 
       <funcprototype>
-        <funcdef>int <function>sd_pid_get_unit</function></funcdef>
+        <funcdef>int <function>sd_pid_get_session</function></funcdef>
         <paramdef>pid_t <parameter>pid</parameter></paramdef>
-        <paramdef>char **<parameter>unit</parameter></paramdef>
+        <paramdef>char **<parameter>session</parameter></paramdef>
       </funcprototype>
 
       <funcprototype>
@@ -87,9 +89,9 @@
       </funcprototype>
 
       <funcprototype>
-        <funcdef>int <function>sd_pid_get_owner_uid</function></funcdef>
+        <funcdef>int <function>sd_pid_get_unit</function></funcdef>
         <paramdef>pid_t <parameter>pid</parameter></paramdef>
-        <paramdef>uid_t *<parameter>uid</parameter></paramdef>
+        <paramdef>char **<parameter>unit</parameter></paramdef>
       </funcprototype>
 
       <funcprototype>
       </funcprototype>
 
       <funcprototype>
-        <funcdef>int <function>sd_peer_get_session</function></funcdef>
+        <funcdef>int <function>sd_peer_get_owner_uid</function></funcdef>
         <paramdef>int <parameter>fd</parameter></paramdef>
-        <paramdef>char **<parameter>session</parameter></paramdef>
+        <paramdef>uid_t *<parameter>uid</parameter></paramdef>
       </funcprototype>
 
       <funcprototype>
-        <funcdef>int <function>sd_peer_get_unit</function></funcdef>
+        <funcdef>int <function>sd_peer_get_session</function></funcdef>
         <paramdef>int <parameter>fd</parameter></paramdef>
-        <paramdef>char **<parameter>unit</parameter></paramdef>
+        <paramdef>char **<parameter>session</parameter></paramdef>
       </funcprototype>
 
       <funcprototype>
       </funcprototype>
 
       <funcprototype>
-        <funcdef>int <function>sd_peer_get_owner_uid</function></funcdef>
+        <funcdef>int <function>sd_peer_get_unit</function></funcdef>
         <paramdef>int <parameter>fd</parameter></paramdef>
-        <paramdef>uid_t *<parameter>uid</parameter></paramdef>
+        <paramdef>char **<parameter>unit</parameter></paramdef>
       </funcprototype>
 
       <funcprototype>
   <refsect1>
     <title>Description</title>
 
+    <para><function>sd_pid_get_owner_uid()</function> may be used to
+    determine the Unix UID (user identifier) which owns the login
+    session or systemd user unit of a process identified by the
+    specified PID. For processes which are not part of a login session
+    and not managed by a user manager, this function will fail with
+    <constant>-ENODATA</constant>.</para>
+
     <para><function>sd_pid_get_session()</function> may be used to
     determine the login session identifier of a process identified by
     the specified process identifier. The session identifier is a
-    short string, suitable for usage in file system paths. Note that
-    not all processes are part of a login session (e.g. system service
-    processes, user processes that are shared between multiple
-    sessions of the same user, or kernel threads). For processes not
-    being part of a login session, this function will fail with
-    <constant>-ENODATA</constant>. The returned string needs to be freed with the libc
-    <citerefentry
+    short string, suitable for usage in file system paths. Please
+    note the login session may be limited to a stub process or two.
+    User processes may instead be started from their systemd user
+    manager, e.g. GUI applications started using DBus activation, as
+    well as service processes which are shared between multiple logins
+    of the same user. For processes which are not part of a login
+    session, this function will fail with <constant>-ENODATA</constant>.
+    The returned string needs to be freed with the libc <citerefentry
+    project='man-pages'><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+    call after use.</para>
+
+    <para><function>sd_pid_get_user_unit()</function> may be used to
+    determine the systemd user unit (i.e. user service or scope unit)
+    identifier of a process identified by the specified PID. The
+    unit name is a short string, suitable for usage in file system
+    paths. For processes which are not managed by a user manager, this
+    function will fail with <constant>-ENODATA</constant>. The
+    returned string needs to be freed with the libc <citerefentry
     project='man-pages'><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
     call after use.</para>
 
     determine the systemd system unit (i.e. system service or scope
     unit) identifier of a process identified by the specified PID. The
     unit name is a short string, suitable for usage in file system
-    paths. Note that not all processes are part of a system
-    unit/service (e.g. user processes, or kernel threads). For
-    processes not being part of a systemd system unit, this function
-    will fail with <constant>-ENODATA</constant>. (More specifically, this call will not
-    work for kernel threads.) The returned string needs to be freed
-    with the libc <citerefentry
+    paths.  Note that not all processes are part of a system
+    unit/service. For processes not being part of a systemd system
+    unit, this function will fail with <constant>-ENODATA</constant>.
+    (More specifically, this call will not work for kernel threads.)
+    The returned string needs to be freed with the libc <citerefentry
     project='man-pages'><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
     call after use.</para>
 
-    <para><function>sd_pid_get_user_unit()</function> may be used to
-    determine the systemd user unit (i.e. user service or scope unit)
-    identifier of a process identified by the specified PID. This is
-    similar to <function>sd_pid_get_unit()</function>, but applies to
-    user units instead of system units.</para>
-
-    <para><function>sd_pid_get_owner_uid()</function> may be used to
-    determine the Unix UID (user identifier) of the owner of the
-    session of a process identified the specified PID. Note that this
-    function will succeed for user processes which are shared between
-    multiple login sessions of the same user, whereas
-    <function>sd_pid_get_session()</function> will fail. For processes
-    not being part of a login session and not being a shared process
-    of a user, this function will fail with <constant>-ENODATA</constant>.</para>
-
     <para><function>sd_pid_get_machine_name()</function> may be used
     to determine the name of the VM or container is a member of. The
     machine name is a short string, suitable for usage in file system
     paths. The returned string needs to be freed with the libc
     <citerefentry
     project='man-pages'><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
-    call after use. For processes not part of a VM or containers, this
+    call after use. For processes not part of a VM or container, this
     function fails with <constant>-ENODATA</constant>.</para>
 
     <para><function>sd_pid_get_slice()</function> may be used to
     functions is passed as 0, the operation is executed for the
     calling process.</para>
 
-    <para>The <function>sd_peer_get_session()</function>,
-    <function>sd_peer_get_unit()</function>,
+    <para>The <function>sd_peer_get_owner_uid()</function>,
+    <function>sd_peer_get_session()</function>,
     <function>sd_peer_get_user_unit()</function>,
-    <function>sd_peer_get_owner_uid()</function>,
+    <function>sd_peer_get_unit()</function>,
     <function>sd_peer_get_machine_name()</function>,
     <function>sd_peer_get_slice()</function>,
     <function>sd_peer_get_user_slice()</function> and
index 3dd461f..57a6b52 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2010 Lennart Poettering
index f95e74e..14993bc 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2010 Lennart Poettering
index 130af76..1183d90 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2010 Lennart Poettering
index 759d930..e85998c 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2013 Lennart Poettering
index a8af387..41fe71f 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2010 Lennart Poettering
index 2836afc..673ca44 100644 (file)
@@ -2,6 +2,28 @@
 <!DOCTYPE refsection PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
           "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
 
+<!--
+  SPDX-License-Identifier: LGPL-2.1+
+
+  This file is part of systemd.
+
+  Copyright 2015 Zbigniew Jędrzejewski-Szmek
+  Copyright 2014 Josh Triplett
+
+  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.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
 <refsection>
   <refsection id='confd'>
     <title>Configuration Directories and Precedence</title>
index f718451..dcc6bb8 100644 (file)
@@ -2,6 +2,27 @@
 <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
           "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
 
+<!--
+  SPDX-License-Identifier: LGPL-2.1+
+
+  This file is part of systemd.
+
+  Copyright 2014 Zbigniew Jędrzejewski-Szmek
+
+  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.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
 <variablelist>
   <varlistentry id='help'>
     <term><option>-h</option></term>
index ccf6c8e..ec69b4c 100644 (file)
@@ -1,6 +1,8 @@
 <?xml version="1.0"?> <!--*-nxml-*-->
 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2011 Lennart Poettering
index 4abee60..60882e5 100644 (file)
@@ -6,6 +6,8 @@
 ]>
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2010 Lennart Poettering
       </varlistentry>
 
       <varlistentry>
+        <term><option>--dry-run</option></term>
+
+        <listitem>
+          <para>Just print what would be done. Currently supported by verbs
+          <command>halt</command>, <command>poweroff</command>, <command>reboot</command>,
+          <command>kexec</command>, <command>suspend</command>,
+          <command>hibernate</command>, <command>hybrid-sleep</command>,
+          <command>default</command>, <command>rescue</command>,
+          <command>emergency</command>, and <command>exit</command>.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
         <term><option>-q</option></term>
         <term><option>--quiet</option></term>
 
@@ -777,9 +792,17 @@ Sun 2017-02-26 20:57:49 EST  2h 3min left  Sun 2017-02-26 11:56:36 EST  6h ago
           <term><command>restart <replaceable>PATTERN</replaceable>…</command></term>
 
           <listitem>
-            <para>Stop and then start one or more units specified on the
-            command line. If the units are not running yet, they will
-            be started.</para>
+            <para>Stop and then start one or more units specified on the command line. If the units are not running
+            yet, they will be started.</para>
+
+            <para>Note that restarting a unit with this command does not necessarily flush out all of the unit's
+            resources before it is started again. For example, the per-service file descriptor storage facility (see
+            <varname>FileDescriptoreStoreMax=</varname> in
+            <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>) will
+            remain intact as long as the unit has a job pending, and is only cleared when the unit is fully stopped and
+            no jobs are pending anymore. If it is intended that the file descriptor store is flushed out, too, during a
+            restart operation an explicit <command>systemctl stop</command> command followed by <command>systemctl
+            start</command> should be issued.</para>
           </listitem>
         </varlistentry>
         <varlistentry>
@@ -797,18 +820,16 @@ Sun 2017-02-26 20:57:49 EST  2h 3min left  Sun 2017-02-26 11:56:36 EST  6h ago
           <term><command>reload-or-restart <replaceable>PATTERN</replaceable>…</command></term>
 
           <listitem>
-            <para>Reload one or more units if they support it. If not,
-            restart them instead. If the units are not running yet, they
-            will be started.</para>
+            <para>Reload one or more units if they support it. If not, stop and then start them instead. If the units
+            are not running yet, they will be started.</para>
           </listitem>
         </varlistentry>
         <varlistentry>
           <term><command>try-reload-or-restart <replaceable>PATTERN</replaceable>…</command></term>
 
           <listitem>
-            <para>Reload one or more units if they support it. If not,
-            restart them instead. This does nothing if the units are not
-            running.</para>
+            <para>Reload one or more units if they support it. If not, stop and then start them instead. This does
+            nothing if the units are not running.</para>
             <!-- Note that we don't document force-reload here, as that is just compatibility support, and we generally
                  don't document that. -->
           </listitem>
@@ -896,7 +917,7 @@ Sun 2017-02-26 20:57:49 EST  2h 3min left  Sun 2017-02-26 11:56:36 EST  6h ago
             convenient.
             </para>
 
-            <para>Systemd implicitly loads units as necessary, so just running the <command>status</command> will
+            <para>systemd implicitly loads units as necessary, so just running the <command>status</command> will
             attempt to load a file. The command is thus not useful for determining if something was already loaded or
             not.  The units may possibly also be quickly unloaded after the operation is completed if there's no reason
             to keep it in memory thereafter.
@@ -1027,14 +1048,11 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
           <term><command>reset-failed [<replaceable>PATTERN</replaceable>…]</command></term>
 
           <listitem>
-            <para>Reset the <literal>failed</literal> state of the
-            specified units, or if no unit name is passed, reset the state of all
-            units. When a unit fails in some way (i.e. process exiting
-            with non-zero error code, terminating abnormally or timing
-            out), it will automatically enter the
-            <literal>failed</literal> state and its exit code and status
-            is recorded for introspection by the administrator until the
-            service is restarted or reset with this command.</para>
+            <para>Reset the <literal>failed</literal> state of the specified units, or if no unit name is passed, reset
+            the state of all units. When a unit fails in some way (i.e. process exiting with non-zero error code,
+            terminating abnormally or timing out), it will automatically enter the <literal>failed</literal> state and
+            its exit code and status is recorded for introspection by the administrator until the service is
+            stopped/re-started or reset with this command.</para>
           </listitem>
         </varlistentry>
 
@@ -1795,7 +1813,7 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
             <command>poweroff</command> otherwise. This command is asynchronous; it will return after the exit
             operation is enqueued, without waiting for it to complete.</para>
 
-            <para>The service manager will exit with the the specified exit code, if
+            <para>The service manager will exit with the specified exit code, if
             <replaceable>EXIT_CODE</replaceable> is passed.</para>
           </listitem>
         </varlistentry>
index e747394..876f96d 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2012 Lennart Poettering
       <arg choice="plain">verify</arg>
       <arg choice="opt" rep="repeat"><replaceable>FILES</replaceable></arg>
     </cmdsynopsis>
+    <cmdsynopsis>
+      <command>systemd-analyze</command>
+      <arg choice="opt" rep="repeat">OPTIONS</arg>
+      <arg choice="plain">calendar</arg>
+      <arg choice="plain" rep="repeat"><replaceable>SPECS</replaceable></arg>
+    </cmdsynopsis>
   </refsynopsisdiv>
 
   <refsect1>
     All units files present in the directories containing the command line arguments will
     be used in preference to the other paths.</para>
 
+    <para><command>systemd-analyze calendar</command> will parse and normalize repetitive calendar time events, and
+    will calculate when they will elapse next. This takes the same input as the <varname>OnCalendar=</varname> setting
+    in <citerefentry><refentrytitle>systemd.timer</refentrytitle><manvolnum>5</manvolnum></citerefentry>, following the
+    syntax described in
+    <citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
+
     <para>If no command is passed, <command>systemd-analyze
     time</command> is implied.</para>
 
index 3c1537d..db318de 100644 (file)
@@ -2,6 +2,8 @@
 <!--*-nxml-*-->
 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2012 Lennart Poettering
index 16ec257..686fa89 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2011 Lennart Poettering
index 3459ed8..e047884 100644 (file)
@@ -2,6 +2,8 @@
 <!--*-nxml-*-->
 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2013 Lennart Poettering
index cccfb49..0c33348 100644 (file)
@@ -2,6 +2,8 @@
 <!--*-nxml-*-->
 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2012 Lennart Poettering
index 160db9f..2c394f2 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2012 Lennart Poettering
index 219514b..128324e 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2010 Lennart Poettering
index be13631..d7ad08e 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2012 Lennart Poettering
index d71fdc6..1ae9ffb 100644 (file)
@@ -3,6 +3,8 @@
         "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2014 Zbigniew Jędrzejewski-Szmek
     <citerefentry project='man-pages'><refentrytitle>sysctl</refentrytitle><manvolnum>8</manvolnum></citerefentry>
     parameter <varname>kernel.core_pattern</varname>. The syntax of this parameter is explained in
     <citerefentry project='man-pages'><refentrytitle>core</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
-    Systemd installs the file <filename>/usr/lib/sysctl.d/50-coredump.conf</filename> which configures
+    systemd installs the file <filename>/usr/lib/sysctl.d/50-coredump.conf</filename> which configures
     <varname>kernel.core_pattern</varname> accordingly. This file may be masked or overridden to use a different
     setting following normal
     <citerefentry><refentrytitle>sysctl.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>
index f036ab9..645e2ee 100644 (file)
@@ -2,6 +2,8 @@
 <!--*-nxml-*-->
 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2012 Lennart Poettering
index 73bd5b7..efcbf24 100644 (file)
@@ -2,6 +2,8 @@
 <!--*-nxml-*-->
 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2012 Lennart Poettering
index 0a66b9b..e8656a3 100644 (file)
@@ -2,6 +2,8 @@
 <!--*-nxml-*-->
 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2014 Lennart Poettering
index be241f6..94f6b09 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2012 Lennart Poettering
index 72ea358..4426827 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2010 Lennart Poettering
index 7950aa9..7bc1dd0 100644 (file)
@@ -6,6 +6,8 @@
 ]>
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2017 Zbigniew Jędrzejewski-Szmek
index fb20d2d..513e9a6 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2014 Lennart Poettering
@@ -73,6 +75,9 @@
     special mode of escaping is applied instead, which assumes the
     string is already escaped but will escape everything that
     appears obviously non-escaped.</para>
+
+    <para>For details on the escaping and unescaping algorithms see the relevant section in
+    <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
   </refsect1>
 
   <refsect1>
         <term><option>--path</option></term>
         <term><option>-p</option></term>
 
-        <listitem><para>When escaping or unescaping a string, assume
-        it refers to a file system path. This eliminates leading,
-        trailing or duplicate <literal>/</literal> characters
-        and rejects <literal>.</literal> and <literal>..</literal>
-        path components.</para></listitem>
+        <listitem><para>When escaping or unescaping a string, assume it refers to a file system path. This eliminates
+        leading, trailing or duplicate <literal>/</literal> characters and rejects <literal>.</literal> and
+        <literal>..</literal> path components. This is particularly useful for generating strings suitable for
+        unescaping with the <literal>%f</literal> specifier in unit files, see
+        <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
+        </para></listitem>
       </varlistentry>
 
       <varlistentry>
@@ -172,6 +178,7 @@ systemd-nspawn@My\x20Container\x201.service systemd-nspawn@containerb.service sy
     <title>See Also</title>
     <para>
       <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
       <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
     </para>
   </refsect1>
index 539422a..0ac5f3b 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2014 Lennart Poettering
@@ -77,6 +79,8 @@
       locale variables <varname>LANG=</varname> and
       <varname>LC_MESSAGES</varname></para></listitem>
 
+      <listitem><para>The system keyboard map</para></listitem>
+
       <listitem><para>The system time zone</para></listitem>
 
       <listitem><para>The system host name</para></listitem>
       </varlistentry>
 
       <varlistentry>
+        <term><option>--keymap=<replaceable>KEYMAP</replaceable></option></term>
+
+        <listitem><para>Sets the system keyboard layout. The argument should be a valid keyboard map,
+        such as <literal>de-latin1</literal>. This controls the <literal>KEYMAP</literal> entry in the
+        <citerefentry project='man-pages'><refentrytitle>vconsole.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+        configuration file.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
         <term><option>--timezone=<replaceable>TIMEZONE</replaceable></option></term>
 
         <listitem><para>Sets the system time zone. The argument should
 
       <varlistentry>
         <term><option>--prompt-locale</option></term>
+        <term><option>--prompt-keymap</option></term>
         <term><option>--prompt-timezone</option></term>
         <term><option>--prompt-hostname</option></term>
         <term><option>--prompt-root-password</option></term>
       <varlistentry>
         <term><option>--prompt</option></term>
 
-        <listitem><para>Query the user for locale, timezone, hostname
+        <listitem><para>Query the user for locale, keymap, timezone, hostname
         and root password. This is equivalent to specifying
         <option>--prompt-locale</option>,
+        <option>--prompt-keymap</option>,
         <option>--prompt-timezone</option>,
         <option>--prompt-hostname</option>,
         <option>--prompt-root-password</option> in combination.</para>
 
       <varlistentry>
         <term><option>--copy-locale</option></term>
+        <term><option>--copy-keymap</option></term>
         <term><option>--copy-timezone</option></term>
         <term><option>--copy-root-password</option></term>
 
       <varlistentry>
         <term><option>--copy</option></term>
 
-        <listitem><para>Copy locale, time zone and root password from
+        <listitem><para>Copy locale, keymap, time zone and root password from
         the host. This is equivalent to specifying
         <option>--copy-locale</option>,
+        <option>--copy-keymap</option>,
         <option>--copy-timezone</option>,
         <option>--copy-root-password</option> in combination.</para>
         </listitem>
     <para>
       <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
       <citerefentry project='man-pages'><refentrytitle>locale.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+      <citerefentry project='man-pages'><refentrytitle>vconsole.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
       <citerefentry><refentrytitle>localtime</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
       <citerefentry><refentrytitle>hostname</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
       <citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
index 711e269..f4d2dc1 100644 (file)
@@ -2,6 +2,8 @@
 <!--*-nxml-*-->
 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2012 Lennart Poettering
index b898d71..51e390a 100644 (file)
@@ -2,6 +2,8 @@
 <!--*-nxml-*-->
 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2012 Lennart Poettering
index 3058444..adb48a7 100644 (file)
@@ -2,6 +2,8 @@
 <!--*-nxml-*-->
 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2012 Lennart Poettering
index 2927fcd..3fbe215 100644 (file)
@@ -2,6 +2,8 @@
 <!--*-nxml-*-->
 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2013 Lennart Poettering
index d16e5d6..b58279d 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2012 Lennart Poettering
index 3bbb6ab..188bdb6 100644 (file)
@@ -2,6 +2,8 @@
 <!--*-nxml-*-->
 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2014 Ivan Shapovalov
index a968adf..cbda089 100644 (file)
@@ -2,6 +2,8 @@
 <!--*-nxml-*-->
 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2014 Ivan Shapovalov
index 17755aa..e905e46 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2012 Lennart Poettering
index 2b363c7..58b1516 100644 (file)
@@ -2,7 +2,30 @@
 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
-<refentry id="systemd-hwdb" conditional="ENABLE_HWDB">
+<!--
+  SPDX-License-Identifier: LGPL-2.1+
+
+  This file is part of systemd.
+
+  Copyright 2014 Tom Gundersen
+
+  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.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd-hwdb" conditional="ENABLE_HWDB"
+          xmlns:xi="http://www.w3.org/2001/XInclude">
+
   <refentryinfo>
     <title>systemd-hwdb</title>
     <productname>systemd</productname>
   <refsect1><title>Options</title>
     <variablelist>
       <varlistentry>
-        <term><option>-h</option></term>
-        <term><option>--help</option></term>
-        <listitem>
-          <para>Print help text.</para>
-        </listitem>
-      </varlistentry>
-      <varlistentry>
         <term><option>--usr</option></term>
         <listitem>
           <para>Generate in /usr/lib/udev instead of /etc/udev.</para>
@@ -67,6 +83,8 @@
           <para>Alternate root path in the filesystem.</para>
         </listitem>
       </varlistentry>
+
+      <xi:include href="standard-options.xml" xpointer="help" />
     </variablelist>
 
     <refsect2><title>systemd-hwdb
index 70a618c..9fd36bb 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2016 Lennart Poettering
index 09b82b8..ce34cc8 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2012 Lennart Poettering
index 5c7f9a4..64211e2 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2012 Lennart Poettering
index 3ee344e..4d461d9 100644 (file)
@@ -3,6 +3,8 @@
 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2012 Zbigniew Jędrzejewski-Szmek
       </varlistentry>
 
       <varlistentry>
+        <term><option>--trust=</option></term>
+
+        <listitem><para>Specify the path to a file containing a
+        CA certificate in PEM format.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
         <term><option>-D <replaceable>DIR</replaceable></option></term>
         <term><option>--directory=<replaceable>DIR</replaceable></option></term>
 
index 1f1c305..658c7e0 100644 (file)
@@ -1,8 +1,13 @@
 <?xml version='1.0'?> <!--*- Mode: nxml; nxml-child-indent: 2; indent-tabs-mode: nil -*-->
 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
-"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
+<!ENTITY % entities SYSTEM "custom-entities.ent" >
+%entities;
+]>
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2012 Zbigniew Jędrzejewski-Szmek
         </listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><option>--key=</option></term>
+
+        <listitem><para>
+          Takes a path to a SSL key file in PEM format.
+          Defaults to <filename>&CERTIFICATE_ROOT;/private/journal-remote.pem</filename>.
+          This option can be used with <option>--listen-https=</option>.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>--cert=</option></term>
+
+        <listitem><para>
+          Takes a path to a SSL certificate file in PEM format.
+          Defaults to <filename>&CERTIFICATE_ROOT;/certs/journal-remote.pem</filename>.
+          This option can be used with <option>--listen-https=</option>.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>--trust=</option></term>
+
+        <listitem><para>
+          Takes a path to a SSL CA certificate file in PEM format,
+          or <option>all</option>. If <option>all</option> is set,
+          then certificate checking will be disabled.
+          Defaults to <filename>&CERTIFICATE_ROOT;/ca/trusted.pem</filename>.
+          This option can be used with <option>--listen-https=</option>.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>--gnutls-log=</option></term>
+
+        <listitem><para>
+          Takes a comma separated list of gnutls logging categories.
+          This option can be used with <option>--listen-http=</option> or
+          <option>--listen-https=</option>.
+        </para></listitem>
+      </varlistentry>
+
     </variablelist>
   </refsect1>
 
index f9723de..a43062a 100644 (file)
@@ -1,8 +1,13 @@
 <?xml version='1.0'?> <!--*- Mode: nxml; nxml-child-indent: 2; indent-tabs-mode: nil -*-->
 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
-"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
+<!ENTITY % entities SYSTEM "custom-entities.ent" >
+%entities;
+]>
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2014 Zbigniew Jędrzejewski-Szmek
         </para></listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><option>--follow</option><optional>=<replaceable>BOOL</replaceable></optional></term>
+
+        <listitem><para>
+          If set to yes, then <command>systemd-journal-upload</command> waits for input.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>--key=</option></term>
+
+        <listitem><para>
+          Takes a path to a SSL key file in PEM format.
+          Defaults to <filename>&CERTIFICATE_ROOT;/private/journal-upload.pem</filename>.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>--cert=</option></term>
+
+        <listitem><para>
+          Takes a path to a SSL certificate file in PEM format.
+          Defaults to <filename>&CERTIFICATE_ROOT;/certs/journal-upload.pem</filename>.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>--trust=</option></term>
+
+        <listitem><para>
+          Takes a path to a SSL CA certificate file in PEM format,
+          or <option>all</option>. If <option>all</option> is set,
+          then certificate checking will be disabled.
+          Defaults to <filename>&CERTIFICATE_ROOT;/ca/trusted.pem</filename>.
+        </para></listitem>
+      </varlistentry>
+
       <xi:include href="standard-options.xml" xpointer="help" />
       <xi:include href="standard-options.xml" xpointer="version" />
     </variablelist>
index fec0e1f..8ca0e89 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2010 Lennart Poettering
     for more information about the collected metadata.
     </para>
 
-    <para>Log data collected by the journal is primarily text-based
-    but can also include binary data where necessary. All objects
-    stored in the journal can be up to 2^64-1 bytes in size.</para>
+    <para>Log data collected by the journal is primarily text-based but can also include binary data where
+    necessary. Individual fields making up a log record stored in the journal may be up to 2^64-1 bytes in size.</para>
+
+    <para>The journal service stores log data either persistently below <filename>/var/log/journal</filename> or in a
+    volatile way below <filename>/run/log/journal/</filename> (in the latter case it is lost at reboot). By default, log
+    data is stored persistently if <filename>/var/log/journal/</filename> exists during boot, with an implicit fallback
+    to volatile storage otherwise. Use <varname>Storage=</varname> in
+    <citerefentry><refentrytitle>journald.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry> to configure
+    where log data is placed, independently of the existence of <filename>/var/log/journal/</filename>.</para>
 
-    <para>By default, the journal stores log data in
-    <filename>/run/log/journal/</filename>. Since
-    <filename>/run/</filename> is volatile, log data is lost at
-    reboot. To make the data persistent, it is sufficient to create
-    <filename>/var/log/journal/</filename> where
-    <filename>systemd-journald</filename> will then store the
-    data:</para>
+    <para>On systems where <filename>/var/log/journal/</filename> does not exist yet but where persistent logging is
+    desired (and the default <filename>journald.conf</filename> is used), it is sufficient to create the directory, and
+    ensure it has the correct access modes and ownership:</para>
 
     <programlisting>mkdir -p /var/log/journal
 systemd-tmpfiles --create --prefix /var/log/journal</programlisting>
@@ -123,7 +127,7 @@ systemd-tmpfiles --create --prefix /var/log/journal</programlisting>
     <para>If <filename>systemd-journald.service</filename> is stopped, the stream connections associated with all
     services are terminated. Further writes to those streams by the service will result in <constant>EPIPE</constant>
     errors. In order to react gracefully in this case it is recommended that programs logging to standard output/error
-    ignore such errors. If the the <constant>SIGPIPE</constant> UNIX signal handler is not blocked or turned off, such
+    ignore such errors. If the <constant>SIGPIPE</constant> UNIX signal handler is not blocked or turned off, such
     write attempts will also result in such process signals being generated, see
     <citerefentry><refentrytitle>signal</refentrytitle><manvolnum>7</manvolnum></citerefentry>. To mitigate this issue,
     systemd service manager explicitly turns off the <constant>SIGPIPE</constant> signal for all invoked processes by
@@ -145,12 +149,12 @@ systemd-tmpfiles --create --prefix /var/log/journal</programlisting>
     transports listed above, which are inherently record based and where the metadata is always associated with the
     individual record.</para>
 
-    <para>In addition to the the implicit standard output/error logging of services, stream logging is also available
+    <para>In addition to the implicit standard output/error logging of services, stream logging is also available
     via the <citerefentry><refentrytitle>systemd-cat</refentrytitle><manvolnum>1</manvolnum></citerefentry> command
     line tool.</para>
 
     <para>Currently, the number of parallel log streams <filename>systemd-journald</filename> will accept is limited to
-    4096. When this limit is reached further log streams may be established but will receieve
+    4096. When this limit is reached further log streams may be established but will receive
     <constant>EPIPE</constant> right from the beginning.</para>
   </refsect1>
 
index 2a796c9..308a848 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2012 Lennart Poettering
index 47089fd..b51158b 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2010 Lennart Poettering
index 39da192..acb4ffb 100644 (file)
@@ -2,6 +2,8 @@
 <!--*-nxml-*-->
 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2014 Didier Roche
index 714317c..527cb7b 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2012 Lennart Poettering
index c4f173f..8bf4e75 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2013 Zbigniew Jędrzejewski-Szmek
diff --git a/man/systemd-makefs@.service.xml b/man/systemd-makefs@.service.xml
new file mode 100644 (file)
index 0000000..073c52f
--- /dev/null
@@ -0,0 +1,120 @@
+<?xml version="1.0"?>
+<!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+<!--
+  SPDX-License-Identifier: LGPL-2.1+
+
+  This file is part of systemd.
+
+  Copyright 2017 Zbigniew Jędrzejewski-Szmek
+
+  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.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+<refentry id="systemd-makefs@.service">
+
+  <refentryinfo>
+    <title>systemd-makefs@.service</title>
+    <productname>systemd</productname>
+
+    <authorgroup>
+      <author>
+        <contrib>Developer</contrib>
+        <firstname>Zbigniew</firstname>
+        <surname>Jędrzejewski-Szmek</surname>
+        <email>zbyszek@in.waw.pl</email>
+      </author>
+    </authorgroup>
+  </refentryinfo>
+
+  <refmeta>
+    <refentrytitle>systemd-makefs@.service</refentrytitle>
+    <manvolnum>8</manvolnum>
+  </refmeta>
+
+  <refnamediv>
+    <refname>systemd-makefs@.service</refname>
+    <refname>systemd-makeswap@.service</refname>
+    <refname>systemd-growfs@.service</refname>
+    <refname>systemd-makefs</refname>
+    <refname>systemd-growfs</refname>
+    <refpurpose>Creating and growing file systems on demand</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <para><filename>systemd-makefs@<replaceable>device</replaceable>.service</filename></para>
+    <para><filename>systemd-makeswap@<replaceable>device</replaceable>.service</filename></para>
+    <para><filename>systemd-growfs@<replaceable>mountpoint</replaceable>.service</filename></para>
+    <para><filename>/usr/lib/systemd/systemd-makefs</filename></para>
+    <para><filename>/usr/lib/systemd/systemd-growfs</filename></para>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para><filename>systemd-makefs@.service</filename>,
+    <filename>systemd-makeswap@.service</filename>, and
+    <filename>systemd-growfs@.service</filename> are used to implement the
+    <option>x-systemd.makefs</option> and <option>x-systemd.growfs</option> options
+    in <citerefentry project='man-pages'><refentrytitle>fstab</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+    see <citerefentry><refentrytitle>systemd.mount</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
+    They are instantiated for each device for which the file system or swap structure
+    needs to be initalized, and for each mount point where the file system needs to
+    be grown.</para>
+
+    <para>These services are started at boot, either right before or right after the
+    mount point or swap device are used.</para>
+
+    <para><filename>systemd-makefs</filename> knows very little about specific file
+    systems and swap devices, and after checking that the block device does not already
+    contain a file system or other content, it will execute binaries specific to
+    each filesystem type (<filename>/sbin/mkfs.*</filename>).</para>
+
+    <para><filename>systemd-growfs</filename> knows very little about specific file
+    systems and swap devices, and will instruct the kernel to grow the mounted
+    filesystem to full size of the underlying block device. Nevertheless, it needs
+    to know the
+    <citerefentry project='man-pages'><refentrytitle>ioctl</refentrytitle><manvolnum>2</manvolnum></citerefentry>
+    number specific to each file system, so only certain types are supported.
+    Currently:
+    <citerefentry project='man-pages'><refentrytitle>ext4</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+    btrfs (see
+    <citerefentry project='man-pages'><refentrytitle>btrfs-man5</refentrytitle><manvolnum>5</manvolnum></citerefentry>),
+    <!-- yes, that's what the man page is called. -->
+    and dm-crypt partitions (see
+    <citerefentry project='die-net'><refentrytitle>cryptsetup</refentrytitle><manvolnum>8</manvolnum></citerefentry>).
+    </para>
+
+    <para>If the creation of a file system or swap device fails, the mount point or
+    swap is failed too. If the growing of a file system fails, a warning is emitted.
+    </para>
+  </refsect1>
+
+  <refsect1>
+    <title>See Also</title>
+    <para>
+      <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>systemd.mount</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>systemd-fstab-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+      <citerefentry project='man-pages'><refentrytitle>mkfs.btrfs</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+      <citerefentry project='man-pages'><refentrytitle>mkfs.cramfs</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+      <citerefentry project='man-pages'><refentrytitle>mkfs.ext4</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+      <citerefentry project='man-pages'><refentrytitle>mkfs.fat</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+      <citerefentry project='man-pages'><refentrytitle>mkfs.hfsplus</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+      <citerefentry project='man-pages'><refentrytitle>mkfs.minix</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+      <citerefentry project='man-pages'><refentrytitle>mkfs.ntfs</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+      <citerefentry project='man-pages'><refentrytitle>mkfs.xfs</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+    </para>
+  </refsect1>
+
+</refentry>
index ee097d7..6f37019 100644 (file)
@@ -2,6 +2,8 @@
 <!--*-nxml-*-->
 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2012 Lennart Poettering
index 40dc70f..87bc2b3 100644 (file)
@@ -3,6 +3,8 @@
 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2016 Lennart Poettering
         supported.</para></listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><option>-G</option></term>
+        <term><option>--collect</option></term>
+
+        <listitem><para>Unload the transient unit after it completed, even if it failed. Normally, without this option,
+        all mount units that mount and failed are kept in memory until the user explicitly resets their failure state with
+        <command>systemctl reset-failed</command> or an equivalent command. On the other hand, units that stopped
+        successfully are unloaded immediately. If this option is turned on the "garbage collection" of units is more
+        agressive, and unloads units regardless if they exited successfully or failed. This option is a shortcut for
+        <command>--property=CollectMode=inactive-or-failed</command>, see the explanation for
+        <varname>CollectMode=</varname> in
+        <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry> for further
+        information.</para></listitem>
+      </varlistentry>
+
       <xi:include href="user-system-options.xml" xpointer="user" />
       <xi:include href="user-system-options.xml" xpointer="system" />
       <xi:include href="user-system-options.xml" xpointer="host" />
index e21c805..96715ca 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2014 Tom Gundersen
index a6e079c..8bc5f5e 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2013 Tom Gundersen
index 467efd5..874bdd8 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2010 Lennart Poettering
index 3951e32..3dbdf37 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2010 Lennart Poettering
       </varlistentry>
 
       <varlistentry>
+        <term><option>--network-namespace-path=</option></term>
+
+        <listitem><para>Takes the path to a file representing a kernel
+        network namespace that the container shall run in. The specified path
+        should refer to a (possibly bind-mounted) network namespace file, as
+        exposed by the kernel below <filename>/proc/$PID/ns/net</filename>.
+        This makes the container enter the given network namespace. One of the
+        typical use cases is to give a network namespace under
+        <filename>/run/netns</filename> created by <citerefentry
+        project='man-pages'><refentrytitle>ip-netns</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+        for example, <option>--network-namespace-path=/run/netns/foo</option>.
+        Note that this option cannot be used together with other
+        network-related options, such as <option>--private-network</option>
+        or <option>--network-interface=</option>.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
         <term><option>--network-interface=</option></term>
 
         <listitem><para>Assign the specified network interface to the
         <option>norbind</option> are allowed, controlling whether to create a recursive or a regular bind
         mount. Defaults to "rbind". Backslash escapes are interpreted, so <literal>\:</literal> may be used to embed
         colons in either path.  This option may be specified multiple times for creating multiple independent bind
-        mount points. The <option>--bind-ro=</option> option creates read-only bind mounts.</para></listitem>
+        mount points. The <option>--bind-ro=</option> option creates read-only bind mounts.</para>
+
+        <para>Note that when this option is used in combination with <option>--private-users</option>, the resulting
+        mount points will be owned by the <constant>nobody</constant> user. That's because the mount and its files and
+        directories continue to be owned by the relevant host users and groups, which do not exist in the container,
+        and thus show up under the wildcard UID 65534 (nobody). If such bind mounts are created, it is recommended to
+        make them read-only, using <option>--bind-ro=</option>.</para></listitem>
       </varlistentry>
 
       <varlistentry>
       <varlistentry>
         <term><option>--keep-unit</option></term>
 
-        <listitem><para>Instead of creating a transient scope unit to
-        run the container in, simply register the service or scope
-        unit <command>systemd-nspawn</command> has been invoked in
-        with
-        <citerefentry><refentrytitle>systemd-machined</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
-        This has no effect if <option>--register=no</option> is used.
-        This switch should be used if
-        <command>systemd-nspawn</command> is invoked from within a
-        service unit, and the service unit's sole purpose is to run a
-        single <command>systemd-nspawn</command> container. This
-        option is not available if run from a user
-        session.</para>
+        <listitem><para>Instead of creating a transient scope unit to run the container in, simply use the service or
+        scope unit <command>systemd-nspawn</command> has been invoked in. If <option>--register=yes</option> is set
+        this unit is registered with
+        <citerefentry><refentrytitle>systemd-machined</refentrytitle><manvolnum>8</manvolnum></citerefentry>. This
+        switch should be used if <command>systemd-nspawn</command> is invoked from within a service unit, and the
+        service unit's sole purpose is to run a single <command>systemd-nspawn</command> container. This option is not
+        available if run from a user session.</para>
         <para>Note that passing <option>--keep-unit</option> disables the effect of <option>--slice=</option> and
-        <option>--property=</option>.</para></listitem>
+        <option>--property=</option>. Use <option>--keep-unit</option> and <option>--register=no</option> in
+        combination to disable any kind of unit allocation or registration with
+        <command>systemd-machined</command>.</para></listitem>
       </varlistentry>
 
       <varlistentry>
     <title>Examples</title>
 
     <example>
-      <title>Download a Fedora image and start a shell in it</title>
+      <title>Download a
+      <ulink url="https://getfedora.org">Fedora</ulink> image and start a shell in it</title>
 
       <programlisting># machinectl pull-raw --verify=no \
       https://download.fedoraproject.org/pub/fedora/linux/releases/25/CloudImages/x86_64/images/Fedora-Cloud-Base-25-1.3.x86_64.raw.xz
     <example>
       <title>Build and boot a minimal Fedora distribution in a container</title>
 
-      <programlisting># dnf -y --releasever=25 --installroot=/srv/mycontainer \
+      <programlisting># dnf -y --releasever=27 --installroot=/var/lib/machines/f27container \
       --disablerepo='*' --enablerepo=fedora --enablerepo=updates install \
       systemd passwd dnf fedora-release vim-minimal
-# systemd-nspawn -bD /srv/mycontainer</programlisting>
+# systemd-nspawn -bD /var/lib/machines/f27container</programlisting>
 
       <para>This installs a minimal Fedora distribution into the
-      directory <filename noindex='true'>/srv/mycontainer/</filename>
-      and then boots an OS in a namespace container in it.</para>
+      directory <filename noindex='true'>/var/lib/machines/f27container</filename>
+      and then boots an OS in a namespace container in it. Because the installation
+      is located underneath the standard <filename>/var/lib/machines/</filename>
+      directory, it is also possible to start the machine using
+      <command>systemd-nspawn -M f27container</command>.</para>
     </example>
 
     <example>
       <para>This installs a minimal Debian unstable distribution into
       the directory <filename>~/debian-tree/</filename> and then
       spawns a shell in a namespace container in it.</para>
+
+      <para><command>debootstrap</command> supports
+      <ulink url="https://www.debian.org">Debian</ulink>,
+      <ulink url="https://www.ubuntu.com">Ubuntu</ulink>,
+      and <ulink url="https://www.tanglu.org">Tanglu</ulink>
+      out of the box, so the same command can be used to install any of those. For other
+      distributions from the Debian family, a mirror has to be specified, see
+      <citerefentry project='die-net'><refentrytitle>debootstrap</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
+      </para>
     </example>
 
     <example>
-      <title>Boot a minimal Arch Linux distribution in a container</title>
+      <title>Boot a minimal
+      <ulink url="https://www.archlinux.org">Arch Linux</ulink> distribution in a container</title>
 
       <programlisting># pacstrap -c -d ~/arch-tree/ base
 # systemd-nspawn -bD ~/arch-tree/</programlisting>
     </example>
 
     <example>
-      <title>Install the OpenSUSE Tumbleweed rolling distribution</title>
+      <title>Install the
+      <ulink url="https://software.opensuse.org/distributions/tumbleweed">OpenSUSE Tumbleweed</ulink>
+      rolling distribution</title>
 
       <programlisting># zypper --root=/var/lib/machines/tumbleweed ar -c \
       https://download.opensuse.org/tumbleweed/repo/oss tumbleweed
index e2b23ee..7144569 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2014 Lennart Poettering
index 9d49762..c3a5e69 100644 (file)
@@ -2,6 +2,8 @@
 <!--*-nxml-*-->
 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2012 Lennart Poettering
index 9ec01b6..658bdf3 100644 (file)
@@ -2,6 +2,8 @@
 <!--*-nxml-*-->
 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2012 Lennart Poettering
index 6a5f0e6..8e68b99 100644 (file)
@@ -2,6 +2,8 @@
 <!--*-nxml-*-->
 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2012 Lennart Poettering
index 53f843f..f924090 100644 (file)
@@ -3,6 +3,8 @@
 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2016 Lennart Poettering
         <listitem><para>Shows the global and per-link DNS settings in currently in effect.</para></listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><option>--set-dns=SERVER</option></term>
+        <term><option>--set-domain=DOMAIN</option></term>
+        <term><option>--set-llmnr=MODE</option></term>
+        <term><option>--set-mdns=MODE</option></term>
+        <term><option>--set-dnssec=MODE</option></term>
+        <term><option>--set-nta=DOMAIN</option></term>
+
+        <listitem><para>Set per-interface DNS configuration. These switches may be used to configure various DNS
+        settings for network interfaces that aren't managed by
+        <citerefentry><refentrytitle>systemd-networkd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>. (These
+        commands will fail when used on interfaces that are managed by <command>systemd-networkd</command>, please
+        configure their DNS settings directly inside the <filename>.network</filename> files instead.) These switches
+        may be used to inform <command>systemd-resolved</command> about per-interface DNS configuration determined
+        through external means. Multiple of these switches may be passed on a single invocation of
+        <command>systemd-resolve</command> in order to set multiple configuration options at once. If any of these
+        switches is used, it must be combined with <option>--interface=</option> to indicate the network interface the
+        new DNS configuration belongs to. The <option>--set-dns=</option> option expects an IPv4 or IPv6 address
+        specification of a DNS server to use, and may be used multiple times to define multiple servers for the same
+        interface. The <option>--set-domain=</option> option expects a valid DNS domain, possibly prefixed with
+        <literal>~</literal>, and configures a per-interface search or route-only domain. It may be used multiple times
+        to configure multiple such domains. The <option>--set-llmnr=</option>, <option>--set-mdns=</option> and
+        <option>--set-dnssec=</option> options may be used to configure the per-interface LLMNR, MulticastDNS and
+        DNSSEC settings. Finally, <option>--set-nta=</option> may be used to configure additional per-interface DNSSEC
+        NTA domains and may also be used multiple times. For details about these settings, their possible values and
+        their effect, see the corresponding options in
+        <citerefentry><refentrytitle>systemd.network</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>--revert</option></term>
+
+        <listitem><para>Revert the per-interface DNS configuration. This option must be combined with
+        <option>--interface=</option> to indicate the network interface the DNS configuration shall be reverted on. If
+        the DNS configuration is reverted all per-interface DNS setting are reset to their defaults, undoing all
+        effects of <option>--set-dns=</option>, <option>--set-domain=</option>, <option>--set-llmnr=</option>,
+        <option>--set-mdns=</option>, <option>--set-dnssec=</option>, <option>--set-nta=</option>. Note that when a
+        network interface disappears all configuration is lost automatically, an explicit reverting is not necessary in
+        that case.</para></listitem>
+      </varlistentry>
+
       <xi:include href="standard-options.xml" xpointer="help" />
       <xi:include href="standard-options.xml" xpointer="version" />
       <xi:include href="standard-options.xml" xpointer="no-pager" />
@@ -401,7 +445,9 @@ _443._tcp.fedoraproject.org IN TLSA 0 0 1 19400be5b7a31fb733917700789d2f0a2471c0
     <title>See Also</title>
     <para>
       <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
-      <citerefentry><refentrytitle>systemd-resolved.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+      <citerefentry><refentrytitle>systemd-resolved.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>systemd.dnssd</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>systemd-networkd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
     </para>
   </refsect1>
 </refentry>
index d07d196..da6e8c4 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2014 Tom Gundersen
@@ -94,7 +96,8 @@
     <citerefentry><refentrytitle>systemd.network</refentrytitle><manvolnum>5</manvolnum></citerefentry> for details
     about systemd's own configuration files for DNS servers. To improve compatibility,
     <filename>/etc/resolv.conf</filename> is read in order to discover configured system DNS servers, but only if it is
-    not a symlink to <filename>/run/systemd/resolve/resolv.conf</filename> (see below).</para>
+    not a symlink to <filename>/run/systemd/resolve/stub-resolv.conf</filename> or
+    <filename>/run/systemd/resolve/resolv.conf</filename> (see below).</para>
 
     <para><command>systemd-resolved</command> synthesizes DNS resource records (RRs) for the following cases:</para>
 
       ending in <literal>.localhost</literal> or <literal>.localhost.localdomain</literal>)
       are resolved to the IP addresses 127.0.0.1 and ::1.</para></listitem>
 
-      <listitem><para>The hostname <literal>gateway</literal> is
+      <listitem><para>The hostname <literal>_gateway</literal> is
       resolved to all current default routing gateway addresses,
       ordered by their metric. This assigns a stable hostname to the
       current gateway, useful for referencing it independently of the
       protocol. Lookups for IPv4 addresses are only sent via LLMNR on
       IPv4, and lookups for IPv6 addresses are only sent via LLMNR on
       IPv6. Lookups for the locally configured host name and the
-      <literal>gateway</literal> host name are never routed to
+      <literal>_gateway</literal> host name are never routed to
       LLMNR.</para></listitem>
 
       <listitem><para>Multi-label names are routed to all local
   <refsect1>
     <title><filename>/etc/resolv.conf</filename></title>
 
-    <para>Three modes of handling <filename>/etc/resolv.conf</filename> (see
+    <para>Four modes of handling <filename>/etc/resolv.conf</filename> (see
     <citerefentry project='man-pages'><refentrytitle>resolv.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>) are
     supported:</para>
 
     <itemizedlist>
+      <listitem><para><command>systemd-resolved</command> maintains the
+      <filename>/run/systemd/resolve/stub-resolv.conf</filename> file for compatibility with traditional Linux
+      programs. This file may be symlinked from <filename>/etc/resolv.conf</filename>. This file lists the 127.0.0.53
+      DNS stub (see above) as the only DNS server. It also contains a list of search domains that are in use by
+      systemd-resolved. The list of search domains is always kept up-to-date. Note that
+      <filename>/run/systemd/resolve/stub-resolv.conf</filename> should not be used directly by applications, but only
+      through a symlink from <filename>/etc/resolv.conf</filename>. This file may be symlinked from
+      <filename>/etc/resolv.conf</filename> in order to connect all local clients that bypass local DNS APIs to
+      <command>systemd-resolved</command> with correct search domains settings. This mode of operation is
+      recommended.</para></listitem>
+
       <listitem><para>A static file <filename>/usr/lib/systemd/resolv.conf</filename> is provided that lists
       the 127.0.0.53 DNS stub (see above) as only DNS server. This file may be symlinked from
       <filename>/etc/resolv.conf</filename> in order to connect all local clients that bypass local DNS APIs to
-      <command>systemd-resolved</command>. This mode of operation is recommended.</para></listitem>
+      <command>systemd-resolved</command>. This file does not contain any search domains.</para></listitem>
 
       <listitem><para><command>systemd-resolved</command> maintains the
       <filename>/run/systemd/resolve/resolv.conf</filename> file for compatibility with traditional Linux
index f464842..cb6fae4 100644 (file)
@@ -2,6 +2,8 @@
 <!--*-nxml-*-->
 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2013 Lennart Poettering
index 7477195..9db6a26 100644 (file)
@@ -3,6 +3,8 @@
 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2013 Zbigniew Jędrzejewski-Szmek
 
         <para>When both <option>--pipe</option> and <option>--pty</option> are used in combination the more appropriate
         option is automatically determined and used. Specifically, when invoked with standard input, output and error
-        connected to a TTY <option>--pty</option> is used, and otherwise <option>--pipe</option>.</para></listitem>
+        connected to a TTY <option>--pty</option> is used, and otherwise <option>--pipe</option>.</para>
+
+        <para>When this option is used the original file descriptors <command>systemd-run</command> receives are passed
+        to the service processes as-is. If the service runs with different privileges than
+        <command>systemd-run</command>, this means the service might not be able to re-open the passed file
+        descriptors, due to normal file descriptor access restrictions. If the invoked process is a shell script that
+        uses the <command>echo "hello" > /dev/stderr</command> construct for writing messages to stderr, this might
+        cause problems, as this only works if stderr can be re-opened. To mitigate this use the construct <command>echo
+        "hello" >&amp;2</command> instead, which is mostly equivalent and avoids this pitfall.</para></listitem>
       </varlistentry>
 
       <varlistentry>
         <option>--no-block</option>, <option>--scope</option> or the various timer options.</para></listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><option>-G</option></term>
+        <term><option>--collect</option></term>
+
+        <listitem><para>Unload the transient unit after it completed, even if it failed. Normally, without this option,
+        all units that ran and failed are kept in memory until the user explicitly resets their failure state with
+        <command>systemctl reset-failed</command> or an equivalent command. On the other hand, units that ran
+        successfully are unloaded immediately. If this option is turned on the "garbage collection" of units is more
+        aggressive, and unloads units regardless if they exited successfully or failed. This option is a shortcut for
+        <command>--property=CollectMode=inactive-or-failed</command>, see the explanation for
+        <varname>CollectMode=</varname> in
+        <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry> for further
+        information.</para></listitem>
+      </varlistentry>
+
       <xi:include href="user-system-options.xml" xpointer="user" />
       <xi:include href="user-system-options.xml" xpointer="system" />
       <xi:include href="user-system-options.xml" xpointer="host" />
index 9a379ec..7fecd66 100644 (file)
@@ -3,6 +3,8 @@
 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2013 Zbigniew Jędrzejewski-Szmek
index 356bc10..79e35dd 100644 (file)
@@ -3,6 +3,8 @@
 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2013 Zbigniew Jędrzejewski-Szmek
index 96702a8..1705374 100644 (file)
@@ -3,6 +3,8 @@
 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
      "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2013 David Strauss
@@ -119,7 +121,7 @@ WantedBy=sockets.target]]></programlisting>
 Requires=nginx.service
 After=nginx.service
 Requires=proxy-to-nginx.socket
-After=proxy-to-nginx.service
+After=proxy-to-nginx.socket
 
 [Service]
 ExecStart=/usr/lib/systemd/systemd-socket-proxyd /tmp/nginx.sock
@@ -161,8 +163,8 @@ WantedBy=sockets.target]]></programlisting>
         <programlisting><![CDATA[[Unit]
 Requires=nginx.service
 After=nginx.service
-Requires=proxy-to-nginx.service
-After=proxy-to-nginx.service
+Requires=proxy-to-nginx.socket
+After=proxy-to-nginx.socket
 JoinsNamespaceOf=nginx.service
 
 [Service]
index 2aa172e..24c213e 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2012 Lennart Poettering
index ee00e8d..3251bc6 100644 (file)
@@ -2,6 +2,8 @@
 <!--*-nxml-*-->
 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2012 Lennart Poettering
index 833ed79..c57dc78 100644 (file)
@@ -2,6 +2,8 @@
 <!--*-nxml-*-->
 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2012 Lennart Poettering
index 81f1b1e..08f6c91 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2010 Lennart Poettering
         <literal>d</literal>, <literal>w</literal>). If
         <varname>RuntimeWatchdogSec=</varname> is set to a non-zero
         value, the watchdog hardware
-        (<filename>/dev/watchdog</filename>) will be programmed to
-        automatically reboot the system if it is not contacted within
+        (<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
       </varlistentry>
 
       <varlistentry>
+        <term><varname>WatchdogDevice=</varname></term>
+
+        <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
+        effect if a hardware watchdog is not available.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
         <term><varname>CapabilityBoundingSet=</varname></term>
 
         <listitem><para>Controls which capabilities to include in the
index 990b935..73ba4e4 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2014 Lennart Poettering
index 2353eb3..3eceb51 100644 (file)
@@ -2,6 +2,8 @@
 <!--*-nxml-*-->
 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2014 Zbigniew Jędrzejewski-Szmek
index fee8602..2dfde3c 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2010 Lennart Poettering
index 7860c0d..e9b5c25 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2014 Kay Sievers
index c1aab51..24a08b0 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2010 Lennart Poettering
       <arg choice="opt" rep="repeat"><replaceable>CONFIGFILE</replaceable></arg>
     </cmdsynopsis>
 
-    <para><filename>systemd-tmpfiles-setup.service</filename></para>
-    <para><filename>systemd-tmpfiles-setup-dev.service</filename></para>
-    <para><filename>systemd-tmpfiles-clean.service</filename></para>
-    <para><filename>systemd-tmpfiles-clean.timer</filename></para>
+    <para>System units:
+<literallayout><filename>systemd-tmpfiles-setup.service</filename>
+<filename>systemd-tmpfiles-setup-dev.service</filename>
+<filename>systemd-tmpfiles-clean.service</filename>
+<filename>systemd-tmpfiles-clean.timer</filename></literallayout></para>
+
+    <para>User units:
+<literallayout><filename>systemd-tmpfiles-setup.service</filename>
+<filename>systemd-tmpfiles-clean.service</filename>
+<filename>systemd-tmpfiles-clean.timer</filename></literallayout></para>
   </refsynopsisdiv>
 
   <refsect1>
         <varname>T</varname>,
         <varname>a</varname>, and
         <varname>A</varname> have their ownership, access mode and
-        security labels set. </para></listitem>
+        security labels set.</para></listitem>
       </varlistentry>
 
       <varlistentry>
         marked with <varname>r</varname> or <varname>R</varname> are
         removed.</para></listitem>
       </varlistentry>
+
+      <varlistentry>
+        <term><option>--user</option></term>
+        <listitem><para>Execute "user" configuration, i.e. <filename>tmpfiles.d</filename>
+        files in user configuration directories.</para></listitem>
+      </varlistentry>
+
       <varlistentry>
         <term><option>--boot</option></term>
         <listitem><para>Also execute lines with an exclamation mark.
         </para></listitem>
       </varlistentry>
+
       <varlistentry>
         <term><option>--prefix=<replaceable>path</replaceable></option></term>
         <listitem><para>Only apply rules with paths that start with
         specified prefix. This option can be specified multiple
         times.</para></listitem>
       </varlistentry>
+
       <varlistentry>
         <term><option>--root=<replaceable>root</replaceable></option></term>
-        <listitem><para>Takes a directory path as an argument. All
-        paths will be prefixed with the given alternate
-        <replaceable>root</replaceable> path, including config search
-        paths. </para></listitem>
+        <listitem><para>Takes a directory path as an argument. All paths will be prefixed with the given alternate
+        <replaceable>root</replaceable> path, including config search paths.</para>
+
+        <para>Note that this option does not alter how the users and groups specified in the configuration files are
+        resolved. With or without this option, users and groups are always resolved according to the host's user and
+        group databases, any such databases stored under the specified root directories are not
+        consulted.</para></listitem>
       </varlistentry>
 
       <xi:include href="standard-options.xml" xpointer="help" />
   <refsect1>
     <title>Exit status</title>
 
-    <para>On success, 0 is returned, a non-zero failure code
-    otherwise.</para>
+    <para>On success, 0 is returned. If the configuration was invalid (invalid syntax, missing
+    arguments, …), so some lines had to be ignored, but no other errors occurred,
+    <constant>65</constant> is returned (<constant>EX_DATAERR</constant> from
+    <filename>/usr/include/sysexits.h</filename>). Otherwise, <constant>1</constant> is returned
+    (<constant>EXIT_FAILURE</constant> from <filename>/usr/include/stdlib.h</filename>).
+    </para>
   </refsect1>
 
   <refsect1>
index 2c114f4..e934649 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2010 Lennart Poettering
index 81b957b..ee18dae 100644 (file)
@@ -2,6 +2,27 @@
 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
+<!--
+  SPDX-License-Identifier: LGPL-2.1+
+
+  This file is part of systemd.
+
+  Copyright 2010-2013 Kay Sievers
+
+  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.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
 <refentry id="systemd-udevd.service"
           xmlns:xi="http://www.w3.org/2001/XInclude">
 
@@ -68,6 +89,7 @@
   <refsect1><title>Options</title>
     <variablelist>
       <varlistentry>
+        <term><option>-d</option></term>
         <term><option>--daemon</option></term>
         <listitem>
           <para>Detach and run in the background.</para>
@@ -75,6 +97,7 @@
       </varlistentry>
 
       <varlistentry>
+        <term><option>-D</option></term>
         <term><option>--debug</option></term>
         <listitem>
           <para>Print debug messages to standard error.</para>
       </varlistentry>
 
       <varlistentry>
+        <term><option>-c=</option></term>
         <term><option>--children-max=</option></term>
         <listitem>
           <para>Limit the number of events executed in parallel.</para>
       </varlistentry>
 
       <varlistentry>
+        <term><option>-e=</option></term>
         <term><option>--exec-delay=</option></term>
         <listitem>
           <para>Delay the execution of <varname>RUN</varname>
       </varlistentry>
 
       <varlistentry>
+        <term><option>-t=</option></term>
         <term><option>--event-timeout=</option></term>
         <listitem>
           <para>Set the number of seconds to wait for events to finish. After
       </varlistentry>
 
       <varlistentry>
+        <term><option>-N=</option></term>
         <term><option>--resolve-names=</option></term>
         <listitem>
           <para>Specify when systemd-udevd should resolve names of users and groups.
         </listitem>
       </varlistentry>
 
-      <varlistentry>
-        <term><option>--help</option></term>
-
-        <xi:include href="standard-options.xml" xpointer="help-text" />
-      </varlistentry>
+      <xi:include href="standard-options.xml" xpointer="help" />
       <xi:include href="standard-options.xml" xpointer="version" />
     </variablelist>
   </refsect1>
index a2dad39..b0dd56f 100644 (file)
@@ -2,6 +2,8 @@
 <!--*-nxml-*-->
 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2014 Lennart Poettering
index be7cec2..286c18e 100644 (file)
@@ -2,6 +2,8 @@
 <!--*-nxml-*-->
 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2012 Lennart Poettering
index 67aba54..c3eaffa 100644 (file)
@@ -2,6 +2,8 @@
 <!--*-nxml-*-->
 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2012 Lennart Poettering
index 6df82ae..3b72234 100644 (file)
@@ -2,6 +2,8 @@
 <!--*-nxml-*-->
 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2012 Lennart Poettering
   <refsect1>
     <title>Description</title>
 
-    <para><filename>systemd-vconsole-setup</filename> is a helper used to prepare either all virtual consoles, or — if
-      the optional <replaceable>TTY</replaceable> parameter is provided — a specific one. When the system is booting up
-      it's called by <citerefentry><refentrytitle>systemd-udevd</refentrytitle><manvolnum>8</manvolnum></citerefentry> during vtconsole subsystem initialization.
-      <productname>Systemd</productname> also calls it internally as needed via
-      <filename>systemd-vconsole-setup.service</filename>. The helper calls
-      <citerefentry project='mankier'><refentrytitle>loadkeys</refentrytitle><manvolnum>1</manvolnum></citerefentry> and
-      <citerefentry project='die-net'><refentrytitle>setfont</refentrytitle><manvolnum>8</manvolnum></citerefentry>
-      internally.
+    <para><filename>systemd-vconsole-setup</filename> sets up and configures either all virtual consoles, or — if the
+    optional <replaceable>TTY</replaceable> parameter is provided — a specific one. When the system is booting up it's
+    called by <citerefentry><refentrytitle>systemd-udevd</refentrytitle><manvolnum>8</manvolnum></citerefentry> during
+    VT console subsystem initialization.  Also,
+    <citerefentry><refentrytitle>systemd-localed.service</refentrytitle><manvolnum>8</manvolnum></citerefentry> invokes
+    it as needed when language or console changes are made. Internally, this program calls <citerefentry
+    project='mankier'><refentrytitle>loadkeys</refentrytitle><manvolnum>1</manvolnum></citerefentry> and <citerefentry
+    project='die-net'><refentrytitle>setfont</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
     </para>
 
-    <para>
-      You may want to use this helper whenever you change <filename>vconsole.conf</filename> to
-      refresh the settings on your consoles — either through the <command>systemctl restart</command> /
-      <command>systemctl start</command> command or directly through the executable.
-    </para>
+    <para>Execute <command>systemctl restart systemd-vconsole-setup.service</command> in order to apply any manual
+    changes made to <filename>/etc/vconsole.conf</filename>.</para>
 
-    <para>See
-    <citerefentry><refentrytitle>vconsole.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
-    for information about the configuration files and kernel command line options understood by this program.</para>
+    <para>See <citerefentry><refentrytitle>vconsole.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry> for
+    information about the configuration files and kernel command line options understood by this program.</para>
   </refsect1>
 
   <refsect1>
index 87d66e9..b6b5b3b 100644 (file)
@@ -2,6 +2,8 @@
 <!--*-nxml-*-->
 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2016 Lennart Poettering
index 173e535..55600e9 100644 (file)
@@ -2,6 +2,8 @@
 <!--*-nxml-*-->
 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2016 Lennart Poettering
index b90a326..ee7c8b3 100644 (file)
@@ -2,6 +2,8 @@
 <!--*-nxml-*-->
 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2016 Lennart Poettering
index 49ea7e5..b0f5b19 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2010 Lennart Poettering
index c60b9c0..a275a88 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2010 Lennart Poettering
     the escaping logic used to convert a file system path to a unit
     name see
     <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
+
+    <para>Device units will be reloaded by systemd whenever the
+    corresponding device generates a <literal>changed</literal> event.
+    Other units can use <varname>ReloadPropagatedFrom=</varname> to react
+    to that event</para>
+
   </refsect1>
 
   <refsect1>
   <refsect1>
     <title>The udev Database</title>
 
-    <para>The settings of device units may either be configured via
-    unit files, or directly from the udev database (which is
-    recommended). The following udev device properties are understood
-    by systemd:</para>
+    <para>Unit settings of device units may either be configured via unit files, or directly from the udev
+    database. The following udev device properties are understood by the service manager:</para>
 
     <variablelist class='udev-directives'>
       <varlistentry>
         <term><varname>SYSTEMD_WANTS=</varname></term>
         <term><varname>SYSTEMD_USER_WANTS=</varname></term>
-        <listitem><para>Adds dependencies of type
-        <varname>Wants</varname> from the device unit to all listed
-        units. The first form is used by the system systemd instance,
-        the second by user systemd instances. Those settings may be
-        used to activate arbitrary units when a specific device
-        becomes available.</para>
-
-        <para>Note that this and the other tags are not taken into
-        account unless the device is tagged with the
-        <literal>systemd</literal> string in the udev database,
-        because otherwise the device is not exposed as a systemd unit
-        (see above).</para>
-
-        <para>Note that systemd will only act on
-        <varname>Wants</varname> dependencies when a device first
-        becomes active. It will not act on them if they are added to
-        devices that are already active. Use
-        <varname>SYSTEMD_READY=</varname> (see below) to influence on
-        which udev event to trigger the dependencies.
-        </para></listitem>
+        <listitem><para>Adds dependencies of type <varname>Wants=</varname> from the device unit to the specified
+        units. <varname>SYSTEMD_WANTS=</varname> is read by the system service manager,
+        <varname>SYSTEMD_USER_WANTS=</varname> by user service manager instances. These properties may be used to
+        activate arbitrary units when a specific device becomes available.</para>
+
+        <para>Note that this and the other udev device properties are not taken into account unless the device is
+        tagged with the <literal>systemd</literal> tag in the udev database, because otherwise the device is not
+        exposed as a systemd unit (see above).</para>
+
+        <para>Note that systemd will only act on <varname>Wants=</varname> dependencies when a device first becomes
+        active. It will not act on them if they are added to devices that are already active. Use
+        <varname>SYSTEMD_READY=</varname> (see below) to configure when a udev device shall be considered active, and
+        thus when to trigger the dependencies.</para>
+
+        <!-- Note that we don't document here that we actually apply unit_name_mangle() to all specified names, since
+             that's kinda ugly, and people should instead specify correctly escaped names -->
+
+        <para>The specified property value should be a space-separated list of valid unit names. If a unit template
+        name is specified (that is, a unit name containing an <literal>@</literal> character indicating a unit name to
+        use for multiple instantiation, but with an empty instance name following the <literal>@</literal>), it will be
+        automatically instantiated by the device's <literal>sysfs</literal> path (that is: the path is escaped and
+        inserted as instance name into the template unit name). This is useful in order to instantiate a specific
+        template unit once for each device that appears and matches specific properties.</para></listitem>
       </varlistentry>
 
       <varlistentry>
 
       <varlistentry>
         <term><varname>SYSTEMD_READY=</varname></term>
-        <listitem><para>If set to 0, systemd will consider this device
-        unplugged even if it shows up in the udev tree. If this
-        property is unset or set to 1, the device will be considered
-        plugged if it is visible in the udev tree. This property has
-        no influence on the behavior when a device disappears from the
-        udev tree.</para>
-
-        <para>This option is useful to support devices that initially
-        show up in an uninitialized state in the tree, and for which a
-        <literal>changed</literal> event is generated the moment they
-        are fully set up. Note that <varname>SYSTEMD_WANTS=</varname>
-        (see above) is not acted on as long as
-        <varname>SYSTEMD_READY=0</varname> is set for a
-        device.</para></listitem>
+        <listitem><para>If set to 0, systemd will consider this device unplugged even if it shows up in the udev
+        tree. If this property is unset or set to 1, the device will be considered plugged if it is visible in the udev
+        tree.</para>
+
+        <para>This option is useful for devices that initially show up in an uninitialized state in the tree, and for
+        which a <literal>changed</literal> event is generated the moment they are fully set up. Note that
+        <varname>SYSTEMD_WANTS=</varname> (see above) is not acted on as long as <varname>SYSTEMD_READY=0</varname> is
+        set for a device.</para></listitem>
       </varlistentry>
 
       <varlistentry>
diff --git a/man/systemd.dnssd.xml b/man/systemd.dnssd.xml
new file mode 100644 (file)
index 0000000..1270e08
--- /dev/null
@@ -0,0 +1,258 @@
+<?xml version='1.0'?> <!--*- Mode: nxml; nxml-child-indent: 2; indent-tabs-mode: nil -*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+  "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2017 Dmitry Rozhkov
+
+  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.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd.dnssd" conditional='ENABLE_RESOLVE'>
+
+  <refentryinfo>
+    <title>systemd.dnssd</title>
+    <productname>systemd</productname>
+
+    <authorgroup>
+      <author>
+        <contrib>Developer</contrib>
+        <firstname>Dmitry</firstname>
+        <surname>Rozhkov</surname>
+        <email>dmitry.rozhkov@intel.com</email>
+      </author>
+    </authorgroup>
+  </refentryinfo>
+
+  <refmeta>
+    <refentrytitle>systemd.dnssd</refentrytitle>
+    <manvolnum>5</manvolnum>
+  </refmeta>
+
+  <refnamediv>
+    <refname>systemd.dnssd</refname>
+    <refpurpose>DNS-SD configuration</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <para><filename><replaceable>network_service</replaceable>.dnssd</filename></para>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>DNS-SD setup is performed by
+    <citerefentry><refentrytitle>systemd-resolved</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
+    </para>
+
+    <para>The main network service file must have the extension <filename>.dnssd</filename>; other
+    extensions are ignored.</para>
+
+    <para>The <filename>.dnssd</filename> files are read from the files located in the system
+    network directory <filename>/usr/lib/systemd/dnssd</filename>, the volatile runtime network
+    directory <filename>/run/systemd/dnssd</filename> and the local administration network
+    directory <filename>/etc/systemd/dnssd</filename>. All configuration files are collectively
+    sorted and processed in lexical order, regardless of the directories in which they live.
+    However, files with identical filenames replace each other. Files in <filename>/etc</filename>
+    have the highest priority, files in <filename>/run</filename> take precedence over files with
+    the same name in <filename>/usr/lib</filename>. This can be used to override a system-supplied
+    configuration file with a local file if needed.</para>
+
+    <para>Along with the network service file <filename>foo.dnssd</filename>, a "drop-in" directory
+    <filename>foo.dnssd.d/</filename> may exist. All files with the suffix
+    <literal>.conf</literal> from this directory will be parsed after the file itself is
+    parsed. This is useful to alter or add configuration settings, without having to modify the main
+    configuration file. Each drop-in file must have appropriate section headers.</para>
+
+    <para>In addition to <filename>/etc/systemd/dnssd</filename>, drop-in <literal>.d</literal>
+    directories can be placed in <filename>/usr/lib/systemd/dnssd</filename> or
+    <filename>/run/systemd/dnssd</filename> directories. Drop-in files in
+    <filename>/etc</filename> take precedence over those in <filename>/run</filename> which in turn
+    take precedence over those in <filename>/usr/lib</filename>. Drop-in files under any of these
+    directories take precedence over the main network service file wherever located. (Of course, since
+    <filename>/run</filename> is temporary and <filename>/usr/lib</filename> is for vendors, it is
+    unlikely drop-ins should be used in either of those places.)</para>
+  </refsect1>
+
+  <refsect1>
+    <title>[Service] Section Options</title>
+
+      <para>The network service file contains a <literal>[Service]</literal>
+      section, which specifies a discoverable network service announced in a
+      local network with Multicast DNS broadcasts.</para>
+
+      <variablelist class='network-directives'>
+        <varlistentry>
+          <term><varname>Name=</varname></term>
+          <listitem>
+            <para>An instance name of the network service as defined in the section 4.1.1 of <ulink
+            url="https://tools.ietf.org/html/rfc6763">RFC 6763</ulink>, e.g. <literal>webserver</literal>.</para>
+            <para>The option supports simple specifier expansion. The following expansions are understood:</para>
+            <table>
+              <title>Specifiers available</title>
+              <tgroup cols='3' align='left' colsep='1' rowsep='1'>
+                <colspec colname="spec" />
+                <colspec colname="mean" />
+                <colspec colname="detail" />
+                <thead>
+                  <row>
+                    <entry>Specifier</entry>
+                    <entry>Meaning</entry>
+                    <entry>Details</entry>
+                  </row>
+                </thead>
+                <tbody>
+                  <row>
+                    <entry><literal>%m</literal></entry>
+                    <entry>Machine ID</entry>
+                    <entry>The machine ID of the running system, formatted as string. See <citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry> for more information.</entry>
+                  </row>
+                  <row>
+                    <entry><literal>%b</literal></entry>
+                    <entry>Boot ID</entry>
+                    <entry>The boot ID of the running system, formatted as string. See <citerefentry><refentrytitle>random</refentrytitle><manvolnum>4</manvolnum></citerefentry> for more information.</entry>
+                  </row>
+                  <row>
+                    <entry><literal>%H</literal></entry>
+                    <entry>Host name</entry>
+                    <entry>The hostname of the running system.</entry>
+                  </row>
+                  <row>
+                    <entry><literal>%v</literal></entry>
+                    <entry>Kernel release</entry>
+                    <entry>Identical to <command>uname -r</command> output.</entry>
+                  </row>
+                </tbody>
+              </tgroup>
+            </table>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><varname>Type=</varname></term>
+          <listitem>
+            <para>A type of the network service as defined in the section 4.1.2 of <ulink
+            url="https://tools.ietf.org/html/rfc6763">RFC 6763</ulink>, e.g. <literal>_http._tcp</literal>.
+            </para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><varname>Port=</varname></term>
+          <listitem>
+            <para>An IP port number of the network service.</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><varname>Priority=</varname></term>
+          <listitem>
+            <para>A priority number set in SRV resource records corresponding to the network service.</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><varname>Weight=</varname></term>
+          <listitem>
+            <para>A weight number set in SRV resource records corresponding to the network service.</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><varname>TxtText=</varname></term>
+          <listitem>
+            <para>A whitespace-separated list of arbitrary key/value pairs
+            conveying additional information about the named service in the corresponding TXT resource record,
+            e.g. <literal>path=/portal/index.html</literal>. Keys and values can contain C-style escape
+            sequences which get translated upon reading configuration files.
+            </para>
+            <para>This option together with <varname>TxtData=</varname> may be specified more than once, in which
+            case multiple TXT resource records will be created for the service. If the empty string is assigned to
+            this option, the list is reset and all prior assignments will have no effect.
+            </para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><varname>TxtData=</varname></term>
+          <listitem>
+            <para>A whitespace-separated list of arbitrary key/value pairs
+            conveying additional information about the named service in the corresponding TXT resource record
+            where values are base64-encoded string representing any binary data,
+            e.g. <literal>data=YW55IGJpbmFyeSBkYXRhCg==</literal>. Keys can contain C-style escape
+            sequences which get translated upon reading configuration files.
+            </para>
+            <para>This option together with <varname>TxtText=</varname> may be specified more than once, in which
+            case multiple TXT resource records will be created for the service. If the empty string is assigned to
+            this option, the list is reset and all prior assignments will have no effect.
+            </para>
+          </listitem>
+        </varlistentry>
+      </variablelist>
+
+  </refsect1>
+
+  <refsect1>
+    <title>Examples</title>
+    <example>
+      <title>HTTP service</title>
+
+      <programlisting># /etc/systemd/dnssd/http.dnssd
+[Service]
+Name=%h
+Type=_http._tcp
+Port=80
+TxtText=path=/stats/index.html t=temperature_sensor</programlisting>
+
+      <para>This makes the http server running on the host discoverable in the local network
+      given MulticastDNS is enabled on the network interface.</para>
+
+      <para>Now the utility <literal>systemd-resolve</literal> should be able to resolve the
+      service to the host's name:</para>
+
+      <programlisting>$ systemd-resolve  --service meteo._http._tcp.local
+meteo._http._tcp.local: meteo.local:80 [priority=0, weight=0]
+                        169.254.208.106%senp0s21f0u2u4
+                        fe80::213:3bff:fe49:8aa%senp0s21f0u2u4
+                        path=/stats/index.html
+                        t=temperature_sensor
+                        (meteo/_http._tcp/local)
+
+-- Information acquired via protocol mDNS/IPv6 in 4.0ms.
+-- Data is authenticated: yes</programlisting>
+
+      <para><literal>Avahi</literal> running on a different host in the same local network should see the service as well:</para>
+
+      <programlisting>$ avahi-browse -a -r
++ enp3s0 IPv6 meteo                                         Web Site             local
++ enp3s0 IPv4 meteo                                         Web Site             local
+= enp3s0 IPv6 meteo                                         Web Site             local
+   hostname = [meteo.local]
+   address = [fe80::213:3bff:fe49:8aa]
+   port = [80]
+   txt = ["path=/stats/index.html" "t=temperature_sensor"]
+= enp3s0 IPv4 meteo                                         Web Site             local
+   hostname = [meteo.local]
+   address = [169.254.208.106]
+   port = [80]
+   txt = ["path=/stats/index.html" "t=temperature_sensor"]</programlisting>
+
+    </example>
+  </refsect1>
+
+  <refsect1>
+    <title>See Also</title>
+    <para>
+      <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>systemd-resolved.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+    </para>
+  </refsect1>
+
+</refentry>
index ff8be92..d5e773e 100644 (file)
@@ -6,6 +6,8 @@
 ]>
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2017 Zbigniew Jędrzejewski-Szmek
@@ -47,7 +49,7 @@
 
   <refnamediv>
     <refname>systemd.environment-generator</refname>
-    <refpurpose>Systemd environment file generators</refpurpose>
+    <refpurpose>systemd environment file generators</refpurpose>
   </refnamediv>
 
   <refsynopsisdiv>
index 42fa460..ce59a88 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2010 Lennart Poettering
   <refsect1>
     <title>Description</title>
 
-    <para>Unit configuration files for services, sockets, mount
-    points, and swap devices share a subset of configuration options
-    which define the execution environment of spawned
-    processes.</para>
+    <para>Unit configuration files for services, sockets, mount points, and swap devices share a subset of
+    configuration options which define the execution environment of spawned processes.</para>
 
-    <para>This man page lists the configuration options shared by
-    these four unit types. See
-    <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
-    for the common options of all unit configuration files, and
+    <para>This man page lists the configuration options shared by these four unit types. See
+    <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry> for the common
+    options of all unit configuration files, and
     <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
     <citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
-    <citerefentry><refentrytitle>systemd.swap</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
-    and
-    <citerefentry><refentrytitle>systemd.mount</refentrytitle><manvolnum>5</manvolnum></citerefentry>
-    for more information on the specific unit configuration files. The
-    execution specific configuration options are configured in the
-    [Service], [Socket], [Mount], or [Swap] sections, depending on the
-    unit type.</para>
+    <citerefentry><refentrytitle>systemd.swap</refentrytitle><manvolnum>5</manvolnum></citerefentry>, and
+    <citerefentry><refentrytitle>systemd.mount</refentrytitle><manvolnum>5</manvolnum></citerefentry> for more
+    information on the specific unit configuration files. The execution specific configuration options are configured
+    in the [Service], [Socket], [Mount], or [Swap] sections, depending on the unit type.</para>
 
     <para>In addition, options which control resources through Linux Control Groups (cgroups) are listed in
     <citerefentry><refentrytitle>systemd.resource-control</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
     <para>A few execution parameters result in additional, automatic dependencies to be added:</para>
 
     <itemizedlist>
-      <listitem><para>Units with <varname>WorkingDirectory=</varname>, <varname>RootDirectory=</varname>, <varname>RootImage=</varname>,
-      <varname>RuntimeDirectory=</varname>, <varname>StateDirectory=</varname>, <varname>CacheDirectory=</varname>,
-      <varname>LogsDirectory=</varname> or <varname>ConfigurationDirectory=</varname> set automatically gain dependencies
-      of type <varname>Requires=</varname> and <varname>After=</varname> on all mount units required to access the specified paths.
-      This is equivalent to having them listed explicitly in <varname>RequiresMountsFor=</varname>.</para></listitem>
-
-      <listitem><para>Similar, units with <varname>PrivateTmp=</varname> enabled automatically get mount unit dependencies for all
-      mounts required to access <filename>/tmp</filename> and <filename>/var/tmp</filename>. They will also gain an
-      automatic <varname>After=</varname> dependency on
+      <listitem><para>Units with <varname>WorkingDirectory=</varname>, <varname>RootDirectory=</varname>,
+      <varname>RootImage=</varname>, <varname>RuntimeDirectory=</varname>, <varname>StateDirectory=</varname>,
+      <varname>CacheDirectory=</varname>, <varname>LogsDirectory=</varname> or
+      <varname>ConfigurationDirectory=</varname> set automatically gain dependencies of type
+      <varname>Requires=</varname> and <varname>After=</varname> on all mount units required to access the specified
+      paths.  This is equivalent to having them listed explicitly in
+      <varname>RequiresMountsFor=</varname>.</para></listitem>
+
+      <listitem><para>Similar, units with <varname>PrivateTmp=</varname> enabled automatically get mount unit
+      dependencies for all mounts required to access <filename>/tmp</filename> and <filename>/var/tmp</filename>. They
+      will also gain an automatic <varname>After=</varname> dependency on
       <citerefentry><refentrytitle>systemd-tmpfiles-setup.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para></listitem>
 
-      <listitem><para>Units whose standard output or error output is connected to <option>journal</option>, <option>syslog</option>
-      or <option>kmsg</option> (or their combinations with console output, see below) automatically acquire dependencies
-      of type <varname>After=</varname> on <filename>systemd-journald.socket</filename>.</para></listitem>
+      <listitem><para>Units whose standard output or error output is connected to <option>journal</option>,
+      <option>syslog</option> or <option>kmsg</option> (or their combinations with console output, see below)
+      automatically acquire dependencies of type <varname>After=</varname> on
+      <filename>systemd-journald.socket</filename>.</para></listitem>
     </itemizedlist>
   </refsect1>
 
   <!-- We don't have any default dependency here. -->
 
   <refsect1>
-    <title>Options</title>
+    <title>Paths</title>
 
     <variablelist class='unit-directives'>
 
 
       <varlistentry>
         <term><varname>RootImage=</varname></term>
+
         <listitem><para>Takes a path to a block device node or regular file as argument. This call is similar to
         <varname>RootDirectory=</varname> however mounts a file system hierarchy from a block device node or loopback
         file instead of a directory. The device node or file system image file needs to contain a file system without a
       </varlistentry>
 
       <varlistentry>
+        <term><varname>BindPaths=</varname></term>
+        <term><varname>BindReadOnlyPaths=</varname></term>
+
+        <listitem><para>Configures unit-specific bind mounts. A bind mount makes a particular file or directory
+        available at an additional place in the unit's view of the file system. Any bind mounts created with this
+        option are specific to the unit, and are not visible in the host's mount table. This option expects a
+        whitespace separated list of bind mount definitions. Each definition consists of a colon-separated triple of
+        source path, destination path and option string, where the latter two are optional. If only a source path is
+        specified the source and destination is taken to be the same. The option string may be either
+        <literal>rbind</literal> or <literal>norbind</literal> for configuring a recursive or non-recursive bind
+        mount. If the destination path is omitted, the option string must be omitted too.</para>
+
+        <para><varname>BindPaths=</varname> creates regular writable bind mounts (unless the source file system mount
+        is already marked read-only), while <varname>BindReadOnlyPaths=</varname> creates read-only bind mounts. These
+        settings may be used more than once, each usage appends to the unit's list of bind mounts. If the empty string
+        is assigned to either of these two options the entire list of bind mounts defined prior to this is reset. Note
+        that in this case both read-only and regular bind mounts are reset, regardless which of the two settings is
+        used.</para>
+
+        <para>This option is particularly useful when <varname>RootDirectory=</varname>/<varname>RootImage=</varname>
+        is used. In this case the source path refers to a path on the host file system, while the destination path
+        refers to a path below the root directory of the unit.</para></listitem>
+      </varlistentry>
+
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Credentials</title>
+
+    <variablelist class='unit-directives'>
+
+      <varlistentry>
         <term><varname>User=</varname></term>
         <term><varname>Group=</varname></term>
 
         <listitem><para>Set the UNIX user or group that the processes are executed as, respectively. Takes a single
-        user or group name, or a numeric ID as argument. For system services (services run by the system service manager,
-        i.e. managed by PID 1) and for user services of the root user (services managed by root's instance of
+        user or group name, or a numeric ID as argument. For system services (services run by the system service
+        manager, i.e. managed by PID 1) and for user services of the root user (services managed by root's instance of
         <command>systemd --user</command>), the default is <literal>root</literal>, but <varname>User=</varname> may be
         used to specify a different user. For user services of any other user, switching user identity is not
         permitted, hence the only valid setting is the same user the user's service manager is running as. If no group
         enabled for a unit, the name of the dynamic user/group is implicitly derived from the unit name. If the unit
         name without the type suffix qualifies as valid user name it is used directly, otherwise a name incorporating a
         hash of it is used. If a statically allocated user or group of the configured name already exists, it is used
-        and no dynamic user/group is allocated. Dynamic users/groups are allocated from the UID/GID range
+        and no dynamic user/group is allocated. Note that if <varname>User=</varname> is specified and the static group
+        with the name exists, then it is required that the static user with the name already exists. Similarly, if
+        <varname>Group=</varname> is specified and the static user with the name exists, then it is required that the
+        static group with the name already exists. Dynamic users/groups are allocated from the UID/GID range
         61184…65519. It is recommended to avoid this range for regular system or login users.  At any point in time
         each UID/GID from this range is only assigned to zero or one dynamically allocated users/groups in
         use. However, UID/GIDs are recycled after a unit is terminated. Care should be taken that any processes running
       <varlistentry>
         <term><varname>SupplementaryGroups=</varname></term>
 
-        <listitem><para>Sets the supplementary Unix groups the
-        processes are executed as. This takes a space-separated list
-        of group names or IDs. This option may be specified more than
-        once, in which case all listed groups are set as supplementary
-        groups. When the empty string is assigned, the list of
-        supplementary groups is reset, and all assignments prior to
-        this one will have no effect. In any way, this option does not
-        override, but extends the list of supplementary groups
-        configured in the system group database for the
-        user. This does not affect commands prefixed with <literal>+</literal>.</para></listitem>
-      </varlistentry>
-
-      <varlistentry>
-        <term><varname>RemoveIPC=</varname></term>
-
-        <listitem><para>Takes a boolean parameter. If set, all System V and POSIX IPC objects owned by the user and
-        group the processes of this unit are run as are removed when the unit is stopped. This setting only has an
-        effect if at least one of <varname>User=</varname>, <varname>Group=</varname> and
-        <varname>DynamicUser=</varname> are used. It has no effect on IPC objects owned by the root user. Specifically,
-        this removes System V semaphores, as well as System V and POSIX shared memory segments and message queues. If
-        multiple units use the same user or group the IPC objects are removed when the last of these units is
-        stopped. This setting is implied if <varname>DynamicUser=</varname> is set.</para></listitem>
+        <listitem><para>Sets the supplementary Unix groups the processes are executed as. This takes a space-separated
+        list of group names or IDs. This option may be specified more than once, in which case all listed groups are
+        set as supplementary groups. When the empty string is assigned, the list of supplementary groups is reset, and
+        all assignments prior to this one will have no effect. In any way, this option does not override, but extends
+        the list of supplementary groups configured in the system group database for the user. This does not affect
+        commands prefixed with <literal>+</literal>.</para></listitem>
       </varlistentry>
 
       <varlistentry>
-        <term><varname>Nice=</varname></term>
+        <term><varname>PAMName=</varname></term>
 
-        <listitem><para>Sets the default nice level (scheduling
-        priority) for executed processes. Takes an integer between -20
-        (highest priority) and 19 (lowest priority). See
-        <citerefentry><refentrytitle>setpriority</refentrytitle><manvolnum>2</manvolnum></citerefentry>
-        for details.</para></listitem>
-      </varlistentry>
+        <listitem><para>Sets the PAM service name to set up a session as. If set, the executed process will be
+        registered as a PAM session under the specified service name. This is only useful in conjunction with the
+        <varname>User=</varname> setting, and is otherwise ignored. If not set, no PAM session will be opened for the
+        executed processes. See <citerefentry
+        project='man-pages'><refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum></citerefentry> for
+        details.</para>
 
-      <varlistentry>
-        <term><varname>OOMScoreAdjust=</varname></term>
+        <para>Note that for each unit making use of this option a PAM session handler process will be maintained as
+        part of the unit and stays around as long as the unit is active, to ensure that appropriate actions can be
+        taken when the unit and hence the PAM session terminates. This process is named <literal>(sd-pam)</literal> and
+        is an immediate child process of the unit's main process.</para>
 
-        <listitem><para>Sets the adjustment level for the
-        Out-Of-Memory killer for executed processes. Takes an integer
-        between -1000 (to disable OOM killing for this process) and
-        1000 (to make killing of this process under memory pressure
-        very likely). See <ulink
-        url="https://www.kernel.org/doc/Documentation/filesystems/proc.txt">proc.txt</ulink>
-        for details.</para></listitem>
+        <para>Note that when this option is used for a unit it is very likely (depending on PAM configuration) that the
+        main unit process will be migrated to its own session scope unit when it is activated. This process will hence
+        be associated with two units: the unit it was originally started from (and for which
+        <varname>PAMName=</varname> was configured), and the session scope unit. Any child processes of that process
+        will however be associated with the session scope unit only. This has implications when used in combination
+        with <varname>NotifyAccess=</varname><option>all</option>, as these child processes will not be able to affect
+        changes in the original unit through notification messages. These messages will be considered belonging to the
+        session scope unit and not the original unit. It is hence not recommended to use <varname>PAMName=</varname> in
+        combination with <varname>NotifyAccess=</varname><option>all</option>.</para>
+        </listitem>
       </varlistentry>
 
-      <varlistentry>
-        <term><varname>IOSchedulingClass=</varname></term>
-
-        <listitem><para>Sets the I/O scheduling class for executed
-        processes. Takes an integer between 0 and 3 or one of the
-        strings <option>none</option>, <option>realtime</option>,
-        <option>best-effort</option> or <option>idle</option>. See
-        <citerefentry><refentrytitle>ioprio_set</refentrytitle><manvolnum>2</manvolnum></citerefentry>
-        for details.</para></listitem>
-      </varlistentry>
+    </variablelist>
+  </refsect1>
 
-      <varlistentry>
-        <term><varname>IOSchedulingPriority=</varname></term>
+  <refsect1>
+    <title>Capabilities</title>
 
-        <listitem><para>Sets the I/O scheduling priority for executed
-        processes. Takes an integer between 0 (highest priority) and 7
-        (lowest priority). The available priorities depend on the
-        selected I/O scheduling class (see above). See
-        <citerefentry><refentrytitle>ioprio_set</refentrytitle><manvolnum>2</manvolnum></citerefentry>
-        for details.</para></listitem>
-      </varlistentry>
+    <variablelist class='unit-directives'>
 
       <varlistentry>
-        <term><varname>CPUSchedulingPolicy=</varname></term>
-
-        <listitem><para>Sets the CPU scheduling policy for executed
-        processes. Takes one of
-        <option>other</option>,
-        <option>batch</option>,
-        <option>idle</option>,
-        <option>fifo</option> or
-        <option>rr</option>. See
-        <citerefentry><refentrytitle>sched_setscheduler</refentrytitle><manvolnum>2</manvolnum></citerefentry>
-        for details.</para></listitem>
-      </varlistentry>
+        <term><varname>CapabilityBoundingSet=</varname></term>
 
-      <varlistentry>
-        <term><varname>CPUSchedulingPriority=</varname></term>
+        <listitem><para>Controls which capabilities to include in the capability bounding set for the executed
+        process. See <citerefentry
+        project='man-pages'><refentrytitle>capabilities</refentrytitle><manvolnum>7</manvolnum></citerefentry> for
+        details. Takes a whitespace-separated list of capability names, e.g. <constant>CAP_SYS_ADMIN</constant>,
+        <constant>CAP_DAC_OVERRIDE</constant>, <constant>CAP_SYS_PTRACE</constant>. Capabilities listed will be
+        included in the bounding set, all others are removed. If the list of capabilities is prefixed with
+        <literal>~</literal>, all but the listed capabilities will be included, the effect of the assignment
+        inverted. Note that this option also affects the respective capabilities in the effective, permitted and
+        inheritable capability sets. If this option is not used, the capability bounding set is not modified on process
+        execution, hence no limits on the capabilities of the process are enforced. This option may appear more than
+        once, in which case the bounding sets are merged by <constant>AND</constant>, or by <constant>OR</constant> if
+        the lines are prefixed with <literal>~</literal> (see below). If the empty string is assigned to this option,
+        the bounding set is reset to the empty capability set, and all prior settings have no effect.  If set to
+        <literal>~</literal> (without any further argument), the bounding set is reset to the full set of available
+        capabilities, also undoing any previous settings. This does not affect commands prefixed with
+        <literal>+</literal>.</para>
 
-        <listitem><para>Sets the CPU scheduling priority for executed
-        processes. The available priority range depends on the
-        selected CPU scheduling policy (see above). For real-time
-        scheduling policies an integer between 1 (lowest priority) and
-        99 (highest priority) can be used. See
-        <citerefentry><refentrytitle>sched_setscheduler</refentrytitle><manvolnum>2</manvolnum></citerefentry>
-        for details. </para></listitem>
+        <para>Example: if a unit has the following,
+        <programlisting>CapabilityBoundingSet=CAP_A CAP_B
+CapabilityBoundingSet=CAP_B CAP_C</programlisting>
+        then <constant>CAP_A</constant>, <constant>CAP_B</constant>, and <constant>CAP_C</constant> are set.
+        If the second line is prefixed with <literal>~</literal>, e.g.,
+        <programlisting>CapabilityBoundingSet=CAP_A CAP_B
+CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
+        then, only <constant>CAP_A</constant> is set.</para></listitem>
       </varlistentry>
 
       <varlistentry>
-        <term><varname>CPUSchedulingResetOnFork=</varname></term>
+        <term><varname>AmbientCapabilities=</varname></term>
 
-        <listitem><para>Takes a boolean argument. If true, elevated
-        CPU scheduling priorities and policies will be reset when the
-        executed processes fork, and can hence not leak into child
-        processes. See
-        <citerefentry><refentrytitle>sched_setscheduler</refentrytitle><manvolnum>2</manvolnum></citerefentry>
-        for details. Defaults to false.</para></listitem>
+        <listitem><para>Controls which capabilities to include in the ambient capability set for the executed
+        process. Takes a whitespace-separated list of capability names, e.g. <constant>CAP_SYS_ADMIN</constant>,
+        <constant>CAP_DAC_OVERRIDE</constant>, <constant>CAP_SYS_PTRACE</constant>. This option may appear more than
+        once in which case the ambient capability sets are merged (see the above examples in
+        <varname>CapabilityBoundingSet=</varname>). If the list of capabilities is prefixed with <literal>~</literal>,
+        all but the listed capabilities will be included, the effect of the assignment inverted. If the empty string is
+        assigned to this option, the ambient capability set is reset to the empty capability set, and all prior
+        settings have no effect.  If set to <literal>~</literal> (without any further argument), the ambient capability
+        set is reset to the full set of available capabilities, also undoing any previous settings. Note that adding
+        capabilities to ambient capability set adds them to the process's inherited capability set.  </para><para>
+        Ambient capability sets are useful if you want to execute a process as a non-privileged user but still want to
+        give it some capabilities.  Note that in this case option <constant>keep-caps</constant> is automatically added
+        to <varname>SecureBits=</varname> to retain the capabilities over the user
+        change. <varname>AmbientCapabilities=</varname> does not affect commands prefixed with
+        <literal>+</literal>.</para></listitem>
       </varlistentry>
 
-      <varlistentry>
-        <term><varname>CPUAffinity=</varname></term>
+    </variablelist>
+  </refsect1>
 
-        <listitem><para>Controls the CPU affinity of the executed
-        processes. Takes a list of CPU indices or ranges separated by
-        either whitespace or commas. CPU ranges are specified by the
-        lower and upper CPU indices separated by a dash.
-        This option may be specified more than once, in which case the
-        specified CPU affinity masks are merged. If the empty string
-        is assigned, the mask is reset, all assignments prior to this
-        will have no effect. See
-        <citerefentry><refentrytitle>sched_setaffinity</refentrytitle><manvolnum>2</manvolnum></citerefentry>
-        for details.</para></listitem>
-      </varlistentry>
 
-      <varlistentry>
-        <term><varname>UMask=</varname></term>
+  <refsect1>
+    <title>Security</title>
 
-        <listitem><para>Controls the file mode creation mask. Takes an
-        access mode in octal notation. See
-        <citerefentry><refentrytitle>umask</refentrytitle><manvolnum>2</manvolnum></citerefentry>
-        for details. Defaults to 0022.</para></listitem>
-      </varlistentry>
+    <variablelist class='unit-directives'>
 
       <varlistentry>
-        <term><varname>Environment=</varname></term>
-
-        <listitem><para>Sets environment variables for executed
-        processes. Takes a space-separated list of variable
-        assignments. This option may be specified more than once, in
-        which case all listed variables will be set. If the same
-        variable is set twice, the later setting will override the
-        earlier setting. If the empty string is assigned to this
-        option, the list of environment variables is reset, all prior
-        assignments have no effect. Variable expansion is not
-        performed inside the strings, however, specifier expansion is
-        possible. The $ character has no special meaning. If you need
-        to assign a value containing spaces or the equals sign to a variable, use double
-        quotes (") for the assignment.</para>
-
-        <para>Example:
-        <programlisting>Environment="VAR1=word1 word2" VAR2=word3 "VAR3=$word 5 6"</programlisting>
-        gives three variables <literal>VAR1</literal>,
-        <literal>VAR2</literal>, <literal>VAR3</literal>
-        with the values <literal>word1 word2</literal>,
-        <literal>word3</literal>, <literal>$word 5 6</literal>.
-        </para>
+        <term><varname>NoNewPrivileges=</varname></term>
 
-        <para>
-        See
-        <citerefentry project='man-pages'><refentrytitle>environ</refentrytitle><manvolnum>7</manvolnum></citerefentry>
-        for details about environment variables.</para></listitem>
-      </varlistentry>
-      <varlistentry>
-        <term><varname>EnvironmentFile=</varname></term>
-        <listitem><para>Similar to <varname>Environment=</varname> but
-        reads the environment variables from a text file. The text
-        file should contain new-line-separated variable assignments.
-        Empty lines, lines without an <literal>=</literal> separator,
-        or lines starting with ; or # will be ignored,
-        which may be used for commenting. A line ending with a
-        backslash will be concatenated with the following one,
-        allowing multiline variable definitions. The parser strips
-        leading and trailing whitespace from the values of
-        assignments, unless you use double quotes (").</para>
-
-        <para>The argument passed should be an absolute filename or
-        wildcard expression, optionally prefixed with
-        <literal>-</literal>, which indicates that if the file does
-        not exist, it will not be read and no error or warning message
-        is logged. This option may be specified more than once in
-        which case all specified files are read. If the empty string
-        is assigned to this option, the list of file to read is reset,
-        all prior assignments have no effect.</para>
-
-        <para>The files listed with this directive will be read
-        shortly before the process is executed (more specifically,
-        after all processes from a previous unit state terminated.
-        This means you can generate these files in one unit state, and
-        read it with this option in the next).</para>
-
-        <para>Settings from these
-        files override settings made with
-        <varname>Environment=</varname>. If the same variable is set
-        twice from these files, the files will be read in the order
-        they are specified and the later setting will override the
-        earlier setting.</para></listitem>
+        <listitem><para>Takes a boolean argument. If true, ensures that the service process and all its children can
+        never gain new privileges through <function>execve()</function> (e.g. via setuid or setgid bits, or filesystem
+        capabilities). This is the simplest and most effective way to ensure that a process and its children can never
+        elevate privileges again. Defaults to false, but certain settings force <varname>NoNewPrivileges=yes</varname>,
+        ignoring the value of this setting.  This is the case when <varname>SystemCallFilter=</varname>,
+        <varname>SystemCallArchitectures=</varname>, <varname>RestrictAddressFamilies=</varname>,
+        <varname>RestrictNamespaces=</varname>, <varname>PrivateDevices=</varname>,
+        <varname>ProtectKernelTunables=</varname>, <varname>ProtectKernelModules=</varname>,
+        <varname>MemoryDenyWriteExecute=</varname>, or <varname>RestrictRealtime=</varname> are specified. Also see
+        <ulink url="https://www.kernel.org/doc/html/latest/userspace-api/no_new_privs.html">No New Privileges
+        Flag</ulink>.  </para></listitem>
       </varlistentry>
 
       <varlistentry>
-        <term><varname>PassEnvironment=</varname></term>
-
-        <listitem><para>Pass environment variables set for the system service manager to executed processes. Takes a
-        space-separated list of variable names. This option may be specified more than once, in which case all listed
-        variables will be passed. If the empty string is assigned to this option, the list of environment variables to
-        pass is reset, all prior assignments have no effect. Variables specified that are not set for the system
-        manager will not be passed and will be silently ignored. Note that this option is only relevant for the system
-        service manager, as system services by default do not automatically inherit any environment variables set for
-        the service manager itself. However, in case of the user service manager all environment variables are passed
-        to the executed processes anyway, hence this option is without effect for the user service manager.</para>
-
-        <para>Variables set for invoked processes due to this setting are subject to being overridden by those
-        configured with <varname>Environment=</varname> or <varname>EnvironmentFile=</varname>.</para>
-
-        <para>Example:
-        <programlisting>PassEnvironment=VAR1 VAR2 VAR3</programlisting>
-        passes three variables <literal>VAR1</literal>,
-        <literal>VAR2</literal>, <literal>VAR3</literal>
-        with the values set for those variables in PID1.</para>
+        <term><varname>SecureBits=</varname></term>
 
-        <para>
-        See
-        <citerefentry project='man-pages'><refentrytitle>environ</refentrytitle><manvolnum>7</manvolnum></citerefentry>
-        for details about environment variables.</para></listitem>
+        <listitem><para>Controls the secure bits set for the executed process. Takes a space-separated combination of
+        options from the following list: <option>keep-caps</option>, <option>keep-caps-locked</option>,
+        <option>no-setuid-fixup</option>, <option>no-setuid-fixup-locked</option>, <option>noroot</option>, and
+        <option>noroot-locked</option>.  This option may appear more than once, in which case the secure bits are
+        ORed. If the empty string is assigned to this option, the bits are reset to 0. This does not affect commands
+        prefixed with <literal>+</literal>.  See <citerefentry
+        project='man-pages'><refentrytitle>capabilities</refentrytitle><manvolnum>7</manvolnum></citerefentry> for
+        details.</para></listitem>
       </varlistentry>
 
-      <varlistentry>
-        <term><varname>UnsetEnvironment=</varname></term>
-
-        <listitem><para>Explicitly unset environment variable assignments that would normally be passed from the
-        service manager to invoked processes of this unit. Takes a space-separated list of variable names or variable
-        assignments. This option may be specified more than once, in which case all listed variables/assignments will
-        be unset. If the empty string is assigned to this option, the list of environment variables/assignments to
-        unset is reset. If a variable assignment is specified (that is: a variable name, followed by
-        <literal>=</literal>, followed by its value), then any environment variable matching this precise assignment is
-        removed. If a variable name is specified (that is a variable name without any following <literal>=</literal> or
-        value), then any assignment matching the variable name, regardless of its value is removed. Note that the
-        effect of <varname>UnsetEnvironment=</varname> is applied as final step when the environment list passed to
-        executed processes is compiled. That means it may undo assignments from any configuration source, including
-        assignments made through <varname>Environment=</varname> or <varname>EnvironmentFile=</varname>, inherited from
-        the system manager's global set of environment variables, inherited via <varname>PassEnvironment=</varname>,
-        set by the service manager itself (such as <varname>$NOTIFY_SOCKET</varname> and such), or set by a PAM module
-        (in case <varname>PAMName=</varname> is used).</para>
+    </variablelist>
+  </refsect1>
 
-        <para>
-        See
-        <citerefentry project='man-pages'><refentrytitle>environ</refentrytitle><manvolnum>7</manvolnum></citerefentry>
-        for details about environment variables.</para></listitem>
-      </varlistentry>
+  <refsect1>
+    <title>Mandatory Access Control</title>
+    <variablelist>
 
       <varlistentry>
-        <term><varname>StandardInput=</varname></term>
-        <listitem><para>Controls where file descriptor 0 (STDIN) of
-        the executed processes is connected to. Takes one of
-        <option>null</option>,
-        <option>tty</option>,
-        <option>tty-force</option>,
-        <option>tty-fail</option>,
-        <option>socket</option> or
-        <option>fd</option>.</para>
-
-        <para>If <option>null</option> is selected, standard input
-        will be connected to <filename>/dev/null</filename>, i.e. all
-        read attempts by the process will result in immediate
-        EOF.</para>
-
-        <para>If <option>tty</option> is selected, standard input is
-        connected to a TTY (as configured by
-        <varname>TTYPath=</varname>, see below) and the executed
-        process becomes the controlling process of the terminal. If
-        the terminal is already being controlled by another process,
-        the executed process waits until the current controlling
-        process releases the terminal.</para>
-
-        <para><option>tty-force</option> is similar to
-        <option>tty</option>, but the executed process is forcefully
-        and immediately made the controlling process of the terminal,
-        potentially removing previous controlling processes from the
-        terminal.</para>
-
-        <para><option>tty-fail</option> is similar to
-        <option>tty</option> but if the terminal already has a
-        controlling process start-up of the executed process
-        fails.</para>
-
-        <para>The <option>socket</option> option is only valid in
-        socket-activated services, and only when the socket
-        configuration file (see
-        <citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry>
-        for details) specifies a single socket only. If this option is
-        set, standard input will be connected to the socket the
-        service was activated from, which is primarily useful for
-        compatibility with daemons designed for use with the
-        traditional
-        <citerefentry project='freebsd'><refentrytitle>inetd</refentrytitle><manvolnum>8</manvolnum></citerefentry>
-        daemon.</para>
-
-        <para>The <option>fd</option> option connects
-        the input stream to a single file descriptor provided by a socket unit.
-        A custom named file descriptor can be specified as part of this option,
-        after a <literal>:</literal> (e.g. <literal>fd:<replaceable>foobar</replaceable></literal>).
-        If no name is specified, <literal>stdin</literal> is assumed
-        (i.e. <literal>fd</literal> is equivalent to <literal>fd:stdin</literal>).
-        At least one socket unit defining such name must be explicitly provided via the
-        <varname>Sockets=</varname> option, and file descriptor name may differ
-        from the name of its containing socket unit.
-        If multiple matches are found, the first one will be used.
-        See <varname>FileDescriptorName=</varname> in
-        <citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry>
-        for more details about named descriptors and ordering.</para>
+        <term><varname>SELinuxContext=</varname></term>
 
-        <para>This setting defaults to
-        <option>null</option>.</para></listitem>
+        <listitem><para>Set the SELinux security context of the executed process. If set, this will override the
+        automated domain transition. However, the policy still needs to authorize the transition. This directive is
+        ignored if SELinux is disabled. If prefixed by <literal>-</literal>, all errors will be ignored. This does not
+        affect commands prefixed with <literal>+</literal>.  See <citerefentry
+        project='die-net'><refentrytitle>setexeccon</refentrytitle><manvolnum>3</manvolnum></citerefentry> for
+        details.</para></listitem>
       </varlistentry>
 
       <varlistentry>
-        <term><varname>StandardOutput=</varname></term>
-        <listitem><para>Controls where file descriptor 1 (STDOUT) of
-        the executed processes is connected to. Takes one of
-        <option>inherit</option>,
-        <option>null</option>,
-        <option>tty</option>,
-        <option>journal</option>,
-        <option>syslog</option>,
-        <option>kmsg</option>,
-        <option>journal+console</option>,
-        <option>syslog+console</option>,
-        <option>kmsg+console</option>,
-        <option>socket</option> or
-        <option>fd</option>.</para>
-
-        <para><option>inherit</option> duplicates the file descriptor
-        of standard input for standard output.</para>
-
-        <para><option>null</option> connects standard output to
-        <filename>/dev/null</filename>, i.e. everything written to it
-        will be lost.</para>
-
-        <para><option>tty</option> connects standard output to a tty
-        (as configured via <varname>TTYPath=</varname>, see below). If
-        the TTY is used for output only, the executed process will not
-        become the controlling process of the terminal, and will not
-        fail or wait for other processes to release the
-        terminal.</para>
-
-        <para><option>journal</option> connects standard output with
-        the journal which is accessible via
-        <citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>.
-        Note that everything that is written to syslog or kmsg (see
-        below) is implicitly stored in the journal as well, the
-        specific two options listed below are hence supersets of this
-        one.</para>
-
-        <para><option>syslog</option> connects standard output to the
-        <citerefentry project='man-pages'><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>
-        system syslog service, in addition to the journal. Note that
-        the journal daemon is usually configured to forward everything
-        it receives to syslog anyway, in which case this option is no
-        different from <option>journal</option>.</para>
-
-        <para><option>kmsg</option> connects standard output with the
-        kernel log buffer which is accessible via
-        <citerefentry project='man-pages'><refentrytitle>dmesg</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
-        in addition to the journal. The journal daemon might be
-        configured to send all logs to kmsg anyway, in which case this
-        option is no different from <option>journal</option>.</para>
-
-        <para><option>journal+console</option>,
-        <option>syslog+console</option> and
-        <option>kmsg+console</option> work in a similar way as the
-        three options above but copy the output to the system console
-        as well.</para>
-
-        <para><option>socket</option> connects standard output to a
-        socket acquired via socket activation. The semantics are
-        similar to the same option of
-        <varname>StandardInput=</varname>.</para>
-
-        <para>The <option>fd</option> option connects
-        the output stream to a single file descriptor provided by a socket unit.
-        A custom named file descriptor can be specified as part of this option,
-        after a <literal>:</literal> (e.g. <literal>fd:<replaceable>foobar</replaceable></literal>).
-        If no name is specified, <literal>stdout</literal> is assumed
-        (i.e. <literal>fd</literal> is equivalent to <literal>fd:stdout</literal>).
-        At least one socket unit defining such name must be explicitly provided via the
-        <varname>Sockets=</varname> option, and file descriptor name may differ
-        from the name of its containing socket unit.
-        If multiple matches are found, the first one will be used.
-        See <varname>FileDescriptorName=</varname> in
-        <citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry>
-        for more details about named descriptors and ordering.</para>
-
-        <para>If the standard output (or error output, see below) of a unit is connected to the journal, syslog or the
-        kernel log buffer, the unit will implicitly gain a dependency of type <varname>After=</varname> on
-        <filename>systemd-journald.socket</filename> (also see the "Implicit Dependencies" section above).</para>
+        <term><varname>AppArmorProfile=</varname></term>
 
-        <para>This setting defaults to the value set with
-        <option>DefaultStandardOutput=</option> in
-        <citerefentry><refentrytitle>systemd-system.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
-        which defaults to <option>journal</option>. Note that setting
-        this parameter might result in additional dependencies to be
-        added to the unit (see above).</para></listitem>
+        <listitem><para>Takes a profile name as argument. The process executed by the unit will switch to this profile
+        when started.  Profiles must already be loaded in the kernel, or the unit will fail. This result in a non
+        operation if AppArmor is not enabled. If prefixed by <literal>-</literal>, all errors will be ignored. This
+        does not affect commands prefixed with <literal>+</literal>.</para></listitem>
       </varlistentry>
 
       <varlistentry>
-        <term><varname>StandardError=</varname></term>
-        <listitem><para>Controls where file descriptor 2 (STDERR) of
-        the executed processes is connected to. The available options
-        are identical to those of <varname>StandardOutput=</varname>,
-        with some exceptions: if set to <option>inherit</option> the
-        file descriptor used for standard output is duplicated for
-        standard error, while <option>fd</option> operates on the error
-        stream and will look by default for a descriptor named
-        <literal>stderr</literal>.</para>
+        <term><varname>SmackProcessLabel=</varname></term>
 
-        <para>This setting defaults to the value set with
-        <option>DefaultStandardError=</option> in
-        <citerefentry><refentrytitle>systemd-system.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
-        which defaults to <option>inherit</option>. Note that setting
-        this parameter might result in additional dependencies to be
-        added to the unit (see above).</para></listitem>
-      </varlistentry>
+        <listitem><para>Takes a <option>SMACK64</option> security label as argument. The process executed by the unit
+        will be started under this label and SMACK will decide whether the process is allowed to run or not, based on
+        it. The process will continue to run under the label specified here unless the executable has its own
+        <option>SMACK64EXEC</option> label, in which case the process will transition to run under that label. When not
+        specified, the label that systemd is running under is used. This directive is ignored if SMACK is
+        disabled.</para>
 
-      <varlistentry>
-        <term><varname>TTYPath=</varname></term>
-        <listitem><para>Sets the terminal device node to use if
-        standard input, output, or error are connected to a TTY (see
-        above). Defaults to
-        <filename>/dev/console</filename>.</para></listitem>
-      </varlistentry>
-      <varlistentry>
-        <term><varname>TTYReset=</varname></term>
-        <listitem><para>Reset the terminal device specified with
-        <varname>TTYPath=</varname> before and after execution.
-        Defaults to <literal>no</literal>.</para></listitem>
-      </varlistentry>
-      <varlistentry>
-        <term><varname>TTYVHangup=</varname></term>
-        <listitem><para>Disconnect all clients which have opened the
-        terminal device specified with <varname>TTYPath=</varname>
-        before and after execution. Defaults to
-        <literal>no</literal>.</para></listitem>
-      </varlistentry>
-      <varlistentry>
-        <term><varname>TTYVTDisallocate=</varname></term>
-        <listitem><para>If the terminal device specified with
-        <varname>TTYPath=</varname> is a virtual console terminal, try
-        to deallocate the TTY before and after execution. This ensures
-        that the screen and scrollback buffer is cleared. Defaults to
-        <literal>no</literal>.</para></listitem>
-      </varlistentry>
-      <varlistentry>
-        <term><varname>SyslogIdentifier=</varname></term>
-        <listitem><para>Sets the process name to prefix log lines sent
-        to the logging system or the kernel log buffer with. If not
-        set, defaults to the process name of the executed process.
-        This option is only useful when
-        <varname>StandardOutput=</varname> or
-        <varname>StandardError=</varname> are set to
-        <option>syslog</option>, <option>journal</option> or
-        <option>kmsg</option> (or to the same settings in combination
-        with <option>+console</option>).</para></listitem>
-      </varlistentry>
-      <varlistentry>
-        <term><varname>SyslogFacility=</varname></term>
-        <listitem><para>Sets the syslog facility to use when logging
-        to syslog. One of <option>kern</option>,
-        <option>user</option>, <option>mail</option>,
-        <option>daemon</option>, <option>auth</option>,
-        <option>syslog</option>, <option>lpr</option>,
-        <option>news</option>, <option>uucp</option>,
-        <option>cron</option>, <option>authpriv</option>,
-        <option>ftp</option>, <option>local0</option>,
-        <option>local1</option>, <option>local2</option>,
-        <option>local3</option>, <option>local4</option>,
-        <option>local5</option>, <option>local6</option> or
-        <option>local7</option>. See
-        <citerefentry project='man-pages'><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>
-        for details. This option is only useful when
-        <varname>StandardOutput=</varname> or
-        <varname>StandardError=</varname> are set to
-        <option>syslog</option>. Defaults to
-        <option>daemon</option>.</para></listitem>
+        <para>The value may be prefixed by <literal>-</literal>, in which case all errors will be ignored. An empty
+        value may be specified to unset previous assignments. This does not affect commands prefixed with
+        <literal>+</literal>.</para></listitem>
       </varlistentry>
-      <varlistentry>
-        <term><varname>SyslogLevel=</varname></term>
-        <listitem><para>The default syslog level to use when logging to
-        syslog or the kernel log buffer. One of
-        <option>emerg</option>,
-        <option>alert</option>,
-        <option>crit</option>,
-        <option>err</option>,
-        <option>warning</option>,
-        <option>notice</option>,
-        <option>info</option>,
-        <option>debug</option>. See
-        <citerefentry project='man-pages'><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>
-        for details. This option is only useful when
-        <varname>StandardOutput=</varname> or
-        <varname>StandardError=</varname> are set to
-        <option>syslog</option> or <option>kmsg</option>. Note that
-        individual lines output by the daemon might be prefixed with a
-        different log level which can be used to override the default
-        log level specified here. The interpretation of these prefixes
-        may be disabled with <varname>SyslogLevelPrefix=</varname>,
-        see below. For details, see
-        <citerefentry><refentrytitle>sd-daemon</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
 
-        Defaults to
-        <option>info</option>.</para></listitem>
-      </varlistentry>
+    </variablelist>
+  </refsect1>
 
-      <varlistentry>
-        <term><varname>SyslogLevelPrefix=</varname></term>
-        <listitem><para>Takes a boolean argument. If true and
-        <varname>StandardOutput=</varname> or
-        <varname>StandardError=</varname> are set to
-        <option>syslog</option>, <option>kmsg</option> or
-        <option>journal</option>, log lines written by the executed
-        process that are prefixed with a log level will be passed on
-        to syslog with this log level set but the prefix removed. If
-        set to false, the interpretation of these prefixes is disabled
-        and the logged lines are passed on as-is. For details about
-        this prefixing see
-        <citerefentry><refentrytitle>sd-daemon</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
-        Defaults to true.</para></listitem>
-      </varlistentry>
+  <refsect1>
+    <title>Process Properties</title>
 
-      <varlistentry>
-        <term><varname>TimerSlackNSec=</varname></term>
-        <listitem><para>Sets the timer slack in nanoseconds for the
-        executed processes. The timer slack controls the accuracy of
-        wake-ups triggered by timers. See
-        <citerefentry><refentrytitle>prctl</refentrytitle><manvolnum>2</manvolnum></citerefentry>
-        for more information. Note that in contrast to most other time
-        span definitions this parameter takes an integer value in
-        nano-seconds if no unit is specified. The usual time units are
-        understood too.</para></listitem>
-      </varlistentry>
+    <variablelist>
 
       <varlistentry>
         <term><varname>LimitCPU=</varname></term>
         <term><varname>LimitNICE=</varname></term>
         <term><varname>LimitRTPRIO=</varname></term>
         <term><varname>LimitRTTIME=</varname></term>
+
         <listitem><para>Set soft and hard limits on various resources for executed processes. See
         <citerefentry><refentrytitle>setrlimit</refentrytitle><manvolnum>2</manvolnum></citerefentry> for details on
         the resource limit concept. Resource limits may be specified in two formats: either as single value to set a
         specific soft and hard limit to the same value, or as colon-separated pair <option>soft:hard</option> to set
-        both limits individually (e.g. <literal>LimitAS=4G:16G</literal>).  Use the string <varname>infinity</varname>
-        to configure no limit on a specific resource. The multiplicative suffixes K, M, G, T, P and E (to the base
-        1024) may be used for resource limits measured in bytes (e.g. LimitAS=16G). For the limits referring to time
-        values, the usual time units ms, s, min, h and so on may be used (see
+        both limits individually (e.g. <literal>LimitAS=4G:16G</literal>).  Use the string <option>infinity</option> to
+        configure no limit on a specific resource. The multiplicative suffixes K, M, G, T, P and E (to the base 1024)
+        may be used for resource limits measured in bytes (e.g. LimitAS=16G). For the limits referring to time values,
+        the usual time units ms, s, min, h and so on may be used (see
         <citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry> for
         details). Note that if no time unit is specified for <varname>LimitCPU=</varname> the default unit of seconds
         is implied, while for <varname>LimitRTTIME=</varname> the default unit of microseconds is implied. Also, note
         prefixed like this the value is understood as raw resource limit parameter in the range 0..40 (with 0 being
         equivalent to 1).</para>
 
-        <para>Note that most process resource limits configured with
-        these options are per-process, and processes may fork in order
-        to acquire a new set of resources that are accounted
-        independently of the original process, and may thus escape
-        limits set. Also note that <varname>LimitRSS=</varname> is not
-        implemented on Linux, and setting it has no effect. Often it
-        is advisable to prefer the resource controls listed in
+        <para>Note that most process resource limits configured with these options are per-process, and processes may
+        fork in order to acquire a new set of resources that are accounted independently of the original process, and
+        may thus escape limits set. Also note that <varname>LimitRSS=</varname> is not implemented on Linux, and
+        setting it has no effect. Often it is advisable to prefer the resource controls listed in
         <citerefentry><refentrytitle>systemd.resource-control</refentrytitle><manvolnum>5</manvolnum></citerefentry>
-        over these per-process limits, as they apply to services as a
-        whole, may be altered dynamically at runtime, and are
-        generally more expressive. For example,
-        <varname>MemoryLimit=</varname> is a more powerful (and
-        working) replacement for <varname>LimitRSS=</varname>.</para>
+        over these per-process limits, as they apply to services as a whole, may be altered dynamically at runtime, and
+        are generally more expressive. For example, <varname>MemoryLimit=</varname> is a more powerful (and working)
+        replacement for <varname>LimitRSS=</varname>.</para>
 
         <para>For system units these resource limits may be chosen freely. For user units however (i.e. units run by a
         per-user instance of
       </varlistentry>
 
       <varlistentry>
-        <term><varname>PAMName=</varname></term>
-        <listitem><para>Sets the PAM service name to set up a session as. If set, the executed process will be
-        registered as a PAM session under the specified service name. This is only useful in conjunction with the
-        <varname>User=</varname> setting, and is otherwise ignored. If not set, no PAM session will be opened for the
-        executed processes. See <citerefentry
-        project='man-pages'><refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum></citerefentry> for
-        details.</para>
+        <term><varname>UMask=</varname></term>
 
-        <para>Note that for each unit making use of this option a PAM session handler process will be maintained as
-        part of the unit and stays around as long as the unit is active, to ensure that appropriate actions can be
-        taken when the unit and hence the PAM session terminates. This process is named <literal>(sd-pam)</literal> and
-        is an immediate child process of the unit's main process.</para>
+        <listitem><para>Controls the file mode creation mask. Takes an access mode in octal notation. See
+        <citerefentry><refentrytitle>umask</refentrytitle><manvolnum>2</manvolnum></citerefentry> for details. Defaults
+        to 0022.</para></listitem>
+      </varlistentry>
 
-        <para>Note that when this option is used for a unit it is very likely (depending on PAM configuration) that the
-        main unit process will be migrated to its own session scope unit when it is activated. This process will hence
-        be associated with two units: the unit it was originally started from (and for which
-        <varname>PAMName=</varname> was configured), and the session scope unit. Any child processes of that process
-        will however be associated with the session scope unit only. This has implications when used in combination
-        with <varname>NotifyAccess=</varname><option>all</option>, as these child processes will not be able to affect
-        changes in the original unit through notification messages. These messages will be considered belonging to the
-        session scope unit and not the original unit. It is hence not recommended to use <varname>PAMName=</varname> in
-        combination with <varname>NotifyAccess=</varname><option>all</option>.</para>
-        </listitem>
+      <varlistentry>
+        <term><varname>KeyringMode=</varname></term>
+
+        <listitem><para>Controls how the kernel session keyring is set up for the service (see <citerefentry
+        project='man-pages'><refentrytitle>session-keyring</refentrytitle><manvolnum>7</manvolnum></citerefentry> for
+        details on the session keyring). Takes one of <option>inherit</option>, <option>private</option>,
+        <option>shared</option>. If set to <option>inherit</option> no special keyring setup is done, and the kernel's
+        default behaviour is applied. If <option>private</option> is used a new session keyring is allocated when a
+        service process is invoked, and it is not linked up with any user keyring. This is the recommended setting for
+        system services, as this ensures that multiple services running under the same system user ID (in particular
+        the root user) do not share their key material among each other. If <option>shared</option> is used a new
+        session keyring is allocated as for <option>private</option>, but the user keyring of the user configured with
+        <varname>User=</varname> is linked into it, so that keys assigned to the user may be requested by the unit's
+        processes. In this modes multiple units running processes under the same user ID may share key material. Unless
+        <option>inherit</option> is selected the unique invocation ID for the unit (see below) is added as a protected
+        key by the name <literal>invocation_id</literal> to the newly created session keyring. Defaults to
+        <option>private</option> for the system service manager and to <option>inherit</option> for the user service
+        manager.</para></listitem>
       </varlistentry>
 
       <varlistentry>
-        <term><varname>CapabilityBoundingSet=</varname></term>
+        <term><varname>OOMScoreAdjust=</varname></term>
 
-        <listitem><para>Controls which capabilities to include in the capability bounding set for the executed
-        process. See <citerefentry
-        project='man-pages'><refentrytitle>capabilities</refentrytitle><manvolnum>7</manvolnum></citerefentry> for
-        details. Takes a whitespace-separated list of capability names, e.g. <constant>CAP_SYS_ADMIN</constant>,
-        <constant>CAP_DAC_OVERRIDE</constant>, <constant>CAP_SYS_PTRACE</constant>. Capabilities listed will be
-        included in the bounding set, all others are removed. If the list of capabilities is prefixed with
-        <literal>~</literal>, all but the listed capabilities will be included, the effect of the assignment
-        inverted. Note that this option also affects the respective capabilities in the effective, permitted and
-        inheritable capability sets. If this option is not used, the capability bounding set is not modified on process
-        execution, hence no limits on the capabilities of the process are enforced. This option may appear more than
-        once, in which case the bounding sets are merged by <constant>AND</constant>, or by <constant>OR</constant>
-        if the lines are prefixed with <literal>~</literal> (see below). If the empty string is assigned
-        to this option, the bounding set is reset to the empty capability set, and all prior settings have no effect.
-        If set to <literal>~</literal> (without any further argument), the bounding set is reset to the full set of available
-        capabilities, also undoing any previous settings. This does not affect commands prefixed with
-        <literal>+</literal>.</para>
+        <listitem><para>Sets the adjustment level for the Out-Of-Memory killer for executed processes. Takes an integer
+        between -1000 (to disable OOM killing for this process) and 1000 (to make killing of this process under memory
+        pressure very likely). See <ulink
+        url="https://www.kernel.org/doc/Documentation/filesystems/proc.txt">proc.txt</ulink> for
+        details.</para></listitem>
+      </varlistentry>
 
-        <para>Example: if a unit has the following,
-        <programlisting>CapabilityBoundingSet=CAP_A CAP_B
-CapabilityBoundingSet=CAP_B CAP_C</programlisting>
-        then <constant>CAP_A</constant>, <constant>CAP_B</constant>, and <constant>CAP_C</constant> are set.
-        If the second line is prefixed with <literal>~</literal>, e.g.,
-        <programlisting>CapabilityBoundingSet=CAP_A CAP_B
-CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
-        then, only <constant>CAP_A</constant> is set.</para></listitem>
+      <varlistentry>
+        <term><varname>TimerSlackNSec=</varname></term>
+        <listitem><para>Sets the timer slack in nanoseconds for the executed processes. The timer slack controls the
+        accuracy of wake-ups triggered by timers. See
+        <citerefentry><refentrytitle>prctl</refentrytitle><manvolnum>2</manvolnum></citerefentry> for more
+        information. Note that in contrast to most other time span definitions this parameter takes an integer value in
+        nano-seconds if no unit is specified. The usual time units are understood too.</para></listitem>
       </varlistentry>
 
       <varlistentry>
-        <term><varname>AmbientCapabilities=</varname></term>
+        <term><varname>Personality=</varname></term>
 
-        <listitem><para>Controls which capabilities to include in the ambient capability set for the executed
-        process. Takes a whitespace-separated list of capability names, e.g. <constant>CAP_SYS_ADMIN</constant>,
-        <constant>CAP_DAC_OVERRIDE</constant>, <constant>CAP_SYS_PTRACE</constant>. This option may appear more than
-        once in which case the ambient capability sets are merged (see the above examples in
-        <varname>CapabilityBoundingSet=</varname>). If the list of capabilities is prefixed with
-        <literal>~</literal>, all but the listed capabilities will be included, the effect of the assignment
-        inverted. If the empty string is assigned to this option, the ambient capability set is reset to the empty
-        capability set, and all prior settings have no effect.  If set to <literal>~</literal> (without any further
-        argument), the ambient capability set is reset to the full set of available capabilities, also undoing any
-        previous settings. Note that adding capabilities to ambient capability set adds them to the process's inherited
-        capability set.  </para><para> Ambient capability sets are useful if you want to execute a process as a
-        non-privileged user but still want to give it some capabilities.  Note that in this case option
-        <constant>keep-caps</constant> is automatically added to <varname>SecureBits=</varname> to retain the
-        capabilities over the user change. <varname>AmbientCapabilities=</varname> does not affect commands prefixed
-        with <literal>+</literal>.</para></listitem>
+        <listitem><para>Controls which kernel architecture <citerefentry
+        project='man-pages'><refentrytitle>uname</refentrytitle><manvolnum>2</manvolnum></citerefentry> shall report,
+        when invoked by unit processes. Takes one of the architecture identifiers <constant>x86</constant>,
+        <constant>x86-64</constant>, <constant>ppc</constant>, <constant>ppc-le</constant>, <constant>ppc64</constant>,
+        <constant>ppc64-le</constant>, <constant>s390</constant> or <constant>s390x</constant>. Which personality
+        architectures are supported depends on the system architecture. Usually the 64bit versions of the various
+        system architectures support their immediate 32bit personality architecture counterpart, but no others. For
+        example, <constant>x86-64</constant> systems support the <constant>x86-64</constant> and
+        <constant>x86</constant> personalities but no others. The personality feature is useful when running 32-bit
+        services on a 64-bit host system. If not specified, the personality is left unmodified and thus reflects the
+        personality of the host system's kernel.</para></listitem>
       </varlistentry>
 
       <varlistentry>
-        <term><varname>SecureBits=</varname></term>
-        <listitem><para>Controls the secure bits set for the executed
-        process. Takes a space-separated combination of options from
-        the following list:
-        <option>keep-caps</option>,
-        <option>keep-caps-locked</option>,
-        <option>no-setuid-fixup</option>,
-        <option>no-setuid-fixup-locked</option>,
-        <option>noroot</option>, and
-        <option>noroot-locked</option>.
-        This option may appear more than once, in which case the secure
-        bits are ORed. If the empty string is assigned to this option,
-        the bits are reset to 0. This does not affect commands prefixed with <literal>+</literal>.
-        See <citerefentry project='man-pages'><refentrytitle>capabilities</refentrytitle><manvolnum>7</manvolnum></citerefentry>
-        for details.</para></listitem>
+        <term><varname>IgnoreSIGPIPE=</varname></term>
+
+        <listitem><para>Takes a boolean argument. If true, causes <constant>SIGPIPE</constant> to be ignored in the
+        executed process. Defaults to true because <constant>SIGPIPE</constant> generally is useful only in shell
+        pipelines.</para></listitem>
+      </varlistentry>
+
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Scheduling</title>
+
+    <variablelist>
+
+      <varlistentry>
+        <term><varname>Nice=</varname></term>
+
+        <listitem><para>Sets the default nice level (scheduling priority) for executed processes. Takes an integer
+        between -20 (highest priority) and 19 (lowest priority). See
+        <citerefentry><refentrytitle>setpriority</refentrytitle><manvolnum>2</manvolnum></citerefentry> for
+        details.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>CPUSchedulingPolicy=</varname></term>
+
+        <listitem><para>Sets the CPU scheduling policy for executed processes. Takes one of <option>other</option>,
+        <option>batch</option>, <option>idle</option>, <option>fifo</option> or <option>rr</option>. See
+        <citerefentry><refentrytitle>sched_setscheduler</refentrytitle><manvolnum>2</manvolnum></citerefentry> for
+        details.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>CPUSchedulingPriority=</varname></term>
+
+        <listitem><para>Sets the CPU scheduling priority for executed processes. The available priority range depends
+        on the selected CPU scheduling policy (see above). For real-time scheduling policies an integer between 1
+        (lowest priority) and 99 (highest priority) can be used. See
+        <citerefentry><refentrytitle>sched_setscheduler</refentrytitle><manvolnum>2</manvolnum></citerefentry> for
+        details. </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>CPUSchedulingResetOnFork=</varname></term>
+
+        <listitem><para>Takes a boolean argument. If true, elevated CPU scheduling priorities and policies will be
+        reset when the executed processes fork, and can hence not leak into child processes. See
+        <citerefentry><refentrytitle>sched_setscheduler</refentrytitle><manvolnum>2</manvolnum></citerefentry> for
+        details. Defaults to false.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>CPUAffinity=</varname></term>
+
+        <listitem><para>Controls the CPU affinity of the executed processes. Takes a list of CPU indices or ranges
+        separated by either whitespace or commas. CPU ranges are specified by the lower and upper CPU indices separated
+        by a dash.  This option may be specified more than once, in which case the specified CPU affinity masks are
+        merged. If the empty string is assigned, the mask is reset, all assignments prior to this will have no
+        effect. See
+        <citerefentry><refentrytitle>sched_setaffinity</refentrytitle><manvolnum>2</manvolnum></citerefentry> for
+        details.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>IOSchedulingClass=</varname></term>
+
+        <listitem><para>Sets the I/O scheduling class for executed processes. Takes an integer between 0 and 3 or one
+        of the strings <option>none</option>, <option>realtime</option>, <option>best-effort</option> or
+        <option>idle</option>. See
+        <citerefentry><refentrytitle>ioprio_set</refentrytitle><manvolnum>2</manvolnum></citerefentry> for
+        details.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>IOSchedulingPriority=</varname></term>
+
+        <listitem><para>Sets the I/O scheduling priority for executed processes. Takes an integer between 0 (highest
+        priority) and 7 (lowest priority). The available priorities depend on the selected I/O scheduling class (see
+        above). See <citerefentry><refentrytitle>ioprio_set</refentrytitle><manvolnum>2</manvolnum></citerefentry> for
+        details.</para></listitem>
+      </varlistentry>
+
+    </variablelist>
+  </refsect1>
+
+
+  <refsect1>
+    <title>Sandboxing</title>
+
+    <variablelist>
+
+      <varlistentry>
+        <term><varname>ProtectSystem=</varname></term>
+
+        <listitem><para>Takes a boolean argument or the special values <literal>full</literal> or
+        <literal>strict</literal>. If true, mounts the <filename>/usr</filename> and <filename>/boot</filename>
+        directories read-only for processes invoked by this unit. If set to <literal>full</literal>, the
+        <filename>/etc</filename> directory is mounted read-only, too. If set to <literal>strict</literal> the entire
+        file system hierarchy is mounted read-only, except for the API file system subtrees <filename>/dev</filename>,
+        <filename>/proc</filename> and <filename>/sys</filename> (protect these directories using
+        <varname>PrivateDevices=</varname>, <varname>ProtectKernelTunables=</varname>,
+        <varname>ProtectControlGroups=</varname>). This setting ensures that any modification of the vendor-supplied
+        operating system (and optionally its configuration, and local mounts) is prohibited for the service.  It is
+        recommended to enable this setting for all long-running services, unless they are involved with system updates
+        or need to modify the operating system in other ways. If this option is used,
+        <varname>ReadWritePaths=</varname> may be used to exclude specific directories from being made read-only. This
+        setting is implied if <varname>DynamicUser=</varname> is set. For this setting the same restrictions regarding
+        mount propagation and privileges apply as for <varname>ReadOnlyPaths=</varname> and related calls, see
+        below. Defaults to off.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>ProtectHome=</varname></term>
+
+        <listitem><para>Takes a boolean argument or <literal>read-only</literal>. If true, the directories
+        <filename>/home</filename>, <filename>/root</filename> and <filename>/run/user</filename> are made inaccessible
+        and empty for processes invoked by this unit. If set to <literal>read-only</literal>, the three directories are
+        made read-only instead. It is recommended to enable this setting for all long-running services (in particular
+        network-facing ones), to ensure they cannot get access to private user data, unless the services actually
+        require access to the user's private data. This setting is implied if <varname>DynamicUser=</varname> is
+        set. For this setting the same restrictions regarding mount propagation and privileges apply as for
+        <varname>ReadOnlyPaths=</varname> and related calls, see below.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>RuntimeDirectory=</varname></term>
+        <term><varname>StateDirectory=</varname></term>
+        <term><varname>CacheDirectory=</varname></term>
+        <term><varname>LogsDirectory=</varname></term>
+        <term><varname>ConfigurationDirectory=</varname></term>
+
+        <listitem><para>These options take a whitespace-separated list of directory names. The specified directory
+        names must be relative, and may not include <literal>.</literal> or <literal>..</literal>. If set, one or more
+        directories by the specified names will be created (including their parents) below <filename>/run</filename>
+        (or <varname>$XDG_RUNTIME_DIR</varname> for user services), <filename>/var/lib</filename> (or
+        <varname>$XDG_CONFIG_HOME</varname> for user services), <filename>/var/cache</filename> (or
+        <varname>$XDG_CACHE_HOME</varname> for user services), <filename>/var/log</filename> (or
+        <varname>$XDG_CONFIG_HOME</varname><filename>/log</filename> for user services), or <filename>/etc</filename>
+        (or <varname>$XDG_CONFIG_HOME</varname> for user services), respectively, when the unit is started.</para>
+
+        <para>In case of <varname>RuntimeDirectory=</varname> the lowest subdirectories are removed when the unit is
+        stopped. It is possible to preserve the specified directories in this case if
+        <varname>RuntimeDirectoryPreserve=</varname> is configured to <option>restart</option> or <option>yes</option>
+        (see below). The directories specified with <varname>StateDirectory=</varname>,
+        <varname>CacheDirectory=</varname>, <varname>LogsDirectory=</varname>,
+        <varname>ConfigurationDirectory=</varname> are not removed when the unit is stopped.</para>
+
+        <para>Except in case of <varname>ConfigurationDirectory=</varname>, the innermost specified directories will be
+        owned by the user and group specified in <varname>User=</varname> and <varname>Group=</varname>. If the
+        specified directories already exist and their owning user or group do not match the configured ones, all files
+        and directories below the specified directories as well as the directories themselves will have their file
+        ownership recursively changed to match what is configured. As an optimization, if the specified directories are
+        already owned by the right user and group, files and directories below of them are left as-is, even if they do
+        not match what is requested. The innermost specified directories will have their access mode adjusted to the
+        what is specified in <varname>RuntimeDirectoryMode=</varname>, <varname>StateDirectoryMode=</varname>,
+        <varname>CacheDirectoryMode=</varname>, <varname>LogsDirectoryMode=</varname> and
+        <varname>ConfigurationDirectoryMode=</varname>.</para>
+
+        <para>These options imply <varname>BindPaths=</varname> for the specified paths. When combined with
+        <varname>RootDirectory=</varname> or <varname>RootImage=</varname> these paths always reside on the host and
+        are mounted from there into the unit's file system namespace.</para>
+
+        <para>If <varname>DynamicUser=</varname> is used in conjunction with <varname>StateDirectory=</varname>,
+        <varname>CacheDirectory=</varname> and <varname>LogsDirectory=</varname> is slightly altered: the directories
+        are created below <filename>/var/lib/private</filename>, <filename>/var/cache/private</filename> and
+        <filename>/var/log/private</filename>, respectively, which are host directories made inaccessible to
+        unprivileged users, which ensures that access to these directories cannot be gained through dynamic user ID
+        recycling. Symbolic links are created to hide this difference in behaviour. Both from perspective of the host
+        and from inside the unit, the relevant directories hence always appear directly below
+        <filename>/var/lib</filename>, <filename>/var/cache</filename> and <filename>/var/log</filename>.</para>
+
+        <para>Use <varname>RuntimeDirectory=</varname> to manage one or more runtime directories for the unit and bind
+        their lifetime to the daemon runtime. This is particularly useful for unprivileged daemons that cannot create
+        runtime directories in <filename>/run</filename> due to lack of privileges, and to make sure the runtime
+        directory is cleaned up automatically after use. For runtime directories that require more complex or different
+        configuration or lifetime guarantees, please consider using
+        <citerefentry><refentrytitle>tmpfiles.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
+
+        <para>Example: if a system service unit has the following,
+        <programlisting>RuntimeDirectory=foo/bar baz</programlisting>
+        the service manager creates <filename>/run/foo</filename> (if it does not exist),
+        <filename>/run/foo/bar</filename>, and <filename>/run/baz</filename>. The directories
+        <filename>/run/foo/bar</filename> and <filename>/run/baz</filename> except <filename>/run/foo</filename> are
+        owned by the user and group specified in <varname>User=</varname> and <varname>Group=</varname>, and removed
+        when the service is stopped.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>RuntimeDirectoryMode=</varname></term>
+        <term><varname>StateDirectoryMode=</varname></term>
+        <term><varname>CacheDirectoryMode=</varname></term>
+        <term><varname>LogsDirectoryMode=</varname></term>
+        <term><varname>ConfigurationDirectoryMode=</varname></term>
+
+        <listitem><para>Specifies the access mode of the directories specified in <varname>RuntimeDirectory=</varname>,
+        <varname>StateDirectory=</varname>, <varname>CacheDirectory=</varname>, <varname>LogsDirectory=</varname>, or
+        <varname>ConfigurationDirectory=</varname>, respectively, as an octal number.  Defaults to
+        <constant>0755</constant>. See "Permissions" in <citerefentry
+        project='man-pages'><refentrytitle>path_resolution</refentrytitle><manvolnum>7</manvolnum></citerefentry> for a
+        discussion of the meaning of permission bits.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>RuntimeDirectoryPreserve=</varname></term>
+
+        <listitem><para>Takes a boolean argument or <option>restart</option>.  If set to <option>no</option> (the
+        default), the directories specified in <varname>RuntimeDirectory=</varname> are always removed when the service
+        stops. If set to <option>restart</option> the directories are preserved when the service is both automatically
+        and manually restarted. Here, the automatic restart means the operation specified in
+        <varname>Restart=</varname>, and manual restart means the one triggered by <command>systemctl restart
+        foo.service</command>. If set to <option>yes</option>, then the directories are not removed when the service is
+        stopped. Note that since the runtime directory <filename>/run</filename> is a mount point of
+        <literal>tmpfs</literal>, then for system services the directories specified in
+        <varname>RuntimeDirectory=</varname> are removed when the system is rebooted.</para></listitem>
       </varlistentry>
 
       <varlistentry>
@@ -1078,31 +943,6 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
       </varlistentry>
 
       <varlistentry>
-        <term><varname>BindPaths=</varname></term>
-        <term><varname>BindReadOnlyPaths=</varname></term>
-
-        <listitem><para>Configures unit-specific bind mounts. A bind mount makes a particular file or directory
-        available at an additional place in the unit's view of the file system. Any bind mounts created with this
-        option are specific to the unit, and are not visible in the host's mount table. This option expects a
-        whitespace separated list of bind mount definitions. Each definition consists of a colon-separated triple of
-        source path, destination path and option string, where the latter two are optional. If only a source path is
-        specified the source and destination is taken to be the same. The option string may be either
-        <literal>rbind</literal> or <literal>norbind</literal> for configuring a recursive or non-recursive bind
-        mount. If the destination path is omitted, the option string must be omitted too.</para>
-
-        <para><varname>BindPaths=</varname> creates regular writable bind mounts (unless the source file system mount
-        is already marked read-only), while <varname>BindReadOnlyPaths=</varname> creates read-only bind mounts. These
-        settings may be used more than once, each usage appends to the unit's list of bind mounts. If the empty string
-        is assigned to either of these two options the entire list of bind mounts defined prior to this is reset. Note
-        that in this case both read-only and regular bind mounts are reset, regardless which of the two settings is
-        used.</para>
-
-        <para>This option is particularly useful when <varname>RootDirectory=</varname>/<varname>RootImage=</varname>
-        is used. In this case the source path refers to a path on the host file system, while the destination path
-        refers to a path below the root directory of the unit.</para></listitem>
-      </varlistentry>
-
-      <varlistentry>
         <term><varname>PrivateTmp=</varname></term>
 
         <listitem><para>Takes a boolean argument. If true, sets up a new file system namespace for the executed
@@ -1122,8 +962,8 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
         <citerefentry><refentrytitle>systemd-tmpfiles-setup.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
         is added.</para>
 
-        <para>Note that the implementation of this setting might be impossible (for example if mount namespaces
-        are not available), and the unit should be written in a way that does not solely rely on this setting for
+        <para>Note that the implementation of this setting might be impossible (for example if mount namespaces are not
+        available), and the unit should be written in a way that does not solely rely on this setting for
         security.</para></listitem>
       </varlistentry>
 
@@ -1132,53 +972,46 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
 
         <listitem><para>Takes a boolean argument. If true, sets up a new <filename>/dev</filename> mount for the
         executed processes and only adds API pseudo devices such as <filename>/dev/null</filename>,
-        <filename>/dev/zero</filename> or
-        <filename>/dev/random</filename> (as well as the pseudo TTY subsystem) to it, but no physical devices such as
-        <filename>/dev/sda</filename>, system memory <filename>/dev/mem</filename>, system ports
-        <filename>/dev/port</filename> and others. This is useful to securely turn off physical device access by the
-        executed process. Defaults to false. Enabling this option will install a system call filter to block low-level
-        I/O system calls that are grouped in the <varname>@raw-io</varname> set, will also remove
-        <constant>CAP_MKNOD</constant> and <constant>CAP_SYS_RAWIO</constant> from the capability bounding set for
-        the unit (see above), and set <varname>DevicePolicy=closed</varname> (see
+        <filename>/dev/zero</filename> or <filename>/dev/random</filename> (as well as the pseudo TTY subsystem) to it,
+        but no physical devices such as <filename>/dev/sda</filename>, system memory <filename>/dev/mem</filename>,
+        system ports <filename>/dev/port</filename> and others. This is useful to securely turn off physical device
+        access by the executed process. Defaults to false. Enabling this option will install a system call filter to
+        block low-level I/O system calls that are grouped in the <varname>@raw-io</varname> set, will also remove
+        <constant>CAP_MKNOD</constant> and <constant>CAP_SYS_RAWIO</constant> from the capability bounding set for the
+        unit (see above), and set <varname>DevicePolicy=closed</varname> (see
         <citerefentry><refentrytitle>systemd.resource-control</refentrytitle><manvolnum>5</manvolnum></citerefentry>
         for details). Note that using this setting will disconnect propagation of mounts from the service to the host
         (propagation in the opposite direction continues to work).  This means that this setting may not be used for
-        services which shall be able to install mount points in the main mount namespace. The new <filename>/dev</filename>
-        will be mounted read-only and 'noexec'. The latter may break old programs which try to set up executable memory by
-        using <citerefentry><refentrytitle>mmap</refentrytitle><manvolnum>2</manvolnum></citerefentry> of
-        <filename>/dev/zero</filename> instead of using <constant>MAP_ANON</constant>. For this setting the same restrictions
-        regarding mount propagation and privileges apply as for <varname>ReadOnlyPaths=</varname> and related calls, see above.
-        If turned on and if running in user mode, or in system mode, but without the <constant>CAP_SYS_ADMIN</constant>
-        capability (e.g. setting <varname>User=</varname>), <varname>NoNewPrivileges=yes</varname> is implied.
-        </para>
+        services which shall be able to install mount points in the main mount namespace. The new
+        <filename>/dev</filename> will be mounted read-only and 'noexec'. The latter may break old programs which try
+        to set up executable memory by using
+        <citerefentry><refentrytitle>mmap</refentrytitle><manvolnum>2</manvolnum></citerefentry> of
+        <filename>/dev/zero</filename> instead of using <constant>MAP_ANON</constant>. For this setting the same
+        restrictions regarding mount propagation and privileges apply as for <varname>ReadOnlyPaths=</varname> and
+        related calls, see above.  If turned on and if running in user mode, or in system mode, but without the
+        <constant>CAP_SYS_ADMIN</constant> capability (e.g. setting <varname>User=</varname>),
+        <varname>NoNewPrivileges=yes</varname> is implied.</para>
 
-        <para>Note that the implementation of this setting might be impossible (for example if mount namespaces
-        are not available), and the unit should be written in a way that does not solely rely on this setting for
+        <para>Note that the implementation of this setting might be impossible (for example if mount namespaces are not
+        available), and the unit should be written in a way that does not solely rely on this setting for
         security.</para></listitem>
       </varlistentry>
 
       <varlistentry>
         <term><varname>PrivateNetwork=</varname></term>
 
-        <listitem><para>Takes a boolean argument. If true, sets up a
-        new network namespace for the executed processes and
-        configures only the loopback network device
-        <literal>lo</literal> inside it. No other network devices will
-        be available to the executed process. This is useful to
-        turn off network access by the executed process.
-        Defaults to false. It is possible to run two or more units
-        within the same private network namespace by using the
-        <varname>JoinsNamespaceOf=</varname> directive, see
-        <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
-        for details. Note that this option will disconnect all socket
-        families from the host, this includes AF_NETLINK and AF_UNIX.
-        The latter has the effect that AF_UNIX sockets in the abstract
-        socket namespace will become unavailable to the processes
-        (however, those located in the file system will continue to be
-        accessible).</para>
-
-        <para>Note that the implementation of this setting might be impossible (for example if network namespaces
-        are not available), and the unit should be written in a way that does not solely rely on this setting for
+        <listitem><para>Takes a boolean argument. If true, sets up a new network namespace for the executed processes
+        and configures only the loopback network device <literal>lo</literal> inside it. No other network devices will
+        be available to the executed process. This is useful to turn off network access by the executed process.
+        Defaults to false. It is possible to run two or more units within the same private network namespace by using
+        the <varname>JoinsNamespaceOf=</varname> directive, see
+        <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry> for
+        details. Note that this option will disconnect all socket families from the host, this includes AF_NETLINK and
+        AF_UNIX.  The latter has the effect that AF_UNIX sockets in the abstract socket namespace will become
+        unavailable to the processes (however, those located in the file system will continue to be accessible).</para>
+
+        <para>Note that the implementation of this setting might be impossible (for example if network namespaces are
+        not available), and the unit should be written in a way that does not solely rely on this setting for
         security.</para></listitem>
       </varlistentry>
 
@@ -1203,46 +1036,13 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
         databases in the root directory and on the host is reduced, as the only users and groups who need to be matched
         are <literal>root</literal>, <literal>nobody</literal> and the unit's own user and group.</para>
 
-        <para>Note that the implementation of this setting might be impossible (for example if user namespaces
-        are not available), and the unit should be written in a way that does not solely rely on this setting for
+        <para>Note that the implementation of this setting might be impossible (for example if user namespaces are not
+        available), and the unit should be written in a way that does not solely rely on this setting for
         security.</para></listitem>
       </varlistentry>
 
       <varlistentry>
-        <term><varname>ProtectSystem=</varname></term>
-
-        <listitem><para>Takes a boolean argument or the special values <literal>full</literal> or
-        <literal>strict</literal>. If true, mounts the <filename>/usr</filename> and <filename>/boot</filename>
-        directories read-only for processes invoked by this unit. If set to <literal>full</literal>, the
-        <filename>/etc</filename> directory is mounted read-only, too. If set to <literal>strict</literal> the entire
-        file system hierarchy is mounted read-only, except for the API file system subtrees <filename>/dev</filename>,
-        <filename>/proc</filename> and <filename>/sys</filename> (protect these directories using
-        <varname>PrivateDevices=</varname>, <varname>ProtectKernelTunables=</varname>,
-        <varname>ProtectControlGroups=</varname>). This setting ensures that any modification of the vendor-supplied
-        operating system (and optionally its configuration, and local mounts) is prohibited for the service.  It is
-        recommended to enable this setting for all long-running services, unless they are involved with system updates
-        or need to modify the operating system in other ways. If this option is used,
-        <varname>ReadWritePaths=</varname> may be used to exclude specific directories from being made read-only. This
-        setting is implied if <varname>DynamicUser=</varname> is set. For this setting the same restrictions regarding
-        mount propagation and privileges apply as for <varname>ReadOnlyPaths=</varname> and related calls, see
-        above. Defaults to off.</para></listitem>
-      </varlistentry>
-
-      <varlistentry>
-        <term><varname>ProtectHome=</varname></term>
-
-        <listitem><para>Takes a boolean argument or <literal>read-only</literal>. If true, the directories
-        <filename>/home</filename>, <filename>/root</filename> and <filename>/run/user</filename> are made inaccessible
-        and empty for processes invoked by this unit. If set to <literal>read-only</literal>, the three directories are
-        made read-only instead. It is recommended to enable this setting for all long-running services (in particular
-        network-facing ones), to ensure they cannot get access to private user data, unless the services actually
-        require access to the user's private data. This setting is implied if <varname>DynamicUser=</varname> is
-        set. For this setting the same restrictions regarding mount propagation and privileges apply as for
-        <varname>ReadOnlyPaths=</varname> and related calls, see above.</para></listitem>
-      </varlistentry>
-
-      <varlistentry>
-        <term><varname>ProtectKernelTunables=</varname></term>
+        <term><varname>ProtectKernelTunables=</varname></term>
 
         <listitem><para>Takes a boolean argument. If true, kernel variables accessible through
         <filename>/proc/sys</filename>, <filename>/sys</filename>, <filename>/proc/sysrq-trigger</filename>,
@@ -1265,25 +1065,20 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
       <varlistentry>
         <term><varname>ProtectKernelModules=</varname></term>
 
-        <listitem><para>Takes a boolean argument. If true, explicit module loading will
-        be denied. This allows to turn off module load and unload operations on modular
-        kernels. It is recommended to turn this on for most services that do not need special
-        file systems or extra kernel modules to work. Default to off. Enabling this option
-        removes <constant>CAP_SYS_MODULE</constant> from the capability bounding set for
-        the unit, and installs a system call filter to block module system calls,
-        also <filename>/usr/lib/modules</filename> is made inaccessible. For this
-        setting the same restrictions regarding mount propagation and privileges
-        apply as for <varname>ReadOnlyPaths=</varname> and related calls, see above.
-        Note that limited automatic module loading due to user configuration or kernel
-        mapping tables might still happen as side effect of requested user operations,
+        <listitem><para>Takes a boolean argument. If true, explicit module loading will be denied. This allows to turn
+        off module load and unload operations on modular kernels. It is recommended to turn this on for most services
+        that do not need special file systems or extra kernel modules to work. Defaults to off. Enabling this option
+        removes <constant>CAP_SYS_MODULE</constant> from the capability bounding set for the unit, and installs a
+        system call filter to block module system calls, also <filename>/usr/lib/modules</filename> is made
+        inaccessible. For this setting the same restrictions regarding mount propagation and privileges apply as for
+        <varname>ReadOnlyPaths=</varname> and related calls, see above.  Note that limited automatic module loading due
+        to user configuration or kernel mapping tables might still happen as side effect of requested user operations,
         both privileged and unprivileged. To disable module auto-load feature please see
         <citerefentry><refentrytitle>sysctl.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>
         <constant>kernel.modules_disabled</constant> mechanism and
-        <filename>/proc/sys/kernel/modules_disabled</filename> documentation.
-        If turned on and if running in user mode, or in system mode, but without the <constant>CAP_SYS_ADMIN</constant>
-        capability (e.g. setting <varname>User=</varname>), <varname>NoNewPrivileges=yes</varname>
-        is implied.
-        </para></listitem>
+        <filename>/proc/sys/kernel/modules_disabled</filename> documentation.  If turned on and if running in user
+        mode, or in system mode, but without the <constant>CAP_SYS_ADMIN</constant> capability (e.g. setting
+        <varname>User=</varname>), <varname>NoNewPrivileges=yes</varname> is implied.</para></listitem>
       </varlistentry>
 
       <varlistentry>
@@ -1295,152 +1090,162 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
         unit. Except for container managers no services should require write access to the control groups hierarchies;
         it is hence recommended to turn this on for most services. For this setting the same restrictions regarding
         mount propagation and privileges apply as for <varname>ReadOnlyPaths=</varname> and related calls, see
-        above. Defaults to off. If <varname>ProtectControlGroups=</varname> is set, <varname>MountAPIVFS=yes</varname> is
-        implied.</para></listitem>
+        above. Defaults to off. If <varname>ProtectControlGroups=</varname> is set, <varname>MountAPIVFS=yes</varname>
+        is implied.</para></listitem>
       </varlistentry>
 
       <varlistentry>
-        <term><varname>MountFlags=</varname></term>
+        <term><varname>RestrictAddressFamilies=</varname></term>
 
-        <listitem><para>Takes a mount propagation flag: <option>shared</option>, <option>slave</option> or
-        <option>private</option>, which control whether mounts in the file system namespace set up for this unit's
-        processes will receive or propagate mounts and unmounts. See <citerefentry
-        project='man-pages'><refentrytitle>mount</refentrytitle><manvolnum>2</manvolnum></citerefentry> for
-        details. Defaults to <option>shared</option>. Use <option>shared</option> to ensure that mounts and unmounts
-        are propagated from systemd's namespace to the service's namespace and vice versa. Use <option>slave</option>
-        to run processes so that none of their mounts and unmounts will propagate to the host. Use <option>private</option>
-        to also ensure that no mounts and unmounts from the host will propagate into the unit processes' namespace.
-        If this is set to <option>slave</option> or <option>private</option>, any mounts created by spawned processes
-        will be unmounted after the completion of the current command line of <varname>ExecStartPre=</varname>,
-        <varname>ExecStartPost=</varname>, <varname>ExecStart=</varname>,
-        and <varname>ExecStopPost=</varname>. Note that
-        <option>slave</option> means that file systems mounted on the host might stay mounted continuously in the
-        unit's namespace, and thus keep the device busy. Note that the file system namespace related options
-        (<varname>PrivateTmp=</varname>, <varname>PrivateDevices=</varname>, <varname>ProtectSystem=</varname>,
-        <varname>ProtectHome=</varname>, <varname>ProtectKernelTunables=</varname>,
-        <varname>ProtectControlGroups=</varname>, <varname>ReadOnlyPaths=</varname>,
-        <varname>InaccessiblePaths=</varname>, <varname>ReadWritePaths=</varname>) require that mount and unmount
-        propagation from the unit's file system namespace is disabled, and hence downgrade <option>shared</option> to
-        <option>slave</option>. </para></listitem>
+        <listitem><para>Restricts the set of socket address families accessible to the processes of this unit. Takes a
+        space-separated list of address family names to whitelist, such as <constant>AF_UNIX</constant>,
+        <constant>AF_INET</constant> or <constant>AF_INET6</constant>. When prefixed with <constant>~</constant> the
+        listed address families will be applied as blacklist, otherwise as whitelist.  Note that this restricts access
+        to the <citerefentry
+        project='man-pages'><refentrytitle>socket</refentrytitle><manvolnum>2</manvolnum></citerefentry> system call
+        only. Sockets passed into the process by other means (for example, by using socket activation with socket
+        units, see <citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry>)
+        are unaffected. Also, sockets created with <function>socketpair()</function> (which creates connected AF_UNIX
+        sockets only) are unaffected. Note that this option has no effect on 32-bit x86, s390, s390x, mips, mips-le,
+        ppc, ppc-le, pcc64, ppc64-le and is ignored (but works correctly on other ABIs, including x86-64). Note that on
+        systems supporting multiple ABIs (such as x86/x86-64) it is recommended to turn off alternative ABIs for
+        services, so that they cannot be used to circumvent the restrictions of this option. Specifically, it is
+        recommended to combine this option with <varname>SystemCallArchitectures=native</varname> or similar. If
+        running in user mode, or in system mode, but without the <constant>CAP_SYS_ADMIN</constant> capability
+        (e.g. setting <varname>User=nobody</varname>), <varname>NoNewPrivileges=yes</varname> is implied. By default,
+        no restrictions apply, all address families are accessible to processes. If assigned the empty string, any
+        previous address familiy restriction changes are undone. This setting does not affect commands prefixed with
+        <literal>+</literal>.</para>
+
+        <para>Use this option to limit exposure of processes to remote access, in particular via exotic and sensitive
+        network protocols, such as <constant>AF_PACKET</constant>. Note that in most cases, the local
+        <constant>AF_UNIX</constant> address family should be included in the configured whitelist as it is frequently
+        used for local communication, including for
+        <citerefentry><refentrytitle>syslog</refentrytitle><manvolnum>2</manvolnum></citerefentry>
+        logging.</para></listitem>
       </varlistentry>
 
       <varlistentry>
-        <term><varname>UtmpIdentifier=</varname></term>
+        <term><varname>RestrictNamespaces=</varname></term>
 
-        <listitem><para>Takes a four character identifier string for
-        an <citerefentry
-        project='man-pages'><refentrytitle>utmp</refentrytitle><manvolnum>5</manvolnum></citerefentry>
-        and wtmp entry for this service. This should only be
-        set for services such as <command>getty</command>
-        implementations (such as <citerefentry
-        project='die-net'><refentrytitle>agetty</refentrytitle><manvolnum>8</manvolnum></citerefentry>)
-        where utmp/wtmp entries must be created and cleared before and
-        after execution, or for services that shall be executed as if
-        they were run by a <command>getty</command> process (see
-        below). If the configured string is longer than four
-        characters, it is truncated and the terminal four characters
-        are used. This setting interprets %I style string
-        replacements. This setting is unset by default, i.e. no
-        utmp/wtmp entries are created or cleaned up for this
-        service.</para></listitem>
+        <listitem><para>Restricts access to Linux namespace functionality for the processes of this unit. For details
+        about Linux namespaces, see <citerefentry
+        project='man-pages'><refentrytitle>namespaces</refentrytitle><manvolnum>7</manvolnum></citerefentry>. Either
+        takes a boolean argument, or a space-separated list of namespace type identifiers. If false (the default), no
+        restrictions on namespace creation and switching are made. If true, access to any kind of namespacing is
+        prohibited. Otherwise, a space-separated list of namespace type identifiers must be specified, consisting of
+        any combination of: <constant>cgroup</constant>, <constant>ipc</constant>, <constant>net</constant>,
+        <constant>mnt</constant>, <constant>pid</constant>, <constant>user</constant> and <constant>uts</constant>. Any
+        namespace type listed is made accessible to the unit's processes, access to namespace types not listed is
+        prohibited (whitelisting). By prepending the list with a single tilde character (<literal>~</literal>) the
+        effect may be inverted: only the listed namespace types will be made inaccessible, all unlisted ones are
+        permitted (blacklisting). If the empty string is assigned, the default namespace restrictions are applied,
+        which is equivalent to false. Internally, this setting limits access to the
+        <citerefentry><refentrytitle>unshare</refentrytitle><manvolnum>2</manvolnum></citerefentry>,
+        <citerefentry><refentrytitle>clone</refentrytitle><manvolnum>2</manvolnum></citerefentry> and
+        <citerefentry><refentrytitle>setns</refentrytitle><manvolnum>2</manvolnum></citerefentry> system calls, taking
+        the specified flags parameters into account. Note that — if this option is used — in addition to restricting
+        creation and switching of the specified types of namespaces (or all of them, if true) access to the
+        <function>setns()</function> system call with a zero flags parameter is prohibited.  This setting is only
+        supported on x86, x86-64, mips, mips-le, mips64, mips64-le, mips64-n32, mips64-le-n32, ppc64, ppc64-le, s390
+        and s390x, and enforces no restrictions on other architectures. If running in user mode, or in system mode, but
+        without the <constant>CAP_SYS_ADMIN</constant> capability (e.g. setting <varname>User=</varname>),
+        <varname>NoNewPrivileges=yes</varname> is implied.  </para></listitem>
       </varlistentry>
 
       <varlistentry>
-         <term><varname>UtmpMode=</varname></term>
+        <term><varname>LockPersonality=</varname></term>
 
-         <listitem><para>Takes one of <literal>init</literal>,
-         <literal>login</literal> or <literal>user</literal>. If
-         <varname>UtmpIdentifier=</varname> is set, controls which
-         type of <citerefentry
-         project='man-pages'><refentrytitle>utmp</refentrytitle><manvolnum>5</manvolnum></citerefentry>/wtmp
-         entries for this service are generated. This setting has no
-         effect unless <varname>UtmpIdentifier=</varname> is set
-         too. If <literal>init</literal> is set, only an
-         <constant>INIT_PROCESS</constant> entry is generated and the
-         invoked process must implement a
-         <command>getty</command>-compatible utmp/wtmp logic. If
-         <literal>login</literal> is set, first an
-         <constant>INIT_PROCESS</constant> entry, followed by a
-         <constant>LOGIN_PROCESS</constant> entry is generated. In
-         this case, the invoked process must implement a <citerefentry
-         project='die-net'><refentrytitle>login</refentrytitle><manvolnum>1</manvolnum></citerefentry>-compatible
-         utmp/wtmp logic. If <literal>user</literal> is set, first an
-         <constant>INIT_PROCESS</constant> entry, then a
-         <constant>LOGIN_PROCESS</constant> entry and finally a
-         <constant>USER_PROCESS</constant> entry is generated. In this
-         case, the invoked process may be any process that is suitable
-         to be run as session leader. Defaults to
-         <literal>init</literal>.</para></listitem>
+        <listitem><para>Takes a boolean argument. If set, locks down the <citerefentry
+        project='man-pages'><refentrytitle>personality</refentrytitle><manvolnum>2</manvolnum></citerefentry> system
+        call so that the kernel execution domain may not be changed from the default or the personality selected with
+        <varname>Personality=</varname> directive. This may be useful to improve security, because odd personality
+        emulations may be poorly tested and source of vulnerabilities. If running in user mode, or in system mode, but
+        without the <constant>CAP_SYS_ADMIN</constant> capability (e.g. setting <varname>User=</varname>),
+        <varname>NoNewPrivileges=yes</varname> is implied.</para></listitem>
       </varlistentry>
 
       <varlistentry>
-        <term><varname>SELinuxContext=</varname></term>
+        <term><varname>MemoryDenyWriteExecute=</varname></term>
 
-        <listitem><para>Set the SELinux security context of the
-        executed process. If set, this will override the automated
-        domain transition. However, the policy still needs to
-        authorize the transition. This directive is ignored if SELinux
-        is disabled. If prefixed by <literal>-</literal>, all errors
-        will be ignored. This does not affect commands prefixed with <literal>+</literal>.
-        See <citerefentry project='die-net'><refentrytitle>setexeccon</refentrytitle><manvolnum>3</manvolnum></citerefentry>
-        for details.</para></listitem>
+        <listitem><para>Takes a boolean argument. If set, attempts to create memory mappings that are writable and
+        executable at the same time, or to change existing memory mappings to become executable, or mapping shared
+        memory segments as executable are prohibited.  Specifically, a system call filter is added that rejects
+        <citerefentry><refentrytitle>mmap</refentrytitle><manvolnum>2</manvolnum></citerefentry> system calls with both
+        <constant>PROT_EXEC</constant> and <constant>PROT_WRITE</constant> set,
+        <citerefentry><refentrytitle>mprotect</refentrytitle><manvolnum>2</manvolnum></citerefentry> or
+        <citerefentry><refentrytitle>pkey_mprotect</refentrytitle><manvolnum>2</manvolnum></citerefentry> system calls
+        with <constant>PROT_EXEC</constant> set and
+        <citerefentry><refentrytitle>shmat</refentrytitle><manvolnum>2</manvolnum></citerefentry> system calls with
+        <constant>SHM_EXEC</constant> set. Note that this option is incompatible with programs and libraries that
+        generate program code dynamically at runtime, including JIT execution engines, executable stacks, and code
+        "trampoline" feature of various C compilers. This option improves service security, as it makes harder for
+        software exploits to change running code dynamically. Note that this feature is fully available on x86-64, and
+        partially on x86. Specifically, the <function>shmat()</function> protection is not available on x86. Note that
+        on systems supporting multiple ABIs (such as x86/x86-64) it is recommended to turn off alternative ABIs for
+        services, so that they cannot be used to circumvent the restrictions of this option. Specifically, it is
+        recommended to combine this option with <varname>SystemCallArchitectures=native</varname> or similar. If
+        running in user mode, or in system mode, but without the <constant>CAP_SYS_ADMIN</constant> capability
+        (e.g. setting <varname>User=</varname>), <varname>NoNewPrivileges=yes</varname> is implied.</para></listitem>
       </varlistentry>
 
       <varlistentry>
-        <term><varname>AppArmorProfile=</varname></term>
+        <term><varname>RestrictRealtime=</varname></term>
 
-        <listitem><para>Takes a profile name as argument. The process
-        executed by the unit will switch to this profile when started.
-        Profiles must already be loaded in the kernel, or the unit
-        will fail. This result in a non operation if AppArmor is not
-        enabled. If prefixed by <literal>-</literal>, all errors will
-        be ignored. This does not affect commands prefixed with <literal>+</literal>.</para></listitem>
+        <listitem><para>Takes a boolean argument. If set, any attempts to enable realtime scheduling in a process of
+        the unit are refused. This restricts access to realtime task scheduling policies such as
+        <constant>SCHED_FIFO</constant>, <constant>SCHED_RR</constant> or <constant>SCHED_DEADLINE</constant>. See
+        <citerefentry project='man-pages'><refentrytitle>sched</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+        for details about these scheduling policies. If running in user mode, or in system mode, but without the
+        <constant>CAP_SYS_ADMIN</constant> capability (e.g. setting <varname>User=</varname>),
+        <varname>NoNewPrivileges=yes</varname> is implied. Realtime scheduling policies may be used to monopolize CPU
+        time for longer periods of time, and may hence be used to lock up or otherwise trigger Denial-of-Service
+        situations on the system. It is hence recommended to restrict access to realtime scheduling to the few programs
+        that actually require them. Defaults to off.</para></listitem>
       </varlistentry>
 
       <varlistentry>
-        <term><varname>SmackProcessLabel=</varname></term>
-
-        <listitem><para>Takes a <option>SMACK64</option> security
-        label as argument. The process executed by the unit will be
-        started under this label and SMACK will decide whether the
-        process is allowed to run or not, based on it. The process
-        will continue to run under the label specified here unless the
-        executable has its own <option>SMACK64EXEC</option> label, in
-        which case the process will transition to run under that
-        label. When not specified, the label that systemd is running
-        under is used. This directive is ignored if SMACK is
-        disabled.</para>
+        <term><varname>RemoveIPC=</varname></term>
 
-        <para>The value may be prefixed by <literal>-</literal>, in
-        which case all errors will be ignored. An empty value may be
-        specified to unset previous assignments. This does not affect
-        commands prefixed with <literal>+</literal>.</para>
-        </listitem>
+        <listitem><para>Takes a boolean parameter. If set, all System V and POSIX IPC objects owned by the user and
+        group the processes of this unit are run as are removed when the unit is stopped. This setting only has an
+        effect if at least one of <varname>User=</varname>, <varname>Group=</varname> and
+        <varname>DynamicUser=</varname> are used. It has no effect on IPC objects owned by the root user. Specifically,
+        this removes System V semaphores, as well as System V and POSIX shared memory segments and message queues. If
+        multiple units use the same user or group the IPC objects are removed when the last of these units is
+        stopped. This setting is implied if <varname>DynamicUser=</varname> is set.</para></listitem>
       </varlistentry>
 
       <varlistentry>
-        <term><varname>IgnoreSIGPIPE=</varname></term>
+        <term><varname>MountFlags=</varname></term>
 
-        <listitem><para>Takes a boolean argument. If true, causes
-        <constant>SIGPIPE</constant> to be ignored in the executed
-        process. Defaults to true because <constant>SIGPIPE</constant>
-        generally is useful only in shell pipelines.</para></listitem>
+        <listitem><para>Takes a mount propagation flag: <option>shared</option>, <option>slave</option> or
+        <option>private</option>, which control whether mounts in the file system namespace set up for this unit's
+        processes will receive or propagate mounts and unmounts. See <citerefentry
+        project='man-pages'><refentrytitle>mount</refentrytitle><manvolnum>2</manvolnum></citerefentry> for
+        details. Defaults to <option>shared</option>. Use <option>shared</option> to ensure that mounts and unmounts
+        are propagated from systemd's namespace to the service's namespace and vice versa. Use <option>slave</option>
+        to run processes so that none of their mounts and unmounts will propagate to the host. Use
+        <option>private</option> to also ensure that no mounts and unmounts from the host will propagate into the unit
+        processes' namespace.  If this is set to <option>slave</option> or <option>private</option>, any mounts created
+        by spawned processes will be unmounted after the completion of the current command line of
+        <varname>ExecStartPre=</varname>, <varname>ExecStartPost=</varname>, <varname>ExecStart=</varname>, and
+        <varname>ExecStopPost=</varname>. Note that <option>slave</option> means that file systems mounted on the host
+        might stay mounted continuously in the unit's namespace, and thus keep the device busy. Note that the file
+        system namespace related options (<varname>PrivateTmp=</varname>, <varname>PrivateDevices=</varname>,
+        <varname>ProtectSystem=</varname>, <varname>ProtectHome=</varname>, <varname>ProtectKernelTunables=</varname>,
+        <varname>ProtectControlGroups=</varname>, <varname>ReadOnlyPaths=</varname>,
+        <varname>InaccessiblePaths=</varname>, <varname>ReadWritePaths=</varname>) require that mount and unmount
+        propagation from the unit's file system namespace is disabled, and hence downgrade <option>shared</option> to
+        <option>slave</option>. </para></listitem>
       </varlistentry>
 
-      <varlistentry>
-        <term><varname>NoNewPrivileges=</varname></term>
+    </variablelist>
+  </refsect1>
 
-        <listitem><para>Takes a boolean argument. If true, ensures that the service process and all its children can
-        never gain new privileges through <function>execve()</function> (e.g. via setuid or setgid bits, or filesystem
-        capabilities). This is the simplest and most effective way to ensure that a process and its children can never
-        elevate privileges again. Defaults to false, but certain settings force
-        <varname>NoNewPrivileges=yes</varname>, ignoring the value of this setting.  This is the case when
-        <varname>SystemCallFilter=</varname>, <varname>SystemCallArchitectures=</varname>,
-        <varname>RestrictAddressFamilies=</varname>, <varname>RestrictNamespaces=</varname>,
-        <varname>PrivateDevices=</varname>, <varname>ProtectKernelTunables=</varname>,
-        <varname>ProtectKernelModules=</varname>, <varname>MemoryDenyWriteExecute=</varname>, or
-        <varname>RestrictRealtime=</varname> are specified.</para></listitem>
-      </varlistentry>
+  <refsect1>
+    <title>System Call Filtering</title>
+    <variablelist>
 
       <varlistentry>
         <term><varname>SystemCallFilter=</varname></term>
@@ -1449,16 +1254,20 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
         executed by the unit processes except for the listed ones will result in immediate process termination with the
         <constant>SIGSYS</constant> signal (whitelisting). If the first character of the list is <literal>~</literal>,
         the effect is inverted: only the listed system calls will result in immediate process termination
-        (blacklisting). If running in user mode, or in system mode, but without the <constant>CAP_SYS_ADMIN</constant>
-        capability (e.g. setting <varname>User=nobody</varname>), <varname>NoNewPrivileges=yes</varname> is
-        implied. This feature makes use of the Secure Computing Mode 2 interfaces of the kernel ('seccomp filtering')
-        and is useful for enforcing a minimal sandboxing environment. Note that the <function>execve</function>,
-        <function>exit</function>, <function>exit_group</function>, <function>getrlimit</function>,
-        <function>rt_sigreturn</function>, <function>sigreturn</function> system calls and the system calls for
-        querying time and sleeping are implicitly whitelisted and do not need to be listed explicitly. This option may
-        be specified more than once, in which case the filter masks are merged. If the empty string is assigned, the
-        filter is reset, all prior assignments will have no effect. This does not affect commands prefixed with
-        <literal>+</literal>.</para>
+        (blacklisting). Blacklisted system calls and system call groups may optionally be suffixed with a colon
+        (<literal>:</literal>) and <literal>errno</literal> error number (between 0 and 4095) or errno name such as
+        <constant>EPERM</constant>, <constant>EACCES</constant> or <constant>EUCLEAN</constant>. This value will be
+        returned when a blacklisted system call is triggered, instead of terminating the processes immediately.  This
+        value takes precedence over the one given in <varname>SystemCallErrorNumber=</varname>.  If running in user
+        mode, or in system mode, but without the <constant>CAP_SYS_ADMIN</constant> capability (e.g. setting
+        <varname>User=nobody</varname>), <varname>NoNewPrivileges=yes</varname> is implied. This feature makes use of
+        the Secure Computing Mode 2 interfaces of the kernel ('seccomp filtering') and is useful for enforcing a
+        minimal sandboxing environment. Note that the <function>execve</function>, <function>exit</function>,
+        <function>exit_group</function>, <function>getrlimit</function>, <function>rt_sigreturn</function>,
+        <function>sigreturn</function> system calls and the system calls for querying time and sleeping are implicitly
+        whitelisted and do not need to be listed explicitly. This option may be specified more than once, in which case
+        the filter masks are merged. If the empty string is assigned, the filter is reset, all prior assignments will
+        have no effect. This does not affect commands prefixed with <literal>+</literal>.</para>
 
         <para>Note that on systems supporting multiple ABIs (such as x86/x86-64) it is recommended to turn off
         alternative ABIs for services, so that they cannot be used to circumvent the restrictions of this
@@ -1473,23 +1282,15 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
         might be necessary to temporarily disable system call filters in order to simplify debugging of such
         failures.</para>
 
-        <para>If you specify both types of this option (i.e.
-        whitelisting and blacklisting), the first encountered will
-        take precedence and will dictate the default action
-        (termination or approval of a system call). Then the next
-        occurrences of this option will add or delete the listed
-        system calls from the set of the filtered system calls,
-        depending of its type and the default action. (For example, if
-        you have started with a whitelisting of
-        <function>read</function> and <function>write</function>, and
-        right after it add a blacklisting of
-        <function>write</function>, then <function>write</function>
-        will be removed from the set.)</para>
-
-        <para>As the number of possible system
-        calls is large, predefined sets of system calls are provided.
-        A set starts with <literal>@</literal> character, followed by
-        name of the set.
+        <para>If you specify both types of this option (i.e.  whitelisting and blacklisting), the first encountered
+        will take precedence and will dictate the default action (termination or approval of a system call). Then the
+        next occurrences of this option will add or delete the listed system calls from the set of the filtered system
+        calls, depending of its type and the default action. (For example, if you have started with a whitelisting of
+        <function>read</function> and <function>write</function>, and right after it add a blacklisting of
+        <function>write</function>, then <function>write</function> will be removed from the set.)</para>
+
+        <para>As the number of possible system calls is large, predefined sets of system calls are provided.  A set
+        starts with <literal>@</literal> character, followed by name of the set.
 
         <table>
           <title>Currently predefined system call sets</title>
@@ -1608,13 +1409,11 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
           </tgroup>
         </table>
 
-        Note, that as new system calls are added to the kernel, additional system calls might be
-        added to the groups above. Contents of the sets may also change between systemd
-        versions. In addition, the list of system calls depends on the kernel version and
-        architecture for which systemd was compiled. Use
-        <command>systemd-analyze syscall-filter</command> to list the actual list of system calls in
-        each filter.
-      </para>
+        Note, that as new system calls are added to the kernel, additional system calls might be added to the groups
+        above. Contents of the sets may also change between systemd versions. In addition, the list of system calls
+        depends on the kernel version and architecture for which systemd was compiled. Use
+        <command>systemd-analyze syscall-filter</command> to list the actual list of system calls in each
+        filter.</para>
 
         <para>It is recommended to combine the file system namespacing related options with
         <varname>SystemCallFilter=~@mount</varname>, in order to prohibit the unit's processes to undo the
@@ -1628,15 +1427,11 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
       <varlistentry>
         <term><varname>SystemCallErrorNumber=</varname></term>
 
-        <listitem><para>Takes an <literal>errno</literal> error number
-        name to return when the system call filter configured with
-        <varname>SystemCallFilter=</varname> is triggered, instead of
-        terminating the process immediately. Takes an error name such
-        as <constant>EPERM</constant>, <constant>EACCES</constant> or
-        <constant>EUCLEAN</constant>. When this setting is not used,
-        or when the empty string is assigned, the process will be
-        terminated immediately when the filter is
-        triggered.</para></listitem>
+        <listitem><para>Takes an <literal>errno</literal> error number (between 1 and 4095) or errno name such as
+        <constant>EPERM</constant>, <constant>EACCES</constant> or <constant>EUCLEAN</constant>, to return when the
+        system call filter configured with <varname>SystemCallFilter=</varname> is triggered, instead of terminating
+        the process immediately. When this setting is not used, or when the empty string is assigned, the process will
+        be terminated immediately when the filter is triggered.</para></listitem>
       </varlistentry>
 
       <varlistentry>
@@ -1669,247 +1464,469 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
         details.</para></listitem>
       </varlistentry>
 
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Environment</title>
+
+    <variablelist>
+
       <varlistentry>
-        <term><varname>RestrictAddressFamilies=</varname></term>
+        <term><varname>Environment=</varname></term>
 
-        <listitem><para>Restricts the set of socket address families accessible to the processes of this unit. Takes a
-        space-separated list of address family names to whitelist, such as <constant>AF_UNIX</constant>,
-        <constant>AF_INET</constant> or <constant>AF_INET6</constant>. When prefixed with <constant>~</constant> the
-        listed address families will be applied as blacklist, otherwise as whitelist.  Note that this restricts access
-        to the <citerefentry
-        project='man-pages'><refentrytitle>socket</refentrytitle><manvolnum>2</manvolnum></citerefentry> system call
-        only. Sockets passed into the process by other means (for example, by using socket activation with socket
-        units, see <citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry>)
-        are unaffected. Also, sockets created with <function>socketpair()</function> (which creates connected AF_UNIX
-        sockets only) are unaffected. Note that this option has no effect on 32-bit x86, s390, s390x, mips, mips-le,
-        ppc, ppc-le, pcc64, ppc64-le and is ignored (but works correctly on other ABIs, including x86-64). Note that on
-        systems supporting multiple ABIs (such as x86/x86-64) it is recommended to turn off alternative ABIs for
-        services, so that they cannot be used to circumvent the restrictions of this option. Specifically, it is
-        recommended to combine this option with <varname>SystemCallArchitectures=native</varname> or similar. If
-        running in user mode, or in system mode, but without the <constant>CAP_SYS_ADMIN</constant> capability
-        (e.g. setting <varname>User=nobody</varname>), <varname>NoNewPrivileges=yes</varname> is implied. By default,
-        no restrictions apply, all address families are accessible to processes. If assigned the empty string, any
-        previous address familiy restriction changes are undone. This setting does not affect commands prefixed with
-        <literal>+</literal>.</para>
+        <listitem><para>Sets environment variables for executed processes. Takes a space-separated list of variable
+        assignments. This option may be specified more than once, in which case all listed variables will be set. If
+        the same variable is set twice, the later setting will override the earlier setting. If the empty string is
+        assigned to this option, the list of environment variables is reset, all prior assignments have no
+        effect. Variable expansion is not performed inside the strings, however, specifier expansion is possible. The $
+        character has no special meaning. If you need to assign a value containing spaces or the equals sign to a
+        variable, use double quotes (") for the assignment.</para>
 
-        <para>Use this option to limit exposure of processes to remote access, in particular via exotic and sensitive
-        network protocols, such as <constant>AF_PACKET</constant>. Note that in most cases, the local
-        <constant>AF_UNIX</constant> address family should be included in the configured whitelist as it is frequently
-        used for local communication, including for
-        <citerefentry><refentrytitle>syslog</refentrytitle><manvolnum>2</manvolnum></citerefentry>
-        logging.</para></listitem>
+        <para>Example:
+        <programlisting>Environment="VAR1=word1 word2" VAR2=word3 "VAR3=$word 5 6"</programlisting>
+        gives three variables <literal>VAR1</literal>,
+        <literal>VAR2</literal>, <literal>VAR3</literal>
+        with the values <literal>word1 word2</literal>,
+        <literal>word3</literal>, <literal>$word 5 6</literal>.
+        </para>
+
+        <para>
+        See <citerefentry
+        project='man-pages'><refentrytitle>environ</refentrytitle><manvolnum>7</manvolnum></citerefentry> for details
+        about environment variables.</para></listitem>
       </varlistentry>
 
       <varlistentry>
-        <term><varname>RestrictNamespaces=</varname></term>
+        <term><varname>EnvironmentFile=</varname></term>
 
-        <listitem><para>Restricts access to Linux namespace functionality for the processes of this unit. For details
-        about Linux namespaces, see
-        <citerefentry project='man-pages'><refentrytitle>namespaces</refentrytitle><manvolnum>7</manvolnum></citerefentry>. Either takes a
-        boolean argument, or a space-separated list of namespace type identifiers. If false (the default), no
-        restrictions on namespace creation and switching are made. If true, access to any kind of namespacing is
-        prohibited. Otherwise, a space-separated list of namespace type identifiers must be specified, consisting of
-        any combination of: <constant>cgroup</constant>, <constant>ipc</constant>, <constant>net</constant>,
-        <constant>mnt</constant>, <constant>pid</constant>, <constant>user</constant> and <constant>uts</constant>. Any
-        namespace type listed is made accessible to the unit's processes, access to namespace types not listed is
-        prohibited (whitelisting). By prepending the list with a single tilde character (<literal>~</literal>) the
-        effect may be inverted: only the listed namespace types will be made inaccessible, all unlisted ones are
-        permitted (blacklisting). If the empty string is assigned, the default namespace restrictions are applied,
-        which is equivalent to false. Internally, this setting limits access to the
-        <citerefentry><refentrytitle>unshare</refentrytitle><manvolnum>2</manvolnum></citerefentry>,
-        <citerefentry><refentrytitle>clone</refentrytitle><manvolnum>2</manvolnum></citerefentry> and
-        <citerefentry><refentrytitle>setns</refentrytitle><manvolnum>2</manvolnum></citerefentry> system calls, taking
-        the specified flags parameters into account. Note that — if this option is used — in addition to restricting
-        creation and switching of the specified types of namespaces (or all of them, if true) access to the
-        <function>setns()</function> system call with a zero flags parameter is prohibited.  This setting is only
-        supported on x86, x86-64, mips, mips-le, mips64, mips64-le, mips64-n32, mips64-le-n32, ppc64, ppc64-le,
-        s390 and s390x, and enforces no restrictions on other architectures. If running in user
-        mode, or in system mode, but without the <constant>CAP_SYS_ADMIN</constant> capability (e.g. setting
-        <varname>User=</varname>), <varname>NoNewPrivileges=yes</varname> is implied.  </para></listitem>
+        <listitem><para>Similar to <varname>Environment=</varname> but reads the environment variables from a text
+        file. The text file should contain new-line-separated variable assignments.  Empty lines, lines without an
+        <literal>=</literal> separator, or lines starting with ; or # will be ignored, which may be used for
+        commenting. A line ending with a backslash will be concatenated with the following one, allowing multiline
+        variable definitions. The parser strips leading and trailing whitespace from the values of assignments, unless
+        you use double quotes (").</para>
+
+        <para>The argument passed should be an absolute filename or wildcard expression, optionally prefixed with
+        <literal>-</literal>, which indicates that if the file does not exist, it will not be read and no error or
+        warning message is logged. This option may be specified more than once in which case all specified files are
+        read. If the empty string is assigned to this option, the list of file to read is reset, all prior assignments
+        have no effect.</para>
+
+        <para>The files listed with this directive will be read shortly before the process is executed (more
+        specifically, after all processes from a previous unit state terminated.  This means you can generate these
+        files in one unit state, and read it with this option in the next).</para>
+
+        <para>Settings from these files override settings made with <varname>Environment=</varname>. If the same
+        variable is set twice from these files, the files will be read in the order they are specified and the later
+        setting will override the earlier setting.</para></listitem>
       </varlistentry>
 
       <varlistentry>
-        <term><varname>Personality=</varname></term>
+        <term><varname>PassEnvironment=</varname></term>
 
-        <listitem><para>Controls which kernel architecture <citerefentry
-        project='man-pages'><refentrytitle>uname</refentrytitle><manvolnum>2</manvolnum></citerefentry> shall report,
-        when invoked by unit processes. Takes one of the architecture identifiers <constant>x86</constant>,
-        <constant>x86-64</constant>, <constant>ppc</constant>, <constant>ppc-le</constant>, <constant>ppc64</constant>,
-        <constant>ppc64-le</constant>, <constant>s390</constant> or <constant>s390x</constant>. Which personality
-        architectures are supported depends on the system architecture. Usually the 64bit versions of the various
-        system architectures support their immediate 32bit personality architecture counterpart, but no others. For
-        example, <constant>x86-64</constant> systems support the <constant>x86-64</constant> and
-        <constant>x86</constant> personalities but no others. The personality feature is useful when running 32-bit
-        services on a 64-bit host system. If not specified, the personality is left unmodified and thus reflects the
-        personality of the host system's kernel.</para></listitem>
+        <listitem><para>Pass environment variables set for the system service manager to executed processes. Takes a
+        space-separated list of variable names. This option may be specified more than once, in which case all listed
+        variables will be passed. If the empty string is assigned to this option, the list of environment variables to
+        pass is reset, all prior assignments have no effect. Variables specified that are not set for the system
+        manager will not be passed and will be silently ignored. Note that this option is only relevant for the system
+        service manager, as system services by default do not automatically inherit any environment variables set for
+        the service manager itself. However, in case of the user service manager all environment variables are passed
+        to the executed processes anyway, hence this option is without effect for the user service manager.</para>
+
+        <para>Variables set for invoked processes due to this setting are subject to being overridden by those
+        configured with <varname>Environment=</varname> or <varname>EnvironmentFile=</varname>.</para>
+
+        <para>Example:
+        <programlisting>PassEnvironment=VAR1 VAR2 VAR3</programlisting>
+        passes three variables <literal>VAR1</literal>,
+        <literal>VAR2</literal>, <literal>VAR3</literal>
+        with the values set for those variables in PID1.</para>
+
+        <para>
+        See <citerefentry
+        project='man-pages'><refentrytitle>environ</refentrytitle><manvolnum>7</manvolnum></citerefentry> for details
+        about environment variables.</para></listitem>
       </varlistentry>
 
       <varlistentry>
-        <term><varname>LockPersonality=</varname></term>
+        <term><varname>UnsetEnvironment=</varname></term>
 
-        <listitem><para>Takes a boolean argument. If set, locks down the <citerefentry
-        project='man-pages'><refentrytitle>personality</refentrytitle><manvolnum>2</manvolnum></citerefentry> system
-        call so that the kernel execution domain may not be changed from the default or the personality selected with
-        <varname>Personality=</varname> directive. This may be useful to improve security, because odd personality
-        emulations may be poorly tested and source of vulnerabilities. If running in user mode, or in system mode, but
-        without the <constant>CAP_SYS_ADMIN</constant> capability (e.g. setting <varname>User=</varname>),
-        <varname>NoNewPrivileges=yes</varname> is implied.</para></listitem>
+        <listitem><para>Explicitly unset environment variable assignments that would normally be passed from the
+        service manager to invoked processes of this unit. Takes a space-separated list of variable names or variable
+        assignments. This option may be specified more than once, in which case all listed variables/assignments will
+        be unset. If the empty string is assigned to this option, the list of environment variables/assignments to
+        unset is reset. If a variable assignment is specified (that is: a variable name, followed by
+        <literal>=</literal>, followed by its value), then any environment variable matching this precise assignment is
+        removed. If a variable name is specified (that is a variable name without any following <literal>=</literal> or
+        value), then any assignment matching the variable name, regardless of its value is removed. Note that the
+        effect of <varname>UnsetEnvironment=</varname> is applied as final step when the environment list passed to
+        executed processes is compiled. That means it may undo assignments from any configuration source, including
+        assignments made through <varname>Environment=</varname> or <varname>EnvironmentFile=</varname>, inherited from
+        the system manager's global set of environment variables, inherited via <varname>PassEnvironment=</varname>,
+        set by the service manager itself (such as <varname>$NOTIFY_SOCKET</varname> and such), or set by a PAM module
+        (in case <varname>PAMName=</varname> is used).</para>
+
+        <para>
+        See <citerefentry
+        project='man-pages'><refentrytitle>environ</refentrytitle><manvolnum>7</manvolnum></citerefentry> for details
+        about environment variables.</para></listitem>
       </varlistentry>
 
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Logging and Standard Input/Output</title>
+
+    <variablelist>
       <varlistentry>
-        <term><varname>KeyringMode=</varname></term>
 
-        <listitem><para>Controls how the kernel session keyring is set up for the service (see <citerefentry
-        project='man-pages'><refentrytitle>session-keyring</refentrytitle><manvolnum>7</manvolnum></citerefentry> for
-        details on the session keyring). Takes one of <option>inherit</option>, <option>private</option>,
-        <option>shared</option>. If set to <option>inherit</option> no special keyring setup is done, and the kernel's
-        default behaviour is applied. If <option>private</option> is used a new session keyring is allocated when a
-        service process is invoked, and it is not linked up with any user keyring. This is the recommended setting for
-        system services, as this ensures that multiple services running under the same system user ID (in particular
-        the root user) do not share their key material among each other. If <option>shared</option> is used a new
-        session keyring is allocated as for <option>private</option>, but the user keyring of the user configured with
-        <varname>User=</varname> is linked into it, so that keys assigned to the user may be requested by the unit's
-        processes. In this modes multiple units running processes under the same user ID may share key material. Unless
-        <option>inherit</option> is selected the unique invocation ID for the unit (see below) is added as a protected
-        key by the name <literal>invocation_id</literal> to the newly created session keyring. Defaults to
-        <option>private</option> for the system service manager and to <option>inherit</option> for the user service
-        manager.</para></listitem>
+        <term><varname>StandardInput=</varname></term>
+
+        <listitem><para>Controls where file descriptor 0 (STDIN) of the executed processes is connected to. Takes one
+        of <option>null</option>, <option>tty</option>, <option>tty-force</option>, <option>tty-fail</option>,
+        <option>data</option>, <option>file:<replaceable>path</replaceable></option>, <option>socket</option> or
+        <option>fd:<replaceable>name</replaceable></option>.</para>
+
+        <para>If <option>null</option> is selected, standard input will be connected to <filename>/dev/null</filename>,
+        i.e. all read attempts by the process will result in immediate EOF.</para>
+
+        <para>If <option>tty</option> is selected, standard input is connected to a TTY (as configured by
+        <varname>TTYPath=</varname>, see below) and the executed process becomes the controlling process of the
+        terminal. If the terminal is already being controlled by another process, the executed process waits until the
+        current controlling process releases the terminal.</para>
+
+        <para><option>tty-force</option> is similar to <option>tty</option>, but the executed process is forcefully and
+        immediately made the controlling process of the terminal, potentially removing previous controlling processes
+        from the terminal.</para>
+
+        <para><option>tty-fail</option> is similar to <option>tty</option>, but if the terminal already has a
+        controlling process start-up of the executed process fails.</para>
+
+        <para>The <option>data</option> option may be used to configure arbitrary textual or binary data to pass via
+        standard input to the executed process. The data to pass is configured via
+        <varname>StandardInputText=</varname>/<varname>StandardInputData=</varname> (see below). Note that the actual
+        file descriptor type passed (memory file, regular file, UNIX pipe, …) might depend on the kernel and available
+        privileges. In any case, the file descriptor is read-only, and when read returns the specified data followed by
+        EOF.</para>
+
+        <para>The <option>file:<replaceable>path</replaceable></option> option may be used to connect a specific file
+        system object to standard input. An absolute path following the <literal>:</literal> character is expected,
+        which may refer to a regular file, a FIFO or special file. If an <constant>AF_UNIX</constant> socket in the
+        file system is specified, a stream socket is connected to it. The latter is useful for connecting standard
+        input of processes to arbitrary system services.</para>
+
+        <para>The <option>socket</option> option is valid in socket-activated services only, and requires the relevant
+        socket unit file (see
+        <citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry> for details)
+        to have <varname>Accept=yes</varname> set, or to specify a single socket only. If this option is set, standard
+        input will be connected to the socket the service was activated from, which is primarily useful for
+        compatibility with daemons designed for use with the traditional <citerefentry
+        project='freebsd'><refentrytitle>inetd</refentrytitle><manvolnum>8</manvolnum></citerefentry> socket activation
+        daemon.</para>
+
+        <para>The <option>fd:<replaceable>name</replaceable></option> option connects standard input to a specific,
+        named file descriptor provided by a socket unit.  The name may be specified as part of this option, following a
+        <literal>:</literal> character (e.g. <literal>fd:foobar</literal>).  If no name is specified, the name
+        <literal>stdin</literal> is implied (i.e. <literal>fd</literal> is equivalent to <literal>fd:stdin</literal>).
+        At least one socket unit defining the specified name must be provided via the <varname>Sockets=</varname>
+        option, and the file descriptor name may differ from the name of its containing socket unit.  If multiple
+        matches are found, the first one will be used.  See <varname>FileDescriptorName=</varname> in
+        <citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry> for more
+        details about named file descriptors and their ordering.</para>
+
+        <para>This setting defaults to <option>null</option>.</para></listitem>
       </varlistentry>
 
       <varlistentry>
-        <term><varname>RuntimeDirectory=</varname></term>
-        <term><varname>StateDirectory=</varname></term>
-        <term><varname>CacheDirectory=</varname></term>
-        <term><varname>LogsDirectory=</varname></term>
-        <term><varname>ConfigurationDirectory=</varname></term>
+        <term><varname>StandardOutput=</varname></term>
 
-        <listitem><para>These options take a whitespace-separated list of directory names. The specified directory
-        names must be relative, and may not include <literal>.</literal> or <literal>..</literal>. If set, one or more
-        directories by the specified names will be created (including their parents) below <filename>/run</filename>
-        (or <varname>$XDG_RUNTIME_DIR</varname> for user services), <filename>/var/lib</filename> (or
-        <varname>$XDG_CONFIG_HOME</varname> for user services), <filename>/var/cache</filename> (or
-        <varname>$XDG_CACHE_HOME</varname> for user services), <filename>/var/log</filename> (or
-        <varname>$XDG_CONFIG_HOME</varname><filename>/log</filename> for user services), or <filename>/etc</filename>
-        (or <varname>$XDG_CONFIG_HOME</varname> for user services), respectively, when the unit is started.</para>
+        <listitem><para>Controls where file descriptor 1 (STDOUT) of the executed processes is connected to. Takes one
+        of <option>inherit</option>, <option>null</option>, <option>tty</option>, <option>journal</option>,
+        <option>syslog</option>, <option>kmsg</option>, <option>journal+console</option>,
+        <option>syslog+console</option>, <option>kmsg+console</option>,
+        <option>file:<replaceable>path</replaceable></option>, <option>socket</option> or
+        <option>fd:<replaceable>name</replaceable></option>.</para>
 
-        <para>In case of <varname>RuntimeDirectory=</varname> the lowest subdirectories are removed when the unit is
-        stopped. It is possible to preserve the specified directories in this case if
-        <varname>RuntimeDirectoryPreserve=</varname> is configured to <option>restart</option> or <option>yes</option>
-        (see below). The directories specified with <varname>StateDirectory=</varname>,
-        <varname>CacheDirectory=</varname>, <varname>LogsDirectory=</varname>,
-        <varname>ConfigurationDirectory=</varname> are not removed when the unit is stopped.</para>
+        <para><option>inherit</option> duplicates the file descriptor of standard input for standard output.</para>
 
-        <para>Except in case of <varname>ConfigurationDirectory=</varname>, the innermost specified directories will be
-        owned by the user and group specified in <varname>User=</varname> and <varname>Group=</varname>. If the
-        specified directories already exist and their owning user or group do not match the configured ones, all files
-        and directories below the specified directories as well as the directories themselves will have their file
-        ownership recursively changed to match what is configured. As an optimization, if the specified directories are
-        already owned by the right user and group, files and directories below of them are left as-is, even if they do
-        not match what is requested. The innermost specified directories will have their access mode adjusted to the
-        what is specified in <varname>RuntimeDirectoryMode=</varname>, <varname>StateDirectoryMode=</varname>,
-        <varname>CacheDirectoryMode=</varname>, <varname>LogsDirectoryMode=</varname> and
-        <varname>ConfigurationDirectoryMode=</varname>.</para>
+        <para><option>null</option> connects standard output to <filename>/dev/null</filename>, i.e. everything written
+        to it will be lost.</para>
 
-        <para>Except in case of <varname>ConfigurationDirectory=</varname>, these options imply
-        <varname>ReadWritePaths=</varname> for the specified paths. When combined with
-        <varname>RootDirectory=</varname> or <varname>RootImage=</varname> these paths always reside on the host and
-        are mounted from there into the unit's file system namespace. If <varname>DynamicUser=</varname> is used in
-        conjunction with <varname>RuntimeDirectory=</varname>, <varname>StateDirectory=</varname>,
-        <varname>CacheDirectory=</varname> and <varname>LogsDirectory=</varname>, the behaviour of these options is
-        slightly altered: the directories are created below <filename>/run/private</filename>,
-        <filename>/var/lib/private</filename>, <filename>/var/cache/private</filename> and
-        <filename>/var/log/private</filename>, respectively, which are host directories made inaccessible to
-        unprivileged users, which ensures that access to these directories cannot be gained through dynamic user ID
-        recycling. Symbolic links are created to hide this difference in behaviour. Both from perspective of the host
-        and from inside the unit, the relevant directories hence always appear directly below
-        <filename>/run</filename>, <filename>/var/lib</filename>, <filename>/var/cache</filename> and
-        <filename>/var/log</filename>.</para>
+        <para><option>tty</option> connects standard output to a tty (as configured via <varname>TTYPath=</varname>,
+        see below). If the TTY is used for output only, the executed process will not become the controlling process of
+        the terminal, and will not fail or wait for other processes to release the terminal.</para>
 
-        <para>Use <varname>RuntimeDirectory=</varname> to manage one or more runtime directories for the unit and bind
-        their lifetime to the daemon runtime. This is particularly useful for unprivileged daemons that cannot create
-        runtime directories in <filename>/run</filename> due to lack of privileges, and to make sure the runtime
-        directory is cleaned up automatically after use. For runtime directories that require more complex or different
-        configuration or lifetime guarantees, please consider using
-        <citerefentry><refentrytitle>tmpfiles.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
+        <para><option>journal</option> connects standard output with the journal which is accessible via
+        <citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>.  Note that
+        everything that is written to syslog or kmsg (see below) is implicitly stored in the journal as well, the
+        specific two options listed below are hence supersets of this one.</para>
 
-        <para>Example: if a system service unit has the following,
-        <programlisting>RuntimeDirectory=foo/bar baz</programlisting>
-        the service manager creates <filename>/run/foo</filename> (if it does not exist), <filename>/run/foo/bar</filename>,
-        and <filename>/run/baz</filename>. The directories <filename>/run/foo/bar</filename> and <filename>/run/baz</filename>
-        except <filename>/run/foo</filename> are owned by the user and group specified in <varname>User=</varname> and
-        <varname>Group=</varname>, and removed when the service is stopped.
-        </para></listitem>
+        <para><option>syslog</option> connects standard output to the <citerefentry
+        project='man-pages'><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry> system syslog
+        service, in addition to the journal. Note that the journal daemon is usually configured to forward everything
+        it receives to syslog anyway, in which case this option is no different from <option>journal</option>.</para>
 
+        <para><option>kmsg</option> connects standard output with the kernel log buffer which is accessible via
+        <citerefentry project='man-pages'><refentrytitle>dmesg</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+        in addition to the journal. The journal daemon might be configured to send all logs to kmsg anyway, in which
+        case this option is no different from <option>journal</option>.</para>
+
+        <para><option>journal+console</option>, <option>syslog+console</option> and <option>kmsg+console</option> work
+        in a similar way as the three options above but copy the output to the system console as well.</para>
+
+        <para>The <option>file:<replaceable>path</replaceable></option> option may be used to connect a specific file
+        system object to standard output. The semantics are similar to the same option of
+        <varname>StandardInputText=</varname>, see above. If standard input and output are directed to the same file
+        path, it is opened only once, for reading as well as writing and duplicated. This is particular useful when the
+        specified path refers to an <constant>AF_UNIX</constant> socket in the file system, as in that case only a
+        single stream connection is created for both input and output.</para>
+
+        <para><option>socket</option> connects standard output to a socket acquired via socket activation. The
+        semantics are similar to the same option of <varname>StandardInput=</varname>, see above.</para>
+
+        <para>The <option>fd:<replaceable>name</replaceable></option> option connects standard output to a specific,
+        named file descriptor provided by a socket unit.  A name may be specified as part of this option, following a
+        <literal>:</literal> character (e.g. <literal>fd:foobar</literal>).  If no name is specified, the name
+        <literal>stdout</literal> is implied (i.e. <literal>fd</literal> is equivalent to
+        <literal>fd:stdout</literal>).  At least one socket unit defining the specified name must be provided via the
+        <varname>Sockets=</varname> option, and the file descriptor name may differ from the name of its containing
+        socket unit.  If multiple matches are found, the first one will be used.  See
+        <varname>FileDescriptorName=</varname> in
+        <citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry> for more
+        details about named descriptors and their ordering.</para>
+
+        <para>If the standard output (or error output, see below) of a unit is connected to the journal, syslog or the
+        kernel log buffer, the unit will implicitly gain a dependency of type <varname>After=</varname> on
+        <filename>systemd-journald.socket</filename> (also see the "Implicit Dependencies" section above). Also note
+        that in this case stdout (or stderr, see below) will be an <constant>AF_UNIX</constant> stream socket, and not
+        a pipe or FIFO that can be re-opened. This means when executing shell scripts the construct <command>echo
+        "hello" &gt; /dev/stderr</command> for writing text to stderr will not work. To mitigate this use the construct
+        <command>echo "hello" >&amp;2</command> instead, which is mostly equivalent and avoids this pitfall.</para>
+
+        <para>This setting defaults to the value set with <varname>DefaultStandardOutput=</varname> in
+        <citerefentry><refentrytitle>systemd-system.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>, which
+        defaults to <option>journal</option>. Note that setting this parameter might result in additional dependencies
+        to be added to the unit (see above).</para></listitem>
       </varlistentry>
 
       <varlistentry>
-        <term><varname>RuntimeDirectoryMode=</varname></term>
-        <term><varname>StateDirectoryMode=</varname></term>
-        <term><varname>CacheDirectoryMode=</varname></term>
-        <term><varname>LogsDirectoryMode=</varname></term>
-        <term><varname>ConfigurationDirectoryMode=</varname></term>
+        <term><varname>StandardError=</varname></term>
 
-        <listitem><para>Specifies the access mode of the directories specified in
-        <varname>RuntimeDirectory=</varname>, <varname>StateDirectory=</varname>, <varname>CacheDirectory=</varname>,
-        <varname>LogsDirectory=</varname>, or <varname>ConfigurationDirectory=</varname>, respectively, as an octal number.
-        Defaults to <constant>0755</constant>. See "Permissions" in
-        <citerefentry project='man-pages'><refentrytitle>path_resolution</refentrytitle><manvolnum>7</manvolnum></citerefentry>
-        for a discussion of the meaning of permission bits.
-        </para></listitem>
+        <listitem><para>Controls where file descriptor 2 (STDERR) of the executed processes is connected to. The
+        available options are identical to those of <varname>StandardOutput=</varname>, with some exceptions: if set to
+        <option>inherit</option> the file descriptor used for standard output is duplicated for standard error, while
+        <option>fd:<replaceable>name</replaceable></option> will use a default file descriptor name of
+        <literal>stderr</literal>.</para>
+
+        <para>This setting defaults to the value set with <varname>DefaultStandardError=</varname> in
+        <citerefentry><refentrytitle>systemd-system.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>, which
+        defaults to <option>inherit</option>. Note that setting this parameter might result in additional dependencies
+        to be added to the unit (see above).</para></listitem>
       </varlistentry>
 
       <varlistentry>
-        <term><varname>RuntimeDirectoryPreserve=</varname></term>
+        <term><varname>StandardInputText=</varname></term>
+        <term><varname>StandardInputData=</varname></term>
 
-        <listitem><para>Takes a boolean argument or <option>restart</option>.
-        If set to <option>no</option> (the default), the directories specified in <varname>RuntimeDirectory=</varname>
-        are always removed when the service stops. If set to <option>restart</option> the directories are preserved
-        when the service is both automatically and manually restarted. Here, the automatic restart means the operation
-        specified in <varname>Restart=</varname>, and manual restart means the one triggered by
-        <command>systemctl restart foo.service</command>. If set to <option>yes</option>, then the directories are not
-        removed when the service is stopped. Note that since the runtime directory <filename>/run</filename> is a mount
-        point of <literal>tmpfs</literal>, then for system services the directories specified in
-        <varname>RuntimeDirectory=</varname> are removed when the system is rebooted.
-        </para></listitem>
+        <listitem><para>Configures arbitrary textual or binary data to pass via file descriptor 0 (STDIN) to the
+        executed processes. These settings have no effect unless <varname>StandardInput=</varname> is set to
+        <option>data</option>. Use this option to embed process input data directly in the unit file.</para>
+
+        <para><varname>StandardInputText=</varname> accepts arbitrary textual data. C-style escapes for special
+        characters as well as the usual <literal>%</literal>-specifiers are resolved. Each time this setting is used
+        the the specified text is appended to the per-unit data buffer, followed by a newline character (thus every use
+        appends a new line to the end of the buffer). Note that leading and trailing whitespace of lines configured
+        with this option is removed. If an empty line is specified the buffer is cleared (hence, in order to insert an
+        empty line, add an additional <literal>\n</literal> to the end or beginning of a line).</para>
+
+        <para><varname>StandardInputData=</varname> accepts arbitrary binary data, encoded in <ulink
+        url="https://tools.ietf.org/html/rfc2045#section-6.8">Base64</ulink>. No escape sequences or specifiers are
+        resolved. Any whitespace in the encoded version is ignored during decoding.</para>
+
+        <para>Note that <varname>StandardInputText=</varname> and <varname>StandardInputData=</varname> operate on the
+        same data buffer, and may be mixed in order to configure both binary and textual data for the same input
+        stream. The textual or binary data is joined strictly in the order the settings appear in the unit
+        file. Assigning an empty string to either will reset the data buffer.</para>
+
+        <para>Please keep in mind that in order to maintain readability long unit file settings may be split into
+        multiple lines, by suffixing each line (except for the last) with a <literal>\</literal> character (see
+        <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry> for
+        details). This is particularly useful for large data configured with these two options. Example:</para>
+
+        <programlisting>…
+StandardInput=data
+StandardInputData=SWNrIHNpdHplIGRhIHVuJyBlc3NlIEtsb3BzLAp1ZmYgZWVtYWwga2xvcHAncy4KSWNrIGtpZWtl \
+                  LCBzdGF1bmUsIHd1bmRyZSBtaXIsCnVmZiBlZW1hbCBqZWh0IHNlIHVmZiBkaWUgVMO8ci4KTmFu \
+                  dSwgZGVuayBpY2ssIGljayBkZW5rIG5hbnUhCkpldHogaXNzZSB1ZmYsIGVyc2NodCB3YXIgc2Ug \
+                  enUhCkljayBqZWhlIHJhdXMgdW5kIGJsaWNrZSDigJQKdW5kIHdlciBzdGVodCBkcmF1w59lbj8g \
+                  SWNrZSEK
+…</programlisting></listitem>
       </varlistentry>
 
       <varlistentry>
-        <term><varname>MemoryDenyWriteExecute=</varname></term>
+        <term><varname>LogLevelMax=</varname></term>
 
-        <listitem><para>Takes a boolean argument. If set, attempts to create memory mappings that are writable and
-        executable at the same time, or to change existing memory mappings to become executable, or mapping shared
-        memory segments as executable are prohibited.  Specifically, a system call filter is added that rejects
-        <citerefentry><refentrytitle>mmap</refentrytitle><manvolnum>2</manvolnum></citerefentry> system calls with both
-        <constant>PROT_EXEC</constant> and <constant>PROT_WRITE</constant> set,
-        <citerefentry><refentrytitle>mprotect</refentrytitle><manvolnum>2</manvolnum></citerefentry> system calls with
-        <constant>PROT_EXEC</constant> set and
-        <citerefentry><refentrytitle>shmat</refentrytitle><manvolnum>2</manvolnum></citerefentry> system calls with
-        <constant>SHM_EXEC</constant> set. Note that this option is incompatible with programs and libraries that
-        generate program code dynamically at runtime, including JIT execution engines, executable stacks, and code
-        "trampoline" feature of various C compilers. This option improves service security, as it makes harder for
-        software exploits to change running code dynamically. Note that this feature is fully available on x86-64, and
-        partially on x86. Specifically, the <function>shmat()</function> protection is not available on x86. Note that
-        on systems supporting multiple ABIs (such as x86/x86-64) it is recommended to turn off alternative ABIs for
-        services, so that they cannot be used to circumvent the restrictions of this option. Specifically, it is
-        recommended to combine this option with <varname>SystemCallArchitectures=native</varname> or similar. If
-        running in user mode, or in system mode, but without the <constant>CAP_SYS_ADMIN</constant> capability
-        (e.g. setting <varname>User=</varname>), <varname>NoNewPrivileges=yes</varname> is implied.</para></listitem>
+        <listitem><para>Configures filtering by log level of log messages generated by this unit. Takes a
+        <command>syslog</command> log level, one of <option>emerg</option> (lowest log level, only highest priority
+        messages), <option>alert</option>, <option>crit</option>, <option>err</option>, <option>warning</option>,
+        <option>notice</option>, <option>info</option>, <option>debug</option> (highest log level, also lowest priority
+        messages). See <citerefentry
+        project='man-pages'><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry> for
+        details. By default no filtering is applied (i.e. the default maximum log level is <option>debug</option>). Use
+        this option to configure the logging system to drop log messages of a specific service above the specified
+        level. For example, set <varname>LogLevelMax=</varname><option>info</option> in order to turn off debug logging
+        of a particularly chatty unit. Note that the the configured level is applied to any log messages written by any
+        of the processes belonging to this unit, sent via any supported logging protocol. The filtering is applied
+        early in the logging pipeline, before any kind of further processing is done. Moreover, messages which pass
+        through this filter successfully might still be dropped by filters applied at a later stage in the logging
+        subsystem. For example, <varname>MaxLevelStore=</varname> configured in
+        <citerefentry><refentrytitle>journald.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry> might
+        prohibit messages of higher log levels to be stored on disk, even though the per-unit
+        <varname>LogLevelMax=</varname> permitted it to be processed.</para></listitem>
       </varlistentry>
 
       <varlistentry>
-        <term><varname>RestrictRealtime=</varname></term>
+        <term><varname>LogExtraFields=</varname></term>
 
-        <listitem><para>Takes a boolean argument. If set, any attempts to enable realtime scheduling in a process of
-        the unit are refused. This restricts access to realtime task scheduling policies such as
-        <constant>SCHED_FIFO</constant>, <constant>SCHED_RR</constant> or <constant>SCHED_DEADLINE</constant>. See
-        <citerefentry project='man-pages'><refentrytitle>sched</refentrytitle><manvolnum>7</manvolnum></citerefentry> for details about
-        these scheduling policies. If running in user mode, or in system mode, but
-        without the <constant>CAP_SYS_ADMIN</constant> capability
-        (e.g. setting <varname>User=</varname>), <varname>NoNewPrivileges=yes</varname>
-        is implied. Realtime scheduling policies may be used to monopolize CPU time for longer periods
-        of time, and may hence be used to lock up or otherwise trigger Denial-of-Service situations on the system. It
-        is hence recommended to restrict access to realtime scheduling to the few programs that actually require
-        them. Defaults to off.</para></listitem>
+        <listitem><para>Configures additional log metadata fields to include in all log records generated by processes
+        associated with this unit. This setting takes one or more journal field assignments in the format
+        <literal>FIELD=VALUE</literal> separated by whitespace. See
+        <citerefentry><refentrytitle>systemd.journal-fields</refentrytitle><manvolnum>7</manvolnum></citerefentry> for
+        details on the journal field concept. Even though the underlying journal implementation permits binary field
+        values, this setting accepts only valid UTF-8 values. To include space characters in a journal field value,
+        enclose the assignment in double quotes ("). The usual specifiers are expanded in all assignments (see
+        below). Note that this setting is not only useful for attaching additional metadata to log records of a unit,
+        but given that all fields and values are indexed may also be used to implement cross-unit log record
+        matching. Assign an empty string to reset the list.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>SyslogIdentifier=</varname></term>
+
+        <listitem><para>Sets the process name ("<command>syslog</command> tag") to prefix log lines sent to the logging
+        system or the kernel log buffer with. If not set, defaults to the process name of the executed process.  This
+        option is only useful when <varname>StandardOutput=</varname> or <varname>StandardError=</varname> are set to
+        <option>journal</option>, <option>syslog</option> or <option>kmsg</option> (or to the same settings in
+        combination with <option>+console</option>) and only applies to log messages written to stdout or
+        stderr.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>SyslogFacility=</varname></term>
+
+        <listitem><para>Sets the <command>syslog</command> facility identifier to use when logging. One of
+        <option>kern</option>, <option>user</option>, <option>mail</option>, <option>daemon</option>,
+        <option>auth</option>, <option>syslog</option>, <option>lpr</option>, <option>news</option>,
+        <option>uucp</option>, <option>cron</option>, <option>authpriv</option>, <option>ftp</option>,
+        <option>local0</option>, <option>local1</option>, <option>local2</option>, <option>local3</option>,
+        <option>local4</option>, <option>local5</option>, <option>local6</option> or <option>local7</option>. See
+        <citerefentry project='man-pages'><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+        for details. This option is only useful when <varname>StandardOutput=</varname> or
+        <varname>StandardError=</varname> are set to <option>journal</option>, <option>syslog</option> or
+        <option>kmsg</option> (or to the same settings in combination with <option>+console</option>), and only applies
+        to log messages written to stdout or stderr. Defaults to <option>daemon</option>.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>SyslogLevel=</varname></term>
+
+        <listitem><para>The default <command>syslog</command> log level to use when logging to the logging system or
+        the kernel log buffer. One of <option>emerg</option>, <option>alert</option>, <option>crit</option>,
+        <option>err</option>, <option>warning</option>, <option>notice</option>, <option>info</option>,
+        <option>debug</option>. See <citerefentry
+        project='man-pages'><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry> for
+        details. This option is only useful when <varname>StandardOutput=</varname> or
+        <varname>StandardError=</varname> are set to <option>journal</option>, <option>syslog</option> or
+        <option>kmsg</option> (or to the same settings in combination with <option>+console</option>), and only applies
+        to log messages written to stdout or stderr. Note that individual lines output by executed processes may be
+        prefixed with a different log level which can be used to override the default log level specified here. The
+        interpretation of these prefixes may be disabled with <varname>SyslogLevelPrefix=</varname>, see below. For
+        details, see <citerefentry><refentrytitle>sd-daemon</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
+        Defaults to <option>info</option>.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>SyslogLevelPrefix=</varname></term>
+
+        <listitem><para>Takes a boolean argument. If true and <varname>StandardOutput=</varname> or
+        <varname>StandardError=</varname> are set to <option>journal</option>, <option>syslog</option> or
+        <option>kmsg</option> (or to the same settings in combination with <option>+console</option>), log lines
+        written by the executed process that are prefixed with a log level will be processed with this log level set
+        but the prefix removed. If set to false, the interpretation of these prefixes is disabled and the logged lines
+        are passed on as-is. This only applies to log messages written to stdout or stderr. For details about this
+        prefixing see <citerefentry><refentrytitle>sd-daemon</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
+        Defaults to true.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>TTYPath=</varname></term>
+
+        <listitem><para>Sets the terminal device node to use if standard input, output, or error are connected to a TTY
+        (see above). Defaults to <filename>/dev/console</filename>.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>TTYReset=</varname></term>
+
+        <listitem><para>Reset the terminal device specified with <varname>TTYPath=</varname> before and after
+        execution.  Defaults to <literal>no</literal>.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>TTYVHangup=</varname></term>
+
+        <listitem><para>Disconnect all clients which have opened the terminal device specified with
+        <varname>TTYPath=</varname> before and after execution. Defaults to <literal>no</literal>.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>TTYVTDisallocate=</varname></term>
+
+        <listitem><para>If the terminal device specified with <varname>TTYPath=</varname> is a virtual console
+        terminal, try to deallocate the TTY before and after execution. This ensures that the screen and scrollback
+        buffer is cleared. Defaults to <literal>no</literal>.</para></listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>System V Compatibility</title>
+    <variablelist>
+
+      <varlistentry>
+        <term><varname>UtmpIdentifier=</varname></term>
+
+        <listitem><para>Takes a four character identifier string for an <citerefentry
+        project='man-pages'><refentrytitle>utmp</refentrytitle><manvolnum>5</manvolnum></citerefentry> and wtmp entry
+        for this service. This should only be set for services such as <command>getty</command> implementations (such
+        as <citerefentry
+        project='die-net'><refentrytitle>agetty</refentrytitle><manvolnum>8</manvolnum></citerefentry>) where utmp/wtmp
+        entries must be created and cleared before and after execution, or for services that shall be executed as if
+        they were run by a <command>getty</command> process (see below). If the configured string is longer than four
+        characters, it is truncated and the terminal four characters are used. This setting interprets %I style string
+        replacements. This setting is unset by default, i.e. no utmp/wtmp entries are created or cleaned up for this
+        service.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+         <term><varname>UtmpMode=</varname></term>
+
+         <listitem><para>Takes one of <literal>init</literal>, <literal>login</literal> or <literal>user</literal>. If
+         <varname>UtmpIdentifier=</varname> is set, controls which type of <citerefentry
+         project='man-pages'><refentrytitle>utmp</refentrytitle><manvolnum>5</manvolnum></citerefentry>/wtmp entries
+         for this service are generated. This setting has no effect unless <varname>UtmpIdentifier=</varname> is set
+         too. If <literal>init</literal> is set, only an <constant>INIT_PROCESS</constant> entry is generated and the
+         invoked process must implement a <command>getty</command>-compatible utmp/wtmp logic. If
+         <literal>login</literal> is set, first an <constant>INIT_PROCESS</constant> entry, followed by a
+         <constant>LOGIN_PROCESS</constant> entry is generated. In this case, the invoked process must implement a
+         <citerefentry
+         project='die-net'><refentrytitle>login</refentrytitle><manvolnum>1</manvolnum></citerefentry>-compatible
+         utmp/wtmp logic. If <literal>user</literal> is set, first an <constant>INIT_PROCESS</constant> entry, then a
+         <constant>LOGIN_PROCESS</constant> entry and finally a <constant>USER_PROCESS</constant> entry is
+         generated. In this case, the invoked process may be any process that is suitable to be run as session
+         leader. Defaults to <literal>init</literal>.</para></listitem>
       </varlistentry>
 
     </variablelist>
@@ -1939,7 +1956,7 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
 
       <listitem><para>Variables set via <varname>Environment=</varname> in the unit file</para></listitem>
 
-      <listitem><para>Variables read from files specified via <varname>EnvironmentFiles=</varname> in the unit file</para></listitem>
+      <listitem><para>Variables read from files specified via <varname>EnvironmentFile=</varname> in the unit file</para></listitem>
 
       <listitem><para>Variables set by any PAM modules in case <varname>PAMName=</varname> is in effect, cf. <citerefentry project='man-pages'><refentrytitle>pam_env</refentrytitle><manvolnum>8</manvolnum></citerefentry></para></listitem>
     </itemizedlist>
@@ -1956,7 +1973,7 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
         <term><varname>$PATH</varname></term>
 
         <listitem><para>Colon-separated list of directories to use
-        when launching executables. Systemd uses a fixed value of
+        when launching executables. systemd uses a fixed value of
         <filename>/usr/local/sbin</filename>:<filename>/usr/local/bin</filename>:<filename>/usr/sbin</filename>:<filename>/usr/bin</filename>:<filename>/sbin</filename>:<filename>/bin</filename>.
         </para></listitem>
       </varlistentry>
@@ -2406,7 +2423,7 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
           <row>
             <entry>205</entry>
             <entry><constant>EXIT_LIMITS</constant></entry>
-            <entry>Failed to adjust resoure limits. See <varname>LimitCPU=</varname> and related settings above.</entry>
+            <entry>Failed to adjust resource limits. See <varname>LimitCPU=</varname> and related settings above.</entry>
           </row>
           <row>
             <entry>206</entry>
@@ -2511,7 +2528,7 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
           <row>
             <entry>227</entry>
             <entry><constant>EXIT_NO_NEW_PRIVILEGES</constant></entry>
-            <entry>Failed to disable new priviliges. See <varname>NoNewPrivileges=yes</varname> above.</entry>
+            <entry>Failed to disable new privileges. See <varname>NoNewPrivileges=yes</varname> above.</entry>
           </row>
           <row>
             <entry>228</entry>
@@ -2526,7 +2543,7 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
           <row>
             <entry>230</entry>
             <entry><constant>EXIT_PERSONALITY</constant></entry>
-            <entry>Failed to set up a execution domain (personality). See <varname>Personality=</varname> above.</entry>
+            <entry>Failed to set up an execution domain (personality). See <varname>Personality=</varname> above.</entry>
           </row>
           <row>
             <entry>231</entry>
@@ -2561,22 +2578,22 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
           <row>
             <entry>238</entry>
             <entry><constant>EXIT_STATE_DIRECTORY</constant></entry>
-            <entry>Failed to set up a the unit's state directory. See <varname>StateDirectory=</varname> above.</entry>
+            <entry>Failed to set up unit's state directory. See <varname>StateDirectory=</varname> above.</entry>
           </row>
           <row>
             <entry>239</entry>
             <entry><constant>EXIT_CACHE_DIRECTORY</constant></entry>
-            <entry>Failed to set up a the unit's cache directory. See <varname>CacheDirectory=</varname> above.</entry>
+            <entry>Failed to set up unit's cache directory. See <varname>CacheDirectory=</varname> above.</entry>
           </row>
           <row>
             <entry>240</entry>
             <entry><constant>EXIT_LOGS_DIRECTORY</constant></entry>
-            <entry>Failed to set up a the unit's logging directory. See <varname>LogsDirectory=</varname> above.</entry>
+            <entry>Failed to set up unit's logging directory. See <varname>LogsDirectory=</varname> above.</entry>
           </row>
           <row>
             <entry>241</entry>
             <entry><constant>EXIT_CONFIGURATION_DIRECTORY</constant></entry>
-            <entry>Failed to set up a the unit's configuration directory. See <varname>ConfigurationDirectory=</varname> above.</entry>
+            <entry>Failed to set up unit's configuration directory. See <varname>ConfigurationDirectory=</varname> above.</entry>
           </row>
         </tbody>
       </tgroup>
index fb0f0c4..55bb2b4 100644 (file)
@@ -6,6 +6,8 @@
 ]>
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2015 Zbigniew Jędrzejewski-Szmek
@@ -46,7 +48,7 @@
 
   <refnamediv>
     <refname>systemd.generator</refname>
-    <refpurpose>Systemd unit generators</refpurpose>
+    <refpurpose>systemd unit generators</refpurpose>
   </refnamediv>
 
   <refsynopsisdiv>
 
   <refsect1>
     <title>Description</title>
-    <para>Generators are small binaries that live in
-    <filename>&usergeneratordir;/</filename> and other directories
-    listed above.
-    <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>
-    will execute those binaries very early at bootup and at
-    configuration reload time — before unit files are loaded.
-    Generators can dynamically generate unit files or create symbolic
-    links to unit files to add additional dependencies, thus extending
-    or overriding existing definitions. Their main purpose is to
-    convert configuration files that are not native unit files
-    dynamically into native unit files.</para>
+    <para>Generators are small executables that live in <filename>&systemgeneratordir;/</filename> and other
+    directories listed above.
+    <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry> will execute those
+    binaries very early at bootup and at configuration reload time — before unit files are loaded.  Generators may
+    dynamically generate unit files (regular ones, instances as well as templates) and unit file
+    <filename>.d/</filename> drop-ins, or create symbolic links to unit files to add additional dependencies or
+    instantiate existing templates, thus extending or overriding existing definitions. Their main purpose is to convert
+    configuration files that are not native unit files dynamically into native unit files.</para>
 
     <para>Generators are loaded from a set of paths determined during
     compilation, as listed above. System and user generators are loaded
         <para><parameter>normal-dir</parameter></para>
         <para>argv[1] may be used to override unit files in
         <filename>/usr</filename>, but not those in
-        <filename>/etc</filename>. This means that unit files placed
+        <filename>/run</filename> or in <filename>/etc</filename>.
+        This means that unit files placed
         in this directory take precedence over vendor unit
         configuration but not over native user/administrator unit
         configuration.</para>
       <listitem>
         <para><parameter>early-dir</parameter></para>
         <para>argv[2] may be used to override unit files in
-        <filename>/usr</filename> and in
+        <filename>/usr</filename>, in <filename>/run</filename> and in
         <filename>/etc</filename>. This means that unit files placed
         in this directory take precedence over all configuration,
         both vendor and user/administrator.</para>
 
         <listitem>
           <para>
-            Generators should only be used to generate unit files, not
-            any other kind of configuration. Due to the lifecycle
-            logic mentioned above, generators are not a good fit to
-            generate dynamic configuration for other services. If you
-            need to generate dynamic configuration for other services,
-            do so in normal services you order before the service in
-            question.
+            Generators should only be used to generate unit files and symlinks to them, not any other kind of
+            configuration. Due to the lifecycle logic mentioned above, generators are not a good fit to generate
+            dynamic configuration for other services. If you need to generate dynamic configuration for other services,
+            do so in normal services you order before the service in question.
           </para>
         </listitem>
 
index e488aff..b08ef17 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2010 Lennart Poettering
 
       <varlistentry>
         <term><varname>_SYSTEMD_CGROUP=</varname></term>
-        <term><varname>_SYSTEMD_SESSION=</varname></term>
+        <term><varname>_SYSTEMD_SLICE=</varname></term>
         <term><varname>_SYSTEMD_UNIT=</varname></term>
         <term><varname>_SYSTEMD_USER_UNIT=</varname></term>
+        <term><varname>_SYSTEMD_SESSION=</varname></term>
         <term><varname>_SYSTEMD_OWNER_UID=</varname></term>
-        <term><varname>_SYSTEMD_SLICE=</varname></term>
 
         <listitem>
           <para>The control group path in the systemd hierarchy, the
-          systemd session ID (if any), the systemd unit name (if any),
-          the systemd user session unit name (if any), the owner UID
-          of the systemd session (if any) and the systemd slice unit
-          of the process the journal entry originates from.</para>
+          the systemd slice unit name, the systemd unit name, the
+          unit name in the systemd user manager (if any), the systemd
+          session ID (if any), and the owner UID of the systemd user
+          unit or systemd session (if any) of the process the journal
+          entry originates from.</para>
         </listitem>
       </varlistentry>
 
index 13b7ab1..1abcd6d 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2012 Lennart Poettering
index 99bb6a1..162674f 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2014 Tom Gundersen
index 58cdb54..663e7fa 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2010 Lennart Poettering
       </varlistentry>
 
       <varlistentry>
+        <term><option>x-systemd.makefs</option></term>
+
+        <listitem><para>The file system or swap structure will be intialized
+        on the device. If the device is not "empty", i.e. it contains any signature,
+        the operation will be skipped. It is hence expected that this option
+        remains set even after the device has been initalized.</para>
+
+        <para>Note that this option can only be used in
+        <filename>/etc/fstab</filename>, and will be ignored when part of the
+        <varname>Options=</varname> setting in a unit file.</para>
+
+        <para>See
+        <citerefentry><refentrytitle>systemd-makefs@.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
+        </para>
+
+        <para><citerefentry project='man-pages'><refentrytitle>wipefs</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+        may be used to remove any signatures from a block device to force
+        <option>x-systemd.makefs</option> to reinitialize the device.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>x-systemd.growfs</option></term>
+
+        <listitem><para>The file system will be grown to occupy the full block
+        device. If the file system is already at maximum size, no action will
+        be performed. It is hence expected that this option remains set even after
+        the file system has been grown. Only certain file system types are supported,
+        see
+        <citerefentry><refentrytitle>systemd-makefs@.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+        for details.</para>
+
+        <para>Note that this option can only be used in
+        <filename>/etc/fstab</filename>, and will be ignored when part of the
+        <varname>Options=</varname> setting in a unit file.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
         <term><option>_netdev</option></term>
 
         <listitem><para>Normally the file system type is used to determine if a
         <term><option>noauto</option></term>
         <term><option>auto</option></term>
 
-        <listitem><para>With <option>noauto</option>, this mount will
-        not be added as a dependency for
-        <filename>local-fs.target</filename> or
-        <filename>remote-fs.target</filename>. This means that it will
-        not be mounted automatically during boot, unless it is pulled
-        in by some other unit. The <option>auto</option> option has the
-        opposite meaning and is the default.</para>
+        <listitem><para>With <option>noauto</option>, the mount unit will not be added as a dependency for
+        <filename>local-fs.target</filename> or <filename>remote-fs.target</filename>. This means that it will not be
+        mounted automatically during boot, unless it is pulled in by some other unit. The <option>auto</option> option
+        has the opposite meaning and is the default. Note that the <option>noauto</option> option has an effect on the
+        mount unit itself only — if <option>x-systemd.automount</option> is used (see above), then the matching
+        automount unit will still be pulled in by these targets.</para>
         </listitem>
       </varlistentry>
 
index 6f8991b..c927923 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2013 Tom Gundersen
           <row><entry><varname>vcan</varname></entry>
           <entry>The virtual CAN driver (vcan). Similar to the network loopback devices, vcan offers a virtual local CAN interface.</entry></row>
 
+          <row><entry><varname>vxcan</varname></entry>
+          <entry>The virtual CAN tunnel driver (vxcan). Similar to the virtual ethernet driver veth, vxcan implements a local CAN traffic tunnel between two virtual CAN network devices. When creating a vxcan, two vxcan devices are created as pair. When one end receives the packet it appears on its pair and vice versa. The vxcan can be used for cross namespace communication.
+          </entry></row>
+
         </tbody>
       </tgroup>
     </table>
       </variablelist>
   </refsect1>
   <refsect1>
+  <title>[VXCAN] Section Options</title>
+      <para>The <literal>[VXCAN]</literal> section only applies for
+      netdevs of kind <literal>vxcan</literal> and accepts the
+      following key:</para>
+
+      <variablelist class='network-directives'>
+        <varlistentry>
+          <term><varname>Peer=</varname></term>
+          <listitem>
+            <para>The peer interface name used when creating the netdev.
+            This option is compulsory.</para>
+          </listitem>
+        </varlistentry>
+      </variablelist>
+  </refsect1>
+  <refsect1>
     <title>[Tun] Section Options</title>
 
     <para>The <literal>[Tun]</literal> section only applies for
index b175967..3466f3a 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2013 Tom Gundersen
           controlled by other applications.</para>
         </listitem>
       </varlistentry>
+      <varlistentry>
+        <term><varname>RequiredForOnline=</varname></term>
+        <listitem>
+          <para>A boolean. When <literal>yes</literal>, the network is deemed
+          required when determining whether the system is online when running
+          <literal>systemd-networkd-wait-online</literal>.
+          When <literal>no</literal>, the network is ignored when checking for
+          online state. Defaults to <literal>yes</literal>.</para>
+          <para>The network will be brought up normally in all cases, but in
+          the event that there is no address being assigned by DHCP or the
+          cable is not plugged in, the link will simply remain offline and be
+          skipped automatically by <literal>systemd-networkd-wait-online</literal>
+          if <literal>RequiredForOnline=true</literal>.</para>
+        </listitem>
+      </varlistentry>
     </variablelist>
   </refsect1>
 
             integer. Higher number means lower priority, and rules get processed in order of increasing number.</para>
           </listitem>
         </varlistentry>
+        <varlistentry>
+          <term><varname>IncomingInterface=</varname></term>
+          <listitem>
+            <para>Specifies incoming device to match. If the interface is loopback, the rule only matches packets originating from this host.</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><varname>OutgoingInterface=</varname></term>
+          <listitem>
+            <para>Specifies the outgoing device to match. The outgoing interface is only available for packets originating from local sockets that are bound to a device.</para>
+          </listitem>
+        </varlistentry>
       </variablelist>
   </refsect1>
 
       </varlistentry>
 
       <varlistentry>
+        <term><varname>EmitDNS=</varname></term>
         <term><varname>DNS=</varname></term>
 
-        <listitem><para>A list of recursive DNS server IPv6 addresses
-        distributed via Router Advertisement messages.
+        <listitem><para><varname>DNS=</varname> specifies a list of recursive
+        DNS server IPv6 addresses that distributed via Router Advertisement
+        messages when <varname>EmitDNS=</varname> is true. If <varname>DNS=
+        </varname> is empty, DNS servers are read from the
+        <literal>[Network]</literal> section. If the
+        <literal>[Network]</literal> section does not contain any DNS servers
+        either, DNS servers from the uplink with the highest priority default
+        route are used. When <varname>EmitDNS=</varname> is false, no DNS server
+        information is sent in Router Advertisement messages.
+        <varname>EmitDNS=</varname> defaults to true.
         </para></listitem>
       </varlistentry>
 
       <varlistentry>
+        <term><varname>EmitDomains=</varname></term>
         <term><varname>Domains=</varname></term>
 
-        <listitem><para>A list of DNS search domains distributed via
-        Router Advertisement messages. Defaults to empty, i.e. no search
-        domains are sent.</para></listitem>
+        <listitem><para>A list of DNS search domains distributed via Router
+        Advertisement messages when <varname>EmitDomains=</varname> is true. If
+        <varname>Domains=</varname> is empty, DNS search domains are read from the
+        <literal>[Network]</literal> section. If the <literal>[Network]</literal>
+        section does not contain any DNS search domains either, DNS search
+        domains from the uplink with the highest priority default route are
+        used. When <varname>EmitDomains=</varname> is false, no DNS search domain
+        information is sent in Router Advertisement messages.
+        <varname>EmitDomains=</varname> defaults to true.
+        </para></listitem>
       </varlistentry>
 
       <varlistentry>
           <term><varname>VLANId=</varname></term>
           <listitem>
             <para>The VLAN ID for the new static MAC table entry. If
-            omitted, no VLAN ID info is appended to the new static MAC
+            omitted, no VLAN ID information is appended to the new static MAC
             table entry.</para>
           </listitem>
         </varlistentry>
index 58024a0..9a6a235 100644 (file)
@@ -6,6 +6,8 @@
 ]>
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2015 Lennart Poettering
         <term><varname>NotifyReady=</varname></term>
 
         <listitem><para>Configures support for notifications from the container's init process.  This is equivalent to
-        the <option>--notify-ready=</option> command line switch, and takes the same paramaters. See
+        the <option>--notify-ready=</option> command line switch, and takes the same parameters. See
         <citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry> for details
         about the specific options supported.</para></listitem>
       </varlistentry>
index b4dce3e..01dd6c5 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2013 Lennart Poettering
     <title>See also</title>
 
     <para>
-      <ulink url="https://www.freedesktop.org/wiki/Software/systemd/SystemUpdates/">Implementing Offline System Updates</ulink>,
       <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
       <citerefentry><refentrytitle>systemd.generator</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
       <citerefentry><refentrytitle>systemd-system-update-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
index 9e8f2c6..30f295d 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2010 Lennart Poettering
index 92eb4e8..4828562 100644 (file)
@@ -2,6 +2,8 @@
 <!--*-nxml-*-->
 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2011 Lennart Poettering
index 0c0c916..18b7bf8 100644 (file)
@@ -3,6 +3,8 @@
 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2013 Zbigniew Jędrzejewski-Szmek
         <varlistentry>
           <term><option>CPU</option></term>
           <listitem>
-            <para>Due to the lack of consensus in the kernel community, the CPU controller support on the unified
-            control group hierarchy requires out-of-tree kernel patches. See <ulink
-            url="https://git.kernel.org/cgit/linux/kernel/git/tj/cgroup.git/tree/Documentation/cgroup-v2-cpu.txt?h=cgroup-v2-cpu">cgroup-v2-cpu.txt</ulink>.</para>
-
             <para><varname>CPUWeight=</varname> and <varname>StartupCPUWeight=</varname> replace
             <varname>CPUShares=</varname> and <varname>StartupCPUShares=</varname>, respectively.</para>
 
         <varlistentry>
           <term><option>IO</option></term>
           <listitem>
-            <para><varname>IO</varname> prefixed settings are superset of and replace <varname>BlockIO</varname>
+            <para><varname>IO</varname> prefixed settings are superset of and replace <varname>BlockIO</varname>
             prefixed ones. On unified hierarchy, IO resource control also applies to buffered writes.</para>
           </listitem>
         </varlistentry>
       </varlistentry>
 
       <varlistentry>
-        <term><varname>IPAddressAllow=<replaceable>ADDDRESS[/PREFIXLENGTH]…</replaceable></varname></term>
+        <term><varname>IPAddressAllow=<replaceable>ADDRESS[/PREFIXLENGTH]…</replaceable></varname></term>
         <term><varname>IPAddressDeny=<replaceable>ADDRESS[/PREFIXLENGTH]…</replaceable></varname></term>
 
         <listitem>
         <term><varname>Delegate=</varname></term>
 
         <listitem>
-          <para>Turns on delegation of further resource control
-          partitioning to processes of the unit. For unprivileged
-          services (i.e. those using the <varname>User=</varname>
-          setting), this allows processes to create a subhierarchy
-          beneath its control group path. For privileged services and
-          scopes, this ensures the processes will have all control
-          group controllers enabled.</para>
+          <para>Turns on delegation of further resource control partitioning to processes of the unit. Units where this
+          is enabled may create and manage their own private subhierarchy of control groups below the control group of
+          the unit itself. For unprivileged services (i.e. those using the <varname>User=</varname> setting) the unit's
+          control group will be made accessible to the relevant user. When enabled the service manager will refrain
+          from manipulating control groups or moving processes below the unit's control group, so that a clear concept
+          of ownership is established: the control group tree above the unit's control group (i.e. towards the root
+          control group) is owned and managed by the service manager of the host, while the control group tree below
+          the unit's control group is owned and managed by the unit itself. Takes either a boolean argument or a list
+          of control group controller names. If true, delegation is turned on, and all supported controllers are
+          enabled for the unit, making them available to the unit's processes for management. If false, delegation is
+          turned off entirely (and no additional controllers are enabled). If set to a list of controllers, delegation
+          is turned on, and the specified controllers are enabled for the unit. Note that additional controllers than
+          the ones specified might be made available as well, depending on configuration of the containing slice unit
+          or other units contained in it. Note that assigning the empty string will enable delegation, but reset the
+          list of controllers, all assignments prior to this will have no effect.  Defaults to false.</para>
+
+          <para>Note that controller delegation to less privileged code is only safe on the unified control group
+          hierarchy. Accordingly, access to the specified controllers will not be granted to unprivileged services on
+          the legacy hierarchy, even when requested.</para>
+
+          <para>The following controller names may be specified: <option>cpu</option>, <option>cpuacct</option>,
+          <option>io</option>, <option>blkio</option>, <option>memory</option>, <option>devices</option>,
+          <option>pids</option>. Not all of these controllers are available on all kernels however, and some are
+          specific to the unified hierarchy while others are specific to the legacy hierarchy. Also note that the
+          kernel might support further controllers, which aren't covered here yet as delegation is either not supported
+          at all for them or not defined cleanly.</para>
         </listitem>
       </varlistentry>
 
index e41493c..092361c 100644 (file)
@@ -3,6 +3,8 @@
 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2013 Zbigniew Jędrzejewski-Szmek
index 626d197..f41a68c 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2010 Lennart Poettering
               <row>
                 <entry><literal>!!</literal></entry>
 
-                <entry>This prefix is very similar to <literal>!!</literal>, however it only has an effect on systems lacking support for ambient process capabilities, i.e. without support for <varname>AmbientCapabilities=</varname>. It's intended to be used for unit files that take benefit of ambient capabilities to run processes with minimal privileges wherever possible while remaining compatible with systems that lack ambient capabilities support. Note that when <literal>!!</literal> is used, and a system lacking ambient capability support is detected any configured <varname>SystemCallFilter=</varname> and <varname>CapabilityBoundingSet=</varname> stanzas are implicitly modified, in order to permit spawned processes to drop credentials and capabilities themselves, even if this is configured to not be allowed. Moreover, if this prefix is used and a system lacking ambient capability support is detected <varname>AmbientCapabilities=</varname> will be skipped and not be applied. On systems supporting ambient capabilities, <literal>!!</literal> has no effect and is redundant.</entry>
+                <entry>This prefix is very similar to <literal>!</literal>, however it only has an effect on systems lacking support for ambient process capabilities, i.e. without support for <varname>AmbientCapabilities=</varname>. It's intended to be used for unit files that take benefit of ambient capabilities to run processes with minimal privileges wherever possible while remaining compatible with systems that lack ambient capabilities support. Note that when <literal>!!</literal> is used, and a system lacking ambient capability support is detected any configured <varname>SystemCallFilter=</varname> and <varname>CapabilityBoundingSet=</varname> stanzas are implicitly modified, in order to permit spawned processes to drop credentials and capabilities themselves, even if this is configured to not be allowed. Moreover, if this prefix is used and a system lacking ambient capability support is detected <varname>AmbientCapabilities=</varname> will be skipped and not be applied. On systems supporting ambient capabilities, <literal>!!</literal> has no effect and is redundant.</entry>
               </row>
             </tbody>
           </tgroup>
         <literal>+</literal>/<literal>!</literal>/<literal>!!</literal> may be used together and they can appear in any
         order. However, only one of <literal>+</literal>, <literal>!</literal>, <literal>!!</literal> may be used at a
         time. Note that these prefixes are also supported for the other command line settings,
-        i.e. <varname>ExecStartPre=</varname>, <varname>ExecStartPost=</varname>, <varname>ExecReload</varname>,
+        i.e. <varname>ExecStartPre=</varname>, <varname>ExecStartPost=</varname>, <varname>ExecReload=</varname>,
         <varname>ExecStop=</varname> and <varname>ExecStopPost=</varname>.</para>
 
         <para>If more than one command is specified, the commands are
         start-up failed, for example because any of the commands specified in <varname>ExecStart=</varname>,
         <varname>ExecStartPre=</varname> or <varname>ExecStartPost=</varname> failed (and weren't prefixed with
         <literal>-</literal>, see above) or timed out. Use <varname>ExecStopPost=</varname> to invoke commands when a
-        service failed to start up correctly and is shut down again.</para>
+        service failed to start up correctly and is shut down again. Also note that, service restart requests are
+        implemented as stop operations followed by start operations. This means that <varname>ExecStop=</varname> and
+        <varname>ExecStopPost=</varname> are executed during a service restart operation.</para>
 
         <para>It is recommended to use this setting for commands that communicate with the service requesting clean
         termination. When the commands specified with this option are executed it should be assumed that the service is
         <varname>Type=oneshot</varname> is used, in which case the
         timeout is disabled by default (see
         <citerefentry><refentrytitle>systemd-system.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>).
+        </para>
+
+        <para>If a service of <varname>Type=notify</varname> sends <literal>EXTEND_TIMEOUT_USEC=…</literal>, this may cause
+        the start time to be extended beyond <varname>TimeoutStartSec=</varname>. The first receipt of this message
+        must occur before <varname>TimeoutStartSec=</varname> is exceeded, and once the start time has exended beyond
+        <varname>TimeoutStartSec=</varname>, the service manager will allow the service to continue to start, provided
+        the service repeats <literal>EXTEND_TIMEOUT_USEC=…</literal> within the interval specified until the service
+        startup status is finished by <literal>READY=1</literal>. (see
+        <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>).
         </para></listitem>
       </varlistentry>
 
         <varname>DefaultTimeoutStopSec=</varname> from the manager
         configuration file (see
         <citerefentry><refentrytitle>systemd-system.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>).
+        </para>
+
+        <para>If a service of <varname>Type=notify</varname> sends <literal>EXTEND_TIMEOUT_USEC=…</literal>, this may cause
+        the stop time to be extended beyond <varname>TimeoutStopSec=</varname>. The first receipt of this message
+        must occur before <varname>TimeoutStopSec=</varname> is exceeded, and once the stop time has exended beyond
+        <varname>TimeoutStopSec=</varname>, the service manager will allow the service to continue to stop, provided
+        the service repeats <literal>EXTEND_TIMEOUT_USEC=…</literal> within the interval specified, or terminates itself
+        (see <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>).
         </para></listitem>
       </varlistentry>
 
         active for longer than the specified time it is terminated and put into a failure state. Note that this setting
         does not have any effect on <varname>Type=oneshot</varname> services, as they terminate immediately after
         activation completed. Pass <literal>infinity</literal> (the default) to configure no runtime
-        limit.</para></listitem>
+        limit.</para>
+
+        <para>If a service of <varname>Type=notify</varname> sends <literal>EXTEND_TIMEOUT_USEC=…</literal>, this may cause
+        the runtime to be extended beyond <varname>RuntimeMaxSec=</varname>. The first receipt of this message
+        must occur before <varname>RuntimeMaxSec=</varname> is exceeded, and once the runtime has exended beyond
+        <varname>RuntimeMaxSec=</varname>, the service manager will allow the service to continue to run, provided
+        the service repeats <literal>EXTEND_TIMEOUT_USEC=…</literal> within the interval specified until the service
+        shutdown is acheived by <literal>STOPPING=1</literal> (or termination). (see
+        <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>).
+        </para></listitem>
       </varlistentry>
 
       <varlistentry>
       </varlistentry>
 
       <varlistentry>
-        <term><varname>FailureAction=</varname></term>
-        <listitem><para>Configure the action to take when the service enters a failed state. Takes the same values as
-        the unit setting <varname>StartLimitAction=</varname> and executes the same actions (see
-        <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>). Defaults to
-        <option>none</option>. </para></listitem>
-      </varlistentry>
-
-      <varlistentry>
         <term><varname>FileDescriptorStoreMax=</varname></term>
         <listitem><para>Configure how many file descriptors may be stored in the service manager for the service using
         <citerefentry><refentrytitle>sd_pid_notify_with_fds</refentrytitle><manvolnum>3</manvolnum></citerefentry>'s
index c46ba7a..d67cce1 100644 (file)
@@ -3,6 +3,8 @@
 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2013 Zbigniew Jędrzejewski-Szmek
@@ -65,7 +67,7 @@
     </para>
 
     <para>Note that slice units cannot be templated, nor is possible to add multiple names to a slice unit by creating
-    additional symlinks to it.</para>
+    additional symlinks to its unit file.</para>
 
     <para>By default, service and scope units are placed in
     <filename>system.slice</filename>, virtual machines and containers
index 68d01cc..a1943f6 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2010 Lennart Poettering
index 4beef07..18689a0 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2010 Lennart Poettering
@@ -81,7 +83,6 @@
     <filename>poweroff.target</filename>,
     <filename>printer.target</filename>,
     <filename>reboot.target</filename>,
-    <filename>remote-cryptsetup-pre.target</filename>,
     <filename>remote-cryptsetup.target</filename>,
     <filename>remote-fs-pre.target</filename>,
     <filename>remote-fs.target</filename>,
           it. Note that networking daemons that simply provide
           functionality to other hosts generally do not need to pull
           this in.</para>
+
+          <para>Note that this unit is only useful during the original system start-up logic. After the system has
+          completed booting up, it will not track the online state of the system anymore. Due to this it cannot be used
+          as a network connection monitor concept, it is purely a one-time system start-up concept.</para>
           </listitem>
       </varlistentry>
       <varlistentry>
         </listitem>
       </varlistentry>
       <varlistentry>
-        <term><filename>remote-cryptsetup-pre.target</filename></term>
-        <listitem>
-          <para>This target unit is automatically ordered before all cryptsetup devices
-          marked with the <option>_netdev</option>. It can be used to execute additional
-          units before such devices are set up.</para>
-
-          <para>It is ordered after <filename>network.target</filename> and
-          <filename>network-online.target</filename>, and also pulls the latter in as a
-          <varname>Wants=</varname> dependency.</para>
-        </listitem>
-      </varlistentry>
-      <varlistentry>
         <term><filename>remote-cryptsetup.target</filename></term>
         <listitem>
           <para>Similar to <filename>cryptsetup.target</filename>, but for encrypted
           shell. Isolate to this target in order to administer the system in single-user mode with all file systems
           mounted but with no services running, except for the most basic. Compare with
           <filename>emergency.target</filename>, which is much more reduced and does not provide the file systems or
-          most basic services.</para>
+          most basic services. Compare with <filename>multi-user.target</filename>, this target could be seen as
+          <filename>single-user.target</filename>.</para>
 
           <para><filename>runlevel1.target</filename> is an alias for this target unit, for compatibility with
           SysV.</para>
         <term><filename>remote-fs-pre.target</filename></term>
         <listitem>
           <para>This target unit is automatically ordered before all
-          remote mount point units (see above). It can be used to run
-          certain units before the remote mounts are established. Note
-          that this unit is generally not part of the initial
+          mount point units (see above) and cryptsetup devices
+          marked with the <option>_netdev</option>. It can be used to run
+          certain units before remote encrypted devices and mounts are established.
+          Note that this unit is generally not part of the initial
           transaction, unless the unit that wants to be ordered before
           all remote mounts pulls it in via a
           <varname>Wants=</varname> type dependency. If the unit wants
@@ -1026,7 +1021,7 @@ PartOf=graphical-session.target
 
     <para>There are four <literal>.slice</literal> units which form the basis of the hierarchy for assignment of
     resources for services, users, and virtual machines or containers. See
-    <citerefentry><refentrytitle>-.slice</refentrytitle><manvolnum>7</manvolnum></citerefentry> for details about slice
+    <citerefentry><refentrytitle>systemd.slice</refentrytitle><manvolnum>7</manvolnum></citerefentry> for details about slice
     units.</para>
 
     <variablelist>
@@ -1077,7 +1072,7 @@ PartOf=graphical-session.target
         <citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
         <citerefentry><refentrytitle>systemd.target</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
         <citerefentry><refentrytitle>systemd.slice</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
-        <citerefentry project='man-pages'><refentrytitle>bootup</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+        <citerefentry><refentrytitle>bootup</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
         <citerefentry><refentrytitle>systemd-fstab-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>
       </para>
   </refsect1>
index 254389e..707b04b 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2010 Lennart Poettering
index 281f5d4..4daa9f5 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2010 Lennart Poettering
@@ -95,7 +97,8 @@
       <listitem><para>Target units will automatically complement all
       configured dependencies of type <varname>Wants=</varname> or
       <varname>Requires=</varname> with dependencies of type
-      <varname>After=</varname>. Note that <varname>Wants=</varname> or
+      <varname>After=</varname> unless <varname>DefaultDependencies=no</varname>
+      is set in the specified units. Note that <varname>Wants=</varname> or
       <varname>Requires=</varname> must be defined in the target unit itself — if
       you for example define <varname>Wants=</varname>some.target in
       some.service, the automatic ordering will not be added.</para></listitem>
index a4f6a78..6cb32f1 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2010 Lennart Poettering
@@ -300,6 +302,10 @@ Wed..Sat,Tue 12-10-15 1:2:3 → Tue..Sat 2012-10-15 01:02:03
       <citerefentry><refentrytitle>systemd.timer</refentrytitle><manvolnum>5</manvolnum></citerefentry>
       for details.</para>
 
+      <para>Use the <command>calendar</command> command of
+      <citerefentry><refentrytitle>systemd-analyze</refentrytitle><manvolnum>1</manvolnum></citerefentry> to validate
+      and normalize calendar time specifications for testing purposes. The tool also calculates when a specified
+      calendar event would elapse next.</para>
   </refsect1>
 
   <refsect1>
@@ -309,7 +315,8 @@ Wed..Sat,Tue 12-10-15 1:2:3 → Tue..Sat 2012-10-15 01:02:03
         <citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
         <citerefentry><refentrytitle>systemd.timer</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
         <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
-        <citerefentry><refentrytitle>systemd.directives</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+        <citerefentry><refentrytitle>systemd.directives</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+        <citerefentry><refentrytitle>systemd-analyze</refentrytitle><manvolnum>1</manvolnum></citerefentry>
       </para>
   </refsect1>
 
index b8f921f..5b1bc8b 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2010 Lennart Poettering
index bec6356..5cd8be3 100644 (file)
@@ -6,6 +6,8 @@
 ]>
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2010 Lennart Poettering
     modify unit files. Each drop-in file must have appropriate section headers. Note that for
     instantiated units, this logic will first look for the instance <literal>.d/</literal>
     subdirectory and read its <literal>.conf</literal> files, followed by the template
-    <literal>.d/</literal> subdirectory and the <literal>.conf</literal> files there. Also note that
-    settings from the <literal>[Install]</literal> section are not honored in drop-in unit files,
-    and have no effect.</para>
+    <literal>.d/</literal> subdirectory and the <literal>.conf</literal> files there.</para>
 
     <para>In addition to <filename>/etc/systemd/system</filename>, the drop-in <literal>.d</literal>
     directories for system services can be placed in <filename>/usr/lib/systemd/system</filename> or
     socket-based activation which make dependencies implicit,
     resulting in a both simpler and more flexible system.</para>
 
-    <para>Some unit names reflect paths existing in the file system
-    namespace. Example: a device unit
-    <filename>dev-sda.device</filename> refers to a device with the
-    device node <filename noindex='true'>/dev/sda</filename> in the
-    file system namespace. If this applies, a special way to escape
-    the path name is used, so that the result is usable as part of a
-    filename. Basically, given a path, "/" is replaced by "-", and all
-    other characters which are not ASCII alphanumerics are replaced by
-    C-style "\x2d" escapes (except that "_" is never replaced and "."
-    is only replaced when it would be the first character in the
-    escaped path). The root directory "/" is encoded as single dash,
-    while otherwise the initial and ending "/" are removed from all
-    paths during transformation. This escaping is reversible. Properly
-    escaped paths can be generated using the
-    <citerefentry><refentrytitle>systemd-escape</refentrytitle><manvolnum>1</manvolnum></citerefentry>
-    command.</para>
-
     <para>Optionally, units may be instantiated from a
     template file at runtime. This allows creation of
     multiple units from a single configuration file. If
   </refsect1>
 
   <refsect1>
+    <title>String Escaping for Inclusion in Unit Names</title>
+
+    <para>Sometimes it is useful to convert arbitrary strings into unit names. To facilitate this, a method of string
+    escaping is used, in order to map strings containing arbitrary byte values (except NUL) into valid unit names and
+    their restricted character set. A common special case are unit names that reflect paths to objects in the file
+    system hierarchy. Example: a device unit <filename>dev-sda.device</filename> refers to a device with the device
+    node <filename noindex='true'>/dev/sda</filename> in the file system.</para>
+
+    <para>The escaping algorithm operates as follows: given a string, any <literal>/</literal> character is replaced by
+    <literal>-</literal>, and all other characters which are not ASCII alphanumerics or <literal>_</literal> are
+    replaced by C-style <literal>\x2d</literal> escapes. In addition, <literal>.</literal> is replaced with such a
+    C-style escape when it would appear as the first character in the escaped string.</para>
+
+    <para>When the input qualifies as absolute file system path, this algorithm is extended slightly: the path to the
+    root directory <literal>/</literal> is encoded as single dash <literal>-</literal>. In addition, any leading,
+    trailing or duplicate <literal>/</literal> characters are removed from the string before transformation. Example:
+    <filename>/foo//bar/baz/</filename> becomes <literal>foo-bar-baz</literal>.</para>
+
+    <para>This escaping is fully reversible, as long as it is known whether the escaped string was a path (the
+    unescaping results are different for paths and non-path strings). The
+    <citerefentry><refentrytitle>systemd-escape</refentrytitle><manvolnum>1</manvolnum></citerefentry> command may be
+    used to apply and reverse escaping on arbitrary strings. Use <command>systemd-escape --path</command> to escape
+    path strings, and <command>systemd-escape</command> without <option>--path</option> otherwise.</para>
+  </refsect1>
+
+  <refsect1>
     <title>Implicit Dependencies</title>
 
     <para>A number of unit dependencies are implicitly established,
     <varname>DefaultDependencies=</varname> in each unit types.</para>
 
     <para>For example, target units will complement all configured
-    dependencies of type type <varname>Wants=</varname> or
+    dependencies of type <varname>Wants=</varname> or
     <varname>Requires=</varname> with dependencies of type
-    <varname>After=</varname>. See
+    <varname>After=</varname> unless <varname>DefaultDependencies=no</varname>
+    is set in the specified units. See
     <citerefentry><refentrytitle>systemd.target</refentrytitle><manvolnum>5</manvolnum></citerefentry>
     for details. Note that this behavior can be turned off by setting
     <varname>DefaultDependencies=no</varname>.</para>
         <colspec colname='expl' />
         <thead>
           <row>
-      <entry>Path</entry>
-      <entry>Description</entry>
+            <entry>Path</entry>
+            <entry>Description</entry>
           </row>
         </thead>
         <tbody>
           <row>
-      <entry><filename>/etc/systemd/system</filename></entry>
-      <entry>Local configuration</entry>
+            <entry><filename>/etc/systemd/system</filename></entry>
+            <entry>Local configuration</entry>
           </row>
           <row>
-      <entry><filename>/run/systemd/system</filename></entry>
-      <entry>Runtime units</entry>
+            <entry><filename>/run/systemd/system</filename></entry>
+            <entry>Runtime units</entry>
           </row>
           <row>
-      <entry><filename>/usr/lib/systemd/system</filename></entry>
-      <entry>Units of installed packages</entry>
+            <entry><filename>/usr/lib/systemd/system</filename></entry>
+            <entry>Units of installed packages</entry>
           </row>
         </tbody>
       </tgroup>
         <colspec colname='expl' />
         <thead>
           <row>
-      <entry>Path</entry>
-      <entry>Description</entry>
+            <entry>Path</entry>
+            <entry>Description</entry>
           </row>
         </thead>
         <tbody>
           <row>
-      <entry><filename>$XDG_CONFIG_HOME/systemd/user</filename></entry>
-      <entry>User configuration (only used when $XDG_CONFIG_HOME is set)</entry>
+            <entry><filename>$XDG_CONFIG_HOME/systemd/user</filename></entry>
+            <entry>User configuration (only used when $XDG_CONFIG_HOME is set)</entry>
           </row>
           <row>
-      <entry><filename>$HOME/.config/systemd/user</filename></entry>
-      <entry>User configuration (only used when $XDG_CONFIG_HOME is not set)</entry>
+            <entry><filename>$HOME/.config/systemd/user</filename></entry>
+            <entry>User configuration (only used when $XDG_CONFIG_HOME is not set)</entry>
           </row>
           <row>
-      <entry><filename>/etc/systemd/user</filename></entry>
-      <entry>Local configuration</entry>
+            <entry><filename>/etc/systemd/user</filename></entry>
+            <entry>Local configuration</entry>
           </row>
           <row>
-      <entry><filename>$XDG_RUNTIME_DIR/systemd/user</filename></entry>
-      <entry>Runtime units (only used when $XDG_RUNTIME_DIR is set)</entry>
+            <entry><filename>$XDG_RUNTIME_DIR/systemd/user</filename></entry>
+            <entry>Runtime units (only used when $XDG_RUNTIME_DIR is set)</entry>
           </row>
           <row>
-      <entry><filename>/run/systemd/user</filename></entry>
-      <entry>Runtime units</entry>
+            <entry><filename>/run/systemd/user</filename></entry>
+            <entry>Runtime units</entry>
           </row>
           <row>
-      <entry><filename>$XDG_DATA_HOME/systemd/user</filename></entry>
-      <entry>Units of packages that have been installed in the home directory (only used when $XDG_DATA_HOME is set)</entry>
+            <entry><filename>$XDG_DATA_HOME/systemd/user</filename></entry>
+            <entry>Units of packages that have been installed in the home directory (only used when $XDG_DATA_HOME is set)</entry>
           </row>
           <row>
-      <entry><filename>$HOME/.local/share/systemd/user</filename></entry>
-      <entry>Units of packages that have been installed in the home directory (only used when $XDG_DATA_HOME is not set)</entry>
+            <entry><filename>$HOME/.local/share/systemd/user</filename></entry>
+            <entry>Units of packages that have been installed in the home directory (only used when $XDG_DATA_HOME is not set)</entry>
           </row>
           <row>
-      <entry><filename>/usr/lib/systemd/user</filename></entry>
-      <entry>Units of packages that have been installed system-wide</entry>
+            <entry><filename>/usr/lib/systemd/user</filename></entry>
+            <entry>Units of packages that have been installed system-wide</entry>
           </row>
         </tbody>
       </tgroup>
   </refsect1>
 
   <refsect1>
+    <title>Unit Garbage Collection</title>
+
+    <para>The system and service manager loads a unit's configuration automatically when a unit is referenced for the
+    first time. It will automatically unload the unit configuration and state again when the unit is not needed anymore
+    ("garbage collection"). A unit may be referenced through a number of different mechanisms:</para>
+
+    <orderedlist>
+      <listitem><para>Another loaded unit references it with a dependency such as <varname>After=</varname>,
+      <varname>Wants=</varname>, …</para></listitem>
+
+      <listitem><para>The unit is currently starting, running, reloading or stopping.</para></listitem>
+
+      <listitem><para>The unit is currently in the <constant>failed</constant> state. (But see below.)</para></listitem>
+
+      <listitem><para>A job for the unit is pending.</para></listitem>
+
+      <listitem><para>The unit is pinned by an active IPC client program.</para></listitem>
+
+      <listitem><para>The unit is a special "perpetual" unit that is always active and loaded. Examples for perpetual
+      units are the root mount unit <filename>-.mount</filename> or the scope unit <filename>init.scope</filename> that
+      the service manager itself lives in.</para></listitem>
+
+      <listitem><para>The unit has running processes associated with it.</para></listitem>
+    </orderedlist>
+
+    <para>The garbage collection logic may be altered with the <varname>CollectMode=</varname> option, which allows
+    configuration whether automatic unloading of units that are in <constant>failed</constant> state is permissible,
+    see below.</para>
+
+    <para>Note that when a unit's configuration and state is unloaded, all execution results, such as exit codes, exit
+    signals, resource consumption and other statistics are lost, except for what is stored in the log subsystem.</para>
+
+    <para>Use <command>systemctl daemon-reload</command> or an equivalent command to reload unit configuration while
+    the unit is already loaded. In this case all configuration settings are flushed out and replaced with the new
+    configuration (which however might not be in effect immediately), however all runtime state is
+    saved/restored.</para>
+  </refsect1>
+
+  <refsect1>
     <title>[Unit] Section Options</title>
 
     <para>The unit file may include a [Unit] section, which carries
 
         <listitem><para>Configures requirement dependencies on other units. If this unit gets activated, the units
         listed here will be activated as well. If one of the other units fails to activate, and an ordering dependency
-        <varname>After=</varname> on the failing unit is set, this
-        unit will not be started. This option may be specified more than once or multiple space-separated units may be
+        <varname>After=</varname> on the failing unit is set, this unit will not be started. Besides, with or without
+        specifying <varname>After=</varname>, this unit will be deactivated if one of the other units get deactivated.
+        This option may be specified more than once or multiple space-separated units may be
         specified in one option in which case requirement dependencies for all listed names will be created. Note that
         requirement dependencies do not influence the order in which services are started or stopped.  This has to be
         configured independently with the <varname>After=</varname> or <varname>Before=</varname> options. If a unit
         <listitem><para>Similar to <varname>Requires=</varname>.
         However, if the units listed here are not started already,
         they will not be started and the transaction will fail
-        immediately. </para></listitem>
+        immediately.</para>
+
+        <para>When <varname>Requisite=b.service</varname> is used on
+        <filename>a.service</filename>, this dependency will show as
+        <varname>RequisiteOf=a.service</varname> in property listing of
+        <filename>b.service</filename>. <varname>RequisiteOf=</varname>
+        dependency cannot be specified directly.</para>
+        </listitem>
       </varlistentry>
 
       <varlistentry>
         enters inactive state, but also one that is bound to another unit that gets skipped due to a failed condition
         check (such as <varname>ConditionPathExists=</varname>, <varname>ConditionPathIsSymbolicLink=</varname>, … —
         see below) will be stopped, should it be running. Hence, in many cases it is best to combine
-        <varname>BindsTo=</varname> with <varname>After=</varname>.</para></listitem>
+        <varname>BindsTo=</varname> with <varname>After=</varname>.</para>
+
+        <para>When <varname>BindsTo=b.service</varname> is used on
+        <filename>a.service</filename>, this dependency will show as
+        <varname>BoundBy=a.service</varname> in property listing of
+        <filename>b.service</filename>. <varname>BoundBy=</varname>
+        dependency cannot be specified directly.</para>
+        </listitem>
       </varlistentry>
 
       <varlistentry>
         restarting of units. When systemd stops or restarts the units
         listed here, the action is propagated to this unit. Note that
         this is a one-way dependency — changes to this unit do not
-        affect the listed units. </para></listitem>
+        affect the listed units.</para>
+
+        <para>When <varname>PartOf=b.service</varname> is used on
+        <filename>a.service</filename>, this dependency will show as
+        <varname>ConsistsOf=a.service</varname> in property listing of
+        <filename>b.service</filename>. <varname>ConsistsOf=</varname>
+        dependency cannot be specified directly.</para>
+        </listitem>
       </varlistentry>
 
       <varlistentry>
       </varlistentry>
 
       <varlistentry>
+        <term><varname>CollectMode=</varname></term>
+
+        <listitem><para>Tweaks the "garbage collection" algorithm for this unit. Takes one of <option>inactive</option>
+        or <option>inactive-or-failed</option>. If set to <option>inactive</option> the unit will be unloaded if it is
+        in the <constant>inactive</constant> state and is not referenced by clients, jobs or other units — however it
+        is not unloaded if it is in the <constant>failed</constant> state. In <option>failed</option> mode, failed
+        units are not unloaded until the user invoked <command>systemctl reset-failed</command> on them to reset the
+        <constant>failed</constant> state, or an equivalent command. This behaviour is altered if this option is set to
+        <option>inactive-or-failed</option>: in this case the unit is unloaded even if the unit is in a
+        <constant>failed</constant> state, and thus an explicitly resetting of the <constant>failed</constant> state is
+        not necessary. Note that if this mode is used unit results (such as exit codes, exit signals, consumed
+        resources, …) are flushed out immediately after the unit completed, except for what is stored in the logging
+        subsystem. Defaults to <option>inactive</option>.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
         <term><varname>JobTimeoutSec=</varname></term>
         <term><varname>JobRunningTimeoutSec=</varname></term>
         <term><varname>JobTimeoutAction=</varname></term>
       </varlistentry>
 
       <varlistentry>
-        <term><varname>StartLimitIntervalSec=</varname></term>
-        <term><varname>StartLimitBurst=</varname></term>
-
-        <listitem><para>Configure unit start rate limiting. By default, units which are started more than 5 times
-        within 10 seconds are not permitted to start any more times until the 10 second interval ends. With these two
-        options, this rate limiting may be modified. Use <varname>StartLimitIntervalSec=</varname> to configure the
-        checking interval (defaults to <varname>DefaultStartLimitIntervalSec=</varname> in manager configuration file,
-        set to 0 to disable any kind of rate limiting). Use <varname>StartLimitBurst=</varname> to configure how many
-        starts per interval are allowed (defaults to <varname>DefaultStartLimitBurst=</varname> in manager
-        configuration file). These configuration options are particularly useful in conjunction with the service
-        setting <varname>Restart=</varname> (see
+        <term><varname>StartLimitIntervalSec=<replaceable>interval</replaceable></varname></term>
+        <term><varname>StartLimitBurst=<replaceable>burst</replaceable></varname></term>
+
+        <listitem><para>Configure unit start rate limiting. Units which are started more than
+        <replaceable>burst</replaceable> times within an <replaceable>interval</replaceable> time interval are not
+        permitted to start any more. Use <varname>StartLimitIntervalSec=</varname> to configure the checking interval
+        (defaults to <varname>DefaultStartLimitIntervalSec=</varname> in manager configuration file, set it to 0 to
+        disable any kind of rate limiting). Use <varname>StartLimitBurst=</varname> to configure how many starts per
+        interval are allowed (defaults to <varname>DefaultStartLimitBurst=</varname> in manager configuration
+        file). These configuration options are particularly useful in conjunction with the service setting
+        <varname>Restart=</varname> (see
         <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>); however,
         they apply to all kinds of starts (including manual), not just those triggered by the
         <varname>Restart=</varname> logic. Note that units which are configured for <varname>Restart=</varname> and
         which reach the start limit are not attempted to be restarted anymore; however, they may still be restarted
-        manually at a later point, from which point on, the restart logic is again activated. Note that
-        <command>systemctl reset-failed</command> will cause the restart rate counter for a service to be flushed,
-        which is useful if the administrator wants to manually start a unit and the start limit interferes with
-        that. Note that this rate-limiting is enforced after any unit condition checks are executed, and hence unit
-        activations with failing conditions are not counted by this rate limiting. Slice, target, device and scope
-        units do not enforce this setting, as they are unit types whose activation may either never fail, or may
-        succeed only a single time.</para></listitem>
+        manually at a later point, after the <replaceable>interval</replaceable> has passed.  From this point on, the
+        restart logic is activated again. Note that <command>systemctl reset-failed</command> will cause the restart
+        rate counter for a service to be flushed, which is useful if the administrator wants to manually start a unit
+        and the start limit interferes with that. Note that this rate-limiting is enforced after any unit condition
+        checks are executed, and hence unit activations with failing conditions do not count towards this rate
+        limit. This setting does not apply to slice, target, device, and scope units, since they are unit types whose
+        activation may either never fail, or may succeed only a single time.</para>
+
+        <para>When a unit is unloaded due to the garbage collection logic (see above) its rate limit counters are
+        flushed out too. This means that configuring start rate limiting for a unit that is not referenced continously
+        has no effect.</para></listitem>
       </varlistentry>
 
       <varlistentry>
       </varlistentry>
 
       <varlistentry>
+        <term><varname>FailureAction=</varname></term>
+        <term><varname>SuccessAction=</varname></term>
+        <listitem><para>Configure the action to take when the unit stops and enters a failed state or inactive
+        state. Takes the same values as the setting <varname>StartLimitAction=</varname> setting and executes the same
+        actions (see
+        <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>). Both options
+        default to <option>none</option>.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
         <term><varname>RebootArgument=</varname></term>
         <listitem><para>Configure the optional argument for the
         <citerefentry><refentrytitle>reboot</refentrytitle><manvolnum>2</manvolnum></citerefentry> system call if
-        <varname>StartLimitAction=</varname> or a service's <varname>FailureAction=</varname> is a reboot action. This
+        <varname>StartLimitAction=</varname> or <varname>FailureAction=</varname> is a reboot action. This
         works just like the optional argument to <command>systemctl reboot</command> command.</para></listitem>
       </varlistentry>
 
         system. Currently, the recognized values are
         <varname>selinux</varname>,
         <varname>apparmor</varname>,
+        <varname>tomoyo</varname>,
         <varname>ima</varname>,
         <varname>smack</varname> and
         <varname>audit</varname>. The test may be negated by
         files. This functionality should not be used in normal
         units.</para></listitem>
       </varlistentry>
-
     </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Mapping of unit properties to their inverses</title>
+
+    <para>Unit settings that create a relationship with a second unit usually show up
+    in properties of both units, for example in <command>systemctl show</command>
+    output. In some cases the name of the property is the same as the name of the
+    configuration setting, but not always. This table lists the pairs of properties
+    that are shown on two units which are connected through some dependency, and shows
+    which property on "source" unit corresponds to which property on the "target" unit.
+    </para>
+
+    <table>
+      <title>
+        "Forward" and "reverse" unit properties
+      </title>
 
+      <tgroup cols='2'>
+        <colspec colname='forward' />
+        <colspec colname='reverse' />
+        <colspec colname='notes' />
+        <thead>
+          <row>
+            <entry>"Forward" property</entry>
+            <entry>"Reverse" property</entry>
+            <entry>Where used</entry>
+          </row>
+        </thead>
+        <tbody>
+          <row>
+            <entry><varname>Before=</varname></entry>
+            <entry><varname>After=</varname></entry>
+            <entry morerows='1' valign='middle'>Both are unit file options</entry>
+          </row>
+          <row>
+            <entry><varname>After=</varname></entry>
+            <entry><varname>Before=</varname></entry>
+          </row>
+          <row>
+            <entry><varname>Requires=</varname></entry>
+            <entry><varname>RequiredBy=</varname></entry>
+            <entry>A unit file option; an option in the [Install] section</entry>
+          </row>
+          <row>
+            <entry><varname>Wants=</varname></entry>
+            <entry><varname>WantedBy=</varname></entry>
+            <entry>A unit file option; an option in the [Install] section</entry>
+          </row>
+          <row>
+            <entry><varname>PartOf=</varname></entry>
+            <entry><varname>ConsistsOf=</varname></entry>
+            <entry>A unit file option; an automatic property</entry>
+          </row>
+          <row>
+            <entry><varname>BindsTo=</varname></entry>
+            <entry><varname>BoundBy=</varname></entry>
+            <entry>A unit file option; an automatic property</entry>
+          </row>
+          <row>
+            <entry><varname>Requisite=</varname></entry>
+            <entry><varname>RequisiteOf=</varname></entry>
+            <entry>A unit file option; an automatic property</entry>
+          </row>
+          <row>
+            <entry><varname>Triggers=</varname></entry>
+            <entry><varname>TriggeredBy=</varname></entry>
+            <entry>Automatic properties, see notes below</entry>
+          </row>
+          <row>
+            <entry><varname>Conflicts=</varname></entry>
+            <entry><varname>ConflictedBy=</varname></entry>
+            <entry>A unit file option; an automatic property</entry>
+          </row>
+          <row>
+            <entry><varname>PropagatesReloadTo=</varname></entry>
+            <entry><varname>ReloadPropagatedFrom=</varname></entry>
+            <entry morerows='1' valign='middle'>Both are unit file options</entry>
+          </row>
+          <row>
+            <entry><varname>ReloadPropagatedFrom=</varname></entry>
+            <entry><varname>PropagatesReloadTo=</varname></entry>
+          </row>
+        </tbody>
+      </tgroup>
+    </table>
+
+    <para>Note: <varname>WantedBy=</varname> and <varname>RequiredBy=</varname> are
+    used in the [Install] section to create symlinks in <filename>.wants/</filename>
+    and <filename>.requires/</filename> directories. They cannot be used directly as a
+    unit configuration setting.</para>
+
+    <para>Note: <varname>ConsistsOf=</varname>, <varname>BoundBy=</varname>,
+    <varname>RequisiteOf=</varname>, <varname>ConflictedBy=</varname> are created
+    implicitly along with their reverse and cannot be specified directly.</para>
+
+    <para>Note: <varname>Triggers=</varname> is created implicitly between a socket,
+    path unit, or an automount unit, and the unit they activate. By default a unit
+    with the same name is triggered, but this can be overriden using
+    <varname>Sockets=</varname>, <varname>Service=</varname>, and <varname>Unit=</varname>
+    settings. See
+    <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+    <citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+    <citerefentry><refentrytitle>systemd.path</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+    and
+    <citerefentry><refentrytitle>systemd.automount</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+    for details. <varname>TriggersBy=</varname> is created implicitly on the
+    triggered unit.</para>
   </refsect1>
 
   <refsect1>
     <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry> during runtime; it is
     used by the <command>enable</command> and <command>disable</command> commands of the
     <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry> tool during
-    installation of a unit. Note that settings in the <literal>[Install]</literal> section may not appear in
-    <filename>.d/*.conf</filename> unit file drop-ins (see above).</para>
+    installation of a unit.</para>
 
     <variablelist class='unit-directives'>
       <varlistentry>
 
     <para>Many settings resolve specifiers which may be used to write
     generic unit files referring to runtime or unit parameters that
-    are replaced when the unit files are loaded. The following
+    are replaced when the unit files are loaded. Specifiers must be known
+    and resolvable for the setting to be valid. The following
     specifiers are understood:</para>
 
     <table>
         <colspec colname="detail" />
         <thead>
           <row>
-      <entry>Specifier</entry>
-      <entry>Meaning</entry>
-      <entry>Details</entry>
+            <entry>Specifier</entry>
+            <entry>Meaning</entry>
+            <entry>Details</entry>
           </row>
         </thead>
         <tbody>
           <row>
-      <entry><literal>%n</literal></entry>
-      <entry>Full unit name</entry>
-      <entry></entry>
+            <entry><literal>%n</literal></entry>
+            <entry>Full unit name</entry>
+            <entry></entry>
+          </row>
+          <row>
+            <entry><literal>%N</literal></entry>
+            <entry>Unescaped full unit name</entry>
+            <entry>Same as <literal>%n</literal>, but with escaping undone. This undoes the escaping used when generating unit names from arbitrary strings (see above). </entry>
+          </row>
+          <row>
+            <entry><literal>%p</literal></entry>
+            <entry>Prefix name</entry>
+            <entry>For instantiated units, this refers to the string before the <literal>@</literal> character of the unit name. For non-instantiated units, this refers to the name of the unit with the type suffix removed.</entry>
+          </row>
+          <row>
+            <entry><literal>%P</literal></entry>
+            <entry>Unescaped prefix name</entry>
+            <entry>Same as <literal>%p</literal>, but with escaping undone</entry>
           </row>
           <row>
-      <entry><literal>%N</literal></entry>
-      <entry>Unescaped full unit name</entry>
-      <entry>Same as <literal>%n</literal>, but with escaping undone</entry>
+            <entry><literal>%i</literal></entry>
+            <entry>Instance name</entry>
+            <entry>For instantiated units: this is the string between the <literal>@</literal> character and the suffix of the unit name.</entry>
           </row>
           <row>
-      <entry><literal>%p</literal></entry>
-      <entry>Prefix name</entry>
-      <entry>For instantiated units, this refers to the string before the <literal>@</literal> character of the unit name. For non-instantiated units, this refers to the name of the unit with the type suffix removed.</entry>
+            <entry><literal>%I</literal></entry>
+            <entry>Unescaped instance name</entry>
+            <entry>Same as <literal>%i</literal>, but with escaping undone</entry>
           </row>
           <row>
-      <entry><literal>%P</literal></entry>
-      <entry>Unescaped prefix name</entry>
-      <entry>Same as <literal>%p</literal>, but with escaping undone</entry>
+            <entry><literal>%f</literal></entry>
+            <entry>Unescaped filename</entry>
+            <entry>This is either the unescaped instance name (if applicable) with <filename>/</filename> prepended (if applicable), or the unescaped prefix name prepended with <filename>/</filename>. This implements unescaping according to the rules for escaping absolute file system paths discussed above.</entry>
           </row>
           <row>
-      <entry><literal>%i</literal></entry>
-      <entry>Instance name</entry>
-      <entry>For instantiated units: this is the string between the <literal>@</literal> character and the suffix of the unit name.</entry>
+            <entry><literal>%t</literal></entry>
+            <entry>Runtime directory root</entry>
+            <entry>This is either <filename>/run</filename> (for the system manager) or the path <literal>$XDG_RUNTIME_DIR</literal> resolves to (for user managers).</entry>
           </row>
           <row>
-      <entry><literal>%I</literal></entry>
-      <entry>Unescaped instance name</entry>
-      <entry>Same as <literal>%i</literal>, but with escaping undone</entry>
+            <entry><literal>%S</literal></entry>
+            <entry>State directory root</entry>
+            <entry>This is either <filename>/var/lib</filename> (for the system manager) or the path <literal>$XDG_CONFIG_HOME</literal> resolves to (for user managers).</entry>
           </row>
           <row>
-      <entry><literal>%f</literal></entry>
-      <entry>Unescaped filename</entry>
-      <entry>This is either the unescaped instance name (if applicable) with <filename>/</filename> prepended (if applicable), or the unescaped prefix name prepended with <filename>/</filename>.</entry>
+            <entry><literal>%C</literal></entry>
+            <entry>Cache directory root</entry>
+            <entry>This is either <filename>/var/cache</filename> (for the system manager) or the path <literal>$XDG_CACHE_HOME</literal> resolves to (for user managers).</entry>
           </row>
           <row>
-      <entry><literal>%t</literal></entry>
-      <entry>Runtime directory</entry>
-      <entry>This is either <filename>/run</filename> (for the system manager) or the path <literal>$XDG_RUNTIME_DIR</literal> resolves to (for user managers).</entry>
+            <entry><literal>%L</literal></entry>
+            <entry>Log directory root</entry>
+            <entry>This is either <filename>/var/log</filename> (for the system manager) or the path <literal>$XDG_CONFIG_HOME</literal> resolves to with <filename noindex='true'>/log</filename> appended (for user managers).</entry>
           </row>
           <row>
-      <entry><literal>%u</literal></entry>
-      <entry>User name</entry>
-      <entry>This is the name of the user running the service manager instance. In case of the system manager this resolves to <literal>root</literal>.</entry>
+            <entry><literal>%u</literal></entry>
+            <entry>User name</entry>
+            <entry>This is the name of the user running the service manager instance. In case of the system manager this resolves to <literal>root</literal>.</entry>
           </row>
           <row>
-      <entry><literal>%U</literal></entry>
-      <entry>User UID</entry>
-      <entry>This is the numeric UID of the user running the service manager instance. In case of the system manager this resolves to <literal>0</literal>.</entry>
+            <entry><literal>%U</literal></entry>
+            <entry>User UID</entry>
+            <entry>This is the numeric UID of the user running the service manager instance. In case of the system manager this resolves to <literal>0</literal>.</entry>
           </row>
           <row>
-      <entry><literal>%h</literal></entry>
-      <entry>User home directory</entry>
-      <entry>This is the home directory of the user running the service manager instance. In case of the system manager this resolves to <literal>/root</literal>.</entry>
+            <entry><literal>%h</literal></entry>
+            <entry>User home directory</entry>
+            <entry>This is the home directory of the user running the service manager instance. In case of the system manager this resolves to <literal>/root</literal>.</entry>
           </row>
           <row>
-      <entry><literal>%s</literal></entry>
-      <entry>User shell</entry>
-      <entry>This is the shell of the user running the service manager instance. In case of the system manager this resolves to <literal>/bin/sh</literal>.</entry>
+            <entry><literal>%s</literal></entry>
+            <entry>User shell</entry>
+            <entry>This is the shell of the user running the service manager instance. In case of the system manager this resolves to <literal>/bin/sh</literal>.</entry>
           </row>
           <row>
-      <entry><literal>%m</literal></entry>
-      <entry>Machine ID</entry>
-      <entry>The machine ID of the running system, formatted as string. See <citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry> for more information.</entry>
+            <entry><literal>%m</literal></entry>
+            <entry>Machine ID</entry>
+            <entry>The machine ID of the running system, formatted as string. See <citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry> for more information.</entry>
           </row>
           <row>
-      <entry><literal>%b</literal></entry>
-      <entry>Boot ID</entry>
-      <entry>The boot ID of the running system, formatted as string. See <citerefentry><refentrytitle>random</refentrytitle><manvolnum>4</manvolnum></citerefentry> for more information.</entry>
+            <entry><literal>%b</literal></entry>
+            <entry>Boot ID</entry>
+            <entry>The boot ID of the running system, formatted as string. See <citerefentry><refentrytitle>random</refentrytitle><manvolnum>4</manvolnum></citerefentry> for more information.</entry>
           </row>
           <row>
-      <entry><literal>%H</literal></entry>
-      <entry>Host name</entry>
-      <entry>The hostname of the running system at the point in time the unit configuration is loaded.</entry>
+            <entry><literal>%H</literal></entry>
+            <entry>Host name</entry>
+            <entry>The hostname of the running system at the point in time the unit configuration is loaded.</entry>
           </row>
           <row>
-      <entry><literal>%v</literal></entry>
-      <entry>Kernel release</entry>
-      <entry>Identical to <command>uname -r</command> output</entry>
+            <entry><literal>%v</literal></entry>
+            <entry>Kernel release</entry>
+            <entry>Identical to <command>uname -r</command> output</entry>
           </row>
           <row>
-      <entry><literal>%%</literal></entry>
-      <entry>Single percent sign</entry>
-      <entry>Use <literal>%%</literal> in place of <literal>%</literal> to specify a single percent sign.</entry>
+            <entry><literal>%%</literal></entry>
+            <entry>Single percent sign</entry>
+            <entry>Use <literal>%%</literal> in place of <literal>%</literal> to specify a single percent sign.</entry>
           </row>
         </tbody>
       </tgroup>
     </table>
-
   </refsect1>
 
   <refsect1>
@@ -1380,13 +1603,6 @@ ExecStart=/usr/sbin/foo-daemon
       disadvantage that some future updates by the vendor might be
       incompatible with the local changes.</para>
 
-      <para>Note that for drop-in files, if one wants to remove
-      entries from a setting that is parsed as a list (and is not a
-      dependency), such as <varname>ConditionPathExists=</varname> (or
-      e.g. <varname>ExecStart=</varname> in service units), one needs
-      to first clear the list before re-adding all entries except the
-      one that is to be removed. See below for an example.</para>
-
       <para>This also applies for user instances of systemd, but with
       different locations for the unit files. See the section on unit
       load paths for further details.</para>
@@ -1458,7 +1674,12 @@ AssertPathExists=/srv/www
 Nice=0
 PrivateTmp=yes</programlisting>
 
-      <para>Note that dependencies (<varname>After=</varname>, etc.)
+      <para>Note that for drop-in files, if one wants to remove
+      entries from a setting that is parsed as a list (and is not a
+      dependency), such as <varname>AssertPathExists=</varname> (or
+      e.g. <varname>ExecStart=</varname> in service units), one needs
+      to first clear the list before re-adding all entries except the
+      one that is to be removed. Dependencies (<varname>After=</varname>, etc.)
       cannot be reset to an empty list, so dependencies can only be
       added in drop-ins. If you want to remove dependencies, you have
       to override the entire unit.</para>
index b455b60..62ececb 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2010 Lennart Poettering
@@ -51,7 +53,7 @@
 
   <refsynopsisdiv>
     <cmdsynopsis>
-      <command>systemd</command>
+      <command>/usr/lib/systemd/systemd</command>
       <arg choice="opt" rep="repeat">OPTIONS</arg>
     </cmdsynopsis>
     <cmdsynopsis>
     verify that it makes sense, fixing it if possible, and only
     failing if it really cannot work.</para>
 
-    <para>Systemd contains native implementations of various tasks
+    <para>systemd contains native implementations of various tasks
     that need to be executed as part of the boot process. For example,
     it sets the hostname or configures the loopback network device. It
     also sets up and mounts various API file systems, such as
index fbe9754..38b749c 100644 (file)
@@ -2,6 +2,8 @@
 <!--*-nxml-*-->
 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2014 Lennart Poettering
index bdd22a6..70044cc 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2010 Lennart Poettering
index 80f63e8..dba94d8 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2012 Lennart Poettering
index 7c84e80..812b16e 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2014 Lennart Poettering
         is used instead.</para></listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><varname>RootDistanceMaxSec=</varname></term>
+        <listitem><para>Maximum acceptable root distance. Takes a time value (in seconds).
+        Defaults to 5 seconds.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>PollIntervalMinSec=</varname></term>
+        <term><varname>PollIntervalMaxSec=</varname></term>
+        <listitem><para>The minimum and maximum poll intervals for NTP messages.
+        Each setting takes a time value (in seconds).
+        <varname>PollIntervalMinSec=</varname> must not be smaller than 16 seconds.
+        <varname>PollIntervalMaxSec=</varname> must be larger than <varname>PollIntervalMinSec=</varname>.
+        <varname>PollIntervalMinSec=</varname> defaults to 32 seconds, and
+        <varname>PollIntervalMaxSec=</varname> defaults to 2048 seconds.</para></listitem>
+      </varlistentry>
+
     </variablelist>
   </refsect1>
 
index 68ae43e..f5d97aa 100644 (file)
@@ -1,6 +1,8 @@
 <?xml version='1.0'?> <!--*- Mode: nxml; nxml-child-indent: 2; indent-tabs-mode: nil -*-->
 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2010 Brandon Philips
   </refnamediv>
 
   <refsynopsisdiv>
-    <para><filename>/etc/tmpfiles.d/*.conf</filename></para>
-    <para><filename>/run/tmpfiles.d/*.conf</filename></para>
-    <para><filename>/usr/lib/tmpfiles.d/*.conf</filename></para>
+    <para><literallayout><filename>/etc/tmpfiles.d/*.conf</filename>
+<filename>/run/tmpfiles.d/*.conf</filename>
+<filename>/usr/lib/tmpfiles.d/*.conf</filename>
+    </literallayout></para>
+
+    <para><literallayout><filename>~/.config/user-tmpfiles.d/*.conf</filename>
+<filename>$XDG_RUNTIME_DIR/user-tmpfiles.d/*.conf</filename>
+<filename>~/.local/share/user-tmpfiles.d/*.conf</filename>
+<filename>…</filename>
+<filename>/usr/share/user-tmpfiles.d/*.conf</filename>
+    </literallayout></para>
   </refsynopsisdiv>
 
   <refsect1>
@@ -480,51 +490,8 @@ r! /tmp/.X[0-9]*-lock</programlisting>
       <title>Path</title>
 
       <para>The file system path specification supports simple
-      specifier expansion. The following expansions are
-      understood:</para>
-
-      <table>
-        <title>Specifiers available</title>
-        <tgroup cols='3' align='left' colsep='1' rowsep='1'>
-          <colspec colname="spec" />
-          <colspec colname="mean" />
-          <colspec colname="detail" />
-          <thead>
-            <row>
-              <entry>Specifier</entry>
-              <entry>Meaning</entry>
-              <entry>Details</entry>
-            </row>
-          </thead>
-          <tbody>
-            <row>
-              <entry><literal>%m</literal></entry>
-              <entry>Machine ID</entry>
-              <entry>The machine ID of the running system, formatted as string. See <citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry> for more information.</entry>
-            </row>
-            <row>
-              <entry><literal>%b</literal></entry>
-              <entry>Boot ID</entry>
-              <entry>The boot ID of the running system, formatted as string. See <citerefentry><refentrytitle>random</refentrytitle><manvolnum>4</manvolnum></citerefentry> for more information.</entry>
-            </row>
-            <row>
-              <entry><literal>%H</literal></entry>
-              <entry>Host name</entry>
-              <entry>The hostname of the running system.</entry>
-            </row>
-            <row>
-              <entry><literal>%v</literal></entry>
-              <entry>Kernel release</entry>
-              <entry>Identical to <command>uname -r</command> output.</entry>
-            </row>
-            <row>
-              <entry><literal>%%</literal></entry>
-              <entry>Escaped %</entry>
-              <entry>Single percent sign.</entry>
-            </row>
-          </tbody>
-        </tgroup>
-      </table>
+      specifier expansion, see below. The path (after expansion) must be
+      absolute.</para>
     </refsect2>
 
     <refsect2>
@@ -626,8 +593,94 @@ r! /tmp/.X[0-9]*-lock</programlisting>
       attributes to be set. For <varname>h</varname> and
       <varname>H</varname>, determines the file attributes to
       set. Ignored for all other lines.</para>
+
+      <para>This field can contain specifiers, see below.</para>
     </refsect2>
+  </refsect1>
 
+  <refsect1>
+    <title>Specifiers</title>
+
+    <para>Specifiers can be used in the "path" and "argument" fields.
+    An unknown or unresolvable specifier is treated as invalid configuration.
+    The following expansions are understood:</para>
+      <table>
+        <title>Specifiers available</title>
+        <tgroup cols='3' align='left' colsep='1' rowsep='1'>
+          <colspec colname="spec" />
+          <colspec colname="mean" />
+          <colspec colname="detail" />
+          <thead>
+            <row>
+              <entry>Specifier</entry>
+              <entry>Meaning</entry>
+              <entry>Details</entry>
+            </row>
+          </thead>
+          <tbody>
+            <row>
+              <entry><literal>%m</literal></entry>
+              <entry>Machine ID</entry>
+              <entry>The machine ID of the running system, formatted as string. See <citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry> for more information.</entry>
+            </row>
+            <row>
+              <entry><literal>%b</literal></entry>
+              <entry>Boot ID</entry>
+              <entry>The boot ID of the running system, formatted as string. See <citerefentry><refentrytitle>random</refentrytitle><manvolnum>4</manvolnum></citerefentry> for more information.</entry>
+            </row>
+            <row>
+              <entry><literal>%H</literal></entry>
+              <entry>Host name</entry>
+              <entry>The hostname of the running system.</entry>
+            </row>
+            <row>
+              <entry><literal>%v</literal></entry>
+              <entry>Kernel release</entry>
+              <entry>Identical to <command>uname -r</command> output.</entry>
+            </row>
+            <row>
+              <entry><literal>%U</literal></entry>
+              <entry>User UID</entry>
+              <entry>This is the numeric UID of the user running the service manager instance. In case of the system manager this resolves to <constant>0</constant>.</entry>
+            </row>
+            <row>
+              <entry><literal>%u</literal></entry>
+              <entry>User name</entry>
+              <entry>This is the name of the user running the service manager instance. In case of the system manager this resolves to <literal>root</literal>.</entry>
+            </row>
+            <row>
+              <entry><literal>%h</literal></entry>
+              <entry>User home directory</entry>
+              <entry>This is the home directory of the user running the service manager instance. In case of the system manager this resolves to <literal>/root</literal>.</entry>
+            </row>
+            <row>
+              <entry><literal>%t</literal></entry>
+              <entry>System or user runtime directory</entry>
+              <entry>In --user mode, this is the same <varname>$XDG_RUNTIME_DIR</varname>, and <filename>/run</filename> otherwise.</entry>
+            </row>
+            <row>
+              <entry><literal>%S</literal></entry>
+              <entry>System or user state directory</entry>
+              <entry>In <option>--user</option> mode, this is the same as <varname>$XDG_CONFIG_HOME</varname>, and <filename>/var/lib</filename> otherwise.</entry>
+            </row>
+            <row>
+              <entry><literal>%C</literal></entry>
+              <entry>System or user cache directory</entry>
+              <entry>In <option>--user</option> mode, this is the same as <varname>$XDG_CACHE_HOME</varname>, and <filename>/var/cache</filename> otherwise.</entry>
+            </row>
+            <row>
+              <entry><literal>%L</literal></entry>
+              <entry>System or user log directory</entry>
+              <entry>In <option>--user</option> mode, this is the same as <varname>$XDG_CONFIG_HOME</varname> with <filename noindex='true'>/log</filename> appended, and <filename>/var/log</filename> otherwise.</entry>
+            </row>
+            <row>
+              <entry><literal>%%</literal></entry>
+              <entry>Escaped <literal>%</literal></entry>
+              <entry>Single percent sign.</entry>
+            </row>
+          </tbody>
+        </tgroup>
+      </table>
   </refsect1>
 
   <refsect1>
index e104e53..2339e8b 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2014 Zbigniew Jędrzejewski-Szmek
index 3359fb0..7b42d23 100644 (file)
@@ -2,6 +2,28 @@
 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
+<!--
+  SPDX-License-Identifier: LGPL-2.1+
+
+  This file is part of systemd.
+
+  Copyright 2012 Kay Sievers
+  Copyright 2014 Jason St. John
+
+  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.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
 <refentry id="udev">
   <refentryinfo>
     <title>udev</title>
index 014f43b..1eb029f 100644 (file)
@@ -6,6 +6,8 @@
 ]>
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2015 David Herrmann <dh.herrmann@gmail.com>
index 4802573..cdfcd7b 100644 (file)
@@ -6,6 +6,8 @@
 ]>
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2015 David Herrmann <dh.herrmann@gmail.com>
index 0bb71c8..13f1b4c 100644 (file)
@@ -6,6 +6,8 @@
 ]>
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2015 David Herrmann <dh.herrmann@gmail.com>
index 5acce00..fee861c 100644 (file)
@@ -6,6 +6,8 @@
 ]>
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2015 David Herrmann <dh.herrmann@gmail.com>
index b5856c5..e195ad5 100644 (file)
@@ -6,6 +6,8 @@
 ]>
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2015 David Herrmann <dh.herrmann@gmail.com>
index e0b6bfb..3abfcef 100644 (file)
@@ -6,6 +6,8 @@
 ]>
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2015 David Herrmann <dh.herrmann@gmail.com>
index a1b531d..12b4835 100644 (file)
@@ -6,6 +6,8 @@
 ]>
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2015 David Herrmann <dh.herrmann@gmail.com>
index f129595..3590a3c 100644 (file)
@@ -6,6 +6,8 @@
 ]>
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2015 David Herrmann <dh.herrmann@gmail.com>
index d73a4ac..90ce121 100644 (file)
@@ -6,6 +6,8 @@
 ]>
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2015 David Herrmann <dh.herrmann@gmail.com>
index 7e842f8..abc9615 100644 (file)
@@ -6,6 +6,8 @@
 ]>
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2015 David Herrmann <dh.herrmann@gmail.com>
index 587835a..b4520d7 100644 (file)
@@ -6,6 +6,8 @@
 ]>
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2015 David Herrmann <dh.herrmann@gmail.com>
index 7ace4f9..753ddf9 100644 (file)
@@ -2,7 +2,30 @@
 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
-<refentry id="udevadm">
+<!--
+  SPDX-License-Identifier: LGPL-2.1+
+
+  This file is part of systemd.
+
+  Copyright 2010-2013 Kay Sievers
+
+  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.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="udevadm"
+          xmlns:xi="http://www.w3.org/2001/XInclude">
+
   <refentryinfo>
     <title>udevadm</title>
     <productname>systemd</productname>
         <arg><option>--help</option></arg>
     </cmdsynopsis>
     <cmdsynopsis>
-      <command>udevadm info <replaceable>options</replaceable></command>
+      <command>udevadm info <optional>options</optional> <optional>devpath</optional></command>
     </cmdsynopsis>
     <cmdsynopsis>
-      <command>udevadm trigger <optional>options</optional></command>
+      <command>udevadm trigger <optional>options</optional> <optional>devpath</optional></command>
     </cmdsynopsis>
     <cmdsynopsis>
       <command>udevadm settle <optional>options</optional></command>
     </cmdsynopsis>
     <cmdsynopsis>
-      <command>udevadm control <replaceable>command</replaceable></command>
+      <command>udevadm control <replaceable>option</replaceable></command>
     </cmdsynopsis>
     <cmdsynopsis>
       <command>udevadm monitor <optional>options</optional></command>
   <refsect1><title>Options</title>
     <variablelist>
       <varlistentry>
+        <term><option>-d</option></term>
         <term><option>--debug</option></term>
         <listitem>
           <para>Print debug messages to standard error.</para>
         </listitem>
       </varlistentry>
-      <varlistentry>
-        <term><option>--version</option></term>
-        <listitem>
-          <para>Print version number.</para>
-        </listitem>
-      </varlistentry>
-      <varlistentry>
-        <term><option>-h</option></term>
-        <term><option>--help</option></term>
-        <listitem>
-          <para>Print help text.</para>
-        </listitem>
-      </varlistentry>
+
+      <xi:include href="standard-options.xml" xpointer="version" />
+      <xi:include href="standard-options.xml" xpointer="help" />
     </variablelist>
 
     <refsect2><title>udevadm info
             <para>Cleanup the udev database.</para>
           </listitem>
         </varlistentry>
-        <varlistentry>
-          <term><option>--version</option></term>
-          <listitem>
-            <para>Print version.</para>
-          </listitem>
-        </varlistentry>
-        <varlistentry>
-          <term><option>-h</option></term>
-          <term><option>--help</option></term>
-          <listitem>
-            <para>Print help text.</para>
-          </listitem>
-        </varlistentry>
+
+        <xi:include href="standard-options.xml" xpointer="version" />
+        <xi:include href="standard-options.xml" xpointer="help" />
       </variablelist>
 
       <para>In addition, an optional positional argument can be used
             device.</para>
           </listitem>
         </varlistentry>
-        <varlistentry>
-          <term><option>-h</option></term>
-          <term><option>--help</option></term>
-          <listitem>
-            <para>Print help text.</para>
-          </listitem>
-        </varlistentry>
+
+        <xi:include href="standard-options.xml" xpointer="version" />
+        <xi:include href="standard-options.xml" xpointer="help" />
       </variablelist>
 
       <para>In addition, optional positional arguments can be used
             <para>Stop waiting if file exists.</para>
           </listitem>
         </varlistentry>
-        <varlistentry>
-          <term><option>-h</option></term>
-          <term><option>--help</option></term>
-          <listitem>
-            <para>Print help text.</para>
-          </listitem>
-        </varlistentry>
+
+        <xi:include href="standard-options.xml" xpointer="version" />
+        <xi:include href="standard-options.xml" xpointer="help" />
       </variablelist>
     </refsect2>
 
-    <refsect2><title>udevadm control <replaceable>command</replaceable></title>
+    <refsect2><title>udevadm control <replaceable>option</replaceable></title>
       <para>Modify the internal state of the running udev daemon.</para>
       <variablelist>
         <varlistentry>
           </listitem>
         </varlistentry>
         <varlistentry>
+          <term><option>-t</option></term>
           <term><option>--timeout=</option><replaceable>seconds</replaceable></term>
           <listitem>
             <para>The maximum number of seconds to wait for a reply from systemd-udevd.</para>
           </listitem>
         </varlistentry>
-        <varlistentry>
-          <term><option>-h</option></term>
-          <term><option>--help</option></term>
-          <listitem>
-            <para>Print help text.</para>
-          </listitem>
-        </varlistentry>
+
+        <xi:include href="standard-options.xml" xpointer="version" />
+        <xi:include href="standard-options.xml" xpointer="help" />
       </variablelist>
     </refsect2>
 
             <para>Filter udev events by tag. Only udev events with a given tag attached will pass.</para>
           </listitem>
         </varlistentry>
-        <varlistentry>
-          <term><option>-h</option></term>
-          <term><option>--help</option></term>
-          <listitem>
-            <para>Print help text.</para>
-          </listitem>
-        </varlistentry>
+
+        <xi:include href="standard-options.xml" xpointer="version" />
+        <xi:include href="standard-options.xml" xpointer="help" />
       </variablelist>
     </refsect2>
 
             and all devices will be owned by root.</para>
           </listitem>
         </varlistentry>
-        <varlistentry>
-          <term><option>-h</option></term>
-          <term><option>--help</option></term>
-          <listitem>
-            <para>Print help text.</para>
-          </listitem>
-        </varlistentry>
+
+        <xi:include href="standard-options.xml" xpointer="version" />
+        <xi:include href="standard-options.xml" xpointer="help" />
       </variablelist>
     </refsect2>
 
       for device <replaceable>DEVPATH</replaceable>, and print debug
       output.</para>
       <variablelist>
-        <varlistentry>
-          <term><option>-h</option></term>
-          <term><option>--help</option></term>
-          <listitem>
-            <para>Print help text.</para>
-          </listitem>
-        </varlistentry>
+        <xi:include href="standard-options.xml" xpointer="version" />
+        <xi:include href="standard-options.xml" xpointer="help" />
       </variablelist>
     </refsect2>
   </refsect1>
index 8616c54..d6a5eef 100644 (file)
@@ -2,6 +2,28 @@
 <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
           "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
 
+<!--
+  SPDX-License-Identifier: LGPL-2.1+
+
+  This file is part of systemd.
+
+  Copyright 2014 Zbigniew Jędrzejewski-Szmek
+  Copyright 2014 Lennart Poettering
+
+  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.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
 <variablelist>
   <varlistentry id='user'>
     <term><option>--user</option></term>
index 4a6672c..fecbfd8 100644 (file)
@@ -3,6 +3,8 @@
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   Copyright 2010 Lennart Poettering
index 2c6dd45..76f27ad 100644 (file)
@@ -1,5 +1,22 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
+# Copyright 2017 Zbigniew Jędrzejewski-Szmek
+#
+# 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.
+#
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
 project('systemd', 'c',
-        version : '235',
+        version : '236',
         license : 'LGPLv2+',
         default_options: [
                 'c_std=gnu99',
@@ -7,11 +24,11 @@ project('systemd', 'c',
                 'sysconfdir=/etc',
                 'localstatedir=/var',
         ],
-        meson_version : '>= 0.40',
+        meson_version : '>= 0.41',
        )
 
-libsystemd_version = '0.19.1'
-libudev_version = '1.6.7'
+libsystemd_version = '0.20.0'
+libudev_version = '1.6.8'
 
 # We need the same data in three different formats, ugh!
 # Also, for hysterical reasons, we use different variable
@@ -37,12 +54,15 @@ endif
 
 #####################################################################
 
+split_usr = get_option('split-usr')
+conf.set10('HAVE_SPLIT_USR', split_usr)
+
 rootprefixdir = get_option('rootprefix')
-conf.set10('HAVE_SPLIT_USR', get_option('split-usr'))
-if get_option('split-usr')
-        rootprefixdir = rootprefixdir != '' ? rootprefixdir : '/'
-else
-        rootprefixdir = rootprefixdir != '' ? rootprefixdir : '/usr'
+# Unusual rootprefixdir values are used by some distros
+# (see https://github.com/systemd/systemd/pull/7461).
+rootprefix_default = get_option('split-usr') ? '/' : '/usr'
+if rootprefixdir == ''
+        rootprefixdir = rootprefix_default
 endif
 
 sysvinit_path = get_option('sysvinit-path')
@@ -83,7 +103,10 @@ polkitpkladir = join_paths(localstatedir, 'lib/polkit-1/localauthority/10-vendor
 varlogdir = join_paths(localstatedir, 'log')
 xinitrcdir = join_paths(sysconfdir, 'X11/xinit/xinitrc.d')
 rpmmacrosdir = get_option('rpmmacrosdir')
-modprobedir = join_paths(prefixdir, 'lib/modprobe.d')
+if rpmmacrosdir != 'no'
+        rpmmacrosdir = join_paths(prefixdir, rpmmacrosdir)
+endif
+modprobedir = join_paths(rootprefixdir, 'lib/modprobe.d')
 
 # Our own paths
 pkgdatadir = join_paths(datadir, 'systemd')
@@ -159,6 +182,8 @@ conf.set_quoted('CATALOG_DATABASE',                           join_paths(catalog
 conf.set_quoted('SYSTEMD_CGROUP_AGENT_PATH',                  join_paths(rootlibexecdir, 'systemd-cgroups-agent'))
 conf.set_quoted('SYSTEMD_BINARY_PATH',                        join_paths(rootlibexecdir, 'systemd'))
 conf.set_quoted('SYSTEMD_FSCK_PATH',                          join_paths(rootlibexecdir, 'systemd-fsck'))
+conf.set_quoted('SYSTEMD_MAKEFS_PATH',                        join_paths(rootlibexecdir, 'systemd-makefs'))
+conf.set_quoted('SYSTEMD_GROWFS_PATH',                        join_paths(rootlibexecdir, 'systemd-growfs'))
 conf.set_quoted('SYSTEMD_SHUTDOWN_BINARY_PATH',               join_paths(rootlibexecdir, 'systemd-shutdown'))
 conf.set_quoted('SYSTEMD_SLEEP_BINARY_PATH',                  join_paths(rootlibexecdir, 'systemd-sleep'))
 conf.set_quoted('SYSTEMCTL_BINARY_PATH',                      join_paths(rootbindir, 'systemctl'))
@@ -260,6 +285,7 @@ foreach arg : ['-Wextra',
                '-Wstrict-prototypes',
                '-Wredundant-decls',
                '-Wmissing-noreturn',
+               '-Wimplicit-fallthrough=5',
                '-Wshadow',
                '-Wendif-labels',
                '-Wstrict-aliasing=2',
@@ -415,6 +441,7 @@ foreach decl : [['IFLA_INET6_ADDR_GEN_MODE',         'linux/if_link.h'],
                 ['IFA_FLAGS',                        'linux/if_addr.h'],
                 ['FRA_UID_RANGE',                    'linux/fib_rules.h'],
                 ['LO_FLAGS_PARTSCAN',                'linux/loop.h'],
+                ['VXCAN_INFO_PEER',                  'linux/can/vxcan.h'],
                ]
         prefix = decl.length() > 2 ? decl[2] : ''
         have = cc.has_header_symbol(decl[1], decl[0], prefix : prefix)
@@ -426,7 +453,8 @@ foreach ident : ['secure_getenv', '__secure_getenv']
 endforeach
 
 foreach ident : [
-        ['memfd_create',      '''#include <sys/memfd.h>'''],
+        ['memfd_create',      '''#define _GNU_SOURCE
+                                 #include <sys/mman.h>'''],
         ['gettid',            '''#include <sys/types.h>'''],
         ['pivot_root',        '''#include <stdlib.h>'''],     # no known header declares pivot_root
         ['name_to_handle_at', '''#define _GNU_SOURCE
@@ -462,7 +490,6 @@ endif
 #####################################################################
 
 sed = find_program('sed')
-grep = find_program('grep')
 awk = find_program('awk')
 m4 = find_program('m4')
 stat = find_program('stat')
@@ -587,9 +614,6 @@ conf.set('SYSTEM_UID_MAX', system_uid_max)
 substs.set('systemuidmax', system_uid_max)
 message('maximum system UID is @0@'.format(system_uid_max))
 
-conf.set_quoted('NOBODY_USER_NAME', get_option('nobody-user'))
-conf.set_quoted('NOBODY_GROUP_NAME', get_option('nobody-group'))
-
 system_gid_max = get_option('system-gid-max')
 if system_gid_max == ''
         system_gid_max = run_command(
@@ -602,10 +626,83 @@ conf.set('SYSTEM_GID_MAX', system_gid_max)
 substs.set('systemgidmax', system_gid_max)
 message('maximum system GID is @0@'.format(system_gid_max))
 
+dynamic_uid_min = get_option('dynamic-uid-min').to_int()
+dynamic_uid_max = get_option('dynamic-uid-max').to_int()
+conf.set('DYNAMIC_UID_MIN', dynamic_uid_min)
+conf.set('DYNAMIC_UID_MAX', dynamic_uid_max)
+substs.set('dynamicuidmin', dynamic_uid_min)
+substs.set('dynamicuidmax', dynamic_uid_max)
+
+container_uid_base_min = get_option('container-uid-base-min').to_int()
+container_uid_base_max = get_option('container-uid-base-max').to_int()
+conf.set('CONTAINER_UID_BASE_MIN', container_uid_base_min)
+conf.set('CONTAINER_UID_BASE_MAX', container_uid_base_max)
+substs.set('containeruidbasemin', container_uid_base_min)
+substs.set('containeruidbasemax', container_uid_base_max)
+
+nobody_user = get_option('nobody-user')
+nobody_group = get_option('nobody-group')
+
+getent_result = run_command('getent', 'passwd', '65534')
+if getent_result.returncode() == 0
+        name = getent_result.stdout().split(':')[0]
+        if name != nobody_user
+                message('WARNING:\n' +
+                        '        The local user with the UID 65534 does not match the configured user name "@0@" of the nobody user (its name is @1@).\n'.format(nobody_user, name) +
+                        '        Your build will result in an user table setup that is incompatible with the local system.')
+        endif
+endif
+id_result = run_command('id', '-u', nobody_user)
+if id_result.returncode() == 0
+        id = id_result.stdout().to_int()
+        if id != 65534
+                message('WARNING:\n' +
+                        '        The local user with the configured user name "@0@" of the nobody user does not have UID 65534 (it has @1@).\n'.format(nobody_user, id) +
+                        '        Your build will result in an user table setup that is incompatible with the local system.')
+        endif
+endif
+
+getent_result = run_command('getent', 'group', '65534')
+if getent_result.returncode() == 0
+        name = getent_result.stdout().split(':')[0]
+        if name != nobody_group
+                message('WARNING:\n' +
+                        '        The local group with the GID 65534 does not match the configured group name "@0@" of the nobody group (its name is @1@).\n'.format(nobody_group, name) +
+                        '        Your build will result in an group table setup that is incompatible with the local system.')
+        endif
+endif
+id_result = run_command('id', '-g', nobody_group)
+if id_result.returncode() == 0
+        id = id_result.stdout().to_int()
+        if id != 65534
+                message('WARNING:\n' +
+                        '        The local group with the configured group name "@0@" of the nobody group does not have UID 65534 (it has @1@).\n'.format(nobody_group, id) +
+                        '        Your build will result in an group table setup that is incompatible with the local system.')
+        endif
+endif
+if nobody_user != nobody_group and not (nobody_user == 'nobody' and nobody_group == 'nogroup')
+        message('WARNING:\n' +
+                '        The configured user name "@0@" and group name "@0@" of the nobody user/group are not equivalent.\n'.format(nobody_user, nobody_group) +
+                '        Please re-check that both "nobody-user" and "nobody-group" options are correctly set.')
+endif
+
+conf.set_quoted('NOBODY_USER_NAME', nobody_user)
+conf.set_quoted('NOBODY_GROUP_NAME', nobody_group)
+substs.set('NOBODY_USER_NAME', nobody_user)
+substs.set('NOBODY_GROUP_NAME', nobody_group)
+
 tty_gid = get_option('tty-gid')
 conf.set('TTY_GID', tty_gid)
 substs.set('TTY_GID', tty_gid)
 
+# Ensure provided GID argument is numeric, otherwise fallback to default assignment
+if get_option('users-gid') != ''
+        users_gid = get_option('users-gid').to_int()
+else
+        users_gid = '-'
+endif
+substs.set('USERS_GID', users_gid)
+
 if get_option('adm-group')
         m4_defines += ['-DENABLE_ADM_GROUP']
 endif
@@ -615,6 +712,7 @@ if get_option('wheel-group')
 endif
 
 substs.set('DEV_KVM_MODE', get_option('dev-kvm-mode'))
+substs.set('GROUP_RENDER_MODE', get_option('group-render-mode'))
 
 kill_user_processes = get_option('default-kill-user-processes')
 conf.set10('KILL_USER_PROCESSES', kill_user_processes)
@@ -1201,10 +1299,10 @@ subdir('src/resolve')
 subdir('src/timedate')
 subdir('src/timesync')
 subdir('src/vconsole')
-subdir('src/sulogin-shell')
 subdir('src/boot/efi')
 
 subdir('src/test')
+subdir('rules')
 subdir('test')
 
 ############################################################
@@ -1235,7 +1333,9 @@ foreach tuple : [['myhostname', 'ENABLE_MYHOSTNAME'],
                         'src/nss-@0@/nss-@0@.c'.format(module),
                         version : '2',
                         include_directories : includes,
-                        link_args : ['-shared',
+                        # Note that we link NSS modules with '-z nodelete' so that mempools never get orphaned
+                        link_args : ['-Wl,-z,nodelete',
+                                     '-shared',
                                      '-Wl,--version-script=' + version_script_arg,
                                      '-Wl,--undefined'],
                         link_with : [libsystemd_internal,
@@ -1909,6 +2009,23 @@ executable('systemd-fsck',
            install : true,
            install_dir : rootlibexecdir)
 
+executable('systemd-growfs',
+           'src/partition/growfs.c',
+           include_directories : includes,
+           link_with : [libshared],
+           dependencies : [libcryptsetup],
+           install_rpath : rootlibexecdir,
+           install : true,
+           install_dir : rootlibexecdir)
+
+executable('systemd-makefs',
+           'src/partition/makefs.c',
+           include_directories : includes,
+           link_with : [libshared],
+           install_rpath : rootlibexecdir,
+           install : true,
+           install_dir : rootlibexecdir)
+
 executable('systemd-sleep',
            'src/sleep/sleep.c',
            include_directories : includes,
@@ -2100,6 +2217,11 @@ if conf.get('ENABLE_TMPFILES') == 1
                          install : true,
                          install_dir : rootbindir)
         public_programs += [exe]
+
+        test('test-systemd-tmpfiles',
+             test_systemd_tmpfiles_py,
+             args : exe.full_path())
+        # https://github.com/mesonbuild/meson/issues/2681
 endif
 
 if conf.get('ENABLE_HWDB') == 1
@@ -2256,6 +2378,15 @@ if conf.get('ENABLE_NETWORKD') == 1
                    install_dir : rootbindir)
         public_programs += [exe]
 endif
+
+executable('systemd-sulogin-shell',
+           ['src/sulogin-shell/sulogin-shell.c'],
+           include_directories : includes,
+           link_with : [libshared],
+           install_rpath : rootlibexecdir,
+           install : true,
+           install_dir : rootlibexecdir)
+
 ############################################################
 
 foreach tuple : tests
@@ -2332,7 +2463,7 @@ subdir('units')
 subdir('sysctl.d')
 subdir('sysusers.d')
 subdir('tmpfiles.d')
-subdir('rules')
+subdir('presets')
 subdir('hwdb')
 subdir('network')
 subdir('man')
@@ -2349,8 +2480,6 @@ install_subdir('factory/etc',
 
 install_data('xorg/50-systemd-user.sh',
              install_dir : xinitrcdir)
-install_data('system-preset/90-systemd.preset',
-             install_dir : systempresetdir)
 install_data('modprobe.d/systemd.conf',
              install_dir : modprobedir)
 install_data('README',
@@ -2428,35 +2557,41 @@ endif
 status = [
         '@0@ @1@'.format(meson.project_name(), meson.project_version()),
 
-        'prefix:                            @0@'.format(prefixdir),
-        'rootprefix:                        @0@'.format(rootprefixdir),
-        'sysconf dir:                       @0@'.format(sysconfdir),
-        'includedir:                        @0@'.format(includedir),
-        'lib dir:                           @0@'.format(libdir),
-        'rootlib dir:                       @0@'.format(rootlibdir),
+        'prefix directory:                  @0@'.format(prefixdir),
+        'rootprefix directory:              @0@'.format(rootprefixdir),
+        'sysconf directory:                 @0@'.format(sysconfdir),
+        'include directory:                 @0@'.format(includedir),
+        'lib directory:                     @0@'.format(libdir),
+        'rootlib directory:                 @0@'.format(rootlibdir),
         'SysV init scripts:                 @0@'.format(sysvinit_path),
         'SysV rc?.d directories:            @0@'.format(sysvrcnd_path),
-        'PAM modules dir:                   @0@'.format(pamlibdir),
-        'PAM configuration dir:             @0@'.format(pamconfdir),
-        'RPM macros dir:                    @0@'.format(rpmmacrosdir),
-        'modprobe.d dir:                    @0@'.format(modprobedir),
-        'D-Bus policy dir:                  @0@'.format(dbuspolicydir),
-        'D-Bus session dir:                 @0@'.format(dbussessionservicedir),
-        'D-Bus system dir:                  @0@'.format(dbussystemservicedir),
-        'bash completions dir:              @0@'.format(bashcompletiondir),
-        'zsh completions dir:               @0@'.format(zshcompletiondir),
+        'PAM modules directory:             @0@'.format(pamlibdir),
+        'PAM configuration directory:       @0@'.format(pamconfdir),
+        'RPM macros directory:              @0@'.format(rpmmacrosdir),
+        'modprobe.d directory:              @0@'.format(modprobedir),
+        'D-Bus policy directory:            @0@'.format(dbuspolicydir),
+        'D-Bus session directory:           @0@'.format(dbussessionservicedir),
+        'D-Bus system directory:            @0@'.format(dbussystemservicedir),
+        'bash completions directory:        @0@'.format(bashcompletiondir),
+        'zsh completions directory:         @0@'.format(zshcompletiondir),
         'extra start script:                @0@'.format(get_option('rc-local')),
         'extra stop script:                 @0@'.format(get_option('halt-local')),
         'debug shell:                       @0@ @ @1@'.format(get_option('debug-shell'),
                                                               get_option('debug-tty')),
         'TTY GID:                           @0@'.format(tty_gid),
+        'users GID:                         @0@'.format(users_gid),
         'maximum system UID:                @0@'.format(system_uid_max),
         'maximum system GID:                @0@'.format(system_gid_max),
+        'minimum dynamic UID:               @0@'.format(dynamic_uid_min),
+        'maximum dynamic UID:               @0@'.format(dynamic_uid_max),
+        'minimum container UID base:        @0@'.format(container_uid_base_min),
+        'maximum container UID base:        @0@'.format(container_uid_base_max),
         '/dev/kvm access mode:              @0@'.format(get_option('dev-kvm-mode')),
-        'certificate root:                  @0@'.format(get_option('certificate-root')),
+        'render group access mode:          @0@'.format(get_option('group-render-mode')),
+        'certificate root directory:        @0@'.format(get_option('certificate-root')),
         'support URL:                       @0@'.format(support_url),
-        'nobody user name:                  @0@'.format(get_option('nobody-user')),
-        'nobody group name:                 @0@'.format(get_option('nobody-group')),
+        'nobody user name:                  @0@'.format(nobody_user),
+        'nobody group name:                 @0@'.format(nobody_group),
         'fallback hostname:                 @0@'.format(get_option('fallback-hostname')),
         'symbolic gateway hostnames:        @0@'.format(', '.join(gateway_hostnames)),
 
@@ -2488,9 +2623,9 @@ if conf.get('ENABLE_EFI') == 1
                 status += [
                         'EFI machine type:                  @0@'.format(EFI_MACHINE_TYPE_NAME),
                         'EFI CC                             @0@'.format(efi_cc),
-                        'EFI libdir:                        @0@'.format(efi_libdir),
-                        'EFI ldsdir:                        @0@'.format(efi_ldsdir),
-                        'EFI includedir:                    @0@'.format(efi_incdir)]
+                        'EFI lib directory:                 @0@'.format(efi_libdir),
+                        'EFI lds directory:                 @0@'.format(efi_ldsdir),
+                        'EFI include directory:             @0@'.format(efi_incdir)]
         endif
 endif
 
@@ -2589,3 +2724,10 @@ status += [
         'disabled features: @0@'.format(', '.join(missing)),
         '']
 message('\n         '.join(status))
+
+if rootprefixdir != rootprefix_default
+        message('WARNING:\n' +
+                '        Note that the installation prefix was changed to "@0@".\n'.format(rootprefixdir) +
+                '        systemd used fixed names for unit file directories and other paths, so anything\n' +
+                '        except the default ("@0@") is strongly discouraged.'.format(rootprefix_default))
+endif
index 6ab841b..4e6e261 100644 (file)
@@ -1,4 +1,20 @@
 # -*- mode: meson -*-
+# SPDX-License-Identifier: LGPL-2.1+
+#
+# Copyright 2017 Zbigniew Jędrzejewski-Szmek
+#
+# 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.
+#
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
 
 option('split-usr', type : 'boolean', value : false,
        description : '''assume that /bin, /sbin aren't symlinks into /usr''')
@@ -131,9 +147,23 @@ option('system-uid-max', type : 'string',
        description : 'maximum system UID')
 option('system-gid-max', type : 'string',
        description : 'maximum system GID')
+option('dynamic-uid-min', type : 'string',
+       description : 'minimum dynamic UID',
+       value : '61184') # That's → 0x0000EF00 in hex
+option('dynamic-uid-max', type : 'string',
+       description : 'maximum dynamic UID',
+       value : '65519') # That's → 0x0000FFEF in hex
+option('container-uid-base-min', type : 'string',
+       description : 'minimum container UID base',
+       value : '524288') # That's → 0x00080000 in hex
+option('container-uid-base-max', type : 'string',
+       description : 'maximum container UID base',
+       value : '1878982656') # That's → 0x6FFF0000 in hex
 option('tty-gid', type : 'string',
        description : 'the numeric GID of the "tty" group',
        value : '5')
+option('users-gid', type : 'string',
+       description : 'the numeric GID of the "users" group')
 option('adm-group', type : 'boolean',
        description : 'the ACL for adm group should be added')
 option('wheel-group', type : 'boolean',
@@ -144,8 +174,10 @@ option('nobody-user', type : 'string',
 option('nobody-group', type : 'string',
        description : 'The name of the nobody group (the one with GID 65534)',
        value : 'nobody')
-option('dev-kvm-mode', type : 'string', value : '0660',
+option('dev-kvm-mode', type : 'string', value : '0666',
        description : '/dev/kvm access mode')
+option('group-render-mode', type : 'string', value : '0666',
+       description : 'Access mode for devices owned by render group (e.g. /dev/dri/renderD*, /dev/kfd).')
 option('default-kill-user-processes', type : 'boolean',
        description : 'the default value for KillUserProcesses= setting')
 option('gshadow', type : 'boolean',
index 92eb55b..0781f0d 100755 (executable)
 # as out-of-tree build dir. Otherwise, let's make up our own builddir.
 [ -z "$BUILDDIR" ] && BUILDDIR=build
 
-export LC_CTYPE=C.UTF-8
+export LC_CTYPE=en_US.UTF-8
 
-[ -f "$BUILDDIR"/build.ninja ] || meson "$BUILDDIR"
+sysvinit_path=`realpath /etc/init.d`
+
+nobody_user=`id -u -n 65534 2> /dev/null`
+if [ "$nobody_user" != "" ] ; then
+        # Validate that we can translate forth and back
+        if [ "`id -u $nobody_user`" != 65534 ] ; then
+                nobody_user=""
+        fi
+fi
+if [ "$nobody_user" = "" ] ; then
+        if id -u nobody 2> /dev/null ; then
+                # The "nobody" user is defined already for something else, pick the Fedora name
+                nobody_user=nfsnobody
+        else
+                # The "nobody" user name is free, use it
+                nobody_user=nobody
+        fi
+fi
+
+nobody_group=`id -g -n 65534 2> /dev/null`
+if [ "$nobody_group" != "" ] ; then
+        # Validate that we can translate forth and back
+        if [ "`id -g $nobody_group`" != 65534 ] ; then
+                nobody_group=""
+        fi
+fi
+if [ "$nobody_group" = "" ] ; then
+        if id -u nobody 2> /dev/null ; then
+                # The "nobody" group is defined already for something else, pick the Fedora name
+                nobody_group=nfsnobody
+        else
+                # The "nobody" group name is free, use it
+                nobody_group=nobody
+        fi
+fi
+
+[ -f "$BUILDDIR"/build.ninja ] || meson "$BUILDDIR" -D "sysvinit-path=$sysvinit_path" -D default-hierarchy=unified -D man=false -D "nobody-user=$nobody_user" -D "nobody-group=$nobody_group"
 ninja -C "$BUILDDIR" all
 [ "$WITH_TESTS" = 0 ] || ninja -C "$BUILDDIR" test || ( RET="$?" ; cat "$BUILDDIR"/meson-logs/testlog.txt ; exit "$RET" )
 ninja -C "$BUILDDIR" install
index d32f3ce..0c4a3ea 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
@@ -12,3 +14,7 @@
 # networkd/NM/etc. Therefore disable bond0 creation.
 
 options bonding max_bonds=0
+
+# Do the same for dummy0.
+
+options dummy numdummies=0
index b012cf9..44c59b7 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index ac796bf..8a8df2f 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 3d532d6..4d4482b 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 79538f9..561bf32 100644 (file)
@@ -1,3 +1,12 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
+#  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.
+
 [Link]
 NamePolicy=kernel database onboard slot path
 MACAddressPolicy=persistent
index 4c33e45..fb17e16 100644 (file)
@@ -1,3 +1,20 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
+# Copyright 2017 Zbigniew Jędrzejewski-Szmek
+#
+# 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.
+#
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
 if conf.get('ENABLE_NETWORKD') == 1
         install_data('80-container-host0.network',
                      '80-container-ve.network',
index 02c4d30..b6fb67a 100644 (file)
@@ -48,7 +48,7 @@
                DESTDIR=%{buildroot} %{__ninja} install %{__ninja_common_opts}
 
 Name:           systemd
-Version:        235
+Version:        236
 Release:        0%{?release_flags}
 # For a breakdown of the licensing, see README
 License:        LGPL-2.1+ and GPL-2.0+
@@ -308,6 +308,9 @@ rm -rf %{buildroot}/%{_prefix}/lib/systemd/system/multi-user.target.wants/system
 rm -rf %{buildroot}/%{_prefix}/lib/systemd/system/systemd-tmpfiles-clean.timer
 rm -rf %{buildroot}/%{_prefix}/lib/systemd/system/systemd-tmpfiles-clean.service
 rm -rf %{buildroot}/%{_prefix}/lib/systemd/system/timers.target.wants/systemd-tmpfiles-clean.timer
+rm -rf %{buildroot}/%{_prefix}/lib/systemd/user/systemd-tmpfiles-clean.timer
+rm -rf %{buildroot}/%{_prefix}/lib/systemd/user/systemd-tmpfiles-clean.service
+rm -rf %{buildroot}/%{_prefix}/lib/systemd/user/systemd-tmpfiles-setup.service
 
 # Exclude ELF binaries
 rm -f %{buildroot}/%{_prefix}/lib/systemd/system-generators/systemd-debug-generator
@@ -574,6 +577,7 @@ fi
 %exclude %{_prefix}/lib/systemd/user/graphical-session-pre.target
 %{_prefix}/lib/systemd/network/99-default.link
 %exclude %{_prefix}/lib/systemd/system-preset/90-systemd.preset
+%exclude %{_prefix}/lib/systemd/user-preset/90-systemd.preset
 %{_prefix}/lib/systemd/user/delayed.target
 %{_prefix}/lib/systemd/user/user-delayed-target-trigger.service
 %{_prefix}/lib/systemd/user/default.target.wants/user-delayed-target-trigger.service
index 2f60eb2..ce8f122 100644 (file)
--- a/po/be.po
+++ b/po/be.po
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
 # Belarusian translation for systemd.
 # Copyright (C) 2015 systemd's COPYRIGHT HOLDER
 # This file is distributed under the same license as the systemd package.
index 121696a..36eb347 100644 (file)
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
 # Belarusian translation for systemd.
 # Copyright (C) 2015 systemd's COPYRIGHT HOLDER
 # This file is distributed under the same license as the systemd package.
index 5f92f8e..b395cc2 100644 (file)
--- a/po/bg.po
+++ b/po/bg.po
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
 # Bulgarian translation of systemd po-file.
 # Copyright (C) 2016 Alexander Shopov <ash@kambanaria.org>
 # This file is distributed under the same license as the systemd package.
index 30fdea0..a625dd6 100644 (file)
--- a/po/ca.po
+++ b/po/ca.po
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
 # Catalan translation for systemd.
 # Copyright (C) 2015 systemd's COPYRIGHT HOLDER
 # This file is distributed under the same license as the systemd package.
index 9622c71..332dc3c 100644 (file)
--- a/po/cs.po
+++ b/po/cs.po
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
 # Czech translation for systemd.
 # Copyright (C) 2016-2017 systemd's author and translators.
 # This file is distributed under the same license as the systemd package.
@@ -9,16 +11,16 @@ msgstr ""
 "Project-Id-Version: systemd master\n"
 "Report-Msgid-Bugs-To: https://github.com/systemd/systemd/issues\n"
 "POT-Creation-Date: 2016-04-23 14:24+0200\n"
-"PO-Revision-Date: 2017-04-20 23:00+0200\n"
+"PO-Revision-Date: 2017-10-10 19:54+0200\n"
 "Last-Translator: Daniel Rusek <mail@asciiwolf.com>\n"
 "Language: cs\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n"
-"%100>=20) ? 1 : 2);\n"
+"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? "
+"1 : 2);\n"
 "Language-Team: \n"
-"X-Generator: Poedit 1.8.7.1\n"
+"X-Generator: Poedit 2.0.3\n"
 
 #: ../src/core/org.freedesktop.systemd1.policy.in.in.h:1
 msgid "Send passphrase back to system"
@@ -50,11 +52,8 @@ msgstr "Nastavit nebo rušit proměnné správce systému a služeb"
 
 #: ../src/core/org.freedesktop.systemd1.policy.in.in.h:8
 msgid ""
-"Authentication is required to set or unset system and service manager environment "
-"variables."
-msgstr ""
-"Pro nastavení nebo rušení proměnných správce systému a služeb je vyžadováno "
-"ověření."
+"Authentication is required to set or unset system and service manager environment variables."
+msgstr "Pro nastavení nebo rušení proměnných správce systému a služeb je vyžadováno ověření."
 
 #: ../src/core/org.freedesktop.systemd1.policy.in.in.h:9
 msgid "Reload the systemd state"
@@ -78,11 +77,11 @@ msgstr "Nastavit statický název stoje"
 
 #: ../src/hostname/org.freedesktop.hostname1.policy.in.h:4
 msgid ""
-"Authentication is required to set the statically configured local host name, as "
-"well as the pretty host name."
+"Authentication is required to set the statically configured local host name, as well as the "
+"pretty host name."
 msgstr ""
-"Pro nastavení staticky konfigurovaného názvu lokálního stroje, stejně tak pro "
-"změnu uživatelsky přívětivého jména je vyžadováno ověření."
+"Pro nastavení staticky konfigurovaného názvu lokálního stroje, stejně tak pro změnu "
+"uživatelsky přívětivého jména je vyžadováno ověření."
 
 #: ../src/hostname/org.freedesktop.hostname1.policy.in.h:5
 msgid "Set machine information"
@@ -169,10 +168,8 @@ msgid "Allow applications to inhibit automatic system suspend"
 msgstr "Povolit aplikacím zakázat automatické vypnutí systému"
 
 #: ../src/login/org.freedesktop.login1.policy.in.h:10
-msgid ""
-"Authentication is required for an application to inhibit automatic system suspend."
-msgstr ""
-"Pro povolení aplikacím zakázat automatické vypnutí systému je vyžadováno ověření."
+msgid "Authentication is required for an application to inhibit automatic system suspend."
+msgstr "Pro povolení aplikacím zakázat automatické vypnutí systému je vyžadováno ověření."
 
 #: ../src/login/org.freedesktop.login1.policy.in.h:11
 msgid "Allow applications to inhibit system handling of the power key"
@@ -180,8 +177,7 @@ msgstr "Povolit aplikacím zakázat chovaní systému na stisknutí vypínacího
 
 #: ../src/login/org.freedesktop.login1.policy.in.h:12
 msgid ""
-"Authentication is required for an application to inhibit system handling of the "
-"power key."
+"Authentication is required for an application to inhibit system handling of the power key."
 msgstr ""
 "Pro povolení aplikacím zakázat chovaní systému na stisknutí vypínacího tlačítka je "
 "vyžadováno ověření."
@@ -192,8 +188,7 @@ msgstr "Povolit aplikacím zakázat chovaní systému na stisknutí uspávacího
 
 #: ../src/login/org.freedesktop.login1.policy.in.h:14
 msgid ""
-"Authentication is required for an application to inhibit system handling of the "
-"suspend key."
+"Authentication is required for an application to inhibit system handling of the suspend key."
 msgstr ""
 "Pro povolení aplikacím zakázat chovaní systému na stisknutí uspávacího tlačítka je "
 "vyžadováno ověření."
@@ -204,11 +199,11 @@ msgstr "Povolit aplikacím zakázat chovaní systému na stisknutí tlačítka h
 
 #: ../src/login/org.freedesktop.login1.policy.in.h:16
 msgid ""
-"Authentication is required for an application to inhibit system handling of the "
-"hibernate key."
+"Authentication is required for an application to inhibit system handling of the hibernate "
+"key."
 msgstr ""
-"Pro povolení aplikacím zakázat chovaní systému na stisknutí tlačítka hibernace je "
-"vyžadováno ověření."
+"Pro povolení aplikacím zakázat chovaní systému na stisknutí tlačítka hibernace je vyžadováno "
+"ověření."
 
 #: ../src/login/org.freedesktop.login1.policy.in.h:17
 msgid "Allow applications to inhibit system handling of the lid switch"
@@ -216,11 +211,8 @@ msgstr "Povolit aplikacím zakázat chovaní systému na zavření víka"
 
 #: ../src/login/org.freedesktop.login1.policy.in.h:18
 msgid ""
-"Authentication is required for an application to inhibit system handling of the "
-"lid switch."
-msgstr ""
-"Pro povolení aplikacím zakázat chovaní systému na zavření víka je vyžadováno "
-"ověření."
+"Authentication is required for an application to inhibit system handling of the lid switch."
+msgstr "Pro povolení aplikacím zakázat chovaní systému na zavření víka je vyžadováno ověření."
 
 #: ../src/login/org.freedesktop.login1.policy.in.h:19
 msgid "Allow non-logged-in user to run programs"
@@ -228,8 +220,7 @@ msgstr "Povolit nepřihlášenému uživateli spouštět programy"
 
 #: ../src/login/org.freedesktop.login1.policy.in.h:20
 msgid "Explicit request is required to run programs as a non-logged-in user."
-msgstr ""
-"Ke spuštění programů jako nepřihlášený uživatel je třeba speciální požadavek."
+msgstr "Ke spuštění programů jako nepřihlášený uživatel je třeba speciální požadavek."
 
 #: ../src/login/org.freedesktop.login1.policy.in.h:21
 msgid "Allow non-logged-in users to run programs"
@@ -253,9 +244,7 @@ msgstr "Odstranit přiřazení zařízení ke stanovištím"
 
 #: ../src/login/org.freedesktop.login1.policy.in.h:26
 msgid "Authentication is required for resetting how devices are attached to seats."
-msgstr ""
-"Pro reset způsobu jak jsou zařízení přiřazována ke stanovištím je vyžadováno "
-"ověření."
+msgstr "Pro reset způsobu jak jsou zařízení přiřazována ke stanovištím je vyžadováno ověření."
 
 #: ../src/login/org.freedesktop.login1.policy.in.h:27
 msgid "Power off the system"
@@ -270,11 +259,8 @@ msgid "Power off the system while other users are logged in"
 msgstr "Vypnout systém, i když jsou přihlášeni další uživatelé"
 
 #: ../src/login/org.freedesktop.login1.policy.in.h:30
-msgid ""
-"Authentication is required for powering off the system while other users are "
-"logged in."
-msgstr ""
-"Pro vypnutí systému, když jsou přihlášeni další uživatelé je vyžadováno ověření."
+msgid "Authentication is required for powering off the system while other users are logged in."
+msgstr "Pro vypnutí systému, když jsou přihlášeni další uživatelé je vyžadováno ověření."
 
 #: ../src/login/org.freedesktop.login1.policy.in.h:31
 msgid "Power off the system while an application asked to inhibit it"
@@ -282,10 +268,9 @@ msgstr "Vypnout systém, i když aplikace požádala o zákaz vypnutí"
 
 #: ../src/login/org.freedesktop.login1.policy.in.h:32
 msgid ""
-"Authentication is required for powering off the system while an application asked "
-"to inhibit it."
-msgstr ""
-"Pro vypnutí systému, když aplikace požádala o zákaz vypnutí je vyžadováno ověření."
+"Authentication is required for powering off the system while an application asked to inhibit "
+"it."
+msgstr "Pro vypnutí systému, když aplikace požádala o zákaz vypnutí je vyžadováno ověření."
 
 #: ../src/login/org.freedesktop.login1.policy.in.h:33
 msgid "Reboot the system"
@@ -300,12 +285,8 @@ msgid "Reboot the system while other users are logged in"
 msgstr "Restartovat systém, i když jsou přihlášeni další uživatelé"
 
 #: ../src/login/org.freedesktop.login1.policy.in.h:36
-msgid ""
-"Authentication is required for rebooting the system while other users are logged "
-"in."
-msgstr ""
-"Pro restartování systému, když jsou přihlášeni další uživatelé je vyžadováno "
-"ověření."
+msgid "Authentication is required for rebooting the system while other users are logged in."
+msgstr "Pro restartování systému, když jsou přihlášeni další uživatelé je vyžadováno ověření."
 
 #: ../src/login/org.freedesktop.login1.policy.in.h:37
 msgid "Reboot the system while an application asked to inhibit it"
@@ -313,104 +294,116 @@ msgstr "Restartovat systém, i když aplikace požádala o zákaz restartu"
 
 #: ../src/login/org.freedesktop.login1.policy.in.h:38
 msgid ""
-"Authentication is required for rebooting the system while an application asked to "
-"inhibit it."
+"Authentication is required for rebooting the system while an application asked to inhibit it."
 msgstr ""
-"Pro restartování systému, když aplikace požádala o zákaz restartu je vyžadováno "
-"ověření."
+"Pro restartování systému, když aplikace požádala o zákaz restartu je vyžadováno ověření."
 
 #: ../src/login/org.freedesktop.login1.policy.in.h:39
+msgid "Halt the system"
+msgstr "Zastavit systém"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:40
+msgid "Authentication is required for halting the system."
+msgstr "Pro zastavení systému je vyžadováno ověření."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:41
+msgid "Halt the system while other users are logged in"
+msgstr "Zastavit systém, i když jsou přihlášeni další uživatelé"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:42
+msgid "Authentication is required for halting the system while other users are logged in."
+msgstr "Pro zastavení systému, když jsou přihlášeni další uživatelé je vyžadováno ověření."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:43
+msgid "Halt the system while an application asked to inhibit it"
+msgstr "Zastavit systém, i když aplikace požádala o zákaz zastavení"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:44
+msgid ""
+"Authentication is required for halting the system while an application asked to inhibit it."
+msgstr "Pro zastavení systému, když aplikace požádala o zákaz zastavení je vyžadováno ověření."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:45
 msgid "Suspend the system"
 msgstr "Uspat systém"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:40
+#: ../src/login/org.freedesktop.login1.policy.in.h:46
 msgid "Authentication is required for suspending the system."
 msgstr "Pro uspání systému je vyžadováno ověření."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:41
+#: ../src/login/org.freedesktop.login1.policy.in.h:47
 msgid "Suspend the system while other users are logged in"
 msgstr "Uspat systém, i když jsou přihlášeni další uživatelé"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:42
-msgid ""
-"Authentication is required for suspending the system while other users are logged "
-"in."
-msgstr ""
-"Pro uspání systému, když jsou přihlášeni další uživatelé je vyžadováno ověření."
+#: ../src/login/org.freedesktop.login1.policy.in.h:48
+msgid "Authentication is required for suspending the system while other users are logged in."
+msgstr "Pro uspání systému, když jsou přihlášeni další uživatelé je vyžadováno ověření."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:43
+#: ../src/login/org.freedesktop.login1.policy.in.h:49
 msgid "Suspend the system while an application asked to inhibit it"
 msgstr "Uspat systém, i když aplikace požádala o zákaz uspání"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:44
+#: ../src/login/org.freedesktop.login1.policy.in.h:50
 msgid ""
-"Authentication is required for suspending the system while an application asked to "
-"inhibit it."
-msgstr ""
-"Pro uspání systému, když aplikace požádala o zákaz uspání je vyžadováno ověření."
+"Authentication is required for suspending the system while an application asked to inhibit "
+"it."
+msgstr "Pro uspání systému, když aplikace požádala o zákaz uspání je vyžadováno ověření."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:45
+#: ../src/login/org.freedesktop.login1.policy.in.h:51
 msgid "Hibernate the system"
 msgstr "Hibernovat systém"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:46
+#: ../src/login/org.freedesktop.login1.policy.in.h:52
 msgid "Authentication is required for hibernating the system."
 msgstr "Pro hibernaci systému je vyžadováno ověření."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:47
+#: ../src/login/org.freedesktop.login1.policy.in.h:53
 msgid "Hibernate the system while other users are logged in"
 msgstr "Hibernovat systém, i když jsou přihlášeni další uživatelé"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:48
-msgid ""
-"Authentication is required for hibernating the system while other users are logged "
-"in."
-msgstr ""
-"Pro hibernaci systému, když jsou přihlášeni další uživatelé je vyžadováno ověření."
+#: ../src/login/org.freedesktop.login1.policy.in.h:54
+msgid "Authentication is required for hibernating the system while other users are logged in."
+msgstr "Pro hibernaci systému, když jsou přihlášeni další uživatelé je vyžadováno ověření."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:49
+#: ../src/login/org.freedesktop.login1.policy.in.h:55
 msgid "Hibernate the system while an application asked to inhibit it"
 msgstr "Hibernovat systém, i když aplikace požádala o zákaz hibernace"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:50
+#: ../src/login/org.freedesktop.login1.policy.in.h:56
 msgid ""
-"Authentication is required for hibernating the system while an application asked "
-"to inhibit it."
-msgstr ""
-"Pro hibernaci systému, když aplikace požádala o zákaz hibernace je vyžadováno "
-"ověření."
+"Authentication is required for hibernating the system while an application asked to inhibit "
+"it."
+msgstr "Pro hibernaci systému, když aplikace požádala o zákaz hibernace je vyžadováno ověření."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:51
+#: ../src/login/org.freedesktop.login1.policy.in.h:57
 msgid "Manage active sessions, users and seats"
 msgstr "Spravovat aktivní sezení, uživatele a stanoviště"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:52
+#: ../src/login/org.freedesktop.login1.policy.in.h:58
 msgid "Authentication is required for managing active sessions, users and seats."
 msgstr "Pro správu aktivních sezení, uživatelů a stanovišť je vyžadováno ověření."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:53
+#: ../src/login/org.freedesktop.login1.policy.in.h:59
 msgid "Lock or unlock active sessions"
 msgstr "Zamknout nebo odemknout aktivní sezení"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:54
+#: ../src/login/org.freedesktop.login1.policy.in.h:60
 msgid "Authentication is required to lock or unlock active sessions."
 msgstr "Pro zamčení nebo odemčení aktivních sezení je vyžadováno ověření."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:55
+#: ../src/login/org.freedesktop.login1.policy.in.h:61
 msgid "Allow indication to the firmware to boot to setup interface"
 msgstr "Povolit indikaci firmwaru bootovat instalační prostředí"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:56
-msgid ""
-"Authentication is required to indicate to the firmware to boot to setup interface."
-msgstr ""
-"K povolení indikace firmwaru bootovat instalační prostředí je vyžadováno ověření."
+#: ../src/login/org.freedesktop.login1.policy.in.h:62
+msgid "Authentication is required to indicate to the firmware to boot to setup interface."
+msgstr "K povolení indikace firmwaru bootovat instalační prostředí je vyžadováno ověření."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:57
+#: ../src/login/org.freedesktop.login1.policy.in.h:63
 msgid "Set a wall message"
 msgstr "Nastavit zprávu všem uživatelům"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:58
+#: ../src/login/org.freedesktop.login1.policy.in.h:64
 msgid "Authentication is required to set a wall message"
 msgstr "K nastavení zprávy všem uživatelům je vyžadováno ověření"
 
@@ -475,10 +468,8 @@ msgid "Manage local virtual machine and container images"
 msgstr "Spravovat lokální obrazy virtuálních strojů a kontejnerů"
 
 #: ../src/machine/org.freedesktop.machine1.policy.in.h:16
-msgid ""
-"Authentication is required to manage local virtual machine and container images."
-msgstr ""
-"Pro správu obrazů lokálních virtuálních strojů a kontejnerů je vyžadováno ověření."
+msgid "Authentication is required to manage local virtual machine and container images."
+msgstr "Pro správu obrazů lokálních virtuálních strojů a kontejnerů je vyžadováno ověření."
 
 #: ../src/timedate/org.freedesktop.timedate1.policy.in.h:1
 msgid "Set system time"
@@ -501,11 +492,9 @@ msgid "Set RTC to local timezone or UTC"
 msgstr "Nastavit RTC na lokální časovou zónu nebo UTC"
 
 #: ../src/timedate/org.freedesktop.timedate1.policy.in.h:6
-msgid ""
-"Authentication is required to control whether the RTC stores the local or UTC time."
+msgid "Authentication is required to control whether the RTC stores the local or UTC time."
 msgstr ""
-"Pro kontrolu jestli RTC ukládá lokální časovou zónu nebo UTC čas je vyžadováno "
-"ověření."
+"Pro kontrolu jestli RTC ukládá lokální časovou zónu nebo UTC čas je vyžadováno ověření."
 
 #: ../src/timedate/org.freedesktop.timedate1.policy.in.h:7
 msgid "Turn network time synchronization on or off"
@@ -513,34 +502,33 @@ msgstr "Zapnout nebo vypnout synchronizaci s časem ze sítě"
 
 #: ../src/timedate/org.freedesktop.timedate1.policy.in.h:8
 msgid ""
-"Authentication is required to control whether network time synchronization shall "
-"be enabled."
+"Authentication is required to control whether network time synchronization shall be enabled."
 msgstr "Pro kontrolu synchronizace času ze sítě je vyžadováno ověření."
 
-#: ../src/core/dbus-unit.c:459
+#: ../src/core/dbus-unit.c:458
 msgid "Authentication is required to start '$(unit)'."
 msgstr "Pro spuštění „$(unit)” je vyžadováno ověření."
 
-#: ../src/core/dbus-unit.c:460
+#: ../src/core/dbus-unit.c:459
 msgid "Authentication is required to stop '$(unit)'."
 msgstr "Pro vypnutí „$(unit)” je vyžadováno ověření."
 
-#: ../src/core/dbus-unit.c:461
+#: ../src/core/dbus-unit.c:460
 msgid "Authentication is required to reload '$(unit)'."
 msgstr "Pro znovu načtení „$(unit)” je vyžadováno ověření."
 
-#: ../src/core/dbus-unit.c:462 ../src/core/dbus-unit.c:463
+#: ../src/core/dbus-unit.c:461 ../src/core/dbus-unit.c:462
 msgid "Authentication is required to restart '$(unit)'."
 msgstr "Pro restart „$(unit)” je vyžadováno ověření."
 
-#: ../src/core/dbus-unit.c:570
+#: ../src/core/dbus-unit.c:569
 msgid "Authentication is required to kill '$(unit)'."
 msgstr "Pro ukončení „$(unit)” je vyžadováno ověření."
 
-#: ../src/core/dbus-unit.c:601
+#: ../src/core/dbus-unit.c:600
 msgid "Authentication is required to reset the \"failed\" state of '$(unit)'."
 msgstr "Pro resetování chybného stavu „$(unit)” je vyžadováno ověření."
 
-#: ../src/core/dbus-unit.c:634
+#: ../src/core/dbus-unit.c:633
 msgid "Authentication is required to set properties on '$(unit)'."
 msgstr "Pro nastavení vlastností na „$(unit)” je vyžadováno ověření."
index a5be579..187103c 100644 (file)
--- a/po/da.po
+++ b/po/da.po
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
 # Danish translation for systemd.
 # Copyright (C) 2014 systemd's COPYRIGHT HOLDER
 # This file is distributed under the same license as the systemd package.
index 72075e8..bb431fe 100644 (file)
--- a/po/de.po
+++ b/po/de.po
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
 # German translation for systemd.
 # Copyright (C) 2014 systemd's COPYRIGHT HOLDER
 # This file is distributed under the same license as the systemd package.
index 94c9986..0e7db7f 100644 (file)
--- a/po/el.po
+++ b/po/el.po
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
 # Greek translation for systemd.
 # Copyright (C) 2014 systemd's COPYRIGHT HOLDER
 # This file is distributed under the same license as the systemd package.
index 6642351..705a47e 100644 (file)
--- a/po/es.po
+++ b/po/es.po
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
 # Spanish translation for systemd.
 # Copyright (C) 2015 systemd's COPYRIGHT HOLDER
 # This file is distributed under the same license as the systemd package.
index 17550c7..c300774 100644 (file)
--- a/po/fr.po
+++ b/po/fr.po
@@ -1,14 +1,16 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
 # French translations for systemd package
 # Traductions françaises du paquet systemd.
 # This file is distributed under the same license as the systemd package.
-# Sylvain Plantefève <sylvain.plantefeve@gmail.com>, 2013-2016
+# Sylvain Plantefève <sylvain.plantefeve@gmail.com>, 2013-2017
 #
 msgid ""
 msgstr ""
 "Project-Id-Version: systemd\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2016-04-24 21:13+0200\n"
-"PO-Revision-Date: 2014-12-28 13:04+0100\n"
+"PO-Revision-Date: 2017-10-18 21:30+0200\n"
 "Last-Translator: Sylvain Plantefève <sylvain.plantefeve@gmail.com>\n"
 "Language-Team: French\n"
 "Language: fr\n"
@@ -358,19 +360,53 @@ msgstr ""
 "a demandé de l'empêcher."
 
 #: ../src/login/org.freedesktop.login1.policy.in.h:39
+msgid "Halt the system"
+msgstr "Arrêter le système"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:40
+msgid "Authentication is required for halting the system."
+msgstr "Authentification requise pour arrêter le système."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:41
+msgid "Halt the system while other users are logged in"
+msgstr ""
+"Arrêter le système alors que d'autres utilisateurs sont connectés"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:42
+msgid ""
+"Authentication is required for halting the system while other users are "
+"logged in."
+msgstr ""
+"Authentification requise pour arrêter le système alors que d'autres "
+"utilisateurs sont connectés."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:43
+msgid "Halt the system while an application asked to inhibit it"
+msgstr ""
+"Arrêter le système alors qu'une application a demandé de l'empêcher"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:44
+msgid ""
+"Authentication is required for halting the system while an application "
+"asked to inhibit it."
+msgstr ""
+"Authentification requise pour arrêter le système alors qu'une "
+"application a demandé de l'empêcher."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:45
 msgid "Suspend the system"
 msgstr "Mettre le système en veille"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:40
+#: ../src/login/org.freedesktop.login1.policy.in.h:46
 msgid "Authentication is required for suspending the system."
 msgstr "Authentification requise pour mettre le système en veille."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:41
+#: ../src/login/org.freedesktop.login1.policy.in.h:47
 msgid "Suspend the system while other users are logged in"
 msgstr ""
 "Mettre le système en veille alors que d'autres utilisateurs sont connectés"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:42
+#: ../src/login/org.freedesktop.login1.policy.in.h:48
 msgid ""
 "Authentication is required for suspending the system while other users are "
 "logged in."
@@ -378,12 +414,12 @@ msgstr ""
 "Authentification requise pour mettre le système en veille alors que d'autres "
 "utilisateurs sont connectés."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:43
+#: ../src/login/org.freedesktop.login1.policy.in.h:49
 msgid "Suspend the system while an application asked to inhibit it"
 msgstr ""
 "Mettre le système en veille alors qu'une application a demandé de l'empêcher"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:44
+#: ../src/login/org.freedesktop.login1.policy.in.h:50
 msgid ""
 "Authentication is required for suspending the system while an application "
 "asked to inhibit it."
@@ -391,21 +427,21 @@ msgstr ""
 "Authentification requise pour mettre le système en veille alors qu'une "
 "application a demandé de l'empêcher."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:45
+#: ../src/login/org.freedesktop.login1.policy.in.h:51
 msgid "Hibernate the system"
 msgstr "Mettre le système en hibernation"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:46
+#: ../src/login/org.freedesktop.login1.policy.in.h:52
 msgid "Authentication is required for hibernating the system."
 msgstr "Authentification requise pour mettre le système en hibernation."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:47
+#: ../src/login/org.freedesktop.login1.policy.in.h:53
 msgid "Hibernate the system while other users are logged in"
 msgstr ""
 "Mettre le système en hibernation alors que d'autres utilisateurs sont "
 "connectés"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:48
+#: ../src/login/org.freedesktop.login1.policy.in.h:54
 msgid ""
 "Authentication is required for hibernating the system while other users are "
 "logged in."
@@ -413,13 +449,13 @@ msgstr ""
 "Authentification requise pour mettre le système en hibernation alors que "
 "d'autres utilisateurs sont connectés."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:49
+#: ../src/login/org.freedesktop.login1.policy.in.h:55
 msgid "Hibernate the system while an application asked to inhibit it"
 msgstr ""
 "Mettre le système en hibernation alors qu'une application a demandé de "
 "l'empêcher"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:50
+#: ../src/login/org.freedesktop.login1.policy.in.h:56
 msgid ""
 "Authentication is required for hibernating the system while an application "
 "asked to inhibit it."
@@ -427,34 +463,34 @@ msgstr ""
 "Authentification requise pour mettre le système en hibernation alors qu'une "
 "application a demandé de l'empêcher."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:51
+#: ../src/login/org.freedesktop.login1.policy.in.h:57
 msgid "Manage active sessions, users and seats"
 msgstr "Gérer les sessions actives, les utilisateurs et les postes (seats)"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:52
+#: ../src/login/org.freedesktop.login1.policy.in.h:58
 msgid ""
 "Authentication is required for managing active sessions, users and seats."
 msgstr ""
 "Authentification requise pour gérer les sessions actives, les utilisateurs "
 "et les postes (seats)."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:53
+#: ../src/login/org.freedesktop.login1.policy.in.h:59
 msgid "Lock or unlock active sessions"
 msgstr "Verrouiller ou déverrouiller des sessions actives"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:54
+#: ../src/login/org.freedesktop.login1.policy.in.h:60
 msgid "Authentication is required to lock or unlock active sessions."
 msgstr ""
 "Authentification requise pour verrouiller ou déverrouiller des sessions "
 "actives."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:55
+#: ../src/login/org.freedesktop.login1.policy.in.h:61
 msgid "Allow indication to the firmware to boot to setup interface"
 msgstr ""
 "Permet d'indiquer au micrologiciel de démarrer sur l'interface de "
 "configuration"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:56
+#: ../src/login/org.freedesktop.login1.policy.in.h:62
 msgid ""
 "Authentication is required to indicate to the firmware to boot to setup "
 "interface."
@@ -462,11 +498,11 @@ msgstr ""
 "Authentification requise pour indiquer au micrologiciel de démarrer sur "
 "l'interface de configuration."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:57
+#: ../src/login/org.freedesktop.login1.policy.in.h:63
 msgid "Set a wall message"
 msgstr "Définir un message wall"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:58
+#: ../src/login/org.freedesktop.login1.policy.in.h:64
 msgid "Authentication is required to set a wall message"
 msgstr "Authentification requise pour définir un message wall."
 
@@ -591,33 +627,33 @@ msgstr ""
 "Authentification requise pour activer ou désactiver la synchronisation de "
 "l'heure avec le réseau."
 
-#: ../src/core/dbus-unit.c:450
+#: ../src/core/dbus-unit.c:458
 msgid "Authentication is required to start '$(unit)'."
 msgstr "Authentification requise pour démarrer « $(unit) »."
 
-#: ../src/core/dbus-unit.c:451
+#: ../src/core/dbus-unit.c:459
 msgid "Authentication is required to stop '$(unit)'."
 msgstr "Authentification requise pour arrêter « $(unit) »."
 
-#: ../src/core/dbus-unit.c:452
+#: ../src/core/dbus-unit.c:460
 msgid "Authentication is required to reload '$(unit)'."
 msgstr "Authentification requise pour recharger « $(unit) »."
 
-#: ../src/core/dbus-unit.c:453 ../src/core/dbus-unit.c:454
+#: ../src/core/dbus-unit.c:461 ../src/core/dbus-unit.c:462
 msgid "Authentication is required to restart '$(unit)'."
 msgstr "Authentification requise pour redémarrer « $(unit) »."
 
-#: ../src/core/dbus-unit.c:560
+#: ../src/core/dbus-unit.c:569
 msgid "Authentication is required to kill '$(unit)'."
 msgstr "Authentification requise pour tuer « $(unit) »."
 
-#: ../src/core/dbus-unit.c:590
+#: ../src/core/dbus-unit.c:600
 msgid "Authentication is required to reset the \"failed\" state of '$(unit)'."
 msgstr ""
 "Authentification requise pour réinitialiser l'état d'« échec » de "
 "« $(unit) »."
 
-#: ../src/core/dbus-unit.c:622
+#: ../src/core/dbus-unit.c:633
 msgid "Authentication is required to set properties on '$(unit)'."
 msgstr "Authentification requise pour définir des propriétés de « $(unit) »."
 
index 59d92e1..92000f5 100644 (file)
--- a/po/gl.po
+++ b/po/gl.po
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
 # Copyright (C) 2015
 # This file is distributed under the same license as the systemd package.
 # Fran Dieguez <frandieguez@gnome.org>, 2015.
index e98e88a..2f282cd 100644 (file)
--- a/po/hr.po
+++ b/po/hr.po
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
 # SOME DESCRIPTIVE TITLE.
 # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
 # This file is distributed under the same license as the PACKAGE package.
index b929217..77b7a00 100644 (file)
--- a/po/hu.po
+++ b/po/hu.po
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
 # Hungarian translation of systemd
 # Copyright (C) 2015, 2016. Free Software Foundation, Inc.
 # This file is distributed under the same license as the systemd package.
index 72eb94c..f7860e6 100644 (file)
--- a/po/id.po
+++ b/po/id.po
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
 # Indonesian translation for systemd.
 # Copyright (C) 2014 systemd's COPYRIGHT HOLDER
 # This file is distributed under the same license as the systemd package.
index 7afa5c3..0ce4859 100644 (file)
--- a/po/it.po
+++ b/po/it.po
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
 # Italian translations for systemd package
 # Traduzione in italiano per il pacchetto systemd
 # This file is distributed under the same license as the systemd package.
diff --git a/po/its/polkit.its b/po/its/polkit.its
new file mode 100644 (file)
index 0000000..1c37e6b
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<its:rules xmlns:its="http://www.w3.org/2005/11/its"
+           version="2.0">
+  <its:translateRule selector="//*" translate="no"/>
+  <its:translateRule selector="//action/description |
+                               //action/message"
+                     translate="yes"/>
+</its:rules>
diff --git a/po/its/polkit.loc b/po/its/polkit.loc
new file mode 100644 (file)
index 0000000..c7427ec
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<locatingRules>
+  <locatingRule name="polkit policy" pattern="*.policy">
+    <documentRule localName="policyconfig" target="polkit.its"/>
+  </locatingRule>
+</locatingRules>
index e78ad2e..7a1e9e1 100644 (file)
--- a/po/ko.po
+++ b/po/ko.po
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
 # Korean translation for the systemd.
 # Copyright (C) 2015 systemd author and translators.
 # This file is distributed under the same license as the systemd package.
index f89291b..7ba08fb 100644 (file)
@@ -1,12 +1,21 @@
-i18n = import('i18n')
-i18n.gettext(meson.project_name())
+# SPDX-License-Identifier: LGPL-2.1+
+#
+# Copyright 2017 Zbigniew Jędrzejewski-Szmek
+#
+# 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.
+#
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
 
-#####################################################################
+i18n = import('i18n')
+i18n.gettext(meson.project_name(), preset: 'glib')
 
-intltool_merge = find_program('intltool-merge')
 po_dir = meson.current_source_dir()
-
-intltool_cache = join_paths(meson.current_build_dir(), 'intltool-merge-cache')
-intltool_command = [intltool_merge, '-x', '-u',
-                    '-c', intltool_cache,
-                    po_dir, '@INPUT@', '@OUTPUT@']
index c289a2c..2e9d134 100644 (file)
--- a/po/pl.po
+++ b/po/pl.po
@@ -1,15 +1,17 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
 # Polish translation for systemd.
-# Copyright © 2011-2016 the systemd authors.
+# Copyright © 2011-2017 the systemd authors.
 # This file is distributed under the same license as the systemd package.
-# Piotr Drąg <piotrdrag@gmail.com>, 2011, 2013-2016.
+# Piotr Drąg <piotrdrag@gmail.com>, 2011, 2013-2017.
 # Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>, 2011.
 #
 msgid ""
 msgstr ""
 "Project-Id-Version: systemd\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2016-10-05 19:01+0200\n"
-"PO-Revision-Date: 2016-10-05 19:02+0200\n"
+"POT-Creation-Date: 2017-10-06 15:29+0200\n"
+"PO-Revision-Date: 2017-10-05 15:30+0200\n"
 "Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
 "Language-Team: Polish <trans-pl@lists.fedoraproject.org>\n"
 "Language: pl\n"
@@ -89,7 +91,7 @@ msgid ""
 "as well as the pretty host name."
 msgstr ""
 "Wymagane jest uwierzytelnienie, aby ustawić statycznie skonfigurowaną nazwę "
-"lokalnego komputera, a także jego ładną nazwę."
+"lokalnego komputera, a także jego nazwę czytelną dla człowieka."
 
 #: ../src/hostname/org.freedesktop.hostname1.policy.in.h:5
 msgid "Set machine information"
@@ -347,18 +349,50 @@ msgstr ""
 "zażądał jego wstrzymania."
 
 #: ../src/login/org.freedesktop.login1.policy.in.h:39
+msgid "Halt the system"
+msgstr "Zatrzymanie systemu"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:40
+msgid "Authentication is required for halting the system."
+msgstr "Wymagane jest uwierzytelnienie, aby zatrzymać system."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:41
+msgid "Halt the system while other users are logged in"
+msgstr "Zatrzymanie systemu, kiedy są zalogowani inni użytkownicy"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:42
+msgid ""
+"Authentication is required for halting the system while other users are "
+"logged in."
+msgstr ""
+"Wymagane jest uwierzytelnienie, aby zatrzymać system, kiedy są zalogowani "
+"inni użytkownicy."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:43
+msgid "Halt the system while an application asked to inhibit it"
+msgstr "Zatrzymanie systemu, kiedy program zażądał jego wstrzymania"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:44
+msgid ""
+"Authentication is required for halting the system while an application asked "
+"to inhibit it."
+msgstr ""
+"Wymagane jest uwierzytelnienie, aby zatrzymać system, kiedy program zażądał "
+"jego wstrzymania."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:45
 msgid "Suspend the system"
 msgstr "Uśpienie systemu"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:40
+#: ../src/login/org.freedesktop.login1.policy.in.h:46
 msgid "Authentication is required for suspending the system."
 msgstr "Wymagane jest uwierzytelnienie, aby uśpić system."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:41
+#: ../src/login/org.freedesktop.login1.policy.in.h:47
 msgid "Suspend the system while other users are logged in"
 msgstr "Uśpienie systemu, kiedy są zalogowani inni użytkownicy"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:42
+#: ../src/login/org.freedesktop.login1.policy.in.h:48
 msgid ""
 "Authentication is required for suspending the system while other users are "
 "logged in."
@@ -366,11 +400,11 @@ msgstr ""
 "Wymagane jest uwierzytelnienie, aby uśpić system, kiedy są zalogowani inni "
 "użytkownicy."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:43
+#: ../src/login/org.freedesktop.login1.policy.in.h:49
 msgid "Suspend the system while an application asked to inhibit it"
 msgstr "Uśpienie systemu, kiedy program zażądał jego wstrzymania"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:44
+#: ../src/login/org.freedesktop.login1.policy.in.h:50
 msgid ""
 "Authentication is required for suspending the system while an application "
 "asked to inhibit it."
@@ -378,19 +412,19 @@ msgstr ""
 "Wymagane jest uwierzytelnienie, aby uśpić system, kiedy program zażądał jego "
 "wstrzymania."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:45
+#: ../src/login/org.freedesktop.login1.policy.in.h:51
 msgid "Hibernate the system"
 msgstr "Hibernacja systemu"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:46
+#: ../src/login/org.freedesktop.login1.policy.in.h:52
 msgid "Authentication is required for hibernating the system."
 msgstr "Wymagane jest uwierzytelnienie, aby zahibernować system."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:47
+#: ../src/login/org.freedesktop.login1.policy.in.h:53
 msgid "Hibernate the system while other users are logged in"
 msgstr "Hibernacja systemu, kiedy są zalogowani inni użytkownicy"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:48
+#: ../src/login/org.freedesktop.login1.policy.in.h:54
 msgid ""
 "Authentication is required for hibernating the system while other users are "
 "logged in."
@@ -398,11 +432,11 @@ msgstr ""
 "Wymagane jest uwierzytelnienie, aby zahibernować system, kiedy są zalogowani "
 "inni użytkownicy."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:49
+#: ../src/login/org.freedesktop.login1.policy.in.h:55
 msgid "Hibernate the system while an application asked to inhibit it"
 msgstr "Hibernacja systemu, kiedy program zażądał jej wstrzymania"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:50
+#: ../src/login/org.freedesktop.login1.policy.in.h:56
 msgid ""
 "Authentication is required for hibernating the system while an application "
 "asked to inhibit it."
@@ -410,31 +444,31 @@ msgstr ""
 "Wymagane jest uwierzytelnienie, aby zahibernować system, kiedy program "
 "zażądał jej wstrzymania."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:51
+#: ../src/login/org.freedesktop.login1.policy.in.h:57
 msgid "Manage active sessions, users and seats"
 msgstr "Zarządzanie aktywnymi sesjami, użytkownikami i stanowiskami"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:52
+#: ../src/login/org.freedesktop.login1.policy.in.h:58
 msgid ""
 "Authentication is required for managing active sessions, users and seats."
 msgstr ""
 "Wymagane jest uwierzytelnienie, aby zarządzać aktywnymi sesjami, "
 "użytkownikami i stanowiskami."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:53
+#: ../src/login/org.freedesktop.login1.policy.in.h:59
 msgid "Lock or unlock active sessions"
 msgstr "Zablokowanie lub odblokowanie aktywnych sesji"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:54
+#: ../src/login/org.freedesktop.login1.policy.in.h:60
 msgid "Authentication is required to lock or unlock active sessions."
 msgstr ""
 "Wymagane jest uwierzytelnienie, aby zablokować lub odblokować aktywne sesje."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:55
+#: ../src/login/org.freedesktop.login1.policy.in.h:61
 msgid "Allow indication to the firmware to boot to setup interface"
 msgstr "Wskazanie oprogramowaniu sprzętowemu, aby uruchomić interfejs ustawień"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:56
+#: ../src/login/org.freedesktop.login1.policy.in.h:62
 msgid ""
 "Authentication is required to indicate to the firmware to boot to setup "
 "interface."
@@ -442,11 +476,11 @@ msgstr ""
 "Wymagane jest uwierzytelnienie, aby wskazać oprogramowaniu sprzętowemu, że "
 "należy uruchomić interfejs ustawień."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:57
+#: ../src/login/org.freedesktop.login1.policy.in.h:63
 msgid "Set a wall message"
 msgstr "Ustawienie komunikatu wall"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:58
+#: ../src/login/org.freedesktop.login1.policy.in.h:64
 msgid "Authentication is required to set a wall message"
 msgstr "Wymagane jest uwierzytelnienie, aby ustawić komunikat wall"
 
@@ -569,36 +603,36 @@ msgstr ""
 "Wymagane jest uwierzytelnienie, aby kontrolować, czy włączyć synchronizację "
 "czasu przez sieć."
 
-#: ../src/core/dbus-unit.c:459
+#: ../src/core/dbus-unit.c:458
 msgid "Authentication is required to start '$(unit)'."
-msgstr "Wymagane jest uwierzytelnienie, aby uruchomić jednostkę „$(unit)”."
+msgstr "Wymagane jest uwierzytelnienie, aby uruchomić jednostkę „$(unit)”."
 
-#: ../src/core/dbus-unit.c:460
+#: ../src/core/dbus-unit.c:459
 msgid "Authentication is required to stop '$(unit)'."
-msgstr "Wymagane jest uwierzytelnienie, aby zatrzymać jednostkę „$(unit)”."
+msgstr "Wymagane jest uwierzytelnienie, aby zatrzymać jednostkę „$(unit)”."
 
-#: ../src/core/dbus-unit.c:461
+#: ../src/core/dbus-unit.c:460
 msgid "Authentication is required to reload '$(unit)'."
 msgstr ""
-"Wymagane jest uwierzytelnienie, aby ponownie wczytać jednostkę „$(unit)”."
+"Wymagane jest uwierzytelnienie, aby ponownie wczytać jednostkę „$(unit)”."
 
-#: ../src/core/dbus-unit.c:462 ../src/core/dbus-unit.c:463
+#: ../src/core/dbus-unit.c:461 ../src/core/dbus-unit.c:462
 msgid "Authentication is required to restart '$(unit)'."
 msgstr ""
-"Wymagane jest uwierzytelnienie, aby ponownie uruchomić jednostkę „$(unit)”."
+"Wymagane jest uwierzytelnienie, aby ponownie uruchomić jednostkę „$(unit)”."
 
-#: ../src/core/dbus-unit.c:570
+#: ../src/core/dbus-unit.c:569
 msgid "Authentication is required to kill '$(unit)'."
 msgstr ""
-"Wymagane jest uwierzytelnienie, aby wymusić wyłączenie jednostki „$(unit)”."
+"Wymagane jest uwierzytelnienie, aby wymusić wyłączenie jednostki „$(unit)”."
 
-#: ../src/core/dbus-unit.c:601
+#: ../src/core/dbus-unit.c:600
 msgid "Authentication is required to reset the \"failed\" state of '$(unit)'."
 msgstr ""
 "Wymagane jest uwierzytelnienie, aby przywrócić stan „failed” (niepowodzenia) "
 "jednostki „$(unit)”."
 
-#: ../src/core/dbus-unit.c:634
+#: ../src/core/dbus-unit.c:633
 msgid "Authentication is required to set properties on '$(unit)'."
 msgstr ""
 "Wymagane jest uwierzytelnienie, aby ustawić właściwości jednostki „$(unit)”."
index a087a47..acc03af 100644 (file)
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
 # Brazilian Portuguese translation for systemd.
 # Copyright (C) 2017 systemd's COPYRIGHT HOLDER
 # This file is distributed under the same license as the systemd package.
index c5b6758..d9109fc 100644 (file)
--- a/po/ro.po
+++ b/po/ro.po
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
 # Romanian translation for systemd.
 # Copyright (C) 2015 systemd's COPYRIGHT HOLDER
 # This file is distributed under the same license as the systemd package.
index 0c0fab7..3cbf13d 100644 (file)
--- a/po/ru.po
+++ b/po/ru.po
@@ -1,13 +1,15 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
 # translation of ru.po to Rissian
 # Julia Dronova <juliette.tux@gmail.com>, 2013.
-# Sergey Ptashnick <0comffdiz@inbox.ru>, 2013-2016.
+# Sergey Ptashnick <0comffdiz@inbox.ru>, 2013-2017.
 #
 msgid ""
 msgstr ""
 "Project-Id-Version: systemd\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2015-11-22 16:37+0100\n"
-"PO-Revision-Date: 2016-02-02 20:22+0300\n"
+"PO-Revision-Date: 2017-10-10 00:28+0300\n"
 "Last-Translator: Sergey Ptashnick <0comffdiz@inbox.ru>\n"
 "Language: ru\n"
 "MIME-Version: 1.0\n"
@@ -255,52 +257,63 @@ msgstr ""
 "крышки ноутбука, необходимо пройти аутентификацию."
 
 #: ../src/login/org.freedesktop.login1.policy.in.h:19
+msgid "Allow non-logged-in user to run programs"
+msgstr ""
+"Разрешить работу программ в фоновом режиме после завершения сеанса"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:20
+msgid "Explicit request is required to run programs as a non-logged-in user."
+msgstr ""
+"Чтобы разрешить работу программ в фоновом режиме после завершения сеанса, "
+"необходимо явное подтверждение."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:21
 msgid "Allow non-logged-in users to run programs"
 msgstr ""
 "Разрешить пользователям оставлять программы в фоновом режиме после "
 "завершения сеанса"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:20
+#: ../src/login/org.freedesktop.login1.policy.in.h:22
 msgid "Authentication is required to run programs as a non-logged-in user."
 msgstr ""
 "Чтобы разрешить пользователям оставлять программы в фоновом режиме после "
 "завершения сеанса, необходимо пройти аутентификацию."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:21
+#: ../src/login/org.freedesktop.login1.policy.in.h:23
 msgid "Allow attaching devices to seats"
 msgstr "Разрешить подключение устройств к рабочим местам"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:22
+#: ../src/login/org.freedesktop.login1.policy.in.h:24
 msgid "Authentication is required for attaching a device to a seat."
 msgstr ""
 "Чтобы разрешить подключение устройств к рабочим местам, необходимо пройти "
 "аутентификацию."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:23
+#: ../src/login/org.freedesktop.login1.policy.in.h:25
 msgid "Flush device to seat attachments"
 msgstr "Сбросить привязки устройств к рабочим местам"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:24
+#: ../src/login/org.freedesktop.login1.policy.in.h:26
 msgid ""
 "Authentication is required for resetting how devices are attached to seats."
 msgstr ""
 "Чтобы сбросить привязки устройств к рабочим местам, необходимо пройти "
 "аутентификацию."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:25
+#: ../src/login/org.freedesktop.login1.policy.in.h:27
 msgid "Power off the system"
 msgstr "Выключить систему"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:26
+#: ../src/login/org.freedesktop.login1.policy.in.h:28
 msgid "Authentication is required for powering off the system."
 msgstr "Чтобы выключить систему, необходимо пройти аутентификацию."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:27
+#: ../src/login/org.freedesktop.login1.policy.in.h:29
 msgid "Power off the system while other users are logged in"
 msgstr ""
 "Выключить систему, несмотря на то, что в ней работают другие пользователи"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:28
+#: ../src/login/org.freedesktop.login1.policy.in.h:30
 msgid ""
 "Authentication is required for powering off the system while other users are "
 "logged in."
@@ -308,13 +321,13 @@ msgstr ""
 "Чтобы выключить систему, несмотря на то, что в ней работают другие "
 "пользователи, необходимо пройти аутентификацию."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:29
+#: ../src/login/org.freedesktop.login1.policy.in.h:31
 msgid "Power off the system while an application asked to inhibit it"
 msgstr ""
 "Выключить систему, несмотря на то, что приложение запросило блокировку "
 "выключения"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:30
+#: ../src/login/org.freedesktop.login1.policy.in.h:32
 msgid ""
 "Authentication is required for powering off the system while an application "
 "asked to inhibit it."
@@ -322,20 +335,20 @@ msgstr ""
 "Чтобы выключить систему, несмотря на то, что приложение запросило блокировку "
 "выключения, необходимо пройти аутентификацию."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:31
+#: ../src/login/org.freedesktop.login1.policy.in.h:33
 msgid "Reboot the system"
 msgstr "Перезагрузить систему"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:32
+#: ../src/login/org.freedesktop.login1.policy.in.h:34
 msgid "Authentication is required for rebooting the system."
 msgstr "Чтобы перезагрузить систему, необходимо пройти аутентификацию."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:33
+#: ../src/login/org.freedesktop.login1.policy.in.h:35
 msgid "Reboot the system while other users are logged in"
 msgstr ""
 "Перезагрузить систему, несмотря на то, что в ней работают другие пользователи"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:34
+#: ../src/login/org.freedesktop.login1.policy.in.h:36
 msgid ""
 "Authentication is required for rebooting the system while other users are "
 "logged in."
@@ -343,13 +356,13 @@ msgstr ""
 "Чтобы перезагрузить систему, несмотря на то, что в ней работают другие "
 "пользователи, необходимо пройти аутентификацию."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:35
+#: ../src/login/org.freedesktop.login1.policy.in.h:37
 msgid "Reboot the system while an application asked to inhibit it"
 msgstr ""
 "Перезагрузить систему, несмотря на то, что приложение запросило блокировку "
 "выключения"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:36
+#: ../src/login/org.freedesktop.login1.policy.in.h:38
 msgid ""
 "Authentication is required for rebooting the system while an application "
 "asked to inhibit it."
@@ -357,22 +370,57 @@ msgstr ""
 "Чтобы перезагрузить систему, несмотря на то, что приложение запросило "
 "блокировку выключения, необходимо пройти аутентификацию."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:37
+#: ../src/login/org.freedesktop.login1.policy.in.h:39
+msgid "Halt the system"
+msgstr "Остановить систему"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:40
+msgid "Authentication is required for halting the system."
+msgstr "Чтобы остановить систему, необходимо пройти аутентификацию."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:41
+msgid "Halt the system while other users are logged in"
+msgstr ""
+"Остановить систему, несмотря на то, что в ней работают другие пользователи"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:42
+msgid ""
+"Authentication is required for halting the system while other users are "
+"logged in."
+msgstr ""
+"Чтобы остановить систему, несмотря на то, что в ней работают другие "
+"пользователи, необходимо пройти аутентификацию."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:43
+msgid "Halt the system while an application asked to inhibit it"
+msgstr ""
+"Остановить систему, несмотря на то, что приложение запросило блокировку "
+"выключения"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:44
+msgid ""
+"Authentication is required for halting the system while an application asked "
+"to inhibit it."
+msgstr ""
+"Чтобы остановить систему, несмотря на то, что приложение запросило "
+"блокировку выключения, необходимо пройти аутентификацию."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:45
 msgid "Suspend the system"
 msgstr "Перевести систему в ждущий режим"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:38
+#: ../src/login/org.freedesktop.login1.policy.in.h:46
 msgid "Authentication is required for suspending the system."
 msgstr ""
 "Чтобы перевести систему в ждущий режим, необходимо пройти аутентификацию."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:39
+#: ../src/login/org.freedesktop.login1.policy.in.h:47
 msgid "Suspend the system while other users are logged in"
 msgstr ""
 "Перевести систему в ждущий режим, несмотря на то, что в ней работают другие "
 "пользователи"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:40
+#: ../src/login/org.freedesktop.login1.policy.in.h:48
 msgid ""
 "Authentication is required for suspending the system while other users are "
 "logged in."
@@ -380,13 +428,13 @@ msgstr ""
 "Чтобы перевести систему в ждущий режим, несмотря на то, что в ней работают "
 "другие пользователи, необходимо пройти аутентификацию."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:41
+#: ../src/login/org.freedesktop.login1.policy.in.h:49
 msgid "Suspend the system while an application asked to inhibit it"
 msgstr ""
 "Перевести систему в ждущий режим, несмотря на то, что приложение запросило "
 "блокировку"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:42
+#: ../src/login/org.freedesktop.login1.policy.in.h:50
 msgid ""
 "Authentication is required for suspending the system while an application "
 "asked to inhibit it."
@@ -394,22 +442,22 @@ msgstr ""
 "Чтобы перевести систему в ждущий режим, несмотря на то, что приложение "
 "запросило блокировку, необходимо пройти аутентификацию."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:43
+#: ../src/login/org.freedesktop.login1.policy.in.h:51
 msgid "Hibernate the system"
 msgstr "Перевести систему в спящий режим"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:44
+#: ../src/login/org.freedesktop.login1.policy.in.h:52
 msgid "Authentication is required for hibernating the system."
 msgstr ""
 "Чтобы перевести систему в спящий режим, необходимо пройти аутентификацию."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:45
+#: ../src/login/org.freedesktop.login1.policy.in.h:53
 msgid "Hibernate the system while other users are logged in"
 msgstr ""
 "Перевести систему в спящий режим, несмотря на то, что в ней работают другие "
 "пользователи"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:46
+#: ../src/login/org.freedesktop.login1.policy.in.h:54
 msgid ""
 "Authentication is required for hibernating the system while other users are "
 "logged in."
@@ -417,13 +465,13 @@ msgstr ""
 "Чтобы перевести систему в спящий режим, несмотря на то, что в ней работают "
 "другие пользователи, необходимо пройти аутентификацию."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:47
+#: ../src/login/org.freedesktop.login1.policy.in.h:55
 msgid "Hibernate the system while an application asked to inhibit it"
 msgstr ""
 "Перевести систему в спящий режим, несмотря на то, что приложение запросило "
 "блокировку"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:48
+#: ../src/login/org.freedesktop.login1.policy.in.h:56
 msgid ""
 "Authentication is required for hibernating the system while an application "
 "asked to inhibit it."
@@ -431,32 +479,32 @@ msgstr ""
 "Чтобы перевести систему в спящий режим, несмотря на то, что приложение "
 "запросило блокировку, необходимо пройти аутентификацию."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:49
+#: ../src/login/org.freedesktop.login1.policy.in.h:57
 msgid "Manage active sessions, users and seats"
 msgstr "Управление текущими сеансами, пользователями и рабочими местами"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:50
+#: ../src/login/org.freedesktop.login1.policy.in.h:58
 msgid ""
 "Authentication is required for managing active sessions, users and seats."
 msgstr ""
 "Для управления текущими сеансами, пользователями и рабочими местами, "
 "необходимо пройти аутентификацию."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:51
+#: ../src/login/org.freedesktop.login1.policy.in.h:59
 msgid "Lock or unlock active sessions"
 msgstr "Заблокировать или разблокировать текущие сеансы"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:52
+#: ../src/login/org.freedesktop.login1.policy.in.h:60
 msgid "Authentication is required to lock or unlock active sessions."
 msgstr ""
 "Чтобы заблокировать или разблокировать текущие сеансы, необходимо пройти "
 "аутентификацию."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:53
+#: ../src/login/org.freedesktop.login1.policy.in.h:61
 msgid "Allow indication to the firmware to boot to setup interface"
 msgstr "Разрешить загрузку в режиме настройки прошивки материнской платы"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:54
+#: ../src/login/org.freedesktop.login1.policy.in.h:62
 msgid ""
 "Authentication is required to indicate to the firmware to boot to setup "
 "interface."
@@ -464,11 +512,11 @@ msgstr ""
 "Чтобы разрешить загрузку в режиме настройки прошивки материнской платы, "
 "необходимо пройти аутентификацию."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:55
+#: ../src/login/org.freedesktop.login1.policy.in.h:63
 msgid "Set a wall message"
 msgstr "Отправить сообщение на все терминалы"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:56
+#: ../src/login/org.freedesktop.login1.policy.in.h:64
 msgid "Authentication is required to set a wall message"
 msgstr ""
 "Чтобы отправить сообщение на все терминалы, необходимо пройти аутентификацию."
@@ -593,35 +641,35 @@ msgstr ""
 "Чтобы включить или выключить синхронизацию времени по сети, необходимо "
 "пройти аутентификацию."
 
-#: ../src/core/dbus-unit.c:428
+#: ../src/core/dbus-unit.c:458
 msgid "Authentication is required to start '$(unit)'."
 msgstr "Чтобы запустить «$(unit)», необходимо пройти аутентификацию."
 
-#: ../src/core/dbus-unit.c:429
+#: ../src/core/dbus-unit.c:459
 msgid "Authentication is required to stop '$(unit)'."
 msgstr "Чтобы остановить «$(unit)», необходимо пройти аутентификацию."
 
-#: ../src/core/dbus-unit.c:430
+#: ../src/core/dbus-unit.c:460
 msgid "Authentication is required to reload '$(unit)'."
 msgstr ""
 "Чтобы заставить «$(unit)» перечитать конфигурацию, необходимо пройти "
 "аутентификацию."
 
-#: ../src/core/dbus-unit.c:431 ../src/core/dbus-unit.c:432
+#: ../src/core/dbus-unit.c:461 ../src/core/dbus-unit.c:462
 msgid "Authentication is required to restart '$(unit)'."
 msgstr "Чтобы перезапустить «$(unit)», необходимо пройти аутентификацию."
 
-#: ../src/core/dbus-unit.c:535
+#: ../src/core/dbus-unit.c:569
 msgid "Authentication is required to kill '$(unit)'."
 msgstr "Чтобы убить юнит «$(unit)», необходимо пройти аутентификацию."
 
-#: ../src/core/dbus-unit.c:565
+#: ../src/core/dbus-unit.c:600
 msgid "Authentication is required to reset the \"failed\" state of '$(unit)'."
 msgstr ""
 "Чтобы сбросить состояние «failed» у юнита «$(unit)», необходимо пройти "
 "аутентификацию."
 
-#: ../src/core/dbus-unit.c:597
+#: ../src/core/dbus-unit.c:633
 msgid "Authentication is required to set properties on '$(unit)'."
 msgstr "Чтобы изменить параметры юнита «$(unit)», необходимо пройти "
 "аутентификацию."
index 84dd732..e1747d8 100644 (file)
--- a/po/sk.po
+++ b/po/sk.po
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
 # Slovak translation for systemd.
 # Copyright (C) 2017 systemd's COPYRIGHT HOLDER
 # This file is distributed under the same license as the systemd package.
index 7f9b2b3..c20bec8 100644 (file)
--- a/po/sr.po
+++ b/po/sr.po
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
 # SOME DESCRIPTIVE TITLE.
 # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
 # This file is distributed under the same license as the PACKAGE package.
index 1de9b46..4a7f3d8 100644 (file)
--- a/po/sv.po
+++ b/po/sv.po
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
 # Swedish translation for systemd.
 # Copyright © 2015 systemd's COPYRIGHT HOLDER
 # This file is distributed under the same license as the systemd package.
@@ -336,6 +338,37 @@ msgstr ""
 "Autentisering krävs för att starta om systemet även då ett program hindrar "
 "det."
 
+#: src/login/org.freedesktop.login1.policy.in:224
+msgid "Halt the system"
+msgstr "Stoppa systemet"
+
+#: src/login/org.freedesktop.login1.policy.in:225
+msgid "Authentication is required for halting the system."
+msgstr "Autentisering krävs för att stoppa systemet."
+
+#: src/login/org.freedesktop.login1.policy.in:235
+msgid "Halt the system while other users are logged in"
+msgstr "Stoppa systemet medan andra användare är inloggade"
+
+#: src/login/org.freedesktop.login1.policy.in:236
+msgid ""
+"Authentication is required for halting the system while other users are "
+"logged in."
+msgstr ""
+"Autentisering krävs för att stoppa systemet medan andra användare är "
+"inloggade."
+
+#: src/login/org.freedesktop.login1.policy.in:246
+msgid "Halt the system while an application asked to inhibit it"
+msgstr "Stoppa systemet även då ett program hindrar det"
+
+#: src/login/org.freedesktop.login1.policy.in:247
+msgid ""
+"Authentication is required for halting the system while an application asked "
+"to inhibit it."
+msgstr ""
+"Autentisering krävs för att stoppa systemet även då ett program hindrar det."
+
 #: ../src/login/org.freedesktop.login1.policy.in.h:39
 msgid "Suspend the system"
 msgstr "Försätt system i vänteläge"
index b71f30b..71b65ea 100644 (file)
--- a/po/tr.po
+++ b/po/tr.po
@@ -1,18 +1,20 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
 # Turkish translation for systemd.
 # Copyright (C) 2014-2015 systemd's COPYRIGHT HOLDER
 # This file is distributed under the same license as the systemd package.
 # Necdet Yücel <necdetyucel@gmail.com>, 2014.
 # Gökhan Gurbetoğlu <ggurbet@gmail.com>, 2015.
-# Muhammet Kara <muhammetk@gmail.com>, 2015, 2016.
+# Muhammet Kara <muhammetk@gmail.com>, 2015, 2016, 2017.
 #
 msgid ""
 msgstr ""
 "Project-Id-Version: systemd master\n"
 "Report-Msgid-Bugs-To: https://github.com/systemd/systemd/issues\n"
-"POT-Creation-Date: 2016-04-24 12:53+0000\n"
-"PO-Revision-Date: 2016-06-09 16:05+0300\n"
+"POT-Creation-Date: 2017-10-06 13:26+0000\n"
+"PO-Revision-Date: 2017-10-06 20:59+0300\n"
 "Last-Translator: Muhammet Kara <muhammetk@gmail.com>\n"
-"Language-Team: Turkish <gnome-turk@gnome.org>\n"
+"Language-Team: Türkçe <gnome-turk@gnome.org>\n"
 "Language: tr_TR\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
@@ -249,12 +251,10 @@ msgstr ""
 "kimlik doğrulaması gereklidir."
 
 #: ../src/login/org.freedesktop.login1.policy.in.h:19
-#| msgid "Allow non-logged-in users to run programs"
 msgid "Allow non-logged-in user to run programs"
 msgstr "Oturum açmamış kullanıcının program çalıştırmasına izin ver"
 
 #: ../src/login/org.freedesktop.login1.policy.in.h:20
-#| msgid "Authentication is required to run programs as a non-logged-in user."
 msgid "Explicit request is required to run programs as a non-logged-in user."
 msgstr ""
 "Oturum açmamış bir kullanıcı olarak program çalıştırmak için açıkça istekte "
@@ -355,18 +355,60 @@ msgstr ""
 "doğrulaması gerektiriyor."
 
 #: ../src/login/org.freedesktop.login1.policy.in.h:39
+#| msgid "Hibernate the system"
+msgid "Halt the system"
+msgstr "Sistemi durdur"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:40
+#| msgid "Authentication is required for hibernating the system."
+msgid "Authentication is required for halting the system."
+msgstr "Sistemi durdurmak kimlik doğrulaması gerektiriyor."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:41
+#| msgid "Hibernate the system while other users are logged in"
+msgid "Halt the system while other users are logged in"
+msgstr "Diğer kullanıcılar oturum açmışken sistemi durdur"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:42
+#| msgid ""
+#| "Authentication is required for hibernating the system while other users "
+#| "are logged in."
+msgid ""
+"Authentication is required for halting the system while other users are "
+"logged in."
+msgstr ""
+"Diğer kullanıcılar oturum açmışken sistemi durdurmak kimlik doğrulaması "
+"gerektiriyor."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:43
+#| msgid "Hibernate the system while an application asked to inhibit it"
+msgid "Halt the system while an application asked to inhibit it"
+msgstr "Bir uygulama engellenmesini isterken sistemi durdur"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:44
+#| msgid ""
+#| "Authentication is required for hibernating the system while an "
+#| "application asked to inhibit it."
+msgid ""
+"Authentication is required for halting the system while an application asked "
+"to inhibit it."
+msgstr ""
+"Bir uygulama engellenmesini isterken sistemi durdurmak kimlik doğrulaması "
+"gerektiriyor."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:45
 msgid "Suspend the system"
 msgstr "Sistemi askıya al"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:40
+#: ../src/login/org.freedesktop.login1.policy.in.h:46
 msgid "Authentication is required for suspending the system."
 msgstr "Sistemi askıya almak kimlik doğrulaması gerektiriyor."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:41
+#: ../src/login/org.freedesktop.login1.policy.in.h:47
 msgid "Suspend the system while other users are logged in"
 msgstr "Diğer kullanıcılar oturum açmışken sistemi askıya al"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:42
+#: ../src/login/org.freedesktop.login1.policy.in.h:48
 msgid ""
 "Authentication is required for suspending the system while other users are "
 "logged in."
@@ -374,11 +416,11 @@ msgstr ""
 "Diğer kullanıcılar oturum açmışken sistemi askıya almak kimlik doğrulaması "
 "gerektiriyor."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:43
+#: ../src/login/org.freedesktop.login1.policy.in.h:49
 msgid "Suspend the system while an application asked to inhibit it"
 msgstr "Bir uygulama engellenmesini isterken sistemi askıya al"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:44
+#: ../src/login/org.freedesktop.login1.policy.in.h:50
 msgid ""
 "Authentication is required for suspending the system while an application "
 "asked to inhibit it."
@@ -386,19 +428,19 @@ msgstr ""
 "Bir uygulama engellenmesini isterken sistemi askıya almak kimlik doğrulaması "
 "gerektiriyor."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:45
+#: ../src/login/org.freedesktop.login1.policy.in.h:51
 msgid "Hibernate the system"
 msgstr "Sistemi hazırda beklet"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:46
+#: ../src/login/org.freedesktop.login1.policy.in.h:52
 msgid "Authentication is required for hibernating the system."
 msgstr "Sistemi hazırda bekletmek kimlik doğrulaması gerektiriyor."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:47
+#: ../src/login/org.freedesktop.login1.policy.in.h:53
 msgid "Hibernate the system while other users are logged in"
 msgstr "Diğer kullanıcılar oturum açmışken sistemi hazırda beklet"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:48
+#: ../src/login/org.freedesktop.login1.policy.in.h:54
 msgid ""
 "Authentication is required for hibernating the system while other users are "
 "logged in."
@@ -406,11 +448,11 @@ msgstr ""
 "Diğer kullanıcılar oturum açmışken sistemi hazırda bekletmek kimlik "
 "doğrulaması gerektiriyor."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:49
+#: ../src/login/org.freedesktop.login1.policy.in.h:55
 msgid "Hibernate the system while an application asked to inhibit it"
 msgstr "Bir uygulama engellenmesini isterken sistemi hazırda beklet"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:50
+#: ../src/login/org.freedesktop.login1.policy.in.h:56
 msgid ""
 "Authentication is required for hibernating the system while an application "
 "asked to inhibit it."
@@ -418,33 +460,33 @@ msgstr ""
 "Bir uygulama engellenmesini isterken sistemi hazırda bekletmek kimlik "
 "doğrulaması gerektiriyor."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:51
+#: ../src/login/org.freedesktop.login1.policy.in.h:57
 msgid "Manage active sessions, users and seats"
 msgstr "Aktif oturumları, kullanıcıları ve yuvaları yönet"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:52
+#: ../src/login/org.freedesktop.login1.policy.in.h:58
 msgid ""
 "Authentication is required for managing active sessions, users and seats."
 msgstr ""
 "Aktif oturumları, kullanıcıları ve yuvaları yönetmek için kimlik doğrulaması "
 "gereklidir."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:53
+#: ../src/login/org.freedesktop.login1.policy.in.h:59
 msgid "Lock or unlock active sessions"
 msgstr "Aktif oturumları kilitle ya da kilidini aç"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:54
+#: ../src/login/org.freedesktop.login1.policy.in.h:60
 msgid "Authentication is required to lock or unlock active sessions."
 msgstr ""
 "Aktif oturumları kilitlemek ve bunların kilidini açmak için kimlik "
 "doğrulaması gereklidir."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:55
+#: ../src/login/org.freedesktop.login1.policy.in.h:61
 msgid "Allow indication to the firmware to boot to setup interface"
 msgstr ""
 "Kurulum arayüzünü önyüklemek için ürün yazılımının belirtilmesine izin ver"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:56
+#: ../src/login/org.freedesktop.login1.policy.in.h:62
 msgid ""
 "Authentication is required to indicate to the firmware to boot to setup "
 "interface."
@@ -452,11 +494,11 @@ msgstr ""
 "Kurulum arayüzünü önyüklemek için ürün yazılımının belirtilmesi için kimlik "
 "doğrulaması gereklidir."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:57
+#: ../src/login/org.freedesktop.login1.policy.in.h:63
 msgid "Set a wall message"
 msgstr "Bir duvar mesajı ayarla"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:58
+#: ../src/login/org.freedesktop.login1.policy.in.h:64
 msgid "Authentication is required to set a wall message"
 msgstr "Duvar mesajı ayarlamak için kimlik doğrulaması gereklidir"
 
@@ -577,33 +619,33 @@ msgid ""
 msgstr ""
 "Ağ zaman eş zamanlamasını kontrol etmek kimlik doğrulaması gerektiriyor."
 
-#: ../src/core/dbus-unit.c:450
+#: ../src/core/dbus-unit.c:458
 msgid "Authentication is required to start '$(unit)'."
 msgstr "'$(unit)' başlatmak için kimlik doğrulaması gereklidir."
 
-#: ../src/core/dbus-unit.c:451
+#: ../src/core/dbus-unit.c:459
 msgid "Authentication is required to stop '$(unit)'."
 msgstr "'$(unit)' durdurmak için kimlik doğrulaması gereklidir."
 
-#: ../src/core/dbus-unit.c:452
+#: ../src/core/dbus-unit.c:460
 msgid "Authentication is required to reload '$(unit)'."
 msgstr "'$(unit)' yeniden yüklemek için kimlik doğrulaması gereklidir."
 
-#: ../src/core/dbus-unit.c:453 ../src/core/dbus-unit.c:454
+#: ../src/core/dbus-unit.c:461 ../src/core/dbus-unit.c:462
 msgid "Authentication is required to restart '$(unit)'."
 msgstr "'$(unit)' yeniden başlatmak için kimlik doğrulaması gereklidir."
 
-#: ../src/core/dbus-unit.c:560
+#: ../src/core/dbus-unit.c:569
 msgid "Authentication is required to kill '$(unit)'."
 msgstr "'$(unit)' sonlandırmak için kimlik doğrulaması gereklidir."
 
-#: ../src/core/dbus-unit.c:590
+#: ../src/core/dbus-unit.c:600
 msgid "Authentication is required to reset the \"failed\" state of '$(unit)'."
 msgstr ""
 "'$(unit)'in \"failed\" (başarısız) durumunu sıfırlamak için kimlik "
 "doğrulaması gereklidir."
 
-#: ../src/core/dbus-unit.c:622
+#: ../src/core/dbus-unit.c:633
 msgid "Authentication is required to set properties on '$(unit)'."
 msgstr ""
 "'$(unit)' üzerindeki özellikleri ayarlamak için kimlik doğrulaması "
index 66044b8..31e5f55 100644 (file)
--- a/po/uk.po
+++ b/po/uk.po
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
 # Ukrainian translation for systemd.
 # Copyright (C) 2014 systemd's COPYRIGHT HOLDER
 # This file is distributed under the same license as the systemd package.
index 10c53d4..7fbbcb1 100644 (file)
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
 # Simplified Chinese translation for systemd.
 # Copyright (C) 2015 systemd's COPYRIGHT HOLDER
 # This file is distributed under the same license as the systemd package.
index affea91..c2b3b08 100644 (file)
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
 # Traditional Chinese translation for systemd.
 # Copyright (C) 2015 systemd's COPYRIGHT HOLDER
 # This file is distributed under the same license as the systemd package.
similarity index 92%
rename from system-preset/90-systemd.preset
rename to presets/90-systemd.preset
index 3ba4bb7..11960e5 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
@@ -9,6 +11,7 @@
 # generally follow a default-off policy.
 
 enable remote-fs.target
+enable remote-cryptsetup.target
 enable machines.target
 
 enable getty@.service
diff --git a/presets/meson.build b/presets/meson.build
new file mode 100644 (file)
index 0000000..48aa8c9
--- /dev/null
@@ -0,0 +1,22 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
+# Copyright 2017 Zbigniew Jędrzejewski-Szmek
+#
+# 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.
+#
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
+install_data('90-systemd.preset',
+             install_dir : systempresetdir)
+
+install_data('user/90-systemd.preset',
+             install_dir : userpresetdir)
similarity index 57%
rename from units/remote-cryptsetup-pre.target
rename to presets/user/90-systemd.preset
index a375e61..22fe41f 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
@@ -5,11 +7,8 @@
 #  the Free Software Foundation; either version 2.1 of the License, or
 #  (at your option) any later version.
 
-[Unit]
-Description=Remote Encrypted Volumes (Pre)
-Documentation=man:systemd.special(7)
-RefuseManualStart=yes
-Before=remote-cryptsetup.target
+# These ones should be enabled by default, even if distributions
+# generally follow a default-off policy.
 
-After=network.target network-online.target
-Wants=network-online.target
+enable systemd-tmpfiles-setup.service
+enable systemd-tmpfiles-clean.timer
index e24eedb..c408a40 100644 (file)
@@ -22,7 +22,7 @@ SUBSYSTEM=="tty", KERNEL=="sclp_line[0-9]*", GROUP="tty", MODE="0620"
 SUBSYSTEM=="tty", KERNEL=="ttysclp[0-9]*", GROUP="tty", MODE="0620"
 SUBSYSTEM=="tty", KERNEL=="3270/tty[0-9]*", GROUP="tty", MODE="0620"
 SUBSYSTEM=="vc", KERNEL=="vcs*|vcsa*", GROUP="tty"
-KERNEL=="tty[A-Z]*[0-9]|pppox[0-9]*|ircomm[0-9]*|noz[0-9]*|rfcomm[0-9]*", GROUP="dialout"
+KERNEL=="tty[A-Z]*[0-9]|ttymxc[0-9]*|pppox[0-9]*|ircomm[0-9]*|noz[0-9]*|rfcomm[0-9]*", GROUP="dialout"
 
 SUBSYSTEM=="mem", KERNEL=="mem|kmem|port", GROUP="kmem", MODE="0640"
 
@@ -31,11 +31,14 @@ SUBSYSTEM=="input", KERNEL=="js[0-9]*", MODE="0664"
 
 SUBSYSTEM=="video4linux", GROUP="video"
 SUBSYSTEM=="graphics", GROUP="video"
-SUBSYSTEM=="drm", GROUP="video"
+SUBSYSTEM=="drm", KERNEL!="renderD*", GROUP="video"
 SUBSYSTEM=="dvb", GROUP="video"
 SUBSYSTEM=="media", GROUP="video"
 SUBSYSTEM=="cec", GROUP="video"
 
+SUBSYSTEM=="drm", KERNEL=="renderD*", GROUP="render", MODE="@GROUP_RENDER_MODE@"
+SUBSYSTEM=="kfd", GROUP="render", MODE="@GROUP_RENDER_MODE@"
+
 SUBSYSTEM=="sound", GROUP="audio", \
   OPTIONS+="static_node=snd/seq", OPTIONS+="static_node=snd/timer"
 
index dee4219..bb8a812 100644 (file)
@@ -3,5 +3,6 @@
 ACTION=="remove", GOTO="id_input_end"
 
 SUBSYSTEM=="input", ENV{ID_INPUT}=="", IMPORT{builtin}="input_id"
+SUBSYSTEM=="input", IMPORT{builtin}="hwdb --subsystem=input --lookup-prefix=id-input:modalias:"
 
 LABEL="id_input_end"
index 91efbe7..255547d 100644 (file)
@@ -5,8 +5,8 @@ SUBSYSTEM!="input", GOTO="persistent_input_end"
 SUBSYSTEMS=="bluetooth", ENV{ID_BUS}="bluetooth", GOTO="persistent_input_end"
 # Bluetooth devices don't always have the bluetooth subsystem
 ATTRS{id/bustype}=="0005", ENV{ID_BUS}="bluetooth", GOTO="persistent_input_end"
-SUBSYSTEMS=="rmi4", ENV{ID_BUS}="rmi", GOTO="persistent_input_end"
-SUBSYSTEMS=="serio", ENV{ID_BUS}="i8042", GOTO="persistent_input_end"
+SUBSYSTEMS=="rmi4", ENV{ID_BUS}="rmi"
+SUBSYSTEMS=="serio", ENV{ID_BUS}="i8042"
 
 SUBSYSTEMS=="usb", ENV{ID_BUS}=="", IMPORT{builtin}="usb_id"
 
index 72fec5c..0de8cf3 100644 (file)
@@ -21,10 +21,14 @@ KERNEL=="nvme*[0-9]n*[0-9]p*[0-9]", ENV{DEVTYPE}=="partition", ATTRS{wwid}=="?*"
 
 KERNEL=="nvme*[0-9]n*[0-9]", ENV{DEVTYPE}=="disk", ATTRS{serial}=="?*", ENV{ID_SERIAL_SHORT}="$attr{serial}"
 KERNEL=="nvme*[0-9]n*[0-9]", ENV{DEVTYPE}=="disk", ATTRS{wwid}=="?*", ENV{ID_WWN}="$attr{wwid}"
-KERNEL=="nvme*[0-9]n*[0-9]", ENV{DEVTYPE}=="disk", ATTRS{model}=="?*", ENV{ID_SERIAL_SHORT}=="?*", ENV{ID_SERIAL}="$attr{model}_$env{ID_SERIAL_SHORT}", SYMLINK+="disk/by-id/nvme-$env{ID_SERIAL}"
+KERNEL=="nvme*[0-9]n*[0-9]", ENV{DEVTYPE}=="disk", ATTRS{model}=="?*", ENV{ID_MODEL}="$attr{model}"
+KERNEL=="nvme*[0-9]n*[0-9]", ENV{DEVTYPE}=="disk", ENV{ID_MODEL}=="?*", ENV{ID_SERIAL_SHORT}=="?*", \
+  ENV{ID_SERIAL}="$env{ID_MODEL}_$env{ID_SERIAL_SHORT}", SYMLINK+="disk/by-id/nvme-$env{ID_SERIAL}"
 
 KERNEL=="nvme*[0-9]n*[0-9]p*[0-9]", ENV{DEVTYPE}=="partition", ATTRS{serial}=="?*", ENV{ID_SERIAL_SHORT}="$attr{serial}"
-KERNEL=="nvme*[0-9]n*[0-9]p*[0-9]", ENV{DEVTYPE}=="partition", ATTRS{model}=="?*", ENV{ID_SERIAL_SHORT}=="?*", ENV{ID_SERIAL}="$attr{model}_$env{ID_SERIAL_SHORT}", SYMLINK+="disk/by-id/nvme-$env{ID_SERIAL}-part%n"
+KERNEL=="nvme*[0-9]n*[0-9]p*[0-9]", ENV{DEVTYPE}=="partition", ATTRS{model}=="?*", ENV{ID_MODEL}="$attr{model}"
+KERNEL=="nvme*[0-9]n*[0-9]p*[0-9]", ENV{DEVTYPE}=="partition", ENV{ID_MODEL}=="?*", ENV{ID_SERIAL_SHORT}=="?*", \
+  ENV{ID_SERIAL}="$env{ID_MODEL}_$env{ID_SERIAL_SHORT}", SYMLINK+="disk/by-id/nvme-$env{ID_SERIAL}-part%n"
 
 # virtio-blk
 KERNEL=="vd*[!0-9]", ATTRS{serial}=="?*", ENV{ID_SERIAL}="$attr{serial}", SYMLINK+="disk/by-id/virtio-$env{ID_SERIAL}"
index eea9360..bf36fd4 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 28c375d..c949911 100644 (file)
@@ -1,3 +1,20 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
+# Copyright 2017 Zbigniew Jędrzejewski-Szmek
+#
+# 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.
+#
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
 rules = files('''
         55-udev-smack-default.rules
         60-block.rules
@@ -25,6 +42,8 @@ rules = files('''
 install_data(rules,
              install_dir : udevrulesdir)
 
+all_rules = rules
+
 rules_in = '''
         50-udev-default.rules
         64-btrfs.rules
@@ -38,4 +57,5 @@ foreach file : rules_in
                 configuration : substs)
         install_data(gen,
                      install_dir : udevrulesdir)
+        all_rules += gen
 endforeach
index c86ec7e..34b1b55 100644 (file)
@@ -1,4 +1,5 @@
 # bootctl(1) completion                               -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1+
 #
 # This file is part of systemd.
 #
index 6a770b1..aa4c1d7 100644 (file)
@@ -1,4 +1,5 @@
 # busctl(1) completion                               -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1+
 #
 # This file is part of systemd.
 #
index 87fe473..842e494 100644 (file)
@@ -1,4 +1,5 @@
 # coredumpctl(1) completion                       -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1+
 #
 # This file is part of systemd.
 #
index 7cf8b6f..a35ac7f 100644 (file)
@@ -1,4 +1,5 @@
 # hostnamectl(1) completion                               -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1+
 #
 # This file is part of systemd.
 #
index c90a114..03ee733 100644 (file)
@@ -1,4 +1,5 @@
 # journalctl(1) completion                                -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1+
 #
 # This file is part of systemd.
 #
index 7cd2494..5a78528 100644 (file)
@@ -1,4 +1,5 @@
 # kernel-install(8) completion                                   -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1+
 #
 # This file is part of systemd.
 #
index e0c06a7..97c91a4 100644 (file)
@@ -1,4 +1,5 @@
 # localectl(1) completion                                 -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1+
 #
 # This file is part of systemd.
 #
index 776eca4..d8d14f8 100644 (file)
@@ -1,4 +1,5 @@
 # loginctl(1) completion                                  -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1+
 #
 # This file is part of systemd.
 #
index aebe483..7865a99 100644 (file)
@@ -1,4 +1,5 @@
 # machinectl(1) completion                      -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1+
 #
 # This file is part of systemd.
 #
index 1123878..347518c 100644 (file)
@@ -1,3 +1,20 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
+# Copyright 2017 Zbigniew Jędrzejewski-Szmek
+#
+# 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.
+#
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
 bashcompletiondir = get_option('bashcompletiondir')
 if bashcompletiondir == ''
         bash_completion = dependency('bash-completion', required : false)
index 68e3338..0c36aaf 100644 (file)
@@ -1,4 +1,5 @@
 # networkctl(1) completion                               -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1+
 #
 # This file is part of systemd.
 #
index bde28ef..5a353f7 100644 (file)
@@ -1,4 +1,5 @@
 # systemctl(1) completion                                 -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1+
 #
 # This file is part of systemd.
 #
index 8c56a1c..45ff7a1 100644 (file)
@@ -1,4 +1,5 @@
 # systemd-analyze(1) completion                      -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1+
 #
 # This file is part of systemd.
 #
index 8d84042..20ff672 100644 (file)
@@ -1,4 +1,5 @@
 # systemd-cat(1) completion                  -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1+
 #
 # This file is part of systemd.
 #
index 0570438..0f579a6 100644 (file)
@@ -1,4 +1,5 @@
 # systemd-cgls(1) completion                  -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1+
 #
 # This file is part of systemd.
 #
index f1ed22f..7a1b4ac 100644 (file)
@@ -1,4 +1,5 @@
 # systemd-cgtop(1) completion                  -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1+
 #
 # This file is part of systemd.
 #
index cb17328..d393343 100644 (file)
@@ -1,4 +1,5 @@
 # systemd-delta(1) completion                      -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1+
 #
 # This file is part of systemd.
 #
index df06c29..21dca2b 100644 (file)
@@ -1,4 +1,5 @@
 # systemd-detect-virt(1) completion             -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1+
 #
 # This file is part of systemd.
 #
index ea4a5e1..4f2fbef 100644 (file)
@@ -1,4 +1,5 @@
 # systemd-nspawn(1) completion                  -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1+
 #
 # This file is part of systemd.
 #
index 2f0c5f5..5d99775 100644 (file)
@@ -1,4 +1,5 @@
 # systemd-path(1) completion                               -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1+
 #
 # This file is part of systemd.
 #
index f59482f..3f789e8 100644 (file)
@@ -1,4 +1,5 @@
 # systemd-resolve(1) completion                             -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1+
 #
 # This file is part of systemd.
 #
index 4116ba7..125cd30 100644 (file)
@@ -1,4 +1,5 @@
 # systemd-run(1) completion                       -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1+
 #
 # This file is part of systemd.
 #
index a57fbd2..b9d0081 100644 (file)
@@ -1,4 +1,5 @@
 # timedatectl(1) completion                               -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1+
 #
 # This file is part of systemd.
 #
index b828b8d..744a388 100644 (file)
@@ -1,4 +1,5 @@
 # udevadm(8) completion                                   -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1+
 #
 # This file is part of systemd.
 #
index 0e1b0a5..f107005 100644 (file)
@@ -1,4 +1,5 @@
 #compdef bootctl
+# SPDX-License-Identifier: LGPL-2.1+
 
 (( $+functions[_bootctl_command] )) || _bootctl_command()
 {
index a425b8c..883ace4 100644 (file)
@@ -1,4 +1,5 @@
 #compdef busctl
+# SPDX-License-Identifier: LGPL-2.1+
 
 # busctl(1) completion                               -*- shell-script -*-
 #
index e469bca..ea8cfb2 100644 (file)
@@ -1,4 +1,5 @@
 #compdef coredumpctl
+# SPDX-License-Identifier: LGPL-2.1+
 
 _coredumpctl_command(){
     local -a _coredumpctl_cmds
index 8c4a354..ea86863 100644 (file)
@@ -1,4 +1,5 @@
 #compdef hostnamectl
+# SPDX-License-Identifier: LGPL-2.1+
 
 _hostnamectl_set-hostname() {
     if (( CURRENT <= 3 )); then
index 4a78a2e..4bffabb 100644 (file)
@@ -1,4 +1,5 @@
 #compdef journalctl
+# SPDX-License-Identifier: LGPL-2.1+
 
 _list_fields() {
     local -a journal_fields
index 4fdd3a4..6358a64 100644 (file)
@@ -1,4 +1,5 @@
 #compdef kernel-install
+# SPDX-License-Identifier: LGPL-2.1+
 
 _images(){
     if [[ "$words[2]" == "remove" ]]; then
index 54c2d45..e5ec65b 100644 (file)
@@ -1,4 +1,5 @@
 #compdef localectl
+# SPDX-License-Identifier: LGPL-2.1+
 
 _localectl_set-locale() {
     local -a _locales locale_fields
index 6f6ff6e..03dde9a 100644 (file)
@@ -1,4 +1,5 @@
 #compdef loginctl
+# SPDX-License-Identifier: LGPL-2.1+
 
 _loginctl_all_sessions() {
   local session description
index 92d7710..933f4d2 100644 (file)
@@ -1,4 +1,5 @@
 #compdef machinectl
+# SPDX-License-Identifier: LGPL-2.1+
 
 __get_available_machines () {
     machinectl --no-legend list-images | {while read -r a b; do echo $a; done;}
index acf7463..ea485d6 100644 (file)
@@ -1,4 +1,5 @@
 #compdef networkctl
+# SPDX-License-Identifier: LGPL-2.1+
 
 _networkctl_command(){
     local -a _networkctl_cmds
index 282f732..11f94f1 100644 (file)
@@ -1,4 +1,5 @@
 #autoload
+# SPDX-License-Identifier: LGPL-2.1+
 
 _alternative \
   'users-hosts:: _user_at_host' \
index a0039ee..ab35cf8 100644 (file)
@@ -1,4 +1,5 @@
 #autoload
+# SPDX-License-Identifier: LGPL-2.1+
 __get_machines () {
         machinectl --full --no-legend --no-pager list |  {while read -r a b; do echo $a; done;};
 }
index 2948f40..3b8850b 100644 (file)
@@ -1,4 +1,5 @@
 #autoload
+# SPDX-License-Identifier: LGPL-2.1+
 
 local -a _output_opts
 _output_opts=(short short-full short-iso short-iso-precise short-precise short-monotonic short-unix verbose export json json-pretty json-sse cat)
index 5e90ea2..cce4442 100644 (file)
@@ -1,4 +1,5 @@
 #autoload
+# SPDX-License-Identifier: LGPL-2.1+
 
 _sd_unit_files() {
     local files expl
index d35c900..47ec997 100644 (file)
@@ -1,4 +1,5 @@
 #compdef systemctl
+# SPDX-License-Identifier: LGPL-2.1+
 
 (( $+functions[_systemctl_command] )) || _systemctl_command()
 {
@@ -375,14 +376,14 @@ _arguments -s \
     '--system[Connect to system manager]' \
     '--user[Connect to user service manager]' \
     "--no-wall[Don't send wall message before halt/power-off/reboot]" \
-    '--global[Enable/disable unit files globally]' \
+    '--global[Enable/disable/mask unit files globally]' \
     "--no-reload[When enabling/disabling unit files, don't reload daemon configuration]" \
     '--no-ask-password[Do not ask for system passwords]' \
     '--kill-who=[Who to send signal to]:killwho:(main control all)' \
     {-s+,--signal=}'[Which signal to send]:signal:_signals' \
     {-f,--force}'[When enabling unit files, override existing symlinks. When shutting down, execute action immediately]' \
-    '--root=[Enable unit files in the specified root directory]:directory:_directories' \
-    '--runtime[Enable unit files only temporarily until next reboot]' \
+    '--root=[Enable/disable/mask unit files in the specified root directory]:directory:_directories' \
+    '--runtime[Enable/disable/mask unit files only temporarily until next reboot]' \
     {-H+,--host=}'[Operate on remote host]:userathost:_sd_hosts_or_user_at_host' \
     {-P,--privileged}'[Acquire privileges before execution]' \
     {-n+,--lines=}'[Journal entries to show]:number of entries' \
index 62114ff..ccac889 100644 (file)
@@ -1,4 +1,5 @@
 #compdef systemd-cat systemd-ask-password systemd-cgls systemd-cgtop systemd-detect-virt systemd-machine-id-setup systemd-notify systemd-tty-ask-password-agent
+# SPDX-License-Identifier: LGPL-2.1+
 
 local curcontext="$curcontext" state lstate line
 case "$service" in
index 22b4c18..ce22217 100644 (file)
@@ -1,4 +1,5 @@
 #compdef systemd-analyze
+# SPDX-License-Identifier: LGPL-2.1+
 
 _systemd_analyze_set-log-level() {
     local -a _levels
index 757f1b6..44e4cb3 100644 (file)
@@ -1,4 +1,5 @@
 #compdef systemd-delta
+# SPDX-License-Identifier: LGPL-2.1+
 
 _delta_type() {
     local -a _delta_types
index 1b3247b..764713e 100644 (file)
@@ -1,4 +1,5 @@
 #compdef systemd-inhibit
+# SPDX-License-Identifier: LGPL-2.1+
 
 _systemd_inhibit_command(){
     if (( CURRENT == 1 )); then
index 77b2e7c..e0bedee 100644 (file)
@@ -1,4 +1,5 @@
 #compdef systemd-nspawn
+# SPDX-License-Identifier: LGPL-2.1+
 
 _nspawn-caps(){
     local -a _caps
index c318ab5..eb7606a 100644 (file)
@@ -1,4 +1,5 @@
 #compdef systemd-resolve
+# SPDX-License-Identifier: LGPL-2.1+
 
 #
 # This file is part of systemd.
index 5c3e65c..0ad4b27 100644 (file)
@@ -1,4 +1,5 @@
 #compdef systemd-run
+# SPDX-License-Identifier: LGPL-2.1+
 
 __systemctl() {
         local -a _modes
index 6ff02e5..0993bca 100644 (file)
@@ -1,4 +1,5 @@
 #compdef systemd-tmpfiles
+# SPDX-License-Identifier: LGPL-2.1+
 
 _arguments \
     {-h,--help}'[Show help]' \
index dfdcfeb..c1ed21e 100644 (file)
@@ -1,4 +1,5 @@
 #compdef timedatectl
+# SPDX-License-Identifier: LGPL-2.1+
 
 _timedatectl_set-timezone(){
     local -a _timezones
index bb23e64..c6bd685 100644 (file)
@@ -1,4 +1,5 @@
 #compdef udevadm
+# SPDX-License-Identifier: LGPL-2.1+
 
 _udevadm_info(){
     _arguments \
index 4e7b33a..cf3c556 100644 (file)
@@ -1,3 +1,20 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
+# Copyright 2017 Zbigniew Jędrzejewski-Szmek
+#
+# 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.
+#
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
 zshcompletiondir = get_option('zshcompletiondir')
 if zshcompletiondir == ''
         zshcompletiondir = join_paths(datadir, 'zsh/site-functions')
index c527788..6d3172d 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 4b82dca..83807ef 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index f34c24c..461e785 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -146,7 +147,7 @@ static int verify_socket(Unit *u) {
 }
 
 static int verify_executable(Unit *u, ExecCommand *exec) {
-        if (exec == NULL)
+        if (!exec)
                 return 0;
 
         if (access(exec->path, X_OK) < 0)
index d5466ec..a895130 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 9fcc20d..d45c1dc 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -30,6 +31,7 @@
 #include "bus-error.h"
 #include "bus-unit-util.h"
 #include "bus-util.h"
+#include "calendarspec.h"
 #include "glob-util.h"
 #include "hashmap.h"
 #include "locale-util.h"
@@ -414,7 +416,7 @@ static int acquire_time_data(sd_bus *bus, struct unit_times **out) {
                         continue;
 
                 t->name = strdup(u.id);
-                if (t->name == NULL) {
+                if (!t->name) {
                         r = log_oom();
                         goto fail;
                 }
@@ -489,11 +491,40 @@ static int pretty_boot_time(sd_bus *bus, char **_buf) {
         size_t size;
         char *ptr;
         int r;
+        usec_t activated_time = USEC_INFINITY;
+        _cleanup_free_ char* path = NULL, *unit_id = NULL;
+        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
 
         r = acquire_boot_times(bus, &t);
         if (r < 0)
                 return r;
 
+        path = unit_dbus_path_from_name(SPECIAL_DEFAULT_TARGET);
+        if (!path)
+                return log_oom();
+
+        r = sd_bus_get_property_string(
+                        bus,
+                        "org.freedesktop.systemd1",
+                        path,
+                        "org.freedesktop.systemd1.Unit",
+                        "Id",
+                        &error,
+                        &unit_id);
+        if (r < 0) {
+                log_error_errno(r, "default.target doesn't seem to exist: %s", bus_error_message(&error, r));
+                unit_id = NULL;
+        }
+
+        r = bus_get_uint64_property(bus, path,
+                        "org.freedesktop.systemd1.Unit",
+                        "ActiveEnterTimestampMonotonic",
+                        &activated_time);
+        if (r < 0) {
+                log_info_errno(r, "default.target seems not to be started. Continuing...");
+                activated_time = USEC_INFINITY;
+        }
+
         ptr = buf;
         size = sizeof(buf);
 
@@ -510,6 +541,9 @@ static int pretty_boot_time(sd_bus *bus, char **_buf) {
         size = strpcpyf(&ptr, size, "%s (userspace) ", format_timespan(ts, sizeof(ts), t->finish_time - t->userspace_time, USEC_PER_MSEC));
         strpcpyf(&ptr, size, "= %s", format_timespan(ts, sizeof(ts), t->firmware_time + t->finish_time, USEC_PER_MSEC));
 
+        if (unit_id && activated_time != USEC_INFINITY)
+                size = strpcpyf(&ptr, size, "\n%s reached after %s in userspace", unit_id, format_timespan(ts, sizeof(ts), activated_time - t->userspace_time, USEC_PER_MSEC));
+
         ptr = strdup(buf);
         if (!ptr)
                 return log_oom();
@@ -786,7 +820,7 @@ static int list_dependencies_get_dependencies(sd_bus *bus, const char *name, cha
         assert(deps);
 
         path = unit_dbus_path_from_name(name);
-        if (path == NULL)
+        if (!path)
                 return -ENOMEM;
 
         return bus_get_unit_property_strv(bus, path, "After", deps);
@@ -844,7 +878,7 @@ static int list_dependencies_one(sd_bus *bus, const char *name, unsigned int lev
                 }
         }
 
-        if (service_longest == 0 )
+        if (service_longest == 0)
                 return r;
 
         STRV_FOREACH(c, deps) {
@@ -903,7 +937,7 @@ static int list_dependencies(sd_bus *bus, const char *name) {
         assert(bus);
 
         path = unit_dbus_path_from_name(name);
-        if (path == NULL)
+        if (!path)
                 return -ENOMEM;
 
         r = sd_bus_get_property(
@@ -1394,6 +1428,70 @@ static int dump_syscall_filters(char** names) {
 }
 #endif
 
+static int test_calendar(char **args) {
+        int ret = 0, r;
+        char **p;
+        usec_t n;
+
+        if (strv_isempty(args)) {
+                log_error("Expected at least one calendar specification string as argument.");
+                return -EINVAL;
+        }
+
+        n = now(CLOCK_REALTIME);
+
+        STRV_FOREACH(p, args) {
+                _cleanup_(calendar_spec_freep) CalendarSpec *spec = NULL;
+                _cleanup_free_ char *t = NULL;
+                usec_t next;
+
+                r = calendar_spec_from_string(*p, &spec);
+                if (r < 0) {
+                        ret = log_error_errno(r, "Failed to parse calendar specification '%s': %m", *p);
+                        continue;
+                }
+
+                r = calendar_spec_normalize(spec);
+                if (r < 0) {
+                        ret = log_error_errno(r, "Failed to normalize calendar specification '%s': %m", *p);
+                        continue;
+                }
+
+                r = calendar_spec_to_string(spec, &t);
+                if (r < 0) {
+                        ret = log_error_errno(r, "Failed to fomat calendar specification '%s': %m", *p);
+                        continue;
+                }
+
+                if (!streq(t, *p))
+                        printf("  Original form: %s\n", *p);
+
+                printf("Normalized form: %s\n", t);
+
+                r = calendar_spec_next_usec(spec, n, &next);
+                if (r == -ENOENT)
+                        printf("    Next elapse: never\n");
+                else if (r < 0) {
+                        ret = log_error_errno(r, "Failed to determine next elapse for '%s': %m", *p);
+                        continue;
+                } else {
+                        char buffer[CONST_MAX(FORMAT_TIMESTAMP_MAX, FORMAT_TIMESTAMP_RELATIVE_MAX)];
+
+                        printf("    Next elapse: %s\n", format_timestamp(buffer, sizeof(buffer), next));
+
+                        if (!in_utc_timezone())
+                                printf("       (in UTC): %s\n", format_timestamp_utc(buffer, sizeof(buffer), next));
+
+                        printf("       From now: %s\n", format_timestamp_relative(buffer, sizeof(buffer), next));
+                }
+
+                if (*(p+1))
+                        putchar('\n');
+        }
+
+        return ret;
+}
+
 static void help(void) {
 
         pager_open(arg_no_pager, false);
@@ -1428,6 +1526,7 @@ static void help(void) {
                "  dump                     Output state serialization of service manager\n"
                "  syscall-filter [NAME...] Print list of syscalls in seccomp filter\n"
                "  verify FILE...           Check unit files for correctness\n"
+               "  calendar SPEC...         Validate repetitive calendar time events\n"
                , program_invocation_short_name);
 
         /* When updating this list, including descriptions, apply
@@ -1617,6 +1716,8 @@ int main(int argc, char *argv[]) {
                         r = get_log_target(bus, argv+optind+1);
                 else if (streq(argv[optind], "syscall-filter"))
                         r = dump_syscall_filters(argv+optind+1);
+                else if (streq(argv[optind], "calendar"))
+                        r = test_calendar(argv+optind+1);
                 else
                         log_error("Unknown operation '%s'.", argv[optind]);
         }
index fcbd814..b323114 100644 (file)
@@ -1,3 +1,20 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
+# Copyright 2017 Zbigniew Jędrzejewski-Szmek
+#
+# 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.
+#
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
 systemd_analyze_sources = files('''
         analyze.c
         analyze-verify.c
index 6d53dd9..48cfaa7 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index c909b5b..8fedf8e 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index a282a21..47adfb4 100644 (file)
 
 #include "MurmurHash2.h"
 
+#if __GNUC__ >= 7
+_Pragma("GCC diagnostic ignored \"-Wimplicit-fallthrough\"")
+#endif
+
 //-----------------------------------------------------------------------------
 // Platform-specific functions and macros
 
index 4b291d1..fa81a69 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 6a4cc03..6565602 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 948389f..cdde4f2 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -37,7 +38,7 @@ void* memdup(const void *p, size_t l) {
         return ret;
 }
 
-void* memdup_suffix0(const void*p, size_t l) {
+void* memdup_suffix0(const void *p, size_t l) {
         void *ret;
 
         assert(l == 0 || p);
index 0a89691..02dee37 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -54,7 +55,7 @@ static inline void *mfree(void *memory) {
         })
 
 void* memdup(const void *p, size_t l) _alloc_(2);
-void* memdup_suffix0(const void*p, size_t l) _alloc_(2);
+void* memdup_suffix0(const void *p, size_t l) _alloc_(2);
 
 static inline void freep(void *p) {
         free(*(void**) p);
index 2518dd8..4615706 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 40a2ce6..c81a1c2 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 2d598dc..5df93a5 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index c0f8758..2222e92 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index a1f163f..d368b92 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 9bd13ff..7eac54d 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 24a6c8a..6a93c91 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 3088951..dba15de 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 0c44e47..cd3638b 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index fbc2d9d..7260d75 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index f6212e6..f1aa7c5 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 63fdbe8..f1d822c 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 53340ec..3aba76b 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index ce6f9e4..3690f81 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 35a41ff..146350d 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index c2061ad..ac96e63 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -41,6 +42,7 @@
 #include "btrfs-util.h"
 #include "chattr-util.h"
 #include "copy.h"
+#include "device-nodes.h"
 #include "fd-util.h"
 #include "fileio.h"
 #include "io-util.h"
@@ -909,7 +911,8 @@ int btrfs_subvol_set_subtree_quota_limit(const char *path, uint64_t subvol_id, u
 
 int btrfs_resize_loopback_fd(int fd, uint64_t new_size, bool grow_only) {
         struct btrfs_ioctl_vol_args args = {};
-        _cleanup_free_ char *p = NULL, *loop = NULL, *backing = NULL;
+        char p[SYS_BLOCK_PATH_MAX("/loop/backing_file")];
+        _cleanup_free_ char *backing = NULL;
         _cleanup_close_ int loop_fd = -1, backing_fd = -1;
         struct stat st;
         dev_t dev = 0;
@@ -929,8 +932,7 @@ int btrfs_resize_loopback_fd(int fd, uint64_t new_size, bool grow_only) {
         if (r == 0)
                 return -ENODEV;
 
-        if (asprintf(&p, "/sys/dev/block/%u:%u/loop/backing_file", major(dev), minor(dev)) < 0)
-                return -ENOMEM;
+        xsprintf_sys_block_path(p, "/loop/backing_file", dev);
         r = read_one_line_file(p, &backing);
         if (r == -ENOENT)
                 return -ENODEV;
@@ -954,9 +956,8 @@ int btrfs_resize_loopback_fd(int fd, uint64_t new_size, bool grow_only) {
         if (grow_only && new_size < (uint64_t) st.st_size)
                 return -EINVAL;
 
-        if (asprintf(&loop, "/dev/block/%u:%u", major(dev), minor(dev)) < 0)
-                return -ENOMEM;
-        loop_fd = open(loop, O_RDWR|O_CLOEXEC|O_NOCTTY);
+        xsprintf_sys_block_path(p, NULL, dev);
+        loop_fd = open(p, O_RDWR|O_CLOEXEC|O_NOCTTY);
         if (loop_fd < 0)
                 return -errno;
 
@@ -1212,7 +1213,7 @@ static int subvol_remove_children(int fd, const char *subvolume, uint64_t subvol
         if (!S_ISDIR(st.st_mode))
                 return -EINVAL;
 
-        subvol_fd = openat(fd, subvolume, O_RDONLY|O_NOCTTY|O_CLOEXEC|O_DIRECTORY);
+        subvol_fd = openat(fd, subvolume, O_RDONLY|O_NOCTTY|O_CLOEXEC|O_DIRECTORY|O_NOFOLLOW);
         if (subvol_fd < 0)
                 return -errno;
 
@@ -1292,7 +1293,7 @@ static int subvol_remove_children(int fd, const char *subvolume, uint64_t subvol
                                  * hence we need to open the
                                  * containing directory first */
 
-                                child_fd = openat(subvol_fd, ino_args.name, O_RDONLY|O_NOCTTY|O_CLOEXEC|O_DIRECTORY);
+                                child_fd = openat(subvol_fd, ino_args.name, O_RDONLY|O_NOCTTY|O_CLOEXEC|O_DIRECTORY|O_NOFOLLOW);
                                 if (child_fd < 0)
                                         return -errno;
 
@@ -1641,7 +1642,7 @@ static int subvol_snapshot_children(int old_fd, int new_fd, const char *subvolum
                         if (!c)
                                 return -ENOMEM;
 
-                        old_child_fd = openat(old_fd, c, O_RDONLY|O_NOCTTY|O_CLOEXEC|O_DIRECTORY);
+                        old_child_fd = openat(old_fd, c, O_RDONLY|O_NOCTTY|O_CLOEXEC|O_DIRECTORY|O_NOFOLLOW);
                         if (old_child_fd < 0)
                                 return -errno;
 
@@ -1649,7 +1650,7 @@ static int subvol_snapshot_children(int old_fd, int new_fd, const char *subvolum
                         if (!np)
                                 return -ENOMEM;
 
-                        new_child_fd = openat(new_fd, np, O_RDONLY|O_NOCTTY|O_CLOEXEC|O_DIRECTORY);
+                        new_child_fd = openat(new_fd, np, O_RDONLY|O_NOCTTY|O_CLOEXEC|O_DIRECTORY|O_NOFOLLOW);
                         if (new_child_fd < 0)
                                 return -errno;
 
@@ -1660,7 +1661,7 @@ static int subvol_snapshot_children(int old_fd, int new_fd, const char *subvolum
                                  * into place. */
 
                                 if (subvolume_fd < 0) {
-                                        subvolume_fd = openat(new_fd, subvolume, O_RDONLY|O_NOCTTY|O_CLOEXEC|O_DIRECTORY);
+                                        subvolume_fd = openat(new_fd, subvolume, O_RDONLY|O_NOCTTY|O_CLOEXEC|O_DIRECTORY|O_NOFOLLOW);
                                         if (subvolume_fd < 0)
                                                 return -errno;
                                 }
index 04a2e12..2c78daa 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 9aaa6e3..ab2a838 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index d4531c7..a072d0a 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 600268b..5c6bc1f 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 1fc9e9b..e6add0c 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -23,6 +24,7 @@
 #include <limits.h>
 #include <stddef.h>
 #include <stdio.h>
+#include <stdio_ext.h>
 #include <stdlib.h>
 #include <string.h>
 #include <sys/mman.h>
@@ -50,10 +52,10 @@ static void free_chain(CalendarComponent *c) {
         }
 }
 
-void calendar_spec_free(CalendarSpec *c) {
+CalendarSpec* calendar_spec_free(CalendarSpec *c) {
 
         if (!c)
-                return;
+                return NULL;
 
         free_chain(c->year);
         free_chain(c->month);
@@ -63,7 +65,7 @@ void calendar_spec_free(CalendarSpec *c) {
         free_chain(c->microsecond);
         free(c->timezone);
 
-        free(c);
+        return mfree(c);
 }
 
 static int component_compare(const void *_a, const void *_b) {
@@ -260,19 +262,19 @@ static void format_weekdays(FILE *f, const CalendarSpec *c) {
 
                         if (l < 0) {
                                 if (need_comma)
-                                        fputc_unlocked(',', f);
+                                        fputc(',', f);
                                 else
                                         need_comma = true;
 
-                                fputs_unlocked(days[x], f);
+                                fputs(days[x], f);
                                 l = x;
                         }
 
                 } else if (l >= 0) {
 
                         if (x > l + 1) {
-                                fputs_unlocked(x > l + 2 ? ".." : ",", f);
-                                fputs_unlocked(days[x-1], f);
+                                fputs(x > l + 2 ? ".." : ",", f);
+                                fputs(days[x-1], f);
                         }
 
                         l = -1;
@@ -280,8 +282,8 @@ static void format_weekdays(FILE *f, const CalendarSpec *c) {
         }
 
         if (l >= 0 && x > l + 1) {
-                fputs_unlocked(x > l + 2 ? ".." : ",", f);
-                fputs_unlocked(days[x-1], f);
+                fputs(x > l + 2 ? ".." : ",", f);
+                fputs(days[x-1], f);
         }
 }
 
@@ -291,12 +293,12 @@ static void format_chain(FILE *f, int space, const CalendarComponent *c, bool us
         assert(f);
 
         if (!c) {
-                fputc_unlocked('*', f);
+                fputc('*', f);
                 return;
         }
 
         if (usec && c->start == 0 && c->repeat == USEC_PER_SEC && !c->next) {
-                fputc_unlocked('*', f);
+                fputc('*', f);
                 return;
         }
 
@@ -317,7 +319,7 @@ static void format_chain(FILE *f, int space, const CalendarComponent *c, bool us
                 fprintf(f, ".%06i", c->repeat % d);
 
         if (c->next) {
-                fputc_unlocked(',', f);
+                fputc(',', f);
                 format_chain(f, space, c->next, usec);
         }
 }
@@ -335,28 +337,30 @@ int calendar_spec_to_string(const CalendarSpec *c, char **p) {
         if (!f)
                 return -ENOMEM;
 
+        (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
+
         if (c->weekdays_bits > 0 && c->weekdays_bits <= BITS_WEEKDAYS) {
                 format_weekdays(f, c);
-                fputc_unlocked(' ', f);
+                fputc(' ', f);
         }
 
         format_chain(f, 4, c->year, false);
-        fputc_unlocked('-', f);
+        fputc('-', f);
         format_chain(f, 2, c->month, false);
-        fputc_unlocked(c->end_of_month ? '~' : '-', f);
+        fputc(c->end_of_month ? '~' : '-', f);
         format_chain(f, 2, c->day, false);
-        fputc_unlocked(' ', f);
+        fputc(' ', f);
         format_chain(f, 2, c->hour, false);
-        fputc_unlocked(':', f);
+        fputc(':', f);
         format_chain(f, 2, c->minute, false);
-        fputc_unlocked(':', f);
+        fputc(':', f);
         format_chain(f, 2, c->microsecond, true);
 
         if (c->utc)
-                fputs_unlocked(" UTC", f);
+                fputs(" UTC", f);
         else if (c->timezone != NULL) {
-                fputc_unlocked(' ', f);
-                fputs_unlocked(c->timezone, f);
+                fputc(' ', f);
+                fputs(c->timezone, f);
         } else if (IN_SET(c->dst, 0, 1)) {
 
                 /* If daylight saving is explicitly on or off, let's show the used timezone. */
@@ -364,8 +368,8 @@ int calendar_spec_to_string(const CalendarSpec *c, char **p) {
                 tzset();
 
                 if (!isempty(tzname[c->dst])) {
-                        fputc_unlocked(' ', f);
-                        fputs_unlocked(tzname[c->dst], f);
+                        fputc(' ', f);
+                        fputs(tzname[c->dst], f);
                 }
         }
 
index 8888251..124f7f5 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -51,7 +52,7 @@ typedef struct CalendarSpec {
         CalendarComponent *microsecond;
 } CalendarSpec;
 
-void calendar_spec_free(CalendarSpec *c);
+CalendarSpec* calendar_spec_free(CalendarSpec *c);
 
 int calendar_spec_normalize(CalendarSpec *spec);
 bool calendar_spec_valid(CalendarSpec *spec);
@@ -60,3 +61,5 @@ int calendar_spec_to_string(const CalendarSpec *spec, char **p);
 int calendar_spec_from_string(const char *p, CalendarSpec **spec);
 
 int calendar_spec_next_usec(const CalendarSpec *spec, usec_t usec, usec_t *next);
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(CalendarSpec*, calendar_spec_free);
index 2e9b2d9..c455766 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -53,8 +54,12 @@ int capability_from_name(const char *name) {
 
         /* Try to parse numeric capability */
         r = safe_atoi(name, &i);
-        if (r >= 0 && i >= 0)
-                return i;
+        if (r >= 0) {
+                if (i >= 0 && i < (int) ELEMENTSOF(capability_names))
+                        return i;
+                else
+                        return -EINVAL;
+        }
 
         /* Try to parse string capability */
         sc = lookup_capability(name, strlen(name));
index f9f6b70..ca9f4aa 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 96c2e99..97778c5 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 3dc9429..fd9370e 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 94b11a2..d771647 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -23,6 +24,7 @@
 #include <limits.h>
 #include <signal.h>
 #include <stddef.h>
+#include <stdio_ext.h>
 #include <stdlib.h>
 #include <string.h>
 #include <sys/stat.h>
@@ -875,115 +877,87 @@ int cg_attach_fallback(const char *controller, const char *path, pid_t pid) {
         return r;
 }
 
-int cg_set_group_access(
+int cg_set_access(
                 const char *controller,
                 const char *path,
-                mode_t mode,
                 uid_t uid,
                 gid_t gid) {
 
-        _cleanup_free_ char *fs = NULL;
-        int r;
-
-        if (mode == MODE_INVALID && uid == UID_INVALID && gid == GID_INVALID)
-                return 0;
-
-        if (mode != MODE_INVALID)
-                mode &= 0777;
-
-        r = cg_get_path(controller, path, NULL, &fs);
-        if (r < 0)
-                return r;
-
-        r = chmod_and_chown(fs, mode, uid, gid);
-        if (r < 0)
-                return r;
-
-        r = cg_hybrid_unified();
-        if (r < 0)
-                return r;
-        if (r > 0 && streq(controller, SYSTEMD_CGROUP_CONTROLLER)) {
-                r = cg_set_group_access(SYSTEMD_CGROUP_CONTROLLER_LEGACY, path, mode, uid, gid);
-                if (r < 0)
-                        log_debug_errno(r, "Failed to set group access on compatibility systemd cgroup %s, ignoring: %m", path);
-        }
-
-        return 0;
-}
-
-int cg_set_task_access(
-                const char *controller,
-                const char *path,
-                mode_t mode,
-                uid_t uid,
-                gid_t gid) {
+        struct Attribute {
+                const char *name;
+                bool fatal;
+        };
+
+        /* cgroupsv1, aka legacy/non-unified */
+        static const struct Attribute legacy_attributes[] = {
+                { "cgroup.procs",           true  },
+                { "tasks",                  false },
+                { "cgroup.clone_children",  false },
+                {},
+        };
+
+        /* cgroupsv2, aka unified */
+        static const struct Attribute unified_attributes[] = {
+                { "cgroup.procs",           true  },
+                { "cgroup.subtree_control", true  },
+                { "cgroup.threads",         false },
+                {},
+        };
+
+        static const struct Attribute* const attributes[] = {
+                [false] = legacy_attributes,
+                [true]  = unified_attributes,
+        };
 
         _cleanup_free_ char *fs = NULL;
-        int r;
+        const struct Attribute *i;
+        int r, unified;
 
         assert(path);
 
-        if (mode == MODE_INVALID && uid == UID_INVALID && gid == GID_INVALID)
+        if (uid == UID_INVALID && gid == GID_INVALID)
                 return 0;
 
-        if (mode != MODE_INVALID)
-                mode &= 0666;
+        unified = cg_unified_controller(controller);
+        if (unified < 0)
+                return unified;
 
-        /* For both the legacy and unified hierarchies, "cgroup.procs" is the main entry point for PIDs */
-        r = cg_get_path(controller, path, "cgroup.procs", &fs);
+        /* Configure access to the cgroup itself */
+        r = cg_get_path(controller, path, NULL, &fs);
         if (r < 0)
                 return r;
 
-        r = chmod_and_chown(fs, mode, uid, gid);
+        r = chmod_and_chown(fs, 0755, uid, gid);
         if (r < 0)
                 return r;
 
-        r = cg_unified_controller(controller);
-        if (r < 0)
-                return r;
-        if (r == 0) {
-                const char *fn;
-
-                /* Compatibility: on cgroupsv1 always keep values for the legacy files "tasks" and
-                 * "cgroup.clone_children" in sync with "cgroup.procs". Since this is legacy stuff, we don't care if
-                 * this fails. */
-
-                FOREACH_STRING(fn,
-                               "tasks",
-                               "cgroup.clone_children") {
-
-                        fs = mfree(fs);
-
-                        r = cg_get_path(controller, path, fn, &fs);
-                        if (r < 0)
-                                log_debug_errno(r, "Failed to get path for %s of %s, ignoring: %m", fn, path);
-
-                        r = chmod_and_chown(fs, mode, uid, gid);
-                        if (r < 0)
-                                log_debug_errno(r, "Failed to to change ownership/access mode for %s of %s, ignoring: %m", fn, path);
-                }
-        } else {
-                /* On the unified controller, we want to permit subtree controllers too. */
-
+        /* Configure access to the cgroup's attributes */
+        for (i = attributes[unified]; i->name; i++) {
                 fs = mfree(fs);
-                r = cg_get_path(controller, path, "cgroup.subtree_control", &fs);
-                if (r < 0)
-                        return r;
 
-                r = chmod_and_chown(fs, mode, uid, gid);
+                r = cg_get_path(controller, path, i->name, &fs);
                 if (r < 0)
                         return r;
-        }
 
-        r = cg_hybrid_unified();
-        if (r < 0)
-                return r;
-        if (r > 0 && streq(controller, SYSTEMD_CGROUP_CONTROLLER)) {
-                /* Always propagate access mode from unified to legacy controller */
+                r = chmod_and_chown(fs, 0644, uid, gid);
+                if (r < 0) {
+                        if (i->fatal)
+                                return r;
+
+                        log_debug_errno(r, "Failed to set access on cgroup %s, ignoring: %m", fs);
+                }
+        }
 
-                r = cg_set_task_access(SYSTEMD_CGROUP_CONTROLLER_LEGACY, path, mode, uid, gid);
+        if (streq(controller, SYSTEMD_CGROUP_CONTROLLER)) {
+                r = cg_hybrid_unified();
                 if (r < 0)
-                        log_debug_errno(r, "Failed to set task access on compatibility systemd cgroup %s, ignoring: %m", path);
+                        return r;
+                if (r > 0) {
+                        /* Always propagate access mode from unified to legacy controller */
+                        r = cg_set_access(SYSTEMD_CGROUP_CONTROLLER_LEGACY, path, uid, gid);
+                        if (r < 0)
+                                log_debug_errno(r, "Failed to set access on compatibility systemd cgroup %s, ignoring: %m", path);
+                }
         }
 
         return 0;
@@ -1059,6 +1033,8 @@ int cg_pid_get_path(const char *controller, pid_t pid, char **path) {
         if (!f)
                 return errno == ENOENT ? -ESRCH : -errno;
 
+        (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
+
         FOREACH_LINE(line, f, return -errno) {
                 char *e, *p;
 
@@ -1103,6 +1079,11 @@ int cg_pid_get_path(const char *controller, pid_t pid, char **path) {
                 if (!p)
                         return -ENOMEM;
 
+                /* Truncate suffix indicating the process is a zombie */
+                e = endswith(p, " (deleted)");
+                if (e)
+                        *e = 0;
+
                 *path = p;
                 return 0;
         }
@@ -1278,7 +1259,7 @@ int cg_split_spec(const char *spec, char **controller, char **path) {
         assert(spec);
 
         if (*spec == '/') {
-                if (!path_is_safe(spec))
+                if (!path_is_normalized(spec))
                         return -EINVAL;
 
                 if (path) {
@@ -1331,7 +1312,7 @@ int cg_split_spec(const char *spec, char **controller, char **path) {
                         return -ENOMEM;
                 }
 
-                if (!path_is_safe(u) ||
+                if (!path_is_normalized(u) ||
                     !path_is_absolute(u)) {
                         free(t);
                         free(u);
@@ -1496,7 +1477,7 @@ static bool valid_slice_name(const char *p, size_t n) {
         if (!p)
                 return false;
 
-        if (n < strlen("x.slice"))
+        if (n < STRLEN("x.slice"))
                 return false;
 
         if (memcmp(p + n - 6, ".slice", 6) == 0) {
@@ -1580,7 +1561,7 @@ static const char *skip_session(const char *p) {
         p += strspn(p, "/");
 
         n = strcspn(p, "/");
-        if (n < strlen("session-x.scope"))
+        if (n < STRLEN("session-x.scope"))
                 return NULL;
 
         if (memcmp(p, "session-", 8) == 0 && memcmp(p + n - 6, ".scope", 6) == 0) {
@@ -1617,7 +1598,7 @@ static const char *skip_user_manager(const char *p) {
         p += strspn(p, "/");
 
         n = strcspn(p, "/");
-        if (n < strlen("user@x.service"))
+        if (n < STRLEN("user@x.service"))
                 return NULL;
 
         if (memcmp(p, "user@", 5) == 0 && memcmp(p + n - 8, ".service", 8) == 0) {
@@ -2089,8 +2070,7 @@ int cg_get_keyed_attribute(const char *controller, const char *path, const char
         for (i = 0; keys[i]; i++) {
                 if (!values[i]) {
                         for (i = 0; keys[i]; i++) {
-                                free(values[i]);
-                                values[i] = NULL;
+                                values[i] = mfree(values[i]);
                         }
                         return -ENOENT;
                 }
@@ -2247,10 +2227,10 @@ int cg_trim_everywhere(CGroupMask supported, const char *path, bool delete_root)
 }
 
 int cg_mask_to_string(CGroupMask mask, char **ret) {
-        const char *controllers[_CGROUP_CONTROLLER_MAX + 1];
+        _cleanup_free_ char *s = NULL;
+        size_t n = 0, allocated = 0;
+        bool space = false;
         CGroupController c;
-        int i = 0;
-        char *s;
 
         assert(ret);
 
@@ -2260,19 +2240,32 @@ int cg_mask_to_string(CGroupMask mask, char **ret) {
         }
 
         for (c = 0; c < _CGROUP_CONTROLLER_MAX; c++) {
+                const char *k;
+                size_t l;
 
                 if (!(mask & CGROUP_CONTROLLER_TO_MASK(c)))
                         continue;
 
-                controllers[i++] = cgroup_controller_to_string(c);
-                controllers[i] = NULL;
+                k = cgroup_controller_to_string(c);
+                l = strlen(k);
+
+                if (!GREEDY_REALLOC(s, allocated, n + space + l + 1))
+                        return -ENOMEM;
+
+                if (space)
+                        s[n] = ' ';
+                memcpy(s + n + space, k, l);
+                n += space + l;
+
+                space = true;
         }
 
-        s = strv_join((char **)controllers, NULL);
-        if (!s)
-                return -ENOMEM;
+        assert(s);
 
+        s[n] = 0;
         *ret = s;
+        s = NULL;
+
         return 0;
 }
 
@@ -2358,24 +2351,34 @@ int cg_mask_supported(CGroupMask *ret) {
         return 0;
 }
 
-int cg_kernel_controllers(Set *controllers) {
+int cg_kernel_controllers(Set **ret) {
+        _cleanup_set_free_free_ Set *controllers = NULL;
         _cleanup_fclose_ FILE *f = NULL;
         int r;
 
-        assert(controllers);
+        assert(ret);
 
         /* Determines the full list of kernel-known controllers. Might
          * include controllers we don't actually support, arbitrary
          * named hierarchies and controllers that aren't currently
          * accessible (because not mounted). */
 
+        controllers = set_new(&string_hash_ops);
+        if (!controllers)
+                return -ENOMEM;
+
         f = fopen("/proc/cgroups", "re");
         if (!f) {
-                if (errno == ENOENT)
+                if (errno == ENOENT) {
+                        *ret = NULL;
                         return 0;
+                }
+
                 return -errno;
         }
 
+        (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
+
         /* Ignore the header line */
         (void) read_line(f, (size_t) -1, NULL);
 
@@ -2410,6 +2413,9 @@ int cg_kernel_controllers(Set *controllers) {
                         return r;
         }
 
+        *ret = controllers;
+        controllers = NULL;
+
         return 0;
 }
 
@@ -2439,28 +2445,39 @@ static int cg_unified_update(void) {
                 return 0;
 
         if (statfs("/sys/fs/cgroup/", &fs) < 0)
-                return -errno;
+                return log_debug_errno(errno, "statfs(\"/sys/fs/cgroup/\" failed: %m");
 
-        if (F_TYPE_EQUAL(fs.f_type, CGROUP2_SUPER_MAGIC))
+        if (F_TYPE_EQUAL(fs.f_type, CGROUP2_SUPER_MAGIC)) {
+                log_debug("Found cgroup2 on /sys/fs/cgroup/, full unified hierarchy");
                 unified_cache = CGROUP_UNIFIED_ALL;
-        else if (F_TYPE_EQUAL(fs.f_type, TMPFS_MAGIC)) {
+        else if (F_TYPE_EQUAL(fs.f_type, TMPFS_MAGIC)) {
                 if (statfs("/sys/fs/cgroup/unified/", &fs) == 0 &&
                     F_TYPE_EQUAL(fs.f_type, CGROUP2_SUPER_MAGIC)) {
+                        log_debug("Found cgroup2 on /sys/fs/cgroup/unified, unified hierarchy for systemd controller");
                         unified_cache = CGROUP_UNIFIED_SYSTEMD;
                         unified_systemd_v232 = false;
-                } else if (statfs("/sys/fs/cgroup/systemd/", &fs) == 0 &&
-                           F_TYPE_EQUAL(fs.f_type, CGROUP2_SUPER_MAGIC)) {
-                        unified_cache = CGROUP_UNIFIED_SYSTEMD;
-                        unified_systemd_v232 = true;
                 } else {
                         if (statfs("/sys/fs/cgroup/systemd/", &fs) < 0)
-                                return -errno;
-                        if (!F_TYPE_EQUAL(fs.f_type, CGROUP_SUPER_MAGIC))
-                                return -ENOMEDIUM;
-                        unified_cache = CGROUP_UNIFIED_NONE;
+                                return log_debug_errno(errno, "statfs(\"/sys/fs/cgroup/systemd\" failed: %m");
+
+                        if (F_TYPE_EQUAL(fs.f_type, CGROUP2_SUPER_MAGIC)) {
+                                log_debug("Found cgroup2 on /sys/fs/cgroup/systemd, unified hierarchy for systemd controller (v232 variant)");
+                                unified_cache = CGROUP_UNIFIED_SYSTEMD;
+                                unified_systemd_v232 = true;
+                        } else if (F_TYPE_EQUAL(fs.f_type, CGROUP_SUPER_MAGIC)) {
+                                log_debug("Found cgroup on /sys/fs/cgroup/systemd, legacy hierarchy");
+                                unified_cache = CGROUP_UNIFIED_NONE;
+                        } else {
+                                log_debug("Unexpected filesystem type %llx mounted on /sys/fs/cgroup/systemd, assuming legacy hierarchy",
+                                          (unsigned long long) fs.f_type);
+                                unified_cache = CGROUP_UNIFIED_NONE;
+                        }
                 }
-        } else
+        } else {
+                log_debug("Unknown filesystem type %llx mounted on /sys/fs/cgroup.",
+                          (unsigned long long) fs.f_type);
                 return -ENOMEDIUM;
+        }
 
         return 0;
 }
@@ -2508,6 +2525,7 @@ int cg_unified_flush(void) {
 }
 
 int cg_enable_everywhere(CGroupMask supported, CGroupMask mask, const char *p) {
+        _cleanup_fclose_ FILE *f = NULL;
         _cleanup_free_ char *fs = NULL;
         CGroupController c;
         int r;
@@ -2541,7 +2559,15 @@ int cg_enable_everywhere(CGroupMask supported, CGroupMask mask, const char *p) {
                         s[0] = mask & bit ? '+' : '-';
                         strcpy(s + 1, n);
 
-                        r = write_string_file(fs, s, 0);
+                        if (!f) {
+                                f = fopen(fs, "we");
+                                if (!f) {
+                                        log_debug_errno(errno, "Failed to open cgroup.subtree_control file of %s: %m", p);
+                                        break;
+                                }
+                        }
+
+                        r = write_string_stream(f, s, 0);
                         if (r < 0)
                                 log_debug_errno(r, "Failed to enable controller %s for %s (%s): %m", n, p, fs);
                 }
index c16a337..05c9f84 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
 #include "macro.h"
 #include "set.h"
 
+#define SYSTEMD_CGROUP_CONTROLLER_LEGACY "name=systemd"
+#define SYSTEMD_CGROUP_CONTROLLER_HYBRID "name=unified"
+#define SYSTEMD_CGROUP_CONTROLLER "_systemd"
+
 /* An enum of well known cgroup controllers */
 typedef enum CGroupController {
         CGROUP_CONTROLLER_CPU,
-        CGROUP_CONTROLLER_CPUACCT,
-        CGROUP_CONTROLLER_IO,
-        CGROUP_CONTROLLER_BLKIO,
+        CGROUP_CONTROLLER_CPUACCT,    /* v1 only */
+        CGROUP_CONTROLLER_IO,         /* v2 only */
+        CGROUP_CONTROLLER_BLKIO,      /* v1 only */
         CGROUP_CONTROLLER_MEMORY,
-        CGROUP_CONTROLLER_DEVICES,
+        CGROUP_CONTROLLER_DEVICES,    /* v1 only */
         CGROUP_CONTROLLER_PIDS,
         _CGROUP_CONTROLLER_MAX,
         _CGROUP_CONTROLLER_INVALID = -1,
@@ -183,8 +188,7 @@ int cg_set_attribute(const char *controller, const char *path, const char *attri
 int cg_get_attribute(const char *controller, const char *path, const char *attribute, char **ret);
 int cg_get_keyed_attribute(const char *controller, const char *path, const char *attribute, const char **keys, char **values);
 
-int cg_set_group_access(const char *controller, const char *path, mode_t mode, uid_t uid, gid_t gid);
-int cg_set_task_access(const char *controller, const char *path, mode_t mode, uid_t uid, gid_t gid);
+int cg_set_access(const char *controller, const char *path, uid_t uid, gid_t gid);
 
 int cg_set_xattr(const char *controller, const char *path, const char *name, const void *value, size_t size, int flags);
 int cg_get_xattr(const char *controller, const char *path, const char *name, void *value, size_t size);
@@ -238,7 +242,7 @@ int cg_mask_supported(CGroupMask *ret);
 int cg_mask_from_string(const char *s, CGroupMask *ret);
 int cg_mask_to_string(CGroupMask mask, char **ret);
 
-int cg_kernel_controllers(Set *controllers);
+int cg_kernel_controllers(Set **controllers);
 
 bool cg_ns_supported(void);
 
index 2896a72..3635dee 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 960cf6d..a4ddaee 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 3b617c0..6fa1fe8 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -72,7 +73,7 @@ int clock_set_hwclock(const struct tm *tm) {
 int clock_is_localtime(const char* adjtime_path) {
         _cleanup_fclose_ FILE *f;
 
-        if (adjtime_path == NULL)
+        if (!adjtime_path)
                 adjtime_path = "/etc/adjtime";
 
         /*
index facf933..c297f16 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 907d135..c0ac202 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 20ecf6e..75dfd05 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index e120b9e..0673ecd 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 4f3e114..59da4c2 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index aec0edc..9f0a61a 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -59,19 +60,19 @@ cpu_set_t* cpu_set_malloc(unsigned *ncpus) {
         }
 }
 
-int parse_cpu_set_and_warn(
+int parse_cpu_set_internal(
                 const char *rvalue,
                 cpu_set_t **cpu_set,
+                bool warn,
                 const char *unit,
                 const char *filename,
                 unsigned line,
                 const char *lvalue) {
 
-        const char *whole_rvalue = rvalue;
         _cleanup_cpu_free_ cpu_set_t *c = NULL;
+        const char *p = rvalue;
         unsigned ncpus = 0;
 
-        assert(lvalue);
         assert(rvalue);
 
         for (;;) {
@@ -79,75 +80,34 @@ int parse_cpu_set_and_warn(
                 unsigned cpu, cpu_lower, cpu_upper;
                 int r;
 
-                r = extract_first_word(&rvalue, &word, WHITESPACE ",", EXTRACT_QUOTES);
+                r = extract_first_word(&p, &word, WHITESPACE ",", EXTRACT_QUOTES);
+                if (r == -ENOMEM)
+                        return warn ? log_oom() : -ENOMEM;
                 if (r < 0)
-                        return log_syntax(unit, LOG_ERR, filename, line, r, "Invalid value for %s: %s", lvalue, whole_rvalue);
+                        return warn ? log_syntax(unit, LOG_ERR, filename, line, r, "Invalid value for %s: %s", lvalue, rvalue) : r;
                 if (r == 0)
                         break;
 
                 if (!c) {
                         c = cpu_set_malloc(&ncpus);
                         if (!c)
-                                return log_oom();
+                                return warn ? log_oom() : -ENOMEM;
                 }
 
                 r = parse_range(word, &cpu_lower, &cpu_upper);
                 if (r < 0)
-                        return log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse CPU affinity '%s'", word);
+                        return warn ? log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse CPU affinity '%s'", word) : r;
                 if (cpu_lower >= ncpus || cpu_upper >= ncpus)
-                        return log_syntax(unit, LOG_ERR, filename, line, EINVAL, "CPU out of range '%s' ncpus is %u", word, ncpus);
-
-                if (cpu_lower > cpu_upper)
-                        log_syntax(unit, LOG_WARNING, filename, line, 0, "Range '%s' is invalid, %u > %u", word, cpu_lower, cpu_upper);
-                else
-                        for (cpu = cpu_lower; cpu <= cpu_upper; cpu++)
-                                CPU_SET_S(cpu, CPU_ALLOC_SIZE(ncpus), c);
-        }
-
-        /* On success, sets *cpu_set and returns ncpus for the system. */
-        if (c) {
-                *cpu_set = c;
-                c = NULL;
-        }
-
-        return (int) ncpus;
-}
-
-int parse_cpu_set(
-                const char *rvalue,
-                cpu_set_t **cpu_set) {
-
-        _cleanup_cpu_free_ cpu_set_t *c = NULL;
-        unsigned ncpus = 0;
+                        return warn ? log_syntax(unit, LOG_ERR, filename, line, EINVAL, "CPU out of range '%s' ncpus is %u", word, ncpus) : -EINVAL;
 
-        assert(rvalue);
-
-        for (;;) {
-                _cleanup_free_ char *word = NULL;
-                unsigned cpu, cpu_lower, cpu_upper;
-                int r;
-
-                r = extract_first_word(&rvalue, &word, WHITESPACE ",", EXTRACT_QUOTES);
-                if (r == -ENOMEM)
-                        return r;
-                if (r <= 0)
-                        break;
-
-                if (!c) {
-                        c = cpu_set_malloc(&ncpus);
-                        if (!c)
-                                return -ENOMEM;
+                if (cpu_lower > cpu_upper) {
+                        if (warn)
+                                log_syntax(unit, LOG_WARNING, filename, line, 0, "Range '%s' is invalid, %u > %u, ignoring", word, cpu_lower, cpu_upper);
+                        continue;
                 }
 
-                r = parse_range(word, &cpu_lower, &cpu_upper);
-                if (r < 0)
-                        return r;
-                if (cpu_lower >= ncpus || cpu_upper >= ncpus)
-                        return -EINVAL;
-
-                if (cpu_lower <= cpu_upper)
-                        for (cpu = cpu_lower; cpu <= cpu_upper; cpu++)
-                                CPU_SET_S(cpu, CPU_ALLOC_SIZE(ncpus), c);
+                for (cpu = cpu_lower; cpu <= cpu_upper; cpu++)
+                        CPU_SET_S(cpu, CPU_ALLOC_SIZE(ncpus), c);
         }
 
         /* On success, sets *cpu_set and returns ncpus for the system. */
index 9b08ba0..c98149e 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
 
 #include "macro.h"
 
+#ifdef __NCPUBITS
+#define CPU_SIZE_TO_NUM(n) ((n) * __NCPUBITS)
+#else
+#define CPU_SIZE_TO_NUM(n) ((n) * sizeof(cpu_set_t) * 8)
+#endif
+
 DEFINE_TRIVIAL_CLEANUP_FUNC(cpu_set_t*, CPU_FREE);
 #define _cleanup_cpu_free_ _cleanup_(CPU_FREEp)
 
+static inline cpu_set_t* cpu_set_mfree(cpu_set_t *p) {
+        if (p)
+                CPU_FREE(p);
+        return NULL;
+}
+
 cpu_set_t* cpu_set_malloc(unsigned *ncpus);
 
-int parse_cpu_set_and_warn(const char *rvalue, cpu_set_t **cpu_set, const char *unit, const char *filename, unsigned line, const char *lvalue);
-int parse_cpu_set(const char *rvalue, cpu_set_t **cpu_set);
+int parse_cpu_set_internal(const char *rvalue, cpu_set_t **cpu_set, bool warn, const char *unit, const char *filename, unsigned line, const char *lvalue);
+
+static inline int parse_cpu_set_and_warn(const char *rvalue, cpu_set_t **cpu_set, const char *unit, const char *filename, unsigned line, const char *lvalue) {
+        assert(lvalue);
+
+        return parse_cpu_set_internal(rvalue, cpu_set, true, unit, filename, line, lvalue);
+}
+
+static inline int parse_cpu_set(const char *rvalue, cpu_set_t **cpu_set){
+        return parse_cpu_set_internal(rvalue, cpu_set, false, NULL, NULL, 0, NULL);
+}
diff --git a/src/basic/crypt-util.c b/src/basic/crypt-util.c
new file mode 100644 (file)
index 0000000..193cf65
--- /dev/null
@@ -0,0 +1,27 @@
+/***
+  This file is part of systemd.
+
+  Copyright 2017 Zbigniew Jędrzejewski-Szmek
+
+  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.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#if HAVE_LIBCRYPTSETUP
+#include "crypt-util.h"
+#include "log.h"
+
+void cryptsetup_log_glue(int level, const char *msg, void *usrptr) {
+        log_debug("%s", msg);
+}
+#endif
diff --git a/src/basic/crypt-util.h b/src/basic/crypt-util.h
new file mode 100644 (file)
index 0000000..537f785
--- /dev/null
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+/***
+  This file is part of systemd.
+
+  Copyright 2017 Zbigniew Jędrzejewski-Szmek
+
+  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.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#if HAVE_LIBCRYPTSETUP
+#include <libcryptsetup.h>
+
+#include "macro.h"
+
+/* libcryptsetup define for any LUKS version, compatible with libcryptsetup 1.x */
+#ifndef CRYPT_LUKS
+#define CRYPT_LUKS NULL
+#endif
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(struct crypt_device *, crypt_free);
+
+void cryptsetup_log_glue(int level, const char *msg, void *usrptr);
+#endif
index c04e58b..77ab735 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
 /* The default value for the net.unix.max_dgram_qlen sysctl */
 #define DEFAULT_UNIX_MAX_DGRAM_QLEN 512UL
 
-#define SYSTEMD_CGROUP_CONTROLLER_LEGACY "name=systemd"
-#define SYSTEMD_CGROUP_CONTROLLER_HYBRID "name=unified"
-#define SYSTEMD_CGROUP_CONTROLLER "_systemd"
-
 #define SIGNALS_CRASH_HANDLER SIGSEGV,SIGILL,SIGFPE,SIGBUS,SIGQUIT,SIGABRT
 #define SIGNALS_IGNORE SIGPIPE
 
index 38c0628..61dc492 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -39,7 +40,7 @@ int whitelisted_char_for_devnode(char c, const char *white) {
 int encode_devnode_name(const char *str, char *str_enc, size_t len) {
         size_t i, j;
 
-        if (str == NULL || str_enc == NULL)
+        if (!str || !str_enc)
                 return -EINVAL;
 
         for (i = 0, j = 0; str[i] != '\0'; i++) {
index 94f385a..7dd8a77 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
 #include <stddef.h>
 #include <sys/types.h>
 
+#include "macro.h"
+#include "stdio-util.h"
+
 int encode_devnode_name(const char *str, char *str_enc, size_t len);
 int whitelisted_char_for_devnode(char c, const char *additional);
+
+#define SYS_BLOCK_PATH_MAX(suffix)                                      \
+        (STRLEN("/sys/dev/block/") + DECIMAL_STR_MAX(dev_t) + 1 + DECIMAL_STR_MAX(dev_t) + strlen_ptr(suffix))
+#define xsprintf_sys_block_path(buf, suffix, devno)                     \
+        xsprintf(buf, "/sys/dev/block/%u:%u%s", major(devno), minor(devno), strempty(suffix))
+
+#define DEV_NUM_PATH_MAX                                                \
+        (STRLEN("/dev/block/") + DECIMAL_STR_MAX(dev_t) + 1 + DECIMAL_STR_MAX(dev_t))
+#define xsprintf_dev_num_path(buf, type, devno)                         \
+        xsprintf(buf, "/dev/%s/%u:%u", type, major(devno), minor(devno))
index 5bf58bc..e2b093b 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 18b9db9..94d5ee8 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index fa42edf..e77f9d6 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -805,14 +806,9 @@ int deserialize_environment(char ***environment, const char *line) {
         assert(environment);
 
         assert(startswith(line, "env="));
-        r = cunescape(line + 4, UNESCAPE_RELAX, &uce);
+        r = cunescape(line + 4, 0, &uce);
         if (r < 0)
                 return r;
 
-        if (!env_assignment_is_valid(uce)) {
-                free(uce);
-                return -EINVAL;
-        }
-
         return strv_env_replace(environment, uce);
 }
index d5da8cd..956a2a8 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index c6a01ee..d8eedfc 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -51,7 +52,3 @@ int errno_from_name(const char *name) {
         assert(sc->id > 0);
         return sc->id;
 }
-
-int errno_max(void) {
-        return ELEMENTSOF(errno_names);
-}
index 4eec0cc..4e9b75a 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
+/*
+ * MAX_ERRNO is defined as 4095 in linux/err.h
+ * We use the same value here.
+ */
+#define ERRNO_MAX 4095
+
 const char *errno_to_name(int id);
 int errno_from_name(const char *name);
-
-int errno_max(void);
index 0a6122c..7d77aef 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 6f5cc60..de89f43 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 5697e8d..bbe8bf0 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -70,7 +71,7 @@ int ether_addr_from_string(const char *s, struct ether_addr *ret, size_t *offset
                         if (s[pos] == '\0')                     \
                                 break;                          \
                         hexoff = strchr(hex, s[pos]);           \
-                        if (hexoff == NULL)                     \
+                        if (!hexoff)                            \
                                 break;                          \
                         assert(hexoff >= hex);                  \
                         x = hexoff - hex;                       \
@@ -98,7 +99,7 @@ int ether_addr_from_string(const char *s, struct ether_addr *ret, size_t *offset
         sep = s[strspn(s, hex)];
         if (sep == '\n')
                 return -EINVAL;
-        if (strchr(":.-", sep) == NULL)
+        if (!strchr(":.-", sep))
                 return -EINVAL;
 
         if (sep == '.') {
index 74e125a..08d05a1 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index ade8511..82ccbdf 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -255,7 +256,7 @@ int execute_directories(
 static int gather_environment_generate(int fd, void *arg) {
         char ***env = arg, **x, **y;
         _cleanup_fclose_ FILE *f = NULL;
-        _cleanup_strv_free_ char **new;
+        _cleanup_strv_free_ char **new = NULL;
         int r;
 
         /* Read a series of VAR=value assignments from fd, use them to update the list of
index 7200979..d69bec7 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 7cfebba..c02681d 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 195b3bc..1e10419 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index f4ac526..5e42560 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 04746c6..300c51b 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 4d2f047..409d029 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
 
 #include "dirent-util.h"
 #include "fd-util.h"
+#include "fileio.h"
 #include "fs-util.h"
 #include "macro.h"
+#include "memfd-util.h"
 #include "missing.h"
 #include "parse-util.h"
 #include "path-util.h"
@@ -365,7 +368,7 @@ bool fdname_is_valid(const char *s) {
 }
 
 int fd_get_path(int fd, char **ret) {
-        char procfs_path[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(int)];
+        char procfs_path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)];
         int r;
 
         xsprintf(procfs_path, "/proc/self/fd/%i", fd);
@@ -377,3 +380,202 @@ int fd_get_path(int fd, char **ret) {
 
         return r;
 }
+
+int move_fd(int from, int to, int cloexec) {
+        int r;
+
+        /* Move fd 'from' to 'to', make sure FD_CLOEXEC remains equal if requested, and release the old fd. If
+         * 'cloexec' is passed as -1, the original FD_CLOEXEC is inherited for the new fd. If it is 0, it is turned
+         * off, if it is > 0 it is turned on. */
+
+        if (from < 0)
+                return -EBADF;
+        if (to < 0)
+                return -EBADF;
+
+        if (from == to) {
+
+                if (cloexec >= 0) {
+                        r = fd_cloexec(to, cloexec);
+                        if (r < 0)
+                                return r;
+                }
+
+                return to;
+        }
+
+        if (cloexec < 0) {
+                int fl;
+
+                fl = fcntl(from, F_GETFD, 0);
+                if (fl < 0)
+                        return -errno;
+
+                cloexec = !!(fl & FD_CLOEXEC);
+        }
+
+        r = dup3(from, to, cloexec ? O_CLOEXEC : 0);
+        if (r < 0)
+                return -errno;
+
+        assert(r == to);
+
+        safe_close(from);
+
+        return to;
+}
+
+int acquire_data_fd(const void *data, size_t size, unsigned flags) {
+
+        char procfs_path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)];
+        _cleanup_close_pair_ int pipefds[2] = { -1, -1 };
+        char pattern[] = "/dev/shm/data-fd-XXXXXX";
+        _cleanup_close_ int fd = -1;
+        int isz = 0, r;
+        ssize_t n;
+        off_t f;
+
+        assert(data || size == 0);
+
+        /* Acquire a read-only file descriptor that when read from returns the specified data. This is much more
+         * complex than I wish it was. But here's why:
+         *
+         * a) First we try to use memfds. They are the best option, as we can seal them nicely to make them
+         *    read-only. Unfortunately they require kernel 3.17, and – at the time of writing – we still support 3.14.
+         *
+         * b) Then, we try classic pipes. They are the second best options, as we can close the writing side, retaining
+         *    a nicely read-only fd in the reading side. However, they are by default quite small, and unprivileged
+         *    clients can only bump their size to a system-wide limit, which might be quite low.
+         *
+         * c) Then, we try an O_TMPFILE file in /dev/shm (that dir is the only suitable one known to exist from
+         *    earliest boot on). To make it read-only we open the fd a second time with O_RDONLY via
+         *    /proc/self/<fd>. Unfortunately O_TMPFILE is not available on older kernels on tmpfs.
+         *
+         * d) Finally, we try creating a regular file in /dev/shm, which we then delete.
+         *
+         * It sucks a bit that depending on the situation we return very different objects here, but that's Linux I
+         * figure. */
+
+        if (size == 0 && ((flags & ACQUIRE_NO_DEV_NULL) == 0)) {
+                /* As a special case, return /dev/null if we have been called for an empty data block */
+                r = open("/dev/null", O_RDONLY|O_CLOEXEC|O_NOCTTY);
+                if (r < 0)
+                        return -errno;
+
+                return r;
+        }
+
+        if ((flags & ACQUIRE_NO_MEMFD) == 0) {
+                fd = memfd_new("data-fd");
+                if (fd < 0)
+                        goto try_pipe;
+
+                n = write(fd, data, size);
+                if (n < 0)
+                        return -errno;
+                if ((size_t) n != size)
+                        return -EIO;
+
+                f = lseek(fd, 0, SEEK_SET);
+                if (f != 0)
+                        return -errno;
+
+                r = memfd_set_sealed(fd);
+                if (r < 0)
+                        return r;
+
+                r = fd;
+                fd = -1;
+
+                return r;
+        }
+
+try_pipe:
+        if ((flags & ACQUIRE_NO_PIPE) == 0) {
+                if (pipe2(pipefds, O_CLOEXEC|O_NONBLOCK) < 0)
+                        return -errno;
+
+                isz = fcntl(pipefds[1], F_GETPIPE_SZ, 0);
+                if (isz < 0)
+                        return -errno;
+
+                if ((size_t) isz < size) {
+                        isz = (int) size;
+                        if (isz < 0 || (size_t) isz != size)
+                                return -E2BIG;
+
+                        /* Try to bump the pipe size */
+                        (void) fcntl(pipefds[1], F_SETPIPE_SZ, isz);
+
+                        /* See if that worked */
+                        isz = fcntl(pipefds[1], F_GETPIPE_SZ, 0);
+                        if (isz < 0)
+                                return -errno;
+
+                        if ((size_t) isz < size)
+                                goto try_dev_shm;
+                }
+
+                n = write(pipefds[1], data, size);
+                if (n < 0)
+                        return -errno;
+                if ((size_t) n != size)
+                        return -EIO;
+
+                (void) fd_nonblock(pipefds[0], false);
+
+                r = pipefds[0];
+                pipefds[0] = -1;
+
+                return r;
+        }
+
+try_dev_shm:
+        if ((flags & ACQUIRE_NO_TMPFILE) == 0) {
+                fd = open("/dev/shm", O_RDWR|O_TMPFILE|O_CLOEXEC, 0500);
+                if (fd < 0)
+                        goto try_dev_shm_without_o_tmpfile;
+
+                n = write(fd, data, size);
+                if (n < 0)
+                        return -errno;
+                if ((size_t) n != size)
+                        return -EIO;
+
+                /* Let's reopen the thing, in order to get an O_RDONLY fd for the original O_RDWR one */
+                xsprintf(procfs_path, "/proc/self/fd/%i", fd);
+                r = open(procfs_path, O_RDONLY|O_CLOEXEC);
+                if (r < 0)
+                        return -errno;
+
+                return r;
+        }
+
+try_dev_shm_without_o_tmpfile:
+        if ((flags & ACQUIRE_NO_REGULAR) == 0) {
+                fd = mkostemp_safe(pattern);
+                if (fd < 0)
+                        return fd;
+
+                n = write(fd, data, size);
+                if (n < 0) {
+                        r = -errno;
+                        goto unlink_and_return;
+                }
+                if ((size_t) n != size) {
+                        r = -EIO;
+                        goto unlink_and_return;
+                }
+
+                /* Let's reopen the thing, in order to get an O_RDONLY fd for the original O_RDWR one */
+                r = open(pattern, O_RDONLY|O_CLOEXEC);
+                if (r < 0)
+                        r = -errno;
+
+        unlink_and_return:
+                (void) unlink(pattern);
+                return r;
+        }
+
+        return -EOPNOTSUPP;
+}
index 34b98d4..84a0816 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -75,6 +76,18 @@ bool fdname_is_valid(const char *s);
 
 int fd_get_path(int fd, char **ret);
 
+int move_fd(int from, int to, int cloexec);
+
+enum {
+        ACQUIRE_NO_DEV_NULL = 1 << 0,
+        ACQUIRE_NO_MEMFD    = 1 << 1,
+        ACQUIRE_NO_PIPE     = 1 << 2,
+        ACQUIRE_NO_TMPFILE  = 1 << 3,
+        ACQUIRE_NO_REGULAR  = 1 << 4,
+};
+
+int acquire_data_fd(const void *data, size_t size, unsigned flags);
+
 /* Hint: ENETUNREACH happens if we try to connect to "non-existing" special IP addresses, such as ::5 */
 #define ERRNO_IS_DISCONNECT(r) \
         IN_SET(r, ENOTCONN, ECONNRESET, ECONNREFUSED, ECONNABORTED, EPIPE, ENETUNREACH)
index ef51c49..bf5fec1 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 9854ea5..0adb895 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
 
 #include "fileio.h"
 
+/* These functions are split out of fileio.h (and not for examplement just as flags to the functions they wrap) in
+ * order to optimize linking: This way, -lselinux is needed only for the callers of these functions that need selinux,
+ * but not for all */
+
 int write_string_file_atomic_label_ts(const char *fn, const char *line, struct timespec *ts);
 static inline int write_string_file_atomic_label(const char *fn, const char *line) {
         return write_string_file_atomic_label_ts(fn, line, NULL);
index 9ee7a4a..4e02d5b 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
 #include <limits.h>
 #include <stdarg.h>
 #include <stdint.h>
+#include <stdio_ext.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/mman.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <unistd.h>
@@ -96,6 +99,7 @@ static int write_string_file_atomic(
         if (r < 0)
                 return r;
 
+        (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
         (void) fchmod_umask(fileno(f), 0644);
 
         r = write_string_stream_ts(f, line, flags, ts);
@@ -138,7 +142,7 @@ int write_string_file_ts(
 
                 return r;
         } else
-                assert(ts == NULL);
+                assert(!ts);
 
         if (flags & WRITE_STRING_FILE_CREATE) {
                 f = fopen(fn, "we");
@@ -165,6 +169,11 @@ int write_string_file_ts(
                 }
         }
 
+        (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
+
+        if (flags & WRITE_STRING_FILE_DISABLE_BUFFER)
+                setvbuf(f, NULL, _IONBF, 0);
+
         r = write_string_stream_ts(f, line, flags, ts);
         if (r < 0)
                 goto fail;
@@ -198,6 +207,8 @@ int read_one_line_file(const char *fn, char **line) {
         if (!f)
                 return -errno;
 
+        (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
+
         r = read_line(f, LONG_LINE_MAX, line);
         return r < 0 ? r : 0;
 }
@@ -223,6 +234,8 @@ int verify_file(const char *fn, const char *blob, bool accept_extra_nl) {
         if (!f)
                 return -errno;
 
+        (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
+
         /* We try to read one byte more than we need, so that we know whether we hit eof */
         errno = 0;
         k = fread(buf, 1, l + accept_extra_nl + 1, f);
@@ -318,6 +331,8 @@ int read_full_file(const char *fn, char **contents, size_t *size) {
         if (!f)
                 return -errno;
 
+        (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
+
         return read_full_stream(f, contents, size);
 }
 
@@ -874,7 +889,8 @@ int write_env_file(const char *fname, char **l) {
         if (r < 0)
                 return r;
 
-        fchmod_umask(fileno(f), 0644);
+        (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
+        (void) fchmod_umask(fileno(f), 0644);
 
         STRV_FOREACH(i, l)
                 write_env_var(f, *i);
@@ -1189,7 +1205,7 @@ int tempfn_xxxxxx(const char *p, const char *extra, char **ret) {
         if (!filename_is_valid(fn))
                 return -EINVAL;
 
-        if (extra == NULL)
+        if (!extra)
                 extra = "";
 
         t = new(char, strlen(p) + 2 + strlen(extra) + 6 + 1);
@@ -1456,7 +1472,7 @@ int link_tmpfile(int fd, const char *path, const char *target) {
                 if (rename_noreplace(AT_FDCWD, path, AT_FDCWD, target) < 0)
                         return -errno;
         } else {
-                char proc_fd_path[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(fd) + 1];
+                char proc_fd_path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(fd) + 1];
 
                 xsprintf(proc_fd_path, "/proc/self/fd/%i", fd);
 
@@ -1527,9 +1543,7 @@ int mkdtemp_malloc(const char *template, char **ret) {
         return 0;
 }
 
-static inline void funlockfilep(FILE **f) {
-        funlockfile(*f);
-}
+DEFINE_TRIVIAL_CLEANUP_FUNC(FILE*, funlockfile);
 
 int read_line(FILE *f, size_t limit, char **ret) {
         _cleanup_free_ char *buffer = NULL;
@@ -1556,7 +1570,7 @@ int read_line(FILE *f, size_t limit, char **ret) {
         }
 
         {
-                _cleanup_(funlockfilep) FILE *flocked = f;
+                _unused_ _cleanup_(funlockfilep) FILE *flocked = f;
                 flockfile(f);
 
                 for (;;) {
index eba05be..da5d5c6 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
 #include "time-util.h"
 
 typedef enum {
-        WRITE_STRING_FILE_CREATE = 1<<0,
-        WRITE_STRING_FILE_ATOMIC = 1<<1,
-        WRITE_STRING_FILE_AVOID_NEWLINE = 1<<2,
+        WRITE_STRING_FILE_CREATE            = 1<<0,
+        WRITE_STRING_FILE_ATOMIC            = 1<<1,
+        WRITE_STRING_FILE_AVOID_NEWLINE     = 1<<2,
         WRITE_STRING_FILE_VERIFY_ON_FAILURE = 1<<3,
-        WRITE_STRING_FILE_SYNC = 1<<4,
+        WRITE_STRING_FILE_SYNC              = 1<<4,
+        WRITE_STRING_FILE_DISABLE_BUFFER    = 1<<5,
+
+        /* And before you wonder, why write_string_file_atomic_label_ts() is a separate function instead of just one
+           more flag here: it's about linking: we don't want to pull -lselinux into all users of write_string_file()
+           and friends. */
+
 } WriteStringFileFlags;
 
 int write_string_stream_ts(FILE *f, const char *line, WriteStringFileFlags flags, struct timespec *ts);
index ae42a8f..d9a78f7 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 88d97d4..0107c47 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -104,7 +105,6 @@ int rmdir_parents(const char *path, const char *stop) {
         return 0;
 }
 
-
 int rename_noreplace(int olddirfd, const char *oldpath, int newdirfd, const char *newpath) {
         struct stat buf;
         int ret;
@@ -509,7 +509,7 @@ static int getenv_tmp_dir(const char **ret_path) {
                         r = -ENOTDIR;
                         goto next;
                 }
-                if (!path_is_safe(e)) {
+                if (!path_is_normalized(e)) {
                         r = -EPERM;
                         goto next;
                 }
@@ -580,7 +580,7 @@ int tmp_dir(const char **ret) {
 }
 
 int inotify_add_watch_fd(int fd, int what, uint32_t mask) {
-        char path[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(int) + 1];
+        char path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int) + 1];
         int r;
 
         /* This is like inotify_add_watch(), except that the file to watch is not referenced by a path, but by an fd */
@@ -750,7 +750,7 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags,
 
                         if (errno == ENOENT &&
                             (flags & CHASE_NONEXISTENT) &&
-                            (isempty(todo) || path_is_safe(todo))) {
+                            (isempty(todo) || path_is_normalized(todo))) {
 
                                 /* If CHASE_NONEXISTENT is set, and the path does not exist, then that's OK, return
                                  * what we got so far. But don't allow this if the remaining path contains "../ or "./"
@@ -779,7 +779,7 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags,
                 previous_stat = st;
 
                 if ((flags & CHASE_NO_AUTOFS) &&
-                    fd_check_fstype(child, AUTOFS_SUPER_MAGIC) > 0)
+                    fd_is_fs_type(child, AUTOFS_SUPER_MAGIC) > 0)
                         return -EREMOTE;
 
                 if (S_ISLNK(st.st_mode)) {
@@ -831,9 +831,9 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags,
 
                                 /* Prefix what's left to do with what we just read, and start the loop again, but
                                  * remain in the current directory. */
-                                joined = strjoin(destination, todo, NULL);
+                                joined = strjoin(destination, todo);
                         } else
-                                joined = strjoin("/", destination, todo, NULL);
+                                joined = strjoin("/", destination, todo);
                         if (!joined)
                                 return -ENOMEM;
 
@@ -890,3 +890,17 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags,
         return exists;
 }
 
+int access_fd(int fd, int mode) {
+        char p[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(fd) + 1];
+        int r;
+
+        /* Like access() but operates on an already open fd */
+
+        xsprintf(p, "/proc/self/fd/%i", fd);
+
+        r = access(p, mode);
+        if (r < 0)
+                r = -errno;
+
+        return r;
+}
index eeef417..c80c8e5 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -100,3 +101,5 @@ static inline void unlink_and_free(char *p) {
         free(p);
 }
 DEFINE_TRIVIAL_CLEANUP_FUNC(char*, unlink_and_free);
+
+int access_fd(int fd, int mode);
index d4cc9aa..aca9ab1 100755 (executable)
@@ -8,6 +8,12 @@ import sys
 name, prefix, input = sys.argv[1:]
 
 print("""\
+%{
+#if __GNUC__ >= 7
+_Pragma("GCC diagnostic ignored \\"-Wimplicit-fallthrough\\"")
+#endif
+%}""")
+print("""\
 struct {}_name {{ const char* name; int id; }};
 %null-strings
 %%""".format(name))
index f611c42..6e80a1e 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index e1f6083..911e6d2 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index c3a4a01..e69f815 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 299189d..959e2c1 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 4bfaa86..cc4423b 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
 
 #include "alloc-util.h"
 #include "hashmap.h"
+#include "fileio.h"
 #include "macro.h"
 #include "mempool.h"
 #include "process-util.h"
 #include "random-util.h"
 #include "set.h"
 #include "siphash24.h"
+#include "string-util.h"
 #include "strv.h"
 #include "util.h"
 
@@ -278,6 +281,28 @@ static const struct hashmap_type_info hashmap_type_info[_HASHMAP_TYPE_MAX] = {
         },
 };
 
+#ifdef VALGRIND
+__attribute__((destructor)) static void cleanup_pools(void) {
+        _cleanup_free_ char *t = NULL;
+        int r;
+
+        /* Be nice to valgrind */
+
+        /* The pool is only allocated by the main thread, but the memory can
+         * be passed to other threads. Let's clean up if we are the main thread
+         * and no other threads are live. */
+        if (!is_main_thread())
+                return;
+
+        r = get_proc_field("/proc/self/status", "Threads", WHITESPACE, &t);
+        if (r < 0 || !streq(t, "1"))
+                return;
+
+        mempool_drop(&hashmap_pool);
+        mempool_drop(&ordered_hashmap_pool);
+}
+#endif
+
 static unsigned n_buckets(HashmapBase *h) {
         return h->has_indirect ? h->indirect.n_buckets
                                : hashmap_type_info[h->type].n_direct_buckets;
index c108965..0eb7639 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -328,6 +329,29 @@ static inline void *ordered_hashmap_first(OrderedHashmap *h) {
         return internal_hashmap_first(HASHMAP_BASE(h));
 }
 
+#define hashmap_clear_with_destructor(_s, _f)                   \
+        ({                                                      \
+                void *_item;                                    \
+                while ((_item = hashmap_steal_first(_s)))       \
+                        _f(_item);                              \
+        })
+#define hashmap_free_with_destructor(_s, _f)                    \
+        ({                                                      \
+                hashmap_clear_with_destructor(_s, _f);          \
+                hashmap_free(_s);                               \
+        })
+#define ordered_hashmap_clear_with_destructor(_s, _f)                   \
+        ({                                                              \
+                void *_item;                                            \
+                while ((_item = ordered_hashmap_steal_first(_s)))       \
+                        _f(_item);                                      \
+        })
+#define ordered_hashmap_free_with_destructor(_s, _f)                    \
+        ({                                                              \
+                ordered_hashmap_clear_with_destructor(_s, _f);          \
+                ordered_hashmap_free(_s);                               \
+        })
+
 /* no hashmap_next */
 void *ordered_hashmap_next(OrderedHashmap *h, const void *key);
 
index 7667703..fe7e495 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -96,7 +97,10 @@ int unhexmem(const char *p, size_t l, void **mem, size_t *len) {
 
         assert(mem);
         assert(len);
-        assert(p);
+        assert(p || l == 0);
+
+        if (l == (size_t) -1)
+                l = strlen(p);
 
         if (l % 2 != 0)
                 return -EINVAL;
@@ -160,6 +164,8 @@ char *base32hexmem(const void *p, size_t l, bool padding) {
         const uint8_t *x;
         size_t len;
 
+        assert(p || l == 0);
+
         if (padding)
                 /* five input bytes makes eight output bytes, padding is added so we must round up */
                 len = 8 * (l + 4) / 5;
@@ -269,7 +275,12 @@ int unbase32hexmem(const char *p, size_t l, bool padding, void **mem, size_t *_l
         size_t len;
         unsigned pad = 0;
 
-        assert(p);
+        assert(p || l == 0);
+        assert(mem);
+        assert(_len);
+
+        if (l == (size_t) -1)
+                l = strlen(p);
 
         /* padding ensures any base32hex input has input divisible by 8 */
         if (padding && l % 8 != 0)
@@ -519,6 +530,9 @@ ssize_t base64mem(const void *p, size_t l, char **out) {
         char *r, *z;
         const uint8_t *x;
 
+        assert(p || l == 0);
+        assert(out);
+
         /* three input bytes makes four output bytes, padding is added so we must round up */
         z = r = malloc(4 * (l + 2) / 3 + 1);
         if (!r)
@@ -554,10 +568,11 @@ ssize_t base64mem(const void *p, size_t l, char **out) {
         return z - r;
 }
 
-static int base64_append_width(char **prefix, int plen,
-                               const char *sep, int indent,
-                               const void *p, size_t l,
-                               int width) {
+static int base64_append_width(
+                char **prefix, int plen,
+                const char *sep, int indent,
+                const void *p, size_t l,
+                int width) {
 
         _cleanup_free_ char *x = NULL;
         char *t, *s;
@@ -596,118 +611,148 @@ static int base64_append_width(char **prefix, int plen,
         return 0;
 }
 
-int base64_append(char **prefix, int plen,
-                  const void *p, size_t l,
-                  int indent, int width) {
+int base64_append(
+                char **prefix, int plen,
+                const void *p, size_t l,
+                int indent, int width) {
+
         if (plen > width / 2 || plen + indent > width)
                 /* leave indent on the left, keep last column free */
                 return base64_append_width(prefix, plen, "\n", indent, p, l, width - indent - 1);
         else
                 /* leave plen on the left, keep last column free */
                 return base64_append_width(prefix, plen, NULL, plen, p, l, width - plen - 1);
-};
+}
 
-
-int unbase64mem(const char *p, size_t l, void **mem, size_t *_len) {
-        _cleanup_free_ uint8_t *r = NULL;
-        int a, b, c, d;
-        uint8_t *z;
-        const char *x;
-        size_t len;
+static int unbase64_next(const char **p, size_t *l) {
+        int ret;
 
         assert(p);
+        assert(l);
 
-        /* padding ensures any base63 input has input divisible by 4 */
-        if (l % 4 != 0)
-                return -EINVAL;
-
-        /* strip the padding */
-        if (l > 0 && p[l - 1] == '=')
-                l--;
-        if (l > 0 && p[l - 1] == '=')
-                l--;
+        /* Find the next non-whitespace character, and decode it. If we find padding, we return it as INT_MAX. We
+         * greedily skip all preceeding and all following whitespace. */
 
-        /* a group of four input bytes needs three output bytes, in case of
-           padding we need to add two or three extra bytes */
-        len = (l / 4) * 3 + (l % 4 ? (l % 4) - 1 : 0);
+        for (;;) {
+                if (*l == 0)
+                        return -EPIPE;
 
-        z = r = malloc(len + 1);
-        if (!r)
-                return -ENOMEM;
+                if (!strchr(WHITESPACE, **p))
+                        break;
 
-        for (x = p; x < p + (l / 4) * 4; x += 4) {
-                /* a == 00XXXXXX; b == 00YYYYYY; c == 00ZZZZZZ; d == 00WWWWWW */
-                a = unbase64char(x[0]);
-                if (a < 0)
-                        return -EINVAL;
+                /* Skip leading whitespace */
+                (*p)++, (*l)--;
+        }
 
-                b = unbase64char(x[1]);
-                if (b < 0)
-                        return -EINVAL;
+        if (**p == '=')
+                ret = INT_MAX; /* return padding as INT_MAX */
+        else {
+                ret = unbase64char(**p);
+                if (ret < 0)
+                        return ret;
+        }
 
-                c = unbase64char(x[2]);
-                if (c < 0)
-                        return -EINVAL;
+        for (;;) {
+                (*p)++, (*l)--;
 
-                d = unbase64char(x[3]);
-                if (d < 0)
-                        return -EINVAL;
+                if (*l == 0)
+                        break;
+                if (!strchr(WHITESPACE, **p))
+                        break;
 
-                *(z++) = (uint8_t) a << 2 | (uint8_t) b >> 4; /* XXXXXXYY */
-                *(z++) = (uint8_t) b << 4 | (uint8_t) c >> 2; /* YYYYZZZZ */
-                *(z++) = (uint8_t) c << 6 | (uint8_t) d;      /* ZZWWWWWW */
+                /* Skip following whitespace */
         }
 
-        switch (l % 4) {
-        case 3:
-                a = unbase64char(x[0]);
+        return ret;
+}
+
+int unbase64mem(const char *p, size_t l, void **ret, size_t *ret_size) {
+        _cleanup_free_ uint8_t *buf = NULL;
+        const char *x;
+        uint8_t *z;
+        size_t len;
+
+        assert(p || l == 0);
+        assert(ret);
+        assert(ret_size);
+
+        if (l == (size_t) -1)
+                l = strlen(p);
+
+        /* A group of four input bytes needs three output bytes, in case of padding we need to add two or three extra
+           bytes. Note that this calculation is an upper boundary, as we ignore whitespace while decoding */
+        len = (l / 4) * 3 + (l % 4 != 0 ? (l % 4) - 1 : 0);
+
+        buf = malloc(len + 1);
+        if (!buf)
+                return -ENOMEM;
+
+        for (x = p, z = buf;;) {
+                int a, b, c, d; /* a == 00XXXXXX; b == 00YYYYYY; c == 00ZZZZZZ; d == 00WWWWWW */
+
+                a = unbase64_next(&x, &l);
+                if (a == -EPIPE) /* End of string */
+                        break;
                 if (a < 0)
+                        return a;
+                if (a == INT_MAX) /* Padding is not allowed at the beginning of a 4ch block */
                         return -EINVAL;
 
-                b = unbase64char(x[1]);
+                b = unbase64_next(&x, &l);
                 if (b < 0)
+                        return b;
+                if (b == INT_MAX) /* Padding is not allowed at the second character of a 4ch block either */
                         return -EINVAL;
 
-                c = unbase64char(x[2]);
+                c = unbase64_next(&x, &l);
                 if (c < 0)
-                        return -EINVAL;
+                        return c;
 
-                /* c == 00ZZZZ00 */
-                if (c & 3)
-                        return -EINVAL;
+                d = unbase64_next(&x, &l);
+                if (d < 0)
+                        return d;
 
-                *(z++) = (uint8_t) a << 2 | (uint8_t) b >> 4; /* XXXXXXYY */
-                *(z++) = (uint8_t) b << 4 | (uint8_t) c >> 2; /* YYYYZZZZ */
+                if (c == INT_MAX) { /* Padding at the third character */
 
-                break;
-        case 2:
-                a = unbase64char(x[0]);
-                if (a < 0)
-                        return -EINVAL;
+                        if (d != INT_MAX) /* If the third character is padding, the fourth must be too */
+                                return -EINVAL;
 
-                b = unbase64char(x[1]);
-                if (b < 0)
-                        return -EINVAL;
+                        /* b == 00YY0000 */
+                        if (b & 15)
+                                return -EINVAL;
 
-                /* b == 00YY0000 */
-                if (b & 15)
-                        return -EINVAL;
+                        if (l > 0) /* Trailing rubbish? */
+                                return -ENAMETOOLONG;
 
-                *(z++) = (uint8_t) a << 2 | (uint8_t) (b >> 4); /* XXXXXXYY */
+                        *(z++) = (uint8_t) a << 2 | (uint8_t) (b >> 4); /* XXXXXXYY */
+                        break;
+                }
 
-                break;
-        case 0:
+                if (d == INT_MAX) {
+                        /* c == 00ZZZZ00 */
+                        if (c & 3)
+                                return -EINVAL;
 
-                break;
-        default:
-                return -EINVAL;
+                        if (l > 0) /* Trailing rubbish? */
+                                return -ENAMETOOLONG;
+
+                        *(z++) = (uint8_t) a << 2 | (uint8_t) b >> 4; /* XXXXXXYY */
+                        *(z++) = (uint8_t) b << 4 | (uint8_t) c >> 2; /* YYYYZZZZ */
+                        break;
+                }
+
+                *(z++) = (uint8_t) a << 2 | (uint8_t) b >> 4; /* XXXXXXYY */
+                *(z++) = (uint8_t) b << 4 | (uint8_t) c >> 2; /* YYYYZZZZ */
+                *(z++) = (uint8_t) c << 6 | (uint8_t) d;      /* ZZWWWWWW */
         }
 
         *z = 0;
 
-        *mem = r;
-        r = NULL;
-        *_len = len;
+        if (ret_size)
+                *ret_size = (size_t) (z - buf);
+
+        *ret = buf;
+        buf = NULL;
 
         return 0;
 }
@@ -716,7 +761,10 @@ void hexdump(FILE *f, const void *p, size_t s) {
         const uint8_t *b = p;
         unsigned n = 0;
 
-        assert(s == 0 || b);
+        assert(b || s == 0);
+
+        if (!f)
+                f = stdout;
 
         while (s > 0) {
                 size_t i;
index 1ba2f69..08d0a52 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index ea9e770..b59e542 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -24,6 +25,8 @@
 #include <sys/utsname.h>
 #include <unistd.h>
 
+#include "alloc-util.h"
+#include "def.h"
 #include "fd-util.h"
 #include "fileio.h"
 #include "hostname-util.h"
@@ -218,35 +221,87 @@ int sethostname_idempotent(const char *s) {
         return 1;
 }
 
-int read_hostname_config(const char *path, char **hostname) {
-        _cleanup_fclose_ FILE *f = NULL;
-        char l[LINE_MAX];
-        char *name = NULL;
+int shorten_overlong(const char *s, char **ret) {
+        char *h, *p;
 
-        assert(path);
-        assert(hostname);
+        /* Shorten an overlong name to HOST_NAME_MAX or to the first dot,
+         * whatever comes earlier. */
 
-        f = fopen(path, "re");
-        if (!f)
-                return -errno;
+        assert(s);
+
+        h = strdup(s);
+        if (!h)
+                return -ENOMEM;
+
+        if (hostname_is_valid(h, false)) {
+                *ret = h;
+                return 0;
+        }
+
+        p = strchr(h, '.');
+        if (p)
+                *p = 0;
+
+        strshorten(h, HOST_NAME_MAX);
+
+        if (!hostname_is_valid(h, false)) {
+                free(h);
+                return -EDOM;
+        }
+
+        *ret = h;
+        return 1;
+}
+
+int read_etc_hostname_stream(FILE *f, char **ret) {
+        int r;
 
-        /* may have comments, ignore them */
-        FOREACH_LINE(l, f, return -errno) {
-                truncate_nl(l);
-                if (!IN_SET(l[0], '\0', '#')) {
-                        /* found line with value */
-                        name = hostname_cleanup(l);
-                        name = strdup(name);
-                        if (!name)
+        assert(f);
+        assert(ret);
+
+        for (;;) {
+                _cleanup_free_ char *line = NULL;
+                char *p;
+
+                r = read_line(f, LONG_LINE_MAX, &line);
+                if (r < 0)
+                        return r;
+                if (r == 0) /* EOF without any hostname? the file is empty, let's treat that exactly like no file at all: ENOENT */
+                        return -ENOENT;
+
+                p = strstrip(line);
+
+                /* File may have empty lines or comments, ignore them */
+                if (!IN_SET(*p, '\0', '#')) {
+                        char *copy;
+
+                        hostname_cleanup(p); /* normalize the hostname */
+
+                        if (!hostname_is_valid(p, true)) /* check that the hostname we return is valid */
+                                return -EBADMSG;
+
+                        copy = strdup(p);
+                        if (!copy)
                                 return -ENOMEM;
-                        break;
+
+                        *ret = copy;
+                        return 0;
                 }
         }
+}
 
-        if (!name)
-                /* no non-empty line found */
-                return -ENOENT;
+int read_etc_hostname(const char *path, char **ret) {
+        _cleanup_fclose_ FILE *f = NULL;
+
+        assert(ret);
+
+        if (!path)
+                path = "/etc/hostname";
+
+        f = fopen(path, "re");
+        if (!f)
+                return -errno;
+
+        return read_etc_hostname_stream(f, ret);
 
-        *hostname = name;
-        return 0;
 }
index 7af4e6c..d837d6f 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -38,4 +39,7 @@ bool is_gateway_hostname(const char *hostname);
 
 int sethostname_idempotent(const char *s);
 
-int read_hostname_config(const char *path, char **hostname);
+int shorten_overlong(const char *s, char **ret);
+
+int read_etc_hostname_stream(FILE *f, char **ret);
+int read_etc_hostname(const char *path, char **ret);
index e27faba..572e172 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 59f8eb7..acaae6d 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index cc6dfa8..77c9bdc 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -199,7 +200,6 @@ int fd_wait_for_event(int fd, int event, usec_t t) {
         r = ppoll(&pollfd, 1, t == USEC_INFINITY ? NULL : timespec_store(&ts, t), NULL);
         if (r < 0)
                 return -errno;
-
         if (r == 0)
                 return 0;
 
index d9b69ad..d81610a 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index e750101..6942c37 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -95,7 +96,7 @@ static int get_line(JournalImporter *imp, char **line, size_t *size) {
         assert(imp->state == IMPORTER_STATE_LINE);
         assert(imp->offset <= imp->filled);
         assert(imp->filled <= imp->size);
-        assert(imp->buf == NULL || imp->size > 0);
+        assert(!imp->buf || imp->size > 0);
         assert(imp->fd >= 0);
 
         for (;;) {
@@ -158,8 +159,8 @@ static int fill_fixed_size(JournalImporter *imp, void **data, size_t size) {
         assert(size <= DATA_SIZE_MAX);
         assert(imp->offset <= imp->filled);
         assert(imp->filled <= imp->size);
-        assert(imp->buf != NULL || imp->size == 0);
-        assert(imp->buf == NULL || imp->size > 0);
+        assert(imp->buf || imp->size == 0);
+        assert(!imp->buf || imp->size > 0);
         assert(imp->fd >= 0);
         assert(data);
 
index b3e308d..d11caa2 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 84648dc..6942105 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -126,9 +127,7 @@ khash* khash_unref(khash *h) {
 
         safe_close(h->fd);
         free(h->algorithm);
-        free(h);
-
-        return NULL;
+        return mfree(h);
 }
 
 int khash_dup(khash *h, khash **ret) {
index 410f302..7041d39 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index f5ab855..ce81d28 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 3e9251a..86447c2 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index c3771a1..7006c3e 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
         for ((i) = (p)->name##_next ? (p)->name##_next : (head);        \
              (i) != (p);                                                \
              (i) = (i)->name##_next ? (i)->name##_next : (head))
+
+#define LIST_IS_EMPTY(head)                                             \
+        (!(head))
index ada0a28..266cb29 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -20,6 +21,7 @@
 #include <dirent.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <ftw.h>
 #include <langinfo.h>
 #include <libintl.h>
 #include <locale.h>
@@ -30,6 +32,7 @@
 #include <sys/mman.h>
 #include <sys/stat.h>
 
+#include "def.h"
 #include "dirent-util.h"
 #include "fd-util.h"
 #include "hashmap.h"
@@ -270,6 +273,99 @@ out:
         return (bool) cached_answer;
 }
 
+static thread_local Set *keymaps = NULL;
+
+static int nftw_cb(
+                const char *fpath,
+                const struct stat *sb,
+                int tflag,
+                struct FTW *ftwbuf) {
+
+        char *p, *e;
+        int r;
+
+        if (tflag != FTW_F)
+                return 0;
+
+        if (!endswith(fpath, ".map") &&
+            !endswith(fpath, ".map.gz"))
+                return 0;
+
+        p = strdup(basename(fpath));
+        if (!p)
+                return FTW_STOP;
+
+        e = endswith(p, ".map");
+        if (e)
+                *e = 0;
+
+        e = endswith(p, ".map.gz");
+        if (e)
+                *e = 0;
+
+        r = set_consume(keymaps, p);
+        if (r < 0 && r != -EEXIST)
+                return r;
+
+        return 0;
+}
+
+int get_keymaps(char ***ret) {
+        _cleanup_strv_free_ char **l = NULL;
+        const char *dir;
+        int r;
+
+        keymaps = set_new(&string_hash_ops);
+        if (!keymaps)
+                return -ENOMEM;
+
+        NULSTR_FOREACH(dir, KBD_KEYMAP_DIRS) {
+                r = nftw(dir, nftw_cb, 20, FTW_MOUNT|FTW_PHYS|FTW_ACTIONRETVAL);
+
+                if (r == FTW_STOP)
+                        log_debug("Directory not found %s", dir);
+                else if (r < 0)
+                        log_debug_errno(r, "Can't add keymap: %m");
+        }
+
+        l = set_get_strv(keymaps);
+        if (!l) {
+                set_free_free(keymaps);
+                return -ENOMEM;
+        }
+
+        set_free(keymaps);
+
+        if (strv_isempty(l))
+                return -ENOENT;
+
+        strv_sort(l);
+
+        *ret = l;
+        l = NULL;
+
+        return 0;
+}
+
+bool keymap_is_valid(const char *name) {
+
+        if (isempty(name))
+                return false;
+
+        if (strlen(name) >= 128)
+                return false;
+
+        if (!utf8_is_valid(name))
+                return false;
+
+        if (!filename_is_valid(name))
+                return false;
+
+        if (!string_is_safe(name))
+                return false;
+
+        return true;
+}
 
 const char *special_glyph(SpecialGlyph code) {
 
index 0630a03..60ce017 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -71,3 +72,6 @@ const char *special_glyph(SpecialGlyph code) _const_;
 
 const char* locale_variable_to_string(LocaleVariable i) _const_;
 LocaleVariable locale_variable_from_string(const char *s) _pure_;
+
+int get_keymaps(char ***l);
+bool keymap_is_valid(const char *name);
index 3ee4191..f4761a9 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 22491ee..1e86ad7 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 4f0fe54..20d9588 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -358,7 +359,7 @@ static int write_to_console(
         highlight = LOG_PRI(level) <= LOG_ERR && show_color;
 
         if (show_location) {
-                snprintf(location, sizeof(location), "(%s:%i) ", file, line);
+                xsprintf(location, "(%s:%i) ", file, line);
                 iovec[n++] = IOVEC_MAKE_STRING(location);
         }
 
@@ -797,7 +798,7 @@ static void log_assert(
                 return;
 
         DISABLE_WARNING_FORMAT_NONLITERAL;
-        snprintf(buffer, sizeof buffer, format, text, file, line, func);
+        xsprintf(buffer, format, text, file, line, func);
         REENABLE_WARNING;
 
         log_abort_msg = buffer;
@@ -847,8 +848,8 @@ int log_oom_internal(LogRealm realm, const char *file, int line, const char *fun
 
 int log_format_iovec(
                 struct iovec *iovec,
-                unsigned iovec_len,
-                unsigned *n,
+                size_t iovec_len,
+                size_t *n,
                 bool newline_separator,
                 int error,
                 const char *format,
@@ -928,7 +929,7 @@ int log_struct_internal(
                 if (journal_fd >= 0) {
                         char header[LINE_MAX];
                         struct iovec iovec[17] = {};
-                        unsigned n = 0, i;
+                        size_t n = 0, i;
                         int r;
                         struct msghdr mh = {
                                 .msg_iov = iovec,
@@ -1046,18 +1047,18 @@ int log_struct_iovec_internal(
         }
 
         for (i = 0; i < n_input_iovec; i++) {
-                if (input_iovec[i].iov_len < strlen("MESSAGE="))
+                if (input_iovec[i].iov_len < STRLEN("MESSAGE="))
                         continue;
 
-                if (memcmp(input_iovec[i].iov_base, "MESSAGE=", strlen("MESSAGE=")) == 0)
+                if (memcmp(input_iovec[i].iov_base, "MESSAGE=", STRLEN("MESSAGE=")) == 0)
                         break;
         }
 
         if (_unlikely_(i >= n_input_iovec)) /* Couldn't find MESSAGE=? */
                 return -error;
 
-        m = strndupa(input_iovec[i].iov_base + strlen("MESSAGE="),
-                     input_iovec[i].iov_len - strlen("MESSAGE="));
+        m = strndupa(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 10a6032..aa5976c 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -180,8 +181,8 @@ int log_oom_internal(
 
 int log_format_iovec(
                 struct iovec *iovec,
-                unsigned iovec_len,
-                unsigned *n,
+                size_t iovec_len,
+                size_t *n,
                 bool newline_separator,
                 int error,
                 const char *format,
index 339e94f..af45394 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index b01ee25..1c558bf 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index a51562d..02d22de 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
 #define _weakref_(x) __attribute__((weakref(#x)))
 #define _alignas_(x) __attribute__((aligned(__alignof(x))))
 #define _cleanup_(x) __attribute__((cleanup(x)))
+#if __GNUC__ >= 7
+#define _fallthrough_ __attribute__((fallthrough))
+#else
+#define _fallthrough_
+#endif
 
 /* Temporarily disable some warnings */
 #define DISABLE_WARNING_DECLARATION_AFTER_STATEMENT                     \
@@ -138,6 +144,14 @@ static inline unsigned long ALIGN_POWER2(unsigned long u) {
                 !__builtin_types_compatible_p(typeof(x), typeof(&*(x))), \
                 sizeof(x)/sizeof((x)[0]),                                \
                 (void)0))
+
+/*
+ * STRLEN - return the length of a string literal, minus the trailing NUL byte.
+ *          Contrary to strlen(), this is a constant expression.
+ * @x: a string literal.
+ */
+#define STRLEN(x) (sizeof(""x"") - 1)
+
 /*
  * container_of - cast a member of a structure out to the containing structure
  * @ptr: the pointer to the member.
index 8f4f0e3..e7eb895 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 46d4989..1d66c98 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index f95e2be..0da8e1f 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 0618b8d..c9235c8 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 1ddefb7..a37e279 100644 (file)
@@ -1,3 +1,20 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
+# Copyright 2017 Zbigniew Jędrzejewski-Szmek
+#
+# 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.
+#
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
 basic_sources_plain = files('''
         MurmurHash2.c
         MurmurHash2.h
@@ -44,6 +61,8 @@ basic_sources_plain = files('''
         copy.h
         cpu-set-util.c
         cpu-set-util.h
+        crypt-util.c
+        crypt-util.h
         def.h
         device-nodes.c
         device-nodes.h
@@ -113,6 +132,7 @@ basic_sources_plain = files('''
         mkdir-label.c
         mkdir.c
         mkdir.h
+        module-util.h
         mount-util.c
         mount-util.h
         nss-util.h
@@ -183,6 +203,8 @@ basic_sources_plain = files('''
         unaligned.h
         unit-name.c
         unit-name.h
+        unit-def.c
+        unit-def.h
         user-util.c
         user-util.h
         utf8.c
index 352d2b0..790f9f5 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -542,10 +543,6 @@ struct btrfs_ioctl_quota_ctl_args {
 #define PR_SET_CHILD_SUBREAPER 36
 #endif
 
-#ifndef MAX_HANDLE_SZ
-#define MAX_HANDLE_SZ 128
-#endif
-
 #if ! HAVE_SECURE_GETENV
 #  if HAVE___SECURE_GETENV
 #    define secure_getenv __secure_getenv
@@ -955,6 +952,10 @@ struct input_mask {
 #define IFLA_VRF_TABLE 1
 #endif
 
+#if !HAVE_VXCAN_INFO_PEER
+#define VXCAN_INFO_PEER 1
+#endif
+
 #if !HAVE_NDA_IFINDEX
 #define NDA_UNSPEC 0
 #define NDA_DST 1
@@ -1266,4 +1267,16 @@ struct fib_rule_uid_range {
 #define AF_VSOCK 40
 #endif
 
+#ifndef EXT4_IOC_RESIZE_FS
+#  define EXT4_IOC_RESIZE_FS              _IOW('f', 16, __u64)
+#endif
+
+#ifndef NSFS_MAGIC
+#define NSFS_MAGIC 0x6e736673
+#endif
+
+#ifndef NS_GET_NSTYPE
+#define NS_GET_NSTYPE _IO(0xb7, 0x3)
+#endif
+
 #include "missing_syscall.h"
index 9b84d46..6d4827c 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -344,6 +345,8 @@ static inline ssize_t missing_copy_file_range(int fd_in, loff_t *off_in,
 #  define copy_file_range missing_copy_file_range
 #endif
 
+/* ======================================================================= */
+
 #if !HAVE_BPF
 #  ifndef __NR_bpf
 #    if defined __i386__
@@ -373,3 +376,31 @@ static inline int bpf(int cmd, union bpf_attr *attr, size_t size) {
 }
 
 #endif
+
+/* ======================================================================= */
+
+#ifndef __IGNORE_pkey_mprotect
+#  ifndef __NR_pkey_mprotect
+#    if defined __i386__
+#      define __NR_pkey_mprotect 380
+#    elif defined __x86_64__
+#      define __NR_pkey_mprotect 329
+#    elif defined __arm__
+#      define __NR_pkey_mprotect 394
+#    elif defined __aarch64__
+#      define __NR_pkey_mprotect 394
+#    elif defined _MIPS_SIM
+#      if _MIPS_SIM == _MIPS_SIM_ABI32
+#        define __NR_pkey_mprotect 4363
+#      endif
+#      if _MIPS_SIM == _MIPS_SIM_NABI32
+#        define __NR_pkey_mprotect 6327
+#      endif
+#      if _MIPS_SIM == _MIPS_SIM_ABI64
+#        define __NR_pkey_mprotect 5323
+#      endif
+#    else
+#      warning "__NR_pkey_mprotect not defined for your architecture"
+#    endif
+#  endif
+#endif
index aa6878c..16eb7ce 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -25,8 +26,8 @@
 #include "label.h"
 #include "mkdir.h"
 
-int mkdir_safe_label(const char *path, mode_t mode, uid_t uid, gid_t gid) {
-        return mkdir_safe_internal(path, mode, uid, gid, mkdir_label);
+int mkdir_safe_label(const char *path, mode_t mode, uid_t uid, gid_t gid, bool follow_symlink) {
+        return mkdir_safe_internal(path, mode, uid, gid, follow_symlink, mkdir_label);
 }
 
 int mkdir_parents_label(const char *path, mode_t mode) {
index 7db09fc..4386b38 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -22,6 +23,7 @@
 #include <string.h>
 #include <sys/stat.h>
 
+#include "alloc-util.h"
 #include "fs-util.h"
 #include "macro.h"
 #include "mkdir.h"
@@ -29,7 +31,7 @@
 #include "stat-util.h"
 #include "user-util.h"
 
-int mkdir_safe_internal(const char *path, mode_t mode, uid_t uid, gid_t gid, mkdir_func_t _mkdir) {
+int mkdir_safe_internal(const char *path, mode_t mode, uid_t uid, gid_t gid, bool follow_symlink, mkdir_func_t _mkdir) {
         struct stat st;
         int r;
 
@@ -42,6 +44,19 @@ int mkdir_safe_internal(const char *path, mode_t mode, uid_t uid, gid_t gid, mkd
         if (lstat(path, &st) < 0)
                 return -errno;
 
+        if (follow_symlink && S_ISLNK(st.st_mode)) {
+                _cleanup_free_ char *p = NULL;
+
+                r = chase_symlinks(path, NULL, CHASE_NONEXISTENT, &p);
+                if (r < 0)
+                        return r;
+                if (r == 0)
+                        return mkdir_safe_internal(p, mode, uid, gid, false, _mkdir);
+
+                if (lstat(p, &st) < 0)
+                        return -errno;
+        }
+
         if ((st.st_mode & 0007) > (mode & 0007) ||
             (st.st_mode & 0070) > (mode & 0070) ||
             (st.st_mode & 0700) > (mode & 0700) ||
@@ -53,8 +68,8 @@ int mkdir_safe_internal(const char *path, mode_t mode, uid_t uid, gid_t gid, mkd
         return 0;
 }
 
-int mkdir_safe(const char *path, mode_t mode, uid_t uid, gid_t gid) {
-        return mkdir_safe_internal(path, mode, uid, gid, mkdir);
+int mkdir_safe(const char *path, mode_t mode, uid_t uid, gid_t gid, bool follow_symlink) {
+        return mkdir_safe_internal(path, mode, uid, gid, follow_symlink, mkdir);
 }
 
 int mkdir_parents_internal(const char *prefix, const char *path, mode_t mode, mkdir_func_t _mkdir) {
index d564a35..04a537f 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
 
 #include <sys/types.h>
 
-int mkdir_safe(const char *path, mode_t mode, uid_t uid, gid_t gid);
+int mkdir_safe(const char *path, mode_t mode, uid_t uid, gid_t gid, bool follow_symlink);
 int mkdir_parents(const char *path, mode_t mode);
 int mkdir_p(const char *path, mode_t mode);
 
 /* mandatory access control(MAC) versions */
-int mkdir_safe_label(const char *path, mode_t mode, uid_t uid, gid_t gid);
+int mkdir_safe_label(const char *path, mode_t mode, uid_t uid, gid_t gid, bool follow_symlink);
 int mkdir_parents_label(const char *path, mode_t mode);
 int mkdir_p_label(const char *path, mode_t mode);
 
 /* internally used */
 typedef int (*mkdir_func_t)(const char *pathname, mode_t mode);
-int mkdir_safe_internal(const char *path, mode_t mode, uid_t uid, gid_t gid, mkdir_func_t _mkdir);
+int mkdir_safe_internal(const char *path, mode_t mode, uid_t uid, gid_t gid, bool follow_symlink, mkdir_func_t _mkdir);
 int mkdir_parents_internal(const char *prefix, const char *path, mode_t mode, mkdir_func_t _mkdir);
 int mkdir_p_internal(const char *prefix, const char *path, mode_t mode, mkdir_func_t _mkdir);
diff --git a/src/basic/module-util.h b/src/basic/module-util.h
new file mode 100644 (file)
index 0000000..07956db
--- /dev/null
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2017 Zbigniew Jędrzejewski-Szmek
+
+  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.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <libkmod.h>
+
+#include "macro.h"
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(struct kmod_ctx*, kmod_unref);
+DEFINE_TRIVIAL_CLEANUP_FUNC(struct kmod_module*, kmod_module_unref);
+DEFINE_TRIVIAL_CLEANUP_FUNC(struct kmod_list*, kmod_module_unref_list);
index c4d451d..a8947ce 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -18,6 +19,7 @@
 ***/
 
 #include <errno.h>
+#include <stdio_ext.h>
 #include <stdlib.h>
 #include <string.h>
 #include <sys/mount.h>
 #include "string-util.h"
 #include "strv.h"
 
+/* This is the original MAX_HANDLE_SZ definition from the kernel, when the API was introduced. We use that in place of
+ * any more currently defined value to future-proof things: if the size is increased in the API headers, and our code
+ * is recompiled then it would cease working on old kernels, as those refuse any sizes larger than this value with
+ * EINVAL right-away. Hence, let's disconnect ourselves from any such API changes, and stick to the original definition
+ * from when it was introduced. We use it as a start value only anyway (see below), and hence should be able to deal
+ * with large file handles anyway. */
+#define ORIGINAL_MAX_HANDLE_SZ 128
+
+int name_to_handle_at_loop(
+                int fd,
+                const char *path,
+                struct file_handle **ret_handle,
+                int *ret_mnt_id,
+                int flags) {
+
+        _cleanup_free_ struct file_handle *h = NULL;
+        size_t n = ORIGINAL_MAX_HANDLE_SZ;
+
+        /* We need to invoke name_to_handle_at() in a loop, given that it might return EOVERFLOW when the specified
+         * buffer is too small. Note that in contrast to what the docs might suggest, MAX_HANDLE_SZ is only good as a
+         * start value, it is not an upper bound on the buffer size required.
+         *
+         * This improves on raw name_to_handle_at() also in one other regard: ret_handle and ret_mnt_id can be passed
+         * as NULL if there's no interest in either. */
+
+        for (;;) {
+                int mnt_id = -1;
+
+                h = malloc0(offsetof(struct file_handle, f_handle) + n);
+                if (!h)
+                        return -ENOMEM;
+
+                h->handle_bytes = n;
+
+                if (name_to_handle_at(fd, path, h, &mnt_id, flags) >= 0) {
+
+                        if (ret_handle) {
+                                *ret_handle = h;
+                                h = NULL;
+                        }
+
+                        if (ret_mnt_id)
+                                *ret_mnt_id = mnt_id;
+
+                        return 0;
+                }
+                if (errno != EOVERFLOW)
+                        return -errno;
+
+                if (!ret_handle && ret_mnt_id && mnt_id >= 0) {
+
+                        /* As it appears, name_to_handle_at() fills in mnt_id even when it returns EOVERFLOW when the
+                         * buffer is too small, but that's undocumented. Hence, let's make use of this if it appears to
+                         * be filled in, and the caller was interested in only the mount ID an nothing else. */
+
+                        *ret_mnt_id = mnt_id;
+                        return 0;
+                }
+
+                /* If name_to_handle_at() didn't increase the byte size, then this EOVERFLOW is caused by something
+                 * else (apparently EOVERFLOW is returned for untriggered nfs4 mounts sometimes), not by the too small
+                 * buffer. In that case propagate EOVERFLOW */
+                if (h->handle_bytes <= n)
+                        return -EOVERFLOW;
+
+                /* The buffer was too small. Size the new buffer by what name_to_handle_at() returned. */
+                n = h->handle_bytes;
+                if (offsetof(struct file_handle, f_handle) + n < n) /* check for addition overflow */
+                        return -EOVERFLOW;
+
+                h = mfree(h);
+        }
+}
+
 static int fd_fdinfo_mnt_id(int fd, const char *filename, int flags, int *mnt_id) {
-        char path[strlen("/proc/self/fdinfo/") + DECIMAL_STR_MAX(int)];
+        char path[STRLEN("/proc/self/fdinfo/") + DECIMAL_STR_MAX(int)];
         _cleanup_free_ char *fdinfo = NULL;
         _cleanup_close_ int subfd = -1;
         char *p;
@@ -60,7 +136,7 @@ static int fd_fdinfo_mnt_id(int fd, const char *filename, int flags, int *mnt_id
         if (r == -ENOENT) /* The fdinfo directory is a relatively new addition */
                 return -EOPNOTSUPP;
         if (r < 0)
-                return -errno;
+                return r;
 
         p = startswith(fdinfo, "mnt_id:");
         if (!p) {
@@ -78,7 +154,7 @@ static int fd_fdinfo_mnt_id(int fd, const char *filename, int flags, int *mnt_id
 }
 
 int fd_is_mount_point(int fd, const char *filename, int flags) {
-        union file_handle_union h = FILE_HANDLE_INIT, h_parent = FILE_HANDLE_INIT;
+        _cleanup_free_ struct file_handle *h = NULL, *h_parent = NULL;
         int mount_id = -1, mount_id_parent = -1;
         bool nosupp = false, check_st_dev = true;
         struct stat a, b;
@@ -110,39 +186,32 @@ int fd_is_mount_point(int fd, const char *filename, int flags) {
          * subvolumes have different st_dev, even though they aren't
          * real mounts of their own. */
 
-        r = name_to_handle_at(fd, filename, &h.handle, &mount_id, flags);
-        if (r < 0) {
-                if (IN_SET(errno, ENOSYS, EACCES, EPERM))
-                        /* This kernel does not support name_to_handle_at() at all, or the syscall was blocked (maybe
-                         * through seccomp, because we are running inside of a container?): fall back to simpler
-                         * logic. */
+        r = name_to_handle_at_loop(fd, filename, &h, &mount_id, flags);
+        if (IN_SET(r, -ENOSYS, -EACCES, -EPERM, -EOVERFLOW, -EINVAL))
+                /* This kernel does not support name_to_handle_at() at all (ENOSYS), or the syscall was blocked
+                 * (EACCES/EPERM; maybe through seccomp, because we are running inside of a container?), or the mount
+                 * point is not triggered yet (EOVERFLOW, think nfs4), or some general name_to_handle_at() flakiness
+                 * (EINVAL): fall back to simpler logic. */
+                goto fallback_fdinfo;
+        else if (r == -EOPNOTSUPP)
+                /* This kernel or file system does not support name_to_handle_at(), hence let's see if the upper fs
+                 * supports it (in which case it is a mount point), otherwise fallback to the traditional stat()
+                 * logic */
+                nosupp = true;
+        else if (r < 0)
+                return r;
+
+        r = name_to_handle_at_loop(fd, "", &h_parent, &mount_id_parent, AT_EMPTY_PATH);
+        if (r == -EOPNOTSUPP) {
+                if (nosupp)
+                        /* Neither parent nor child do name_to_handle_at()?  We have no choice but to fall back. */
                         goto fallback_fdinfo;
-                else if (errno == EOPNOTSUPP)
-                        /* This kernel or file system does not support
-                         * name_to_handle_at(), hence let's see if the
-                         * upper fs supports it (in which case it is a
-                         * mount point), otherwise fallback to the
-                         * traditional stat() logic */
-                        nosupp = true;
                 else
-                        return -errno;
-        }
-
-        r = name_to_handle_at(fd, "", &h_parent.handle, &mount_id_parent, AT_EMPTY_PATH);
-        if (r < 0) {
-                if (errno == EOPNOTSUPP) {
-                        if (nosupp)
-                                /* Neither parent nor child do name_to_handle_at()?
-                                   We have no choice but to fall back. */
-                                goto fallback_fdinfo;
-                        else
-                                /* The parent can't do name_to_handle_at() but the
-                                 * directory we are interested in can?
-                                 * If so, it must be a mount point. */
-                                return 1;
-                } else
-                        return -errno;
-        }
+                        /* The parent can't do name_to_handle_at() but the directory we are interested in can?  If so,
+                         * it must be a mount point. */
+                        return 1;
+        } else if (r < 0)
+                return r;
 
         /* The parent can do name_to_handle_at() but the
          * directory we are interested in can't? If so, it
@@ -155,9 +224,9 @@ int fd_is_mount_point(int fd, const char *filename, int flags) {
          * assume this is the root directory, which is a mount
          * point. */
 
-        if (h.handle.handle_bytes == h_parent.handle.handle_bytes &&
-            h.handle.handle_type == h_parent.handle.handle_type &&
-            memcmp(h.handle.f_handle, h_parent.handle.f_handle, h.handle.handle_bytes) == 0)
+        if (h->handle_bytes == h_parent->handle_bytes &&
+            h->handle_type == h_parent->handle_type &&
+            memcmp(h->f_handle, h_parent->f_handle, h->handle_bytes) == 0)
                 return 1;
 
         return mount_id != mount_id_parent;
@@ -213,6 +282,7 @@ int path_is_mount_point(const char *t, const char *root, int flags) {
         int r;
 
         assert(t);
+        assert((flags & ~AT_SYMLINK_FOLLOW) == 0);
 
         if (path_equal(t, "/"))
                 return 1;
@@ -237,7 +307,17 @@ int path_is_mount_point(const char *t, const char *root, int flags) {
         if (fd < 0)
                 return -errno;
 
-        return fd_is_mount_point(fd, basename(t), flags);
+        return fd_is_mount_point(fd, last_path_component(t), flags);
+}
+
+int path_get_mnt_id(const char *path, int *ret) {
+        int r;
+
+        r = name_to_handle_at_loop(AT_FDCWD, path, NULL, ret, 0);
+        if (IN_SET(r, -EOPNOTSUPP, -ENOSYS, -EACCES, -EPERM, -EOVERFLOW, -EINVAL)) /* kernel/fs don't support this, or seccomp blocks access, or untriggered mount, or name_to_handle_at() is flaky */
+                return fd_fdinfo_mnt_id(AT_FDCWD, path, 0, ret);
+
+        return r;
 }
 
 int umount_recursive(const char *prefix, int flags) {
@@ -258,6 +338,8 @@ int umount_recursive(const char *prefix, int flags) {
                 if (!proc_self_mountinfo)
                         return -errno;
 
+                (void) __fsetlocking(proc_self_mountinfo, FSETLOCKING_BYCALLER);
+
                 for (;;) {
                         _cleanup_free_ char *path = NULL, *p = NULL;
                         int k;
@@ -504,6 +586,8 @@ int bind_remount_recursive(const char *prefix, bool ro, char **blacklist) {
         if (!proc_self_mountinfo)
                 return -errno;
 
+        (void) __fsetlocking(proc_self_mountinfo, FSETLOCKING_BYCALLER);
+
         return bind_remount_recursive_with_mountinfo(prefix, ro, blacklist, proc_self_mountinfo);
 }
 
@@ -589,6 +673,22 @@ bool fstype_can_discard(const char *fstype) {
                           "xfs");
 }
 
+bool fstype_can_uid_gid(const char *fstype) {
+
+        /* All file systems that have a uid=/gid= mount option that fixates the owners of all files and directories,
+         * current and future. */
+
+        return STR_IN_SET(fstype,
+                          "adfs",
+                          "fat",
+                          "hfs",
+                          "hpfs",
+                          "iso9660",
+                          "msdos",
+                          "ntfs",
+                          "vfat");
+}
+
 int repeat_unmount(const char *path, int flags) {
         bool done = false;
 
index 1e066d8..a81d019 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
 #include "macro.h"
 #include "missing.h"
 
+int name_to_handle_at_loop(int fd, const char *path, struct file_handle **ret_handle, int *ret_mnt_id, int flags);
+
+int path_get_mnt_id(const char *path, int *ret);
+
 int fd_is_mount_point(int fd, const char *filename, int flags);
 int path_is_mount_point(const char *path, const char *root, int flags);
 
@@ -47,16 +52,10 @@ bool fstype_is_network(const char *fstype);
 bool fstype_is_api_vfs(const char *fstype);
 bool fstype_is_ro(const char *fsype);
 bool fstype_can_discard(const char *fstype);
-
-union file_handle_union {
-        struct file_handle handle;
-        char padding[sizeof(struct file_handle) + MAX_HANDLE_SZ];
-};
+bool fstype_can_uid_gid(const char *fstype);
 
 const char* mode_to_inaccessible_node(mode_t mode);
 
-#define FILE_HANDLE_INIT { .handle.handle_bytes = MAX_HANDLE_SZ }
-
 int mount_verbose(
                 int error_log_level,
                 const char *what,
index 9d927a8..4fc6763 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 2e0bdf6..afcf2db 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index e1dfc86..c4dbd79 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 4e2bf7f..bf8ee7a 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -25,6 +26,7 @@
 #include <string.h>
 
 #include "alloc-util.h"
+#include "errno-list.h"
 #include "extract-word.h"
 #include "macro.h"
 #include "parse-util.h"
@@ -268,6 +270,64 @@ int parse_range(const char *t, unsigned *lower, unsigned *upper) {
         return 0;
 }
 
+int parse_errno(const char *t) {
+        int r, e;
+
+        assert(t);
+
+        r = errno_from_name(t);
+        if (r > 0)
+                return r;
+
+        r = safe_atoi(t, &e);
+        if (r < 0)
+                return r;
+
+        if (e < 0 || e > ERRNO_MAX)
+                return -ERANGE;
+
+        return e;
+}
+
+int parse_syscall_and_errno(const char *in, char **name, int *error) {
+        _cleanup_free_ char *n = NULL;
+        char *p;
+        int e = -1;
+
+        assert(in);
+        assert(name);
+        assert(error);
+
+        /*
+         * This parse "syscall:errno" like "uname:EILSEQ", "@sync:255".
+         * If errno is omitted, then error is set to -1.
+         * Empty syscall name is not allowed.
+         * Here, we do not check that the syscall name is valid or not.
+         */
+
+        p = strchr(in, ':');
+        if (p) {
+                e = parse_errno(p + 1);
+                if (e < 0)
+                        return e;
+
+                n = strndup(in, p - in);
+        } else
+                n = strdup(in);
+
+        if (!n)
+                return -ENOMEM;
+
+        if (isempty(n))
+                return -EINVAL;
+
+        *error = e;
+        *name = n;
+        n = NULL;
+
+        return 0;
+}
+
 char *format_bytes(char *buf, size_t l, uint64_t t) {
         unsigned i;
 
index 80716e9..7274220 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -37,6 +38,8 @@ int parse_ifindex(const char *s, int *ret);
 
 int parse_size(const char *t, uint64_t base, uint64_t *size);
 int parse_range(const char *t, unsigned *lower, unsigned *upper);
+int parse_errno(const char *t);
+int parse_syscall_and_errno(const char *in, char **name, int *error);
 
 #define FORMAT_BYTES_MAX 8
 char *format_bytes(char *buf, size_t l, uint64_t t);
index 6c06bd2..ab4778d 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -222,8 +223,8 @@ int path_strv_make_absolute_cwd(char **l) {
                 if (r < 0)
                         return r;
 
-                free(*s);
-                *s = t;
+                path_kill_slashes(t);
+                free_and_replace(*s, t);
         }
 
         return 0;
@@ -537,7 +538,7 @@ bool paths_check_timestamp(const char* const* paths, usec_t *timestamp, bool upd
 
         assert(timestamp);
 
-        if (paths == NULL)
+        if (!paths)
                 return false;
 
         STRV_FOREACH(i, paths) {
@@ -702,6 +703,37 @@ char* dirname_malloc(const char *path) {
         return dir2;
 }
 
+const char *last_path_component(const char *path) {
+        /* Finds the last component of the path, preserving the
+         * optional trailing slash that signifies a directory.
+         *    a/b/c → c
+         *    a/b/c/ → c/
+         *    / → /
+         *    // → /
+         *    /foo/a → a
+         *    /foo/a/ → a/
+         * This is different than basename, which returns "" when
+         * a trailing slash is present.
+         */
+
+        unsigned l, k;
+
+        l = k = strlen(path);
+        if (l == 0) /* special case — an empty string */
+                return path;
+
+        while (k > 0 && path[k-1] == '/')
+                k--;
+
+        if (k == 0) /* the root directory */
+                return path + l - 1;
+
+        while (k > 0 && path[k-1] != '/')
+                k--;
+
+        return path + k;
+}
+
 bool filename_is_valid(const char *p) {
         const char *e;
 
@@ -721,7 +753,7 @@ bool filename_is_valid(const char *p) {
         return true;
 }
 
-bool path_is_safe(const char *p) {
+bool path_is_normalized(const char *p) {
 
         if (isempty(p))
                 return false;
@@ -735,7 +767,6 @@ bool path_is_safe(const char *p) {
         if (strlen(p)+1 > PATH_MAX)
                 return false;
 
-        /* The following two checks are not really dangerous, but hey, they still are confusing */
         if (startswith(p, "./") || endswith(p, "/.") || strstr(p, "/./"))
                 return false;
 
@@ -851,7 +882,9 @@ int systemd_installation_has_version(const char *root, unsigned minimal_version)
                         * for Gentoo which does a merge without making /lib a symlink.
                         */
                        "lib/systemd/libsystemd-shared-*.so\0"
-                       "usr/lib/systemd/libsystemd-shared-*.so\0") {
+                       "lib64/systemd/libsystemd-shared-*.so\0"
+                       "usr/lib/systemd/libsystemd-shared-*.so\0"
+                       "usr/lib64/systemd/libsystemd-shared-*.so\0") {
 
                 _cleanup_strv_free_ char **names = NULL;
                 _cleanup_free_ char *path = NULL;
index 5462465..f79cdf9 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -129,9 +130,10 @@ char *prefix_root(const char *root, const char *path);
 int parse_path_argument_and_warn(const char *path, bool suppress_root, char **arg);
 
 char* dirname_malloc(const char *path);
+const char *last_path_component(const char *path);
 
 bool filename_is_valid(const char *p) _pure_;
-bool path_is_safe(const char *p) _pure_;
+bool path_is_normalized(const char *p) _pure_;
 
 char *file_in_same_dir(const char *path, const char *filename);
 
index 4570b8e..407b17e 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 113c73d..a222955 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 8592a42..c5d1fb1 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -270,17 +271,21 @@ static const char * const rlmap_initrd[] = {
 };
 
 const char* runlevel_to_target(const char *word) {
+        const char * const *rlmap_ptr;
         size_t i;
-        const char * const *rlmap_ptr = in_initrd() ? rlmap_initrd
-                                                    : rlmap;
 
         if (!word)
                 return NULL;
 
-        if (in_initrd() && (word = startswith(word, "rd.")) == NULL)
-                return NULL;
+        if (in_initrd()) {
+                word = startswith(word, "rd.");
+                if (!word)
+                        return NULL;
+        }
+
+        rlmap_ptr = in_initrd() ? rlmap_initrd : rlmap;
 
-        for (i = 0; rlmap_ptr[i] != NULL; i += 2)
+        for (i = 0; rlmap_ptr[i]; i += 2)
                 if (streq(word, rlmap_ptr[i]))
                         return rlmap_ptr[i+1];
 
index ebfed35..16ccfbc 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 99b0946..17c94f4 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -25,6 +26,7 @@
 #include <signal.h>
 #include <stdbool.h>
 #include <stdio.h>
+#include <stdio_ext.h>
 #include <stdlib.h>
 #include <string.h>
 #include <sys/mman.h>
@@ -129,6 +131,8 @@ int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char *
                 return -errno;
         }
 
+        (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
+
         if (max_length == 1) {
 
                 /* If there's only room for one byte, return the empty string */
@@ -405,6 +409,8 @@ int is_kernel_thread(pid_t pid) {
                 return -errno;
         }
 
+        (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
+
         count = fread(&c, 1, 1, f);
         eof = feof(f);
         fclose(f);
@@ -486,6 +492,8 @@ static int get_process_id(pid_t pid, const char *field, uid_t *uid) {
                 return -errno;
         }
 
+        (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
+
         FOREACH_LINE(line, f, return -errno) {
                 char *l;
 
@@ -564,6 +572,8 @@ int get_process_environ(pid_t pid, char **env) {
                 return -errno;
         }
 
+        (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
+
         while ((c = fgetc(f)) != EOF) {
                 if (!GREEDY_REALLOC(outcome, allocated, sz + 5))
                         return -ENOMEM;
@@ -698,6 +708,67 @@ int wait_for_terminate_and_warn(const char *name, pid_t pid, bool check_exit_cod
         return -EPROTO;
 }
 
+/*
+ * Return values:
+ * < 0 : wait_for_terminate_with_timeout() failed to get the state of the
+ *       process, the process timed out, the process was terminated by a
+ *       signal, or failed for an unknown reason.
+ * >=0 : The process terminated normally with no failures.
+ *
+ * Success is indicated by a return value of zero, a timeout is indicated
+ * by ETIMEDOUT, and all other child failure states are indicated by error
+ * is indicated by a non-zero value.
+ */
+int wait_for_terminate_with_timeout(pid_t pid, usec_t timeout) {
+        sigset_t mask;
+        int r;
+        usec_t until;
+
+        assert_se(sigemptyset(&mask) == 0);
+        assert_se(sigaddset(&mask, SIGCHLD) == 0);
+
+        /* Drop into a sigtimewait-based timeout. Waiting for the
+         * pid to exit. */
+        until = now(CLOCK_MONOTONIC) + timeout;
+        for (;;) {
+                usec_t n;
+                siginfo_t status = {};
+                struct timespec ts;
+
+                n = now(CLOCK_MONOTONIC);
+                if (n >= until)
+                        break;
+
+                r = sigtimedwait(&mask, NULL, timespec_store(&ts, until - n)) < 0 ? -errno : 0;
+                /* Assuming we woke due to the child exiting. */
+                if (waitid(P_PID, pid, &status, WEXITED|WNOHANG) == 0) {
+                        if (status.si_pid == pid) {
+                                /* This is the correct child.*/
+                                if (status.si_code == CLD_EXITED)
+                                        return (status.si_status == 0) ? 0 : -EPROTO;
+                                else
+                                        return -EPROTO;
+                        }
+                }
+                /* Not the child, check for errors and proceed appropriately */
+                if (r < 0) {
+                        switch (r) {
+                        case -EAGAIN:
+                                /* Timed out, child is likely hung. */
+                                return -ETIMEDOUT;
+                        case -EINTR:
+                                /* Received a different signal and should retry */
+                                continue;
+                        default:
+                                /* Return any unexpected errors */
+                                return r;
+                        }
+                }
+        }
+
+        return -EPROTO;
+}
+
 void sigkill_wait(pid_t pid) {
         assert(pid > 1);
 
@@ -748,6 +819,8 @@ int getenv_for_pid(pid_t pid, const char *field, char **_value) {
                 return -errno;
         }
 
+        (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
+
         l = strlen(field);
         r = 0;
 
@@ -1052,6 +1125,15 @@ pid_t getpid_cached(void) {
         }
 }
 
+int must_be_root(void) {
+
+        if (geteuid() == 0)
+                return 0;
+
+        log_error("Need to be root.");
+        return -EPERM;
+}
+
 static const char *const ioprio_class_table[] = {
         [IOPRIO_CLASS_NONE] = "none",
         [IOPRIO_CLASS_RT] = "realtime",
index 82af2f9..1b7e692 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -32,6 +33,7 @@
 #include "format-util.h"
 #include "ioprio.h"
 #include "macro.h"
+#include "time-util.h"
 
 #define procfs_file_alloca(pid, field)                                  \
         ({                                                              \
@@ -40,7 +42,7 @@
                 if (_pid_ == 0) {                                       \
                         _r_ = ("/proc/self/" field);                    \
                 } else {                                                \
-                        _r_ = alloca(strlen("/proc/") + DECIMAL_STR_MAX(pid_t) + 1 + sizeof(field)); \
+                        _r_ = alloca(STRLEN("/proc/") + DECIMAL_STR_MAX(pid_t) + 1 + sizeof(field)); \
                         sprintf((char*) _r_, "/proc/"PID_FMT"/" field, _pid_);                       \
                 }                                                       \
                 _r_;                                                    \
@@ -60,6 +62,7 @@ int get_process_ppid(pid_t pid, pid_t *ppid);
 
 int wait_for_terminate(pid_t pid, siginfo_t *status);
 int wait_for_terminate_and_warn(const char *name, pid_t pid, bool check_exit_code);
+int wait_for_terminate_with_timeout(pid_t pid, usec_t timeout);
 
 void sigkill_wait(pid_t pid);
 void sigkill_waitp(pid_t *pid);
@@ -137,3 +140,5 @@ static inline bool pid_is_valid(pid_t p) {
 int ioprio_parse_priority(const char *s, int *ret);
 
 pid_t getpid_cached(void);
+
+int must_be_root(void);
index 146c8f5..1bc8000 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 804e225..dd87015 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 3ca5625..5b684e2 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 9c8dddf..19acf9c 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index c6e531a..f01b73a 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 1d77a64..ae2e446 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index d264281..c73ed97 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 31eb057..3d59061 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 5c41429..0064821 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index d4594ec..4494b89 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 0bbafb4..2839f37 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index e13f700..1127e32 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 011ec36..b5f6418 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index b4d970c..aaa192f 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 93bcdb2..0c6e99b 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 5bf7236..9780dca 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index fd398b8..e554e82 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -38,7 +39,7 @@ int set_make(Set **ret, const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS, vo
 
                 va_start(ap, add);
 
-                for(;;) {
+                for (;;) {
                         void *arg = va_arg(ap, void*);
 
                         if (!arg)
index 12d0fda..156ab4b 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -107,6 +108,18 @@ static inline void *set_steal_first(Set *s) {
         return internal_hashmap_steal_first(HASHMAP_BASE(s));
 }
 
+#define set_clear_with_destructor(_s, _f)               \
+        ({                                              \
+                void *_item;                            \
+                while ((_item = set_steal_first(_s)))   \
+                        _f(_item);                      \
+        })
+#define set_free_with_destructor(_s, _f)                \
+        ({                                              \
+                set_clear_with_destructor(_s, _f);      \
+                set_free(_s);                           \
+        })
+
 /* no set_steal_first_key */
 /* no set_first_key */
 
index 0ce4f75..2416929 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 980243d..90b0c96 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index df6b742..27caabe 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -225,7 +226,7 @@ static const char *const __signal_table[] = {
 DEFINE_PRIVATE_STRING_TABLE_LOOKUP(__signal, int);
 
 const char *signal_to_string(int signo) {
-        static thread_local char buf[sizeof("RTMIN+")-1 + DECIMAL_STR_MAX(int) + 1];
+        static thread_local char buf[STRLEN("RTMIN+") + DECIMAL_STR_MAX(int) + 1];
         const char *name;
 
         name = __signal_to_string(signo);
index dfd6eb5..76b239b 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -44,11 +45,11 @@ static inline void block_signals_reset(sigset_t *ss) {
         assert_se(sigprocmask(SIG_SETMASK, ss, NULL) >= 0);
 }
 
-#define BLOCK_SIGNALS(...)                                                        \
-        _cleanup_(block_signals_reset) _unused_ sigset_t _saved_sigset = ({       \
-                sigset_t t;                                                       \
-                assert_se(sigprocmask_many(SIG_BLOCK, &t, __VA_ARGS__, -1) >= 0); \
-                t;                                                                \
+#define BLOCK_SIGNALS(...)                                                         \
+        _cleanup_(block_signals_reset) _unused_ sigset_t _saved_sigset = ({        \
+                sigset_t _t;                                                       \
+                assert_se(sigprocmask_many(SIG_BLOCK, &_t, __VA_ARGS__, -1) >= 0); \
+                _t;                                                                \
         })
 
 static inline bool SIGNAL_VALID(int signo) {
index 4bb4178..d3a81b7 100644 (file)
@@ -127,25 +127,25 @@ void siphash24_compress(const void *_in, size_t inlen, struct siphash *state) {
         switch (left) {
                 case 7:
                         state->padding |= ((uint64_t) in[6]) << 48;
-                        /* fall through */
+                        _fallthrough_;
                 case 6:
                         state->padding |= ((uint64_t) in[5]) << 40;
-                        /* fall through */
+                        _fallthrough_;
                 case 5:
                         state->padding |= ((uint64_t) in[4]) << 32;
-                        /* fall through */
+                        _fallthrough_;
                 case 4:
                         state->padding |= ((uint64_t) in[3]) << 24;
-                        /* fall through */
+                        _fallthrough_;
                 case 3:
                         state->padding |= ((uint64_t) in[2]) << 16;
-                        /* fall through */
+                        _fallthrough_;
                 case 2:
                         state->padding |= ((uint64_t) in[1]) <<  8;
-                        /* fall through */
+                        _fallthrough_;
                 case 1:
                         state->padding |= ((uint64_t) in[0]);
-                        /* fall through */
+                        _fallthrough_;
                 case 0:
                         break;
         }
index 7bed6bd..ef16367 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index f90ba0a..e4d46d7 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 6e7cdaa..20be406 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 29c7795..a458fc2 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -121,7 +122,7 @@ int socket_address_parse(SocketAddress *a, const char *s) {
 
         } else if (startswith(s, "vsock:")) {
                 /* AF_VSOCK socket in vsock:cid:port notation */
-                const char *cid_start = s + strlen("vsock:");
+                const char *cid_start = s + STRLEN("vsock:");
 
                 e = strchr(cid_start, ':');
                 if (!e)
index 43edc05..272e74b 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index a3573b8..5e59de5 100644 (file)
@@ -1,4 +1,6 @@
-/* Copyright (c) 2012 Josh Triplett <josh@joshtriplett.org>
+/* SPDX-License-Identifier: MIT
+ *
+ * Copyright (c) 2012 Josh Triplett <josh@joshtriplett.org>
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to
index 012ac8d..eea6919 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index d87370e..96fc8b3 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -192,7 +193,7 @@ bool is_fs_type(const struct statfs *s, statfs_f_type_t magic_value) {
         return F_TYPE_EQUAL(s->f_type, magic_value);
 }
 
-int fd_check_fstype(int fd, statfs_f_type_t magic_value) {
+int fd_is_fs_type(int fd, statfs_f_type_t magic_value) {
         struct statfs s;
 
         if (fstatfs(fd, &s) < 0)
@@ -201,14 +202,14 @@ int fd_check_fstype(int fd, statfs_f_type_t magic_value) {
         return is_fs_type(&s, magic_value);
 }
 
-int path_check_fstype(const char *path, statfs_f_type_t magic_value) {
+int path_is_fs_type(const char *path, statfs_f_type_t magic_value) {
         _cleanup_close_ int fd = -1;
 
         fd = open(path, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_PATH);
         if (fd < 0)
                 return -errno;
 
-        return fd_check_fstype(fd, magic_value);
+        return fd_is_fs_type(fd, magic_value);
 }
 
 bool is_temporary_fs(const struct statfs *s) {
@@ -225,6 +226,18 @@ int fd_is_temporary_fs(int fd) {
         return is_temporary_fs(&s);
 }
 
+int fd_is_network_ns(int fd) {
+        int r;
+
+        r = fd_is_fs_type(fd, NSFS_MAGIC);
+        if (r <= 0)
+                return r;
+        r = ioctl(fd, NS_GET_NSTYPE);
+        if (r < 0)
+                return -errno;
+        return r == CLONE_NEWNET;
+}
+
 int path_is_temporary_fs(const char *path) {
         _cleanup_close_ int fd = -1;
 
index cd204ac..d8d3c20 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -56,11 +57,12 @@ int files_same(const char *filea, const char *fileb, int flags);
 typedef typeof(((struct statfs*)NULL)->f_type) statfs_f_type_t;
 
 bool is_fs_type(const struct statfs *s, statfs_f_type_t magic_value) _pure_;
-int fd_check_fstype(int fd, statfs_f_type_t magic_value);
-int path_check_fstype(const char *path, statfs_f_type_t magic_value);
+int fd_is_fs_type(int fd, statfs_f_type_t magic_value);
+int path_is_fs_type(const char *path, statfs_f_type_t magic_value);
 
 bool is_temporary_fs(const struct statfs *s) _pure_;
 int fd_is_temporary_fs(int fd);
+int fd_is_network_ns(int fd);
 int path_is_temporary_fs(const char *path);
 
 /* Because statfs.t_type can be int on some architectures, we have to cast
index c594010..d3fed36 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 00aaf9e..8befffa 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index a1632da..d5888a0 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index a1499ab..d4b7c69 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 369610e..4306b90 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 
 #pragma once
 
index 3179fba..7e2f596 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -21,6 +22,7 @@
 #include <stdarg.h>
 #include <stdint.h>
 #include <stdio.h>
+#include <stdio_ext.h>
 #include <stdlib.h>
 #include <string.h>
 
@@ -278,6 +280,9 @@ char *strjoin_real(const char *x, ...) {
 char *strstrip(char *s) {
         char *e;
 
+        if (!s)
+                return NULL;
+
         /* Drops trailing whitespace. Modifies the string in
          * place. Returns pointer to first non-space character */
 
@@ -295,7 +300,13 @@ char *strstrip(char *s) {
 char *delete_chars(char *s, const char *bad) {
         char *f, *t;
 
-        /* Drops all whitespace, regardless where in the string */
+        /* Drops all specified bad characters, regardless where in the string */
+
+        if (!s)
+                return NULL;
+
+        if (!bad)
+                bad = WHITESPACE;
 
         for (f = s, t = s; *f; f++) {
                 if (strchr(bad, *f))
@@ -309,6 +320,26 @@ char *delete_chars(char *s, const char *bad) {
         return s;
 }
 
+char *delete_trailing_chars(char *s, const char *bad) {
+        char *p, *c = s;
+
+        /* Drops all specified bad characters, at the end of the string */
+
+        if (!s)
+                return NULL;
+
+        if (!bad)
+                bad = WHITESPACE;
+
+        for (p = s; *p; p++)
+                if (!strchr(bad, *p))
+                        c = p + 1;
+
+        *c = 0;
+
+        return s;
+}
+
 char *truncate_nl(char *s) {
         assert(s);
 
@@ -472,6 +503,10 @@ char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigne
 
         assert(s);
         assert(percent <= 100);
+
+        if (new_length == (size_t) -1)
+                return strndup(s, old_length);
+
         assert(new_length >= 3);
 
         /* if no multibyte characters use ascii_ellipsize_mem for speed */
@@ -539,6 +574,10 @@ char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigne
 }
 
 char *ellipsize(const char *s, size_t length, unsigned percent) {
+
+        if (length == (size_t) -1)
+                return strdup(s);
+
         return ellipsize_mem(s, strlen(s), length, percent);
 }
 
@@ -565,26 +604,26 @@ char* strshorten(char *s, size_t l) {
 }
 
 char *strreplace(const char *text, const char *old_string, const char *new_string) {
+        size_t l, old_len, new_len, allocated = 0;
+        char *t, *ret = NULL;
         const char *f;
-        char *t, *r;
-        size_t l, old_len, new_len;
 
-        assert(text);
         assert(old_string);
         assert(new_string);
 
+        if (!text)
+                return NULL;
+
         old_len = strlen(old_string);
         new_len = strlen(new_string);
 
         l = strlen(text);
-        r = new(char, l+1);
-        if (!r)
+        if (!GREEDY_REALLOC(ret, allocated, l+1))
                 return NULL;
 
         f = text;
-        t = r;
+        t = ret;
         while (*f) {
-                char *a;
                 size_t d, nl;
 
                 if (!startswith(f, old_string)) {
@@ -592,25 +631,21 @@ char *strreplace(const char *text, const char *old_string, const char *new_strin
                         continue;
                 }
 
-                d = t - r;
+                d = t - ret;
                 nl = l - old_len + new_len;
-                a = realloc(r, nl + 1);
-                if (!a)
-                        goto oom;
+
+                if (!GREEDY_REALLOC(ret, allocated, nl + 1))
+                        return mfree(ret);
 
                 l = nl;
-                r = a;
-                t = r + d;
+                t = ret + d;
 
                 t = stpcpy(t, new_string);
                 f += old_len;
         }
 
         *t = 0;
-        return r;
-
-oom:
-        return mfree(r);
+        return ret;
 }
 
 char *strip_tab_ansi(char **ibuf, size_t *_isz) {
@@ -635,10 +670,10 @@ char *strip_tab_ansi(char **ibuf, size_t *_isz) {
         if (!f)
                 return NULL;
 
-        /* Note we use the _unlocked() stdio variants on f for performance
-         * reasons.  It's safe to do so since we created f here and it
-         * doesn't leave our scope.
-         */
+        /* Note we turn off internal locking on f for performance reasons.  It's safe to do so since we created f here
+         * and it doesn't leave our scope. */
+
+        (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
 
         for (i = *ibuf; i < *ibuf + isz + 1; i++) {
 
@@ -650,21 +685,21 @@ char *strip_tab_ansi(char **ibuf, size_t *_isz) {
                         else if (*i == '\x1B')
                                 state = STATE_ESCAPE;
                         else if (*i == '\t')
-                                fputs_unlocked("        ", f);
+                                fputs("        ", f);
                         else
-                                fputc_unlocked(*i, f);
+                                fputc(*i, f);
                         break;
 
                 case STATE_ESCAPE:
                         if (i >= *ibuf + isz) { /* EOT */
-                                fputc_unlocked('\x1B', f);
+                                fputc('\x1B', f);
                                 break;
                         } else if (*i == '[') {
                                 state = STATE_BRACKET;
                                 begin = i + 1;
                         } else {
-                                fputc_unlocked('\x1B', f);
-                                fputc_unlocked(*i, f);
+                                fputc('\x1B', f);
+                                fputc(*i, f);
                                 state = STATE_OTHER;
                         }
 
@@ -674,8 +709,8 @@ char *strip_tab_ansi(char **ibuf, size_t *_isz) {
 
                         if (i >= *ibuf + isz || /* EOT */
                             (!(*i >= '0' && *i <= '9') && !IN_SET(*i, ';', 'm'))) {
-                                fputc_unlocked('\x1B', f);
-                                fputc_unlocked('[', f);
+                                fputc('\x1B', f);
+                                fputc('[', f);
                                 state = STATE_OTHER;
                                 i = begin-1;
                         } else if (*i == 'm')
@@ -700,16 +735,20 @@ char *strip_tab_ansi(char **ibuf, size_t *_isz) {
         return obuf;
 }
 
-char *strextend(char **x, ...) {
-        va_list ap;
-        size_t f, l;
+char *strextend_with_separator(char **x, const char *separator, ...) {
+        bool need_separator;
+        size_t f, l, l_separator;
         char *r, *p;
+        va_list ap;
 
         assert(x);
 
         l = f = strlen_ptr(*x);
 
-        va_start(ap, x);
+        need_separator = !isempty(*x);
+        l_separator = strlen_ptr(separator);
+
+        va_start(ap, separator);
         for (;;) {
                 const char *t;
                 size_t n;
@@ -719,22 +758,29 @@ char *strextend(char **x, ...) {
                         break;
 
                 n = strlen(t);
+
+                if (need_separator)
+                        n += l_separator;
+
                 if (n > ((size_t) -1) - l) {
                         va_end(ap);
                         return NULL;
                 }
 
                 l += n;
+                need_separator = true;
         }
         va_end(ap);
 
+        need_separator = !isempty(*x);
+
         r = realloc(*x, l+1);
         if (!r)
                 return NULL;
 
         p = r + f;
 
-        va_start(ap, x);
+        va_start(ap, separator);
         for (;;) {
                 const char *t;
 
@@ -742,10 +788,17 @@ char *strextend(char **x, ...) {
                 if (!t)
                         break;
 
+                if (need_separator && separator)
+                        p = stpcpy(p, separator);
+
                 p = stpcpy(p, t);
+
+                need_separator = true;
         }
         va_end(ap);
 
+        assert(p == r + l);
+
         *p = 0;
         *x = r;
 
index 4c94b18..09a737a 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -133,8 +134,20 @@ char *strjoin_real(const char *x, ...) _sentinel_;
 
 char *strstrip(char *s);
 char *delete_chars(char *s, const char *bad);
+char *delete_trailing_chars(char *s, const char *bad);
 char *truncate_nl(char *s);
 
+static inline char *skip_leading_chars(const char *s, const char *bad) {
+
+        if (!s)
+                return NULL;
+
+        if (!bad)
+                bad = WHITESPACE;
+
+        return (char*) s + strspn(s, bad);
+}
+
 char ascii_tolower(char x);
 char *ascii_strlower(char *s);
 char *ascii_strlower_n(char *s, size_t n);
@@ -166,7 +179,9 @@ char *strreplace(const char *text, const char *old_string, const char *new_strin
 
 char *strip_tab_ansi(char **p, size_t *l);
 
-char *strextend(char **x, ...) _sentinel_;
+char *strextend_with_separator(char **x, const char *separator, ...) _sentinel_;
+
+#define strextend(x, ...) strextend_with_separator(x, NULL, __VA_ARGS__)
 
 char *strrep(const char *s, unsigned n);
 
index c63f11c..54c701a 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 172b99e..d3fa72e 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -173,3 +174,11 @@ char **strv_skip(char **l, size_t n);
 int strv_extend_n(char ***l, const char *value, size_t n);
 
 int fputstrv(FILE *f, char **l, const char *separator, bool *space);
+
+#define strv_free_and_replace(a, b)             \
+        ({                                      \
+                strv_free(a);                   \
+                (a) = (b);                      \
+                (b) = NULL;                     \
+                0;                              \
+        })
index c6fbe79..b440a9a 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 80ff587..0554454 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index db34051..4f4e235 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 5cb606a..8f44e3f 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 28c8c35..48ee799 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -245,7 +246,6 @@ int ask_string(char **ret, const char *text, ...) {
 
 int reset_terminal_fd(int fd, bool switch_to_text) {
         struct termios termios;
-        _cleanup_free_ char *utf8 = NULL;
         int r = 0;
 
         /* Set terminal to some sane defaults */
@@ -992,7 +992,7 @@ int get_ctty_devnr(pid_t pid, dev_t *d) {
 }
 
 int get_ctty(pid_t pid, dev_t *_devnr, char **r) {
-        char fn[sizeof("/dev/char/")-1 + 2*DECIMAL_STR_MAX(unsigned) + 1 + 1], *b = NULL;
+        char fn[STRLEN("/dev/char/") + 2*DECIMAL_STR_MAX(unsigned) + 1 + 1], *b = NULL;
         _cleanup_free_ char *s = NULL;
         const char *p;
         dev_t devnr;
index c3045eb..e82719b 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index f7f5e61..d56576d 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -892,7 +893,7 @@ int parse_timestamp(const char *t, usec_t *usec) {
         if (last_space != NULL && timezone_is_valid(last_space + 1))
                 tz = last_space + 1;
 
-        if (tz == NULL || endswith_no_case(t, " UTC"))
+        if (!tz || endswith_no_case(t, " UTC"))
                 return parse_timestamp_impl(t, usec, false);
 
         shared = mmap(NULL, sizeof *shared, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
@@ -1381,8 +1382,7 @@ bool clock_supported(clockid_t clock) {
                 if (!clock_boottime_supported())
                         return false;
 
-                /* fall through */
-
+                _fallthrough_;
         default:
                 /* For everything else, check properly */
                 return clock_gettime(clock, &ts) >= 0;
@@ -1456,3 +1456,9 @@ usec_t usec_shift_clock(usec_t x, clockid_t from, clockid_t to) {
                 /* x lies in the past */
                 return usec_sub_unsigned(b, usec_sub_unsigned(a, x));
 }
+
+bool in_utc_timezone(void) {
+        tzset();
+
+        return timezone == 0 && daylight == 0;
+}
index 3b7f0e9..dc4a159 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -148,10 +149,6 @@ clockid_t clock_boottime_or_monotonic(void);
 
 usec_t usec_shift_clock(usec_t, clockid_t from, clockid_t to);
 
-#define xstrftime(buf, fmt, tm) \
-        assert_message_se(strftime(buf, ELEMENTSOF(buf), fmt, tm) > 0, \
-                          "xstrftime: " #buf "[] must be big enough")
-
 int get_timezone(char **timezone);
 
 time_t mktime_or_timegm(struct tm *tm, bool utc);
@@ -159,6 +156,8 @@ struct tm *localtime_or_gmtime_r(const time_t *t, struct tm *tm, bool utc);
 
 unsigned long usec_to_jiffies(usec_t usec);
 
+bool in_utc_timezone(void);
+
 static inline usec_t usec_add(usec_t a, usec_t b) {
         usec_t c;
 
index 359d87d..638b37d 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 7c847a3..201b3d2 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
diff --git a/src/basic/unit-def.c b/src/basic/unit-def.c
new file mode 100644 (file)
index 0000000..387533f
--- /dev/null
@@ -0,0 +1,290 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  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.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "alloc-util.h"
+#include "bus-label.h"
+#include "string-table.h"
+#include "unit-def.h"
+#include "unit-name.h"
+
+char *unit_dbus_path_from_name(const char *name) {
+        _cleanup_free_ char *e = NULL;
+
+        assert(name);
+
+        e = bus_label_escape(name);
+        if (!e)
+                return NULL;
+
+        return strappend("/org/freedesktop/systemd1/unit/", e);
+}
+
+int unit_name_from_dbus_path(const char *path, char **name) {
+        const char *e;
+        char *n;
+
+        e = startswith(path, "/org/freedesktop/systemd1/unit/");
+        if (!e)
+                return -EINVAL;
+
+        n = bus_label_unescape(e);
+        if (!n)
+                return -ENOMEM;
+
+        *name = n;
+        return 0;
+}
+
+const char* unit_dbus_interface_from_type(UnitType t) {
+
+        static const char *const table[_UNIT_TYPE_MAX] = {
+                [UNIT_SERVICE] = "org.freedesktop.systemd1.Service",
+                [UNIT_SOCKET] = "org.freedesktop.systemd1.Socket",
+                [UNIT_TARGET] = "org.freedesktop.systemd1.Target",
+                [UNIT_DEVICE] = "org.freedesktop.systemd1.Device",
+                [UNIT_MOUNT] = "org.freedesktop.systemd1.Mount",
+                [UNIT_AUTOMOUNT] = "org.freedesktop.systemd1.Automount",
+                [UNIT_SWAP] = "org.freedesktop.systemd1.Swap",
+                [UNIT_TIMER] = "org.freedesktop.systemd1.Timer",
+                [UNIT_PATH] = "org.freedesktop.systemd1.Path",
+                [UNIT_SLICE] = "org.freedesktop.systemd1.Slice",
+                [UNIT_SCOPE] = "org.freedesktop.systemd1.Scope",
+        };
+
+        if (t < 0)
+                return NULL;
+        if (t >= _UNIT_TYPE_MAX)
+                return NULL;
+
+        return table[t];
+}
+
+const char *unit_dbus_interface_from_name(const char *name) {
+        UnitType t;
+
+        t = unit_name_to_type(name);
+        if (t < 0)
+                return NULL;
+
+        return unit_dbus_interface_from_type(t);
+}
+
+static const char* const unit_type_table[_UNIT_TYPE_MAX] = {
+        [UNIT_SERVICE] = "service",
+        [UNIT_SOCKET] = "socket",
+        [UNIT_TARGET] = "target",
+        [UNIT_DEVICE] = "device",
+        [UNIT_MOUNT] = "mount",
+        [UNIT_AUTOMOUNT] = "automount",
+        [UNIT_SWAP] = "swap",
+        [UNIT_TIMER] = "timer",
+        [UNIT_PATH] = "path",
+        [UNIT_SLICE] = "slice",
+        [UNIT_SCOPE] = "scope",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(unit_type, UnitType);
+
+static const char* const unit_load_state_table[_UNIT_LOAD_STATE_MAX] = {
+        [UNIT_STUB] = "stub",
+        [UNIT_LOADED] = "loaded",
+        [UNIT_NOT_FOUND] = "not-found",
+        [UNIT_ERROR] = "error",
+        [UNIT_MERGED] = "merged",
+        [UNIT_MASKED] = "masked"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(unit_load_state, UnitLoadState);
+
+static const char* const unit_active_state_table[_UNIT_ACTIVE_STATE_MAX] = {
+        [UNIT_ACTIVE] = "active",
+        [UNIT_RELOADING] = "reloading",
+        [UNIT_INACTIVE] = "inactive",
+        [UNIT_FAILED] = "failed",
+        [UNIT_ACTIVATING] = "activating",
+        [UNIT_DEACTIVATING] = "deactivating"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(unit_active_state, UnitActiveState);
+
+static const char* const automount_state_table[_AUTOMOUNT_STATE_MAX] = {
+        [AUTOMOUNT_DEAD] = "dead",
+        [AUTOMOUNT_WAITING] = "waiting",
+        [AUTOMOUNT_RUNNING] = "running",
+        [AUTOMOUNT_FAILED] = "failed"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(automount_state, AutomountState);
+
+static const char* const device_state_table[_DEVICE_STATE_MAX] = {
+        [DEVICE_DEAD] = "dead",
+        [DEVICE_TENTATIVE] = "tentative",
+        [DEVICE_PLUGGED] = "plugged",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(device_state, DeviceState);
+
+static const char* const mount_state_table[_MOUNT_STATE_MAX] = {
+        [MOUNT_DEAD] = "dead",
+        [MOUNT_MOUNTING] = "mounting",
+        [MOUNT_MOUNTING_DONE] = "mounting-done",
+        [MOUNT_MOUNTED] = "mounted",
+        [MOUNT_REMOUNTING] = "remounting",
+        [MOUNT_UNMOUNTING] = "unmounting",
+        [MOUNT_REMOUNTING_SIGTERM] = "remounting-sigterm",
+        [MOUNT_REMOUNTING_SIGKILL] = "remounting-sigkill",
+        [MOUNT_UNMOUNTING_SIGTERM] = "unmounting-sigterm",
+        [MOUNT_UNMOUNTING_SIGKILL] = "unmounting-sigkill",
+        [MOUNT_FAILED] = "failed"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(mount_state, MountState);
+
+static const char* const path_state_table[_PATH_STATE_MAX] = {
+        [PATH_DEAD] = "dead",
+        [PATH_WAITING] = "waiting",
+        [PATH_RUNNING] = "running",
+        [PATH_FAILED] = "failed"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(path_state, PathState);
+
+static const char* const scope_state_table[_SCOPE_STATE_MAX] = {
+        [SCOPE_DEAD] = "dead",
+        [SCOPE_RUNNING] = "running",
+        [SCOPE_ABANDONED] = "abandoned",
+        [SCOPE_STOP_SIGTERM] = "stop-sigterm",
+        [SCOPE_STOP_SIGKILL] = "stop-sigkill",
+        [SCOPE_FAILED] = "failed",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(scope_state, ScopeState);
+
+static const char* const service_state_table[_SERVICE_STATE_MAX] = {
+        [SERVICE_DEAD] = "dead",
+        [SERVICE_START_PRE] = "start-pre",
+        [SERVICE_START] = "start",
+        [SERVICE_START_POST] = "start-post",
+        [SERVICE_RUNNING] = "running",
+        [SERVICE_EXITED] = "exited",
+        [SERVICE_RELOAD] = "reload",
+        [SERVICE_STOP] = "stop",
+        [SERVICE_STOP_SIGABRT] = "stop-sigabrt",
+        [SERVICE_STOP_SIGTERM] = "stop-sigterm",
+        [SERVICE_STOP_SIGKILL] = "stop-sigkill",
+        [SERVICE_STOP_POST] = "stop-post",
+        [SERVICE_FINAL_SIGTERM] = "final-sigterm",
+        [SERVICE_FINAL_SIGKILL] = "final-sigkill",
+        [SERVICE_FAILED] = "failed",
+        [SERVICE_AUTO_RESTART] = "auto-restart",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(service_state, ServiceState);
+
+static const char* const slice_state_table[_SLICE_STATE_MAX] = {
+        [SLICE_DEAD] = "dead",
+        [SLICE_ACTIVE] = "active"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(slice_state, SliceState);
+
+static const char* const socket_state_table[_SOCKET_STATE_MAX] = {
+        [SOCKET_DEAD] = "dead",
+        [SOCKET_START_PRE] = "start-pre",
+        [SOCKET_START_CHOWN] = "start-chown",
+        [SOCKET_START_POST] = "start-post",
+        [SOCKET_LISTENING] = "listening",
+        [SOCKET_RUNNING] = "running",
+        [SOCKET_STOP_PRE] = "stop-pre",
+        [SOCKET_STOP_PRE_SIGTERM] = "stop-pre-sigterm",
+        [SOCKET_STOP_PRE_SIGKILL] = "stop-pre-sigkill",
+        [SOCKET_STOP_POST] = "stop-post",
+        [SOCKET_FINAL_SIGTERM] = "final-sigterm",
+        [SOCKET_FINAL_SIGKILL] = "final-sigkill",
+        [SOCKET_FAILED] = "failed"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(socket_state, SocketState);
+
+static const char* const swap_state_table[_SWAP_STATE_MAX] = {
+        [SWAP_DEAD] = "dead",
+        [SWAP_ACTIVATING] = "activating",
+        [SWAP_ACTIVATING_DONE] = "activating-done",
+        [SWAP_ACTIVE] = "active",
+        [SWAP_DEACTIVATING] = "deactivating",
+        [SWAP_DEACTIVATING_SIGTERM] = "deactivating-sigterm",
+        [SWAP_DEACTIVATING_SIGKILL] = "deactivating-sigkill",
+        [SWAP_FAILED] = "failed"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(swap_state, SwapState);
+
+static const char* const target_state_table[_TARGET_STATE_MAX] = {
+        [TARGET_DEAD] = "dead",
+        [TARGET_ACTIVE] = "active"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(target_state, TargetState);
+
+static const char* const timer_state_table[_TIMER_STATE_MAX] = {
+        [TIMER_DEAD] = "dead",
+        [TIMER_WAITING] = "waiting",
+        [TIMER_RUNNING] = "running",
+        [TIMER_ELAPSED] = "elapsed",
+        [TIMER_FAILED] = "failed"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(timer_state, TimerState);
+
+static const char* const unit_dependency_table[_UNIT_DEPENDENCY_MAX] = {
+        [UNIT_REQUIRES] = "Requires",
+        [UNIT_REQUISITE] = "Requisite",
+        [UNIT_WANTS] = "Wants",
+        [UNIT_BINDS_TO] = "BindsTo",
+        [UNIT_PART_OF] = "PartOf",
+        [UNIT_REQUIRED_BY] = "RequiredBy",
+        [UNIT_REQUISITE_OF] = "RequisiteOf",
+        [UNIT_WANTED_BY] = "WantedBy",
+        [UNIT_BOUND_BY] = "BoundBy",
+        [UNIT_CONSISTS_OF] = "ConsistsOf",
+        [UNIT_CONFLICTS] = "Conflicts",
+        [UNIT_CONFLICTED_BY] = "ConflictedBy",
+        [UNIT_BEFORE] = "Before",
+        [UNIT_AFTER] = "After",
+        [UNIT_ON_FAILURE] = "OnFailure",
+        [UNIT_TRIGGERS] = "Triggers",
+        [UNIT_TRIGGERED_BY] = "TriggeredBy",
+        [UNIT_PROPAGATES_RELOAD_TO] = "PropagatesReloadTo",
+        [UNIT_RELOAD_PROPAGATED_FROM] = "ReloadPropagatedFrom",
+        [UNIT_JOINS_NAMESPACE_OF] = "JoinsNamespaceOf",
+        [UNIT_REFERENCES] = "References",
+        [UNIT_REFERENCED_BY] = "ReferencedBy",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(unit_dependency, UnitDependency);
+
+static const char* const notify_access_table[_NOTIFY_ACCESS_MAX] = {
+        [NOTIFY_NONE] = "none",
+        [NOTIFY_MAIN] = "main",
+        [NOTIFY_EXEC] = "exec",
+        [NOTIFY_ALL] = "all"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(notify_access, NotifyAccess);
diff --git a/src/basic/unit-def.h b/src/basic/unit-def.h
new file mode 100644 (file)
index 0000000..c142e06
--- /dev/null
@@ -0,0 +1,302 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  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.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdbool.h>
+
+#include "macro.h"
+
+typedef enum UnitType {
+        UNIT_SERVICE = 0,
+        UNIT_SOCKET,
+        UNIT_TARGET,
+        UNIT_DEVICE,
+        UNIT_MOUNT,
+        UNIT_AUTOMOUNT,
+        UNIT_SWAP,
+        UNIT_TIMER,
+        UNIT_PATH,
+        UNIT_SLICE,
+        UNIT_SCOPE,
+        _UNIT_TYPE_MAX,
+        _UNIT_TYPE_INVALID = -1
+} UnitType;
+
+typedef enum UnitLoadState {
+        UNIT_STUB = 0,
+        UNIT_LOADED,
+        UNIT_NOT_FOUND,
+        UNIT_ERROR,
+        UNIT_MERGED,
+        UNIT_MASKED,
+        _UNIT_LOAD_STATE_MAX,
+        _UNIT_LOAD_STATE_INVALID = -1
+} UnitLoadState;
+
+typedef enum UnitActiveState {
+        UNIT_ACTIVE,
+        UNIT_RELOADING,
+        UNIT_INACTIVE,
+        UNIT_FAILED,
+        UNIT_ACTIVATING,
+        UNIT_DEACTIVATING,
+        _UNIT_ACTIVE_STATE_MAX,
+        _UNIT_ACTIVE_STATE_INVALID = -1
+} UnitActiveState;
+
+typedef enum AutomountState {
+        AUTOMOUNT_DEAD,
+        AUTOMOUNT_WAITING,
+        AUTOMOUNT_RUNNING,
+        AUTOMOUNT_FAILED,
+        _AUTOMOUNT_STATE_MAX,
+        _AUTOMOUNT_STATE_INVALID = -1
+} AutomountState;
+
+/* We simply watch devices, we cannot plug/unplug them. That
+ * simplifies the state engine greatly */
+typedef enum DeviceState {
+        DEVICE_DEAD,
+        DEVICE_TENTATIVE, /* mounted or swapped, but not (yet) announced by udev */
+        DEVICE_PLUGGED,   /* announced by udev */
+        _DEVICE_STATE_MAX,
+        _DEVICE_STATE_INVALID = -1
+} DeviceState;
+
+typedef enum MountState {
+        MOUNT_DEAD,
+        MOUNT_MOUNTING,               /* /usr/bin/mount is running, but the mount is not done yet. */
+        MOUNT_MOUNTING_DONE,          /* /usr/bin/mount is running, and the mount is done. */
+        MOUNT_MOUNTED,
+        MOUNT_REMOUNTING,
+        MOUNT_UNMOUNTING,
+        MOUNT_REMOUNTING_SIGTERM,
+        MOUNT_REMOUNTING_SIGKILL,
+        MOUNT_UNMOUNTING_SIGTERM,
+        MOUNT_UNMOUNTING_SIGKILL,
+        MOUNT_FAILED,
+        _MOUNT_STATE_MAX,
+        _MOUNT_STATE_INVALID = -1
+} MountState;
+
+typedef enum PathState {
+        PATH_DEAD,
+        PATH_WAITING,
+        PATH_RUNNING,
+        PATH_FAILED,
+        _PATH_STATE_MAX,
+        _PATH_STATE_INVALID = -1
+} PathState;
+
+typedef enum ScopeState {
+        SCOPE_DEAD,
+        SCOPE_RUNNING,
+        SCOPE_ABANDONED,
+        SCOPE_STOP_SIGTERM,
+        SCOPE_STOP_SIGKILL,
+        SCOPE_FAILED,
+        _SCOPE_STATE_MAX,
+        _SCOPE_STATE_INVALID = -1
+} ScopeState;
+
+typedef enum ServiceState {
+        SERVICE_DEAD,
+        SERVICE_START_PRE,
+        SERVICE_START,
+        SERVICE_START_POST,
+        SERVICE_RUNNING,
+        SERVICE_EXITED,            /* Nothing is running anymore, but RemainAfterExit is true hence this is OK */
+        SERVICE_RELOAD,
+        SERVICE_STOP,              /* No STOP_PRE state, instead just register multiple STOP executables */
+        SERVICE_STOP_SIGABRT,      /* Watchdog timeout */
+        SERVICE_STOP_SIGTERM,
+        SERVICE_STOP_SIGKILL,
+        SERVICE_STOP_POST,
+        SERVICE_FINAL_SIGTERM,     /* In case the STOP_POST executable hangs, we shoot that down, too */
+        SERVICE_FINAL_SIGKILL,
+        SERVICE_FAILED,
+        SERVICE_AUTO_RESTART,
+        _SERVICE_STATE_MAX,
+        _SERVICE_STATE_INVALID = -1
+} ServiceState;
+
+typedef enum SliceState {
+        SLICE_DEAD,
+        SLICE_ACTIVE,
+        _SLICE_STATE_MAX,
+        _SLICE_STATE_INVALID = -1
+} SliceState;
+
+typedef enum SocketState {
+        SOCKET_DEAD,
+        SOCKET_START_PRE,
+        SOCKET_START_CHOWN,
+        SOCKET_START_POST,
+        SOCKET_LISTENING,
+        SOCKET_RUNNING,
+        SOCKET_STOP_PRE,
+        SOCKET_STOP_PRE_SIGTERM,
+        SOCKET_STOP_PRE_SIGKILL,
+        SOCKET_STOP_POST,
+        SOCKET_FINAL_SIGTERM,
+        SOCKET_FINAL_SIGKILL,
+        SOCKET_FAILED,
+        _SOCKET_STATE_MAX,
+        _SOCKET_STATE_INVALID = -1
+} SocketState;
+
+typedef enum SwapState {
+        SWAP_DEAD,
+        SWAP_ACTIVATING,               /* /sbin/swapon is running, but the swap not yet enabled. */
+        SWAP_ACTIVATING_DONE,          /* /sbin/swapon is running, and the swap is done. */
+        SWAP_ACTIVE,
+        SWAP_DEACTIVATING,
+        SWAP_DEACTIVATING_SIGTERM,
+        SWAP_DEACTIVATING_SIGKILL,
+        SWAP_FAILED,
+        _SWAP_STATE_MAX,
+        _SWAP_STATE_INVALID = -1
+} SwapState;
+
+typedef enum TargetState {
+        TARGET_DEAD,
+        TARGET_ACTIVE,
+        _TARGET_STATE_MAX,
+        _TARGET_STATE_INVALID = -1
+} TargetState;
+
+typedef enum TimerState {
+        TIMER_DEAD,
+        TIMER_WAITING,
+        TIMER_RUNNING,
+        TIMER_ELAPSED,
+        TIMER_FAILED,
+        _TIMER_STATE_MAX,
+        _TIMER_STATE_INVALID = -1
+} TimerState;
+
+typedef enum UnitDependency {
+        /* Positive dependencies */
+        UNIT_REQUIRES,
+        UNIT_REQUISITE,
+        UNIT_WANTS,
+        UNIT_BINDS_TO,
+        UNIT_PART_OF,
+
+        /* Inverse of the above */
+        UNIT_REQUIRED_BY,             /* inverse of 'requires' is 'required_by' */
+        UNIT_REQUISITE_OF,            /* inverse of 'requisite' is 'requisite_of' */
+        UNIT_WANTED_BY,               /* inverse of 'wants' */
+        UNIT_BOUND_BY,                /* inverse of 'binds_to' */
+        UNIT_CONSISTS_OF,             /* inverse of 'part_of' */
+
+        /* Negative dependencies */
+        UNIT_CONFLICTS,               /* inverse of 'conflicts' is 'conflicted_by' */
+        UNIT_CONFLICTED_BY,
+
+        /* Order */
+        UNIT_BEFORE,                  /* inverse of 'before' is 'after' and vice versa */
+        UNIT_AFTER,
+
+        /* On Failure */
+        UNIT_ON_FAILURE,
+
+        /* Triggers (i.e. a socket triggers a service) */
+        UNIT_TRIGGERS,
+        UNIT_TRIGGERED_BY,
+
+        /* Propagate reloads */
+        UNIT_PROPAGATES_RELOAD_TO,
+        UNIT_RELOAD_PROPAGATED_FROM,
+
+        /* Joins namespace of */
+        UNIT_JOINS_NAMESPACE_OF,
+
+        /* Reference information for GC logic */
+        UNIT_REFERENCES,              /* Inverse of 'references' is 'referenced_by' */
+        UNIT_REFERENCED_BY,
+
+        _UNIT_DEPENDENCY_MAX,
+        _UNIT_DEPENDENCY_INVALID = -1
+} UnitDependency;
+
+typedef enum NotifyAccess {
+        NOTIFY_NONE,
+        NOTIFY_ALL,
+        NOTIFY_MAIN,
+        NOTIFY_EXEC,
+        _NOTIFY_ACCESS_MAX,
+        _NOTIFY_ACCESS_INVALID = -1
+} NotifyAccess;
+
+char *unit_dbus_path_from_name(const char *name);
+int unit_name_from_dbus_path(const char *path, char **name);
+
+const char* unit_dbus_interface_from_type(UnitType t);
+const char *unit_dbus_interface_from_name(const char *name);
+
+const char *unit_type_to_string(UnitType i) _const_;
+UnitType unit_type_from_string(const char *s) _pure_;
+
+const char *unit_load_state_to_string(UnitLoadState i) _const_;
+UnitLoadState unit_load_state_from_string(const char *s) _pure_;
+
+const char *unit_active_state_to_string(UnitActiveState i) _const_;
+UnitActiveState unit_active_state_from_string(const char *s) _pure_;
+
+const char* automount_state_to_string(AutomountState i) _const_;
+AutomountState automount_state_from_string(const char *s) _pure_;
+
+const char* device_state_to_string(DeviceState i) _const_;
+DeviceState device_state_from_string(const char *s) _pure_;
+
+const char* mount_state_to_string(MountState i) _const_;
+MountState mount_state_from_string(const char *s) _pure_;
+
+const char* path_state_to_string(PathState i) _const_;
+PathState path_state_from_string(const char *s) _pure_;
+
+const char* scope_state_to_string(ScopeState i) _const_;
+ScopeState scope_state_from_string(const char *s) _pure_;
+
+const char* service_state_to_string(ServiceState i) _const_;
+ServiceState service_state_from_string(const char *s) _pure_;
+
+const char* slice_state_to_string(SliceState i) _const_;
+SliceState slice_state_from_string(const char *s) _pure_;
+
+const char* socket_state_to_string(SocketState i) _const_;
+SocketState socket_state_from_string(const char *s) _pure_;
+
+const char* swap_state_to_string(SwapState i) _const_;
+SwapState swap_state_from_string(const char *s) _pure_;
+
+const char* target_state_to_string(TargetState i) _const_;
+TargetState target_state_from_string(const char *s) _pure_;
+
+const char *timer_state_to_string(TimerState i) _const_;
+TimerState timer_state_from_string(const char *s) _pure_;
+
+const char *unit_dependency_to_string(UnitDependency i) _const_;
+UnitDependency unit_dependency_from_string(const char *s) _pure_;
+
+const char* notify_access_to_string(NotifyAccess i) _const_;
+NotifyAccess notify_access_from_string(const char *s) _pure_;
index f9c034c..403f288 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
 #include <string.h>
 
 #include "alloc-util.h"
-#include "bus-label.h"
 #include "glob-util.h"
 #include "hexdecoct.h"
-#include "macro.h"
 #include "path-util.h"
-#include "string-table.h"
 #include "string-util.h"
 #include "strv.h"
 #include "unit-name.h"
@@ -385,19 +383,14 @@ int unit_name_path_escape(const char *f, char **ret) {
         if (STR_IN_SET(p, "/", ""))
                 s = strdup("-");
         else {
-                char *e;
-
-                if (!path_is_safe(p))
+                if (!path_is_normalized(p))
                         return -EINVAL;
 
                 /* Truncate trailing slashes */
-                e = endswith(p, "/");
-                if (e)
-                        *e = 0;
+                delete_trailing_chars(p, "/");
 
                 /* Truncate leading slashes */
-                if (p[0] == '/')
-                        p++;
+                p = skip_leading_chars(p, "/");
 
                 s = unit_name_escape(p);
         }
@@ -440,7 +433,7 @@ int unit_name_path_unescape(const char *f, char **ret) {
                 if (!s)
                         return -ENOMEM;
 
-                if (!path_is_safe(s)) {
+                if (!path_is_normalized(s)) {
                         free(s);
                         return -EINVAL;
                 }
@@ -575,68 +568,6 @@ int unit_name_to_path(const char *name, char **ret) {
         return unit_name_path_unescape(prefix, ret);
 }
 
-char *unit_dbus_path_from_name(const char *name) {
-        _cleanup_free_ char *e = NULL;
-
-        assert(name);
-
-        e = bus_label_escape(name);
-        if (!e)
-                return NULL;
-
-        return strappend("/org/freedesktop/systemd1/unit/", e);
-}
-
-int unit_name_from_dbus_path(const char *path, char **name) {
-        const char *e;
-        char *n;
-
-        e = startswith(path, "/org/freedesktop/systemd1/unit/");
-        if (!e)
-                return -EINVAL;
-
-        n = bus_label_unescape(e);
-        if (!n)
-                return -ENOMEM;
-
-        *name = n;
-        return 0;
-}
-
-const char* unit_dbus_interface_from_type(UnitType t) {
-
-        static const char *const table[_UNIT_TYPE_MAX] = {
-                [UNIT_SERVICE] = "org.freedesktop.systemd1.Service",
-                [UNIT_SOCKET] = "org.freedesktop.systemd1.Socket",
-                [UNIT_TARGET] = "org.freedesktop.systemd1.Target",
-                [UNIT_DEVICE] = "org.freedesktop.systemd1.Device",
-                [UNIT_MOUNT] = "org.freedesktop.systemd1.Mount",
-                [UNIT_AUTOMOUNT] = "org.freedesktop.systemd1.Automount",
-                [UNIT_SWAP] = "org.freedesktop.systemd1.Swap",
-                [UNIT_TIMER] = "org.freedesktop.systemd1.Timer",
-                [UNIT_PATH] = "org.freedesktop.systemd1.Path",
-                [UNIT_SLICE] = "org.freedesktop.systemd1.Slice",
-                [UNIT_SCOPE] = "org.freedesktop.systemd1.Scope",
-        };
-
-        if (t < 0)
-                return NULL;
-        if (t >= _UNIT_TYPE_MAX)
-                return NULL;
-
-        return table[t];
-}
-
-const char *unit_dbus_interface_from_name(const char *name) {
-        UnitType t;
-
-        t = unit_name_to_type(name);
-        if (t < 0)
-                return NULL;
-
-        return unit_dbus_interface_from_type(t);
-}
-
 static char *do_escape_mangle(const char *f, UnitNameMangle allow_globs, char *t) {
         const char *valid_chars;
 
@@ -834,206 +765,3 @@ bool slice_name_is_valid(const char *name) {
 
         return true;
 }
-
-static const char* const unit_type_table[_UNIT_TYPE_MAX] = {
-        [UNIT_SERVICE] = "service",
-        [UNIT_SOCKET] = "socket",
-        [UNIT_TARGET] = "target",
-        [UNIT_DEVICE] = "device",
-        [UNIT_MOUNT] = "mount",
-        [UNIT_AUTOMOUNT] = "automount",
-        [UNIT_SWAP] = "swap",
-        [UNIT_TIMER] = "timer",
-        [UNIT_PATH] = "path",
-        [UNIT_SLICE] = "slice",
-        [UNIT_SCOPE] = "scope",
-};
-
-DEFINE_STRING_TABLE_LOOKUP(unit_type, UnitType);
-
-static const char* const unit_load_state_table[_UNIT_LOAD_STATE_MAX] = {
-        [UNIT_STUB] = "stub",
-        [UNIT_LOADED] = "loaded",
-        [UNIT_NOT_FOUND] = "not-found",
-        [UNIT_ERROR] = "error",
-        [UNIT_MERGED] = "merged",
-        [UNIT_MASKED] = "masked"
-};
-
-DEFINE_STRING_TABLE_LOOKUP(unit_load_state, UnitLoadState);
-
-static const char* const unit_active_state_table[_UNIT_ACTIVE_STATE_MAX] = {
-        [UNIT_ACTIVE] = "active",
-        [UNIT_RELOADING] = "reloading",
-        [UNIT_INACTIVE] = "inactive",
-        [UNIT_FAILED] = "failed",
-        [UNIT_ACTIVATING] = "activating",
-        [UNIT_DEACTIVATING] = "deactivating"
-};
-
-DEFINE_STRING_TABLE_LOOKUP(unit_active_state, UnitActiveState);
-
-static const char* const automount_state_table[_AUTOMOUNT_STATE_MAX] = {
-        [AUTOMOUNT_DEAD] = "dead",
-        [AUTOMOUNT_WAITING] = "waiting",
-        [AUTOMOUNT_RUNNING] = "running",
-        [AUTOMOUNT_FAILED] = "failed"
-};
-
-DEFINE_STRING_TABLE_LOOKUP(automount_state, AutomountState);
-
-static const char* const device_state_table[_DEVICE_STATE_MAX] = {
-        [DEVICE_DEAD] = "dead",
-        [DEVICE_TENTATIVE] = "tentative",
-        [DEVICE_PLUGGED] = "plugged",
-};
-
-DEFINE_STRING_TABLE_LOOKUP(device_state, DeviceState);
-
-static const char* const mount_state_table[_MOUNT_STATE_MAX] = {
-        [MOUNT_DEAD] = "dead",
-        [MOUNT_MOUNTING] = "mounting",
-        [MOUNT_MOUNTING_DONE] = "mounting-done",
-        [MOUNT_MOUNTED] = "mounted",
-        [MOUNT_REMOUNTING] = "remounting",
-        [MOUNT_UNMOUNTING] = "unmounting",
-        [MOUNT_REMOUNTING_SIGTERM] = "remounting-sigterm",
-        [MOUNT_REMOUNTING_SIGKILL] = "remounting-sigkill",
-        [MOUNT_UNMOUNTING_SIGTERM] = "unmounting-sigterm",
-        [MOUNT_UNMOUNTING_SIGKILL] = "unmounting-sigkill",
-        [MOUNT_FAILED] = "failed"
-};
-
-DEFINE_STRING_TABLE_LOOKUP(mount_state, MountState);
-
-static const char* const path_state_table[_PATH_STATE_MAX] = {
-        [PATH_DEAD] = "dead",
-        [PATH_WAITING] = "waiting",
-        [PATH_RUNNING] = "running",
-        [PATH_FAILED] = "failed"
-};
-
-DEFINE_STRING_TABLE_LOOKUP(path_state, PathState);
-
-static const char* const scope_state_table[_SCOPE_STATE_MAX] = {
-        [SCOPE_DEAD] = "dead",
-        [SCOPE_RUNNING] = "running",
-        [SCOPE_ABANDONED] = "abandoned",
-        [SCOPE_STOP_SIGTERM] = "stop-sigterm",
-        [SCOPE_STOP_SIGKILL] = "stop-sigkill",
-        [SCOPE_FAILED] = "failed",
-};
-
-DEFINE_STRING_TABLE_LOOKUP(scope_state, ScopeState);
-
-static const char* const service_state_table[_SERVICE_STATE_MAX] = {
-        [SERVICE_DEAD] = "dead",
-        [SERVICE_START_PRE] = "start-pre",
-        [SERVICE_START] = "start",
-        [SERVICE_START_POST] = "start-post",
-        [SERVICE_RUNNING] = "running",
-        [SERVICE_EXITED] = "exited",
-        [SERVICE_RELOAD] = "reload",
-        [SERVICE_STOP] = "stop",
-        [SERVICE_STOP_SIGABRT] = "stop-sigabrt",
-        [SERVICE_STOP_SIGTERM] = "stop-sigterm",
-        [SERVICE_STOP_SIGKILL] = "stop-sigkill",
-        [SERVICE_STOP_POST] = "stop-post",
-        [SERVICE_FINAL_SIGTERM] = "final-sigterm",
-        [SERVICE_FINAL_SIGKILL] = "final-sigkill",
-        [SERVICE_FAILED] = "failed",
-        [SERVICE_AUTO_RESTART] = "auto-restart",
-};
-
-DEFINE_STRING_TABLE_LOOKUP(service_state, ServiceState);
-
-static const char* const slice_state_table[_SLICE_STATE_MAX] = {
-        [SLICE_DEAD] = "dead",
-        [SLICE_ACTIVE] = "active"
-};
-
-DEFINE_STRING_TABLE_LOOKUP(slice_state, SliceState);
-
-static const char* const socket_state_table[_SOCKET_STATE_MAX] = {
-        [SOCKET_DEAD] = "dead",
-        [SOCKET_START_PRE] = "start-pre",
-        [SOCKET_START_CHOWN] = "start-chown",
-        [SOCKET_START_POST] = "start-post",
-        [SOCKET_LISTENING] = "listening",
-        [SOCKET_RUNNING] = "running",
-        [SOCKET_STOP_PRE] = "stop-pre",
-        [SOCKET_STOP_PRE_SIGTERM] = "stop-pre-sigterm",
-        [SOCKET_STOP_PRE_SIGKILL] = "stop-pre-sigkill",
-        [SOCKET_STOP_POST] = "stop-post",
-        [SOCKET_FINAL_SIGTERM] = "final-sigterm",
-        [SOCKET_FINAL_SIGKILL] = "final-sigkill",
-        [SOCKET_FAILED] = "failed"
-};
-
-DEFINE_STRING_TABLE_LOOKUP(socket_state, SocketState);
-
-static const char* const swap_state_table[_SWAP_STATE_MAX] = {
-        [SWAP_DEAD] = "dead",
-        [SWAP_ACTIVATING] = "activating",
-        [SWAP_ACTIVATING_DONE] = "activating-done",
-        [SWAP_ACTIVE] = "active",
-        [SWAP_DEACTIVATING] = "deactivating",
-        [SWAP_DEACTIVATING_SIGTERM] = "deactivating-sigterm",
-        [SWAP_DEACTIVATING_SIGKILL] = "deactivating-sigkill",
-        [SWAP_FAILED] = "failed"
-};
-
-DEFINE_STRING_TABLE_LOOKUP(swap_state, SwapState);
-
-static const char* const target_state_table[_TARGET_STATE_MAX] = {
-        [TARGET_DEAD] = "dead",
-        [TARGET_ACTIVE] = "active"
-};
-
-DEFINE_STRING_TABLE_LOOKUP(target_state, TargetState);
-
-static const char* const timer_state_table[_TIMER_STATE_MAX] = {
-        [TIMER_DEAD] = "dead",
-        [TIMER_WAITING] = "waiting",
-        [TIMER_RUNNING] = "running",
-        [TIMER_ELAPSED] = "elapsed",
-        [TIMER_FAILED] = "failed"
-};
-
-DEFINE_STRING_TABLE_LOOKUP(timer_state, TimerState);
-
-static const char* const unit_dependency_table[_UNIT_DEPENDENCY_MAX] = {
-        [UNIT_REQUIRES] = "Requires",
-        [UNIT_REQUISITE] = "Requisite",
-        [UNIT_WANTS] = "Wants",
-        [UNIT_BINDS_TO] = "BindsTo",
-        [UNIT_PART_OF] = "PartOf",
-        [UNIT_REQUIRED_BY] = "RequiredBy",
-        [UNIT_REQUISITE_OF] = "RequisiteOf",
-        [UNIT_WANTED_BY] = "WantedBy",
-        [UNIT_BOUND_BY] = "BoundBy",
-        [UNIT_CONSISTS_OF] = "ConsistsOf",
-        [UNIT_CONFLICTS] = "Conflicts",
-        [UNIT_CONFLICTED_BY] = "ConflictedBy",
-        [UNIT_BEFORE] = "Before",
-        [UNIT_AFTER] = "After",
-        [UNIT_ON_FAILURE] = "OnFailure",
-        [UNIT_TRIGGERS] = "Triggers",
-        [UNIT_TRIGGERED_BY] = "TriggeredBy",
-        [UNIT_PROPAGATES_RELOAD_TO] = "PropagatesReloadTo",
-        [UNIT_RELOAD_PROPAGATED_FROM] = "ReloadPropagatedFrom",
-        [UNIT_JOINS_NAMESPACE_OF] = "JoinsNamespaceOf",
-        [UNIT_REFERENCES] = "References",
-        [UNIT_REFERENCED_BY] = "ReferencedBy",
-};
-
-DEFINE_STRING_TABLE_LOOKUP(unit_dependency, UnitDependency);
-
-static const char* const notify_access_table[_NOTIFY_ACCESS_MAX] = {
-        [NOTIFY_NONE] = "none",
-        [NOTIFY_MAIN] = "main",
-        [NOTIFY_EXEC] = "exec",
-        [NOTIFY_ALL] = "all"
-};
-
-DEFINE_STRING_TABLE_LOOKUP(notify_access, NotifyAccess);
index 15558b4..b47327d 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
 #include <stdbool.h>
 
 #include "macro.h"
+#include "unit-def.h"
 
 #define UNIT_NAME_MAX 256
 
-typedef enum UnitType {
-        UNIT_SERVICE = 0,
-        UNIT_SOCKET,
-        UNIT_TARGET,
-        UNIT_DEVICE,
-        UNIT_MOUNT,
-        UNIT_AUTOMOUNT,
-        UNIT_SWAP,
-        UNIT_TIMER,
-        UNIT_PATH,
-        UNIT_SLICE,
-        UNIT_SCOPE,
-        _UNIT_TYPE_MAX,
-        _UNIT_TYPE_INVALID = -1
-} UnitType;
-
-typedef enum UnitLoadState {
-        UNIT_STUB = 0,
-        UNIT_LOADED,
-        UNIT_NOT_FOUND,
-        UNIT_ERROR,
-        UNIT_MERGED,
-        UNIT_MASKED,
-        _UNIT_LOAD_STATE_MAX,
-        _UNIT_LOAD_STATE_INVALID = -1
-} UnitLoadState;
-
-typedef enum UnitActiveState {
-        UNIT_ACTIVE,
-        UNIT_RELOADING,
-        UNIT_INACTIVE,
-        UNIT_FAILED,
-        UNIT_ACTIVATING,
-        UNIT_DEACTIVATING,
-        _UNIT_ACTIVE_STATE_MAX,
-        _UNIT_ACTIVE_STATE_INVALID = -1
-} UnitActiveState;
-
-typedef enum AutomountState {
-        AUTOMOUNT_DEAD,
-        AUTOMOUNT_WAITING,
-        AUTOMOUNT_RUNNING,
-        AUTOMOUNT_FAILED,
-        _AUTOMOUNT_STATE_MAX,
-        _AUTOMOUNT_STATE_INVALID = -1
-} AutomountState;
-
-/* We simply watch devices, we cannot plug/unplug them. That
- * simplifies the state engine greatly */
-typedef enum DeviceState {
-        DEVICE_DEAD,
-        DEVICE_TENTATIVE, /* mounted or swapped, but not (yet) announced by udev */
-        DEVICE_PLUGGED,   /* announced by udev */
-        _DEVICE_STATE_MAX,
-        _DEVICE_STATE_INVALID = -1
-} DeviceState;
-
-typedef enum MountState {
-        MOUNT_DEAD,
-        MOUNT_MOUNTING,               /* /usr/bin/mount is running, but the mount is not done yet. */
-        MOUNT_MOUNTING_DONE,          /* /usr/bin/mount is running, and the mount is done. */
-        MOUNT_MOUNTED,
-        MOUNT_REMOUNTING,
-        MOUNT_UNMOUNTING,
-        MOUNT_REMOUNTING_SIGTERM,
-        MOUNT_REMOUNTING_SIGKILL,
-        MOUNT_UNMOUNTING_SIGTERM,
-        MOUNT_UNMOUNTING_SIGKILL,
-        MOUNT_FAILED,
-        _MOUNT_STATE_MAX,
-        _MOUNT_STATE_INVALID = -1
-} MountState;
-
-typedef enum PathState {
-        PATH_DEAD,
-        PATH_WAITING,
-        PATH_RUNNING,
-        PATH_FAILED,
-        _PATH_STATE_MAX,
-        _PATH_STATE_INVALID = -1
-} PathState;
-
-typedef enum ScopeState {
-        SCOPE_DEAD,
-        SCOPE_RUNNING,
-        SCOPE_ABANDONED,
-        SCOPE_STOP_SIGTERM,
-        SCOPE_STOP_SIGKILL,
-        SCOPE_FAILED,
-        _SCOPE_STATE_MAX,
-        _SCOPE_STATE_INVALID = -1
-} ScopeState;
-
-typedef enum ServiceState {
-        SERVICE_DEAD,
-        SERVICE_START_PRE,
-        SERVICE_START,
-        SERVICE_START_POST,
-        SERVICE_RUNNING,
-        SERVICE_EXITED,            /* Nothing is running anymore, but RemainAfterExit is true hence this is OK */
-        SERVICE_RELOAD,
-        SERVICE_STOP,              /* No STOP_PRE state, instead just register multiple STOP executables */
-        SERVICE_STOP_SIGABRT,      /* Watchdog timeout */
-        SERVICE_STOP_SIGTERM,
-        SERVICE_STOP_SIGKILL,
-        SERVICE_STOP_POST,
-        SERVICE_FINAL_SIGTERM,     /* In case the STOP_POST executable hangs, we shoot that down, too */
-        SERVICE_FINAL_SIGKILL,
-        SERVICE_FAILED,
-        SERVICE_AUTO_RESTART,
-        _SERVICE_STATE_MAX,
-        _SERVICE_STATE_INVALID = -1
-} ServiceState;
-
-typedef enum SliceState {
-        SLICE_DEAD,
-        SLICE_ACTIVE,
-        _SLICE_STATE_MAX,
-        _SLICE_STATE_INVALID = -1
-} SliceState;
-
-typedef enum SocketState {
-        SOCKET_DEAD,
-        SOCKET_START_PRE,
-        SOCKET_START_CHOWN,
-        SOCKET_START_POST,
-        SOCKET_LISTENING,
-        SOCKET_RUNNING,
-        SOCKET_STOP_PRE,
-        SOCKET_STOP_PRE_SIGTERM,
-        SOCKET_STOP_PRE_SIGKILL,
-        SOCKET_STOP_POST,
-        SOCKET_FINAL_SIGTERM,
-        SOCKET_FINAL_SIGKILL,
-        SOCKET_FAILED,
-        _SOCKET_STATE_MAX,
-        _SOCKET_STATE_INVALID = -1
-} SocketState;
-
-typedef enum SwapState {
-        SWAP_DEAD,
-        SWAP_ACTIVATING,               /* /sbin/swapon is running, but the swap not yet enabled. */
-        SWAP_ACTIVATING_DONE,          /* /sbin/swapon is running, and the swap is done. */
-        SWAP_ACTIVE,
-        SWAP_DEACTIVATING,
-        SWAP_DEACTIVATING_SIGTERM,
-        SWAP_DEACTIVATING_SIGKILL,
-        SWAP_FAILED,
-        _SWAP_STATE_MAX,
-        _SWAP_STATE_INVALID = -1
-} SwapState;
-
-typedef enum TargetState {
-        TARGET_DEAD,
-        TARGET_ACTIVE,
-        _TARGET_STATE_MAX,
-        _TARGET_STATE_INVALID = -1
-} TargetState;
-
-typedef enum TimerState {
-        TIMER_DEAD,
-        TIMER_WAITING,
-        TIMER_RUNNING,
-        TIMER_ELAPSED,
-        TIMER_FAILED,
-        _TIMER_STATE_MAX,
-        _TIMER_STATE_INVALID = -1
-} TimerState;
-
-typedef enum UnitDependency {
-        /* Positive dependencies */
-        UNIT_REQUIRES,
-        UNIT_REQUISITE,
-        UNIT_WANTS,
-        UNIT_BINDS_TO,
-        UNIT_PART_OF,
-
-        /* Inverse of the above */
-        UNIT_REQUIRED_BY,             /* inverse of 'requires' is 'required_by' */
-        UNIT_REQUISITE_OF,            /* inverse of 'requisite' is 'requisite_of' */
-        UNIT_WANTED_BY,               /* inverse of 'wants' */
-        UNIT_BOUND_BY,                /* inverse of 'binds_to' */
-        UNIT_CONSISTS_OF,             /* inverse of 'part_of' */
-
-        /* Negative dependencies */
-        UNIT_CONFLICTS,               /* inverse of 'conflicts' is 'conflicted_by' */
-        UNIT_CONFLICTED_BY,
-
-        /* Order */
-        UNIT_BEFORE,                  /* inverse of 'before' is 'after' and vice versa */
-        UNIT_AFTER,
-
-        /* On Failure */
-        UNIT_ON_FAILURE,
-
-        /* Triggers (i.e. a socket triggers a service) */
-        UNIT_TRIGGERS,
-        UNIT_TRIGGERED_BY,
-
-        /* Propagate reloads */
-        UNIT_PROPAGATES_RELOAD_TO,
-        UNIT_RELOAD_PROPAGATED_FROM,
-
-        /* Joins namespace of */
-        UNIT_JOINS_NAMESPACE_OF,
-
-        /* Reference information for GC logic */
-        UNIT_REFERENCES,              /* Inverse of 'references' is 'referenced_by' */
-        UNIT_REFERENCED_BY,
-
-        _UNIT_DEPENDENCY_MAX,
-        _UNIT_DEPENDENCY_INVALID = -1
-} UnitDependency;
-
-typedef enum NotifyAccess {
-        NOTIFY_NONE,
-        NOTIFY_ALL,
-        NOTIFY_MAIN,
-        NOTIFY_EXEC,
-        _NOTIFY_ACCESS_MAX,
-        _NOTIFY_ACCESS_INVALID = -1
-} NotifyAccess;
-
 typedef enum UnitNameFlags {
         UNIT_NAME_PLAIN = 1,      /* Allow foo.service */
         UNIT_NAME_INSTANCE = 2,   /* Allow foo@bar.service */
@@ -288,12 +67,6 @@ int unit_name_from_path(const char *path, const char *suffix, char **ret);
 int unit_name_from_path_instance(const char *prefix, const char *path, const char *suffix, char **ret);
 int unit_name_to_path(const char *name, char **ret);
 
-char *unit_dbus_path_from_name(const char *name);
-int unit_name_from_dbus_path(const char *path, char **name);
-
-const char* unit_dbus_interface_from_type(UnitType t);
-const char *unit_dbus_interface_from_name(const char *name);
-
 typedef enum UnitNameMangle {
         UNIT_NAME_NOGLOB,
         UNIT_NAME_GLOB,
@@ -308,51 +81,3 @@ static inline int unit_name_mangle(const char *name, UnitNameMangle allow_globs,
 int slice_build_parent_slice(const char *slice, char **ret);
 int slice_build_subslice(const char *slice, const char*name, char **subslice);
 bool slice_name_is_valid(const char *name);
-
-const char *unit_type_to_string(UnitType i) _const_;
-UnitType unit_type_from_string(const char *s) _pure_;
-
-const char *unit_load_state_to_string(UnitLoadState i) _const_;
-UnitLoadState unit_load_state_from_string(const char *s) _pure_;
-
-const char *unit_active_state_to_string(UnitActiveState i) _const_;
-UnitActiveState unit_active_state_from_string(const char *s) _pure_;
-
-const char* automount_state_to_string(AutomountState i) _const_;
-AutomountState automount_state_from_string(const char *s) _pure_;
-
-const char* device_state_to_string(DeviceState i) _const_;
-DeviceState device_state_from_string(const char *s) _pure_;
-
-const char* mount_state_to_string(MountState i) _const_;
-MountState mount_state_from_string(const char *s) _pure_;
-
-const char* path_state_to_string(PathState i) _const_;
-PathState path_state_from_string(const char *s) _pure_;
-
-const char* scope_state_to_string(ScopeState i) _const_;
-ScopeState scope_state_from_string(const char *s) _pure_;
-
-const char* service_state_to_string(ServiceState i) _const_;
-ServiceState service_state_from_string(const char *s) _pure_;
-
-const char* slice_state_to_string(SliceState i) _const_;
-SliceState slice_state_from_string(const char *s) _pure_;
-
-const char* socket_state_to_string(SocketState i) _const_;
-SocketState socket_state_from_string(const char *s) _pure_;
-
-const char* swap_state_to_string(SwapState i) _const_;
-SwapState swap_state_from_string(const char *s) _pure_;
-
-const char* target_state_to_string(TargetState i) _const_;
-TargetState target_state_from_string(const char *s) _pure_;
-
-const char *timer_state_to_string(TimerState i) _const_;
-TimerState timer_state_from_string(const char *s) _pure_;
-
-const char *unit_dependency_to_string(UnitDependency i) _const_;
-UnitDependency unit_dependency_from_string(const char *s) _pure_;
-
-const char* notify_access_to_string(NotifyAccess i) _const_;
-NotifyAccess notify_access_from_string(const char *s) _pure_;
index a691a0d..abb0b76 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -116,15 +117,14 @@ int get_user_creds(
         assert(username);
         assert(*username);
 
-        /* We enforce some special rules for uid=0: in order to avoid
-         * NSS lookups for root we hardcode its data. */
+        /* We enforce some special rules for uid=0 and uid=65534: in order to avoid NSS lookups for root we hardcode
+         * their user record data. */
 
-        if (streq(*username, "root") || streq(*username, "0")) {
+        if (STR_IN_SET(*username, "root", "0")) {
                 *username = "root";
 
                 if (uid)
                         *uid = 0;
-
                 if (gid)
                         *gid = 0;
 
@@ -137,6 +137,23 @@ int get_user_creds(
                 return 0;
         }
 
+        if (STR_IN_SET(*username, NOBODY_USER_NAME, "65534")) {
+                *username = NOBODY_USER_NAME;
+
+                if (uid)
+                        *uid = UID_NOBODY;
+                if (gid)
+                        *gid = GID_NOBODY;
+
+                if (home)
+                        *home = "/";
+
+                if (shell)
+                        *shell = "/sbin/nologin";
+
+                return 0;
+        }
+
         if (parse_uid(*username, &u) >= 0) {
                 errno = 0;
                 p = getpwuid(u);
@@ -217,7 +234,7 @@ int get_group_creds(const char **groupname, gid_t *gid) {
         /* We enforce some special rules for gid=0: in order to avoid
          * NSS lookups for root we hardcode its data. */
 
-        if (streq(*groupname, "root") || streq(*groupname, "0")) {
+        if (STR_IN_SET(*groupname, "root", "0")) {
                 *groupname = "root";
 
                 if (gid)
@@ -226,6 +243,15 @@ int get_group_creds(const char **groupname, gid_t *gid) {
                 return 0;
         }
 
+        if (STR_IN_SET(*groupname, NOBODY_GROUP_NAME, "65534")) {
+                *groupname = NOBODY_GROUP_NAME;
+
+                if (gid)
+                        *gid = GID_NOBODY;
+
+                return 0;
+        }
+
         if (parse_gid(*groupname, &id) >= 0) {
                 errno = 0;
                 g = getgrgid(id);
@@ -257,6 +283,8 @@ char* uid_to_name(uid_t uid) {
         /* Shortcut things to avoid NSS lookups */
         if (uid == 0)
                 return strdup("root");
+        if (uid == UID_NOBODY)
+                return strdup(NOBODY_USER_NAME);
 
         if (uid_is_valid(uid)) {
                 long bufsize;
@@ -295,6 +323,8 @@ char* gid_to_name(gid_t gid) {
 
         if (gid == 0)
                 return strdup("root");
+        if (gid == GID_NOBODY)
+                return strdup(NOBODY_GROUP_NAME);
 
         if (gid_is_valid(gid)) {
                 long bufsize;
@@ -386,7 +416,7 @@ int get_home_dir(char **_h) {
                 return 0;
         }
 
-        /* Hardcode home directory for root to avoid NSS */
+        /* Hardcode home directory for root and nobody to avoid NSS */
         u = getuid();
         if (u == 0) {
                 h = strdup("/root");
@@ -396,6 +426,14 @@ int get_home_dir(char **_h) {
                 *_h = h;
                 return 0;
         }
+        if (u == UID_NOBODY) {
+                h = strdup("/");
+                if (!h)
+                        return -ENOMEM;
+
+                *_h = h;
+                return 0;
+        }
 
         /* Check the database... */
         errno = 0;
@@ -433,7 +471,7 @@ int get_shell(char **_s) {
                 return 0;
         }
 
-        /* Hardcode home directory for root to avoid NSS */
+        /* Hardcode shell for root and nobody to avoid NSS */
         u = getuid();
         if (u == 0) {
                 s = strdup("/bin/sh");
@@ -443,6 +481,14 @@ int get_shell(char **_s) {
                 *_s = s;
                 return 0;
         }
+        if (u == UID_NOBODY) {
+                s = strdup("/sbin/nologin");
+                if (!s)
+                        return -ENOMEM;
+
+                *_s = s;
+                return 0;
+        }
 
         /* Check the database... */
         errno = 0;
@@ -605,7 +651,7 @@ bool valid_home(const char *p) {
         if (!path_is_absolute(p))
                 return false;
 
-        if (!path_is_safe(p))
+        if (!path_is_normalized(p))
                 return false;
 
         /* Colons are used as field separators, and hence not OK */
index dfea561..79adf91 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -59,17 +60,25 @@ int take_etc_passwd_lock(const char *root);
 #define UID_INVALID ((uid_t) -1)
 #define GID_INVALID ((gid_t) -1)
 
-/* Let's pick a UIDs within the 16bit range, so that we are compatible with containers using 16bit
- * user namespacing. At least on Fedora normal users are allocated until UID 60000, hence do not
- * allocate from below this. Also stay away from the upper end of the range as that is often used
- * for overflow/nobody users. */
-#define DYNAMIC_UID_MIN ((uid_t) UINT32_C(0x0000EF00))
-#define DYNAMIC_UID_MAX ((uid_t) UINT32_C(0x0000FFEF))
+#define UID_NOBODY ((uid_t) 65534U)
+#define GID_NOBODY ((gid_t) 65534U)
 
 static inline bool uid_is_dynamic(uid_t uid) {
         return DYNAMIC_UID_MIN <= uid && uid <= DYNAMIC_UID_MAX;
 }
 
+static inline bool gid_is_dynamic(gid_t gid) {
+        return uid_is_dynamic((uid_t) gid);
+}
+
+static inline bool uid_is_system(uid_t uid) {
+        return uid <= SYSTEM_UID_MAX;
+}
+
+static inline bool gid_is_system(gid_t gid) {
+        return gid <= SYSTEM_GID_MAX;
+}
+
 /* The following macros add 1 when converting things, since UID 0 is a valid UID, while the pointer
  * NULL is special */
 #define PTR_TO_UID(p) ((uid_t) (((uintptr_t) (p))-1))
index 7a52fac..4da9a40 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index f9b9c94..b0a7485 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 687de40..8f9f2b9 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -38,6 +39,7 @@
 #include "build.h"
 #include "cgroup-util.h"
 #include "def.h"
+#include "device-nodes.h"
 #include "dirent-util.h"
 #include "fd-util.h"
 #include "fileio.h"
@@ -103,7 +105,7 @@ int socket_from_display(const char *display, char **path) {
 
         k = strspn(display+1, "0123456789");
 
-        f = new(char, strlen("/tmp/.X11-unix/X") + k + 1);
+        f = new(char, STRLEN("/tmp/.X11-unix/X") + k + 1);
         if (!f)
                 return -ENOMEM;
 
@@ -117,75 +119,51 @@ int socket_from_display(const char *display, char **path) {
 }
 
 int block_get_whole_disk(dev_t d, dev_t *ret) {
-        char *p, *s;
+        char p[SYS_BLOCK_PATH_MAX("/partition")];
+        _cleanup_free_ char *s = NULL;
         int r;
         unsigned n, m;
 
         assert(ret);
 
         /* If it has a queue this is good enough for us */
-        if (asprintf(&p, "/sys/dev/block/%u:%u/queue", major(d), minor(d)) < 0)
-                return -ENOMEM;
-
-        r = access(p, F_OK);
-        free(p);
-
-        if (r >= 0) {
+        xsprintf_sys_block_path(p, "/queue", d);
+        if (access(p, F_OK) >= 0) {
                 *ret = d;
                 return 0;
         }
 
         /* If it is a partition find the originating device */
-        if (asprintf(&p, "/sys/dev/block/%u:%u/partition", major(d), minor(d)) < 0)
-                return -ENOMEM;
-
-        r = access(p, F_OK);
-        free(p);
-
-        if (r < 0)
+        xsprintf_sys_block_path(p, "/partition", d);
+        if (access(p, F_OK) < 0)
                 return -ENOENT;
 
         /* Get parent dev_t */
-        if (asprintf(&p, "/sys/dev/block/%u:%u/../dev", major(d), minor(d)) < 0)
-                return -ENOMEM;
-
+        xsprintf_sys_block_path(p, "/../dev", d);
         r = read_one_line_file(p, &s);
-        free(p);
-
         if (r < 0)
                 return r;
 
         r = sscanf(s, "%u:%u", &m, &n);
-        free(s);
-
         if (r != 2)
                 return -EINVAL;
 
         /* Only return this if it is really good enough for us. */
-        if (asprintf(&p, "/sys/dev/block/%u:%u/queue", m, n) < 0)
-                return -ENOMEM;
-
-        r = access(p, F_OK);
-        free(p);
-
-        if (r >= 0) {
-                *ret = makedev(m, n);
-                return 0;
-        }
+        xsprintf_sys_block_path(p, "/queue", makedev(m, n));
+        if (access(p, F_OK) < 0)
+                return -ENOENT;
 
-        return -ENOENT;
+        *ret = makedev(m, n);
+        return 0;
 }
 
 bool kexec_loaded(void) {
-       bool loaded = false;
-       char *s;
-
-       if (read_one_line_file("/sys/kernel/kexec_loaded", &s) >= 0) {
-               if (s[0] == '1')
-                       loaded = true;
-               free(s);
-       }
-       return loaded;
+       _cleanup_free_ char *s = NULL;
+
+       if (read_one_line_file("/sys/kernel/kexec_loaded", &s) < 0)
+               return false;
+
+       return s[0] == '1';
 }
 
 int prot_from_flags(int flags) {
@@ -751,7 +729,8 @@ int get_block_device(const char *path, dev_t *dev) {
 
 int get_block_device_harder(const char *path, dev_t *dev) {
         _cleanup_closedir_ DIR *d = NULL;
-        _cleanup_free_ char *p = NULL, *t = NULL;
+        _cleanup_free_ char *t = NULL;
+        char p[SYS_BLOCK_PATH_MAX("/slaves")];
         struct dirent *de, *found = NULL;
         const char *q;
         unsigned maj, min;
@@ -769,9 +748,7 @@ int get_block_device_harder(const char *path, dev_t *dev) {
         if (r <= 0)
                 return r;
 
-        if (asprintf(&p, "/sys/dev/block/%u:%u/slaves", major(dt), minor(dt)) < 0)
-                return -ENOMEM;
-
+        xsprintf_sys_block_path(p, "/slaves", dt);
         d = opendir(p);
         if (!d) {
                 if (errno == ENOENT)
index b31dfd1..a79907d 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index d9cdb38..cb42e6d 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -32,7 +33,7 @@ int dispatch_verb(int argc, char *argv[], const Verb verbs[], void *userdata) {
         const Verb *verb;
         const char *name;
         unsigned i;
-        int left;
+        int left, r;
 
         assert(verbs);
         assert(verbs[0].dispatch);
@@ -88,6 +89,12 @@ int dispatch_verb(int argc, char *argv[], const Verb verbs[], void *userdata) {
                 return 0;
         }
 
+        if (verb->flags & VERB_MUSTBEROOT) {
+                r = must_be_root();
+                if (r < 0)
+                        return r;
+        }
+
         if (name)
                 return verb->dispatch(left, argv + optind, userdata);
         else {
index 7b5e185..5f44a18 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
 ***/
 
 #define VERB_ANY ((unsigned) -1)
-#define VERB_DEFAULT 1U
-#define VERB_NOCHROOT 2U
+
+typedef enum VerbFlags {
+        VERB_DEFAULT    = 1 << 0,
+        VERB_NOCHROOT   = 1 << 1,
+        VERB_MUSTBEROOT = 1 << 2,
+} VerbFlags;
 
 typedef struct {
         const char *verb;
         unsigned min_args, max_args;
-        unsigned flags;
+        VerbFlags flags;
         int (* const dispatch)(int argc, char *argv[], void *userdata);
 } Verb;
 
index d8eeb54..b0db28a 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -200,8 +201,6 @@ static int detect_vm_dmi(void) {
                         return r;
                 }
 
-
-
                 for (j = 0; j < ELEMENTSOF(dmi_vendor_table); j++)
                         if (startswith(s, dmi_vendor_table[j].vendor)) {
                                 log_debug("Virtualization %s found in DMI (%s)", s, dmi_vendors[i]);
@@ -216,27 +215,48 @@ static int detect_vm_dmi(void) {
 }
 
 static int detect_vm_xen(void) {
+
         /* Check for Dom0 will be executed later in detect_vm_xen_dom0
-           Thats why we dont check the content of /proc/xen/capabilities here. */
-        if (access("/proc/xen/capabilities", F_OK) < 0) {
-                log_debug("Virtualization XEN not found, /proc/xen/capabilities does not exist");
+           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/capabilities exists)");
-        return  VIRTUALIZATION_XEN;
-
+        log_debug("Virtualization XEN found (/proc/xen exists)");
+        return VIRTUALIZATION_XEN;
 }
 
-static bool detect_vm_xen_dom0(void) {
+#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 */
+static int detect_vm_xen_dom0(void) {
         _cleanup_free_ char *domcap = NULL;
         char *cap, *i;
         int r;
 
+        r = read_one_line_file(PATH_FEATURES, &domcap);
+        if (r < 0 && r != -ENOENT)
+                return r;
+        if (r == 0) {
+                unsigned long features;
+
+                r = safe_atolu(domcap, &features);
+                if (r == 0) {
+                        r = !!(features & (1U << XENFEAT_dom0));
+                        log_debug("Virtualization XEN, found %s with value %08lx, "
+                                  "XENFEAT_dom0 (indicating the 'hardware domain') is%s set.",
+                                  PATH_FEATURES, features, r ? "" : " not");
+                        return r;
+                }
+                log_debug("Virtualization XEN, found %s, unhandled content '%s'",
+                          PATH_FEATURES, domcap);
+        }
+
         r = read_one_line_file("/proc/xen/capabilities", &domcap);
         if (r == -ENOENT) {
-                log_debug("Virtualization XEN not found, /proc/xen/capabilities does not exist");
-                return false;
+                log_debug("Virtualization XEN because /proc/xen/capabilities does not exist");
+                return 0;
         }
         if (r < 0)
                 return r;
@@ -247,11 +267,11 @@ static bool detect_vm_xen_dom0(void) {
                         break;
         if (!cap) {
                 log_debug("Virtualization XEN DomU found (/proc/xen/capabilites)");
-                return false;
+                return 0;
         }
 
         log_debug("Virtualization XEN Dom0 ignored (/proc/xen/capabilities)");
-        return true;
+        return 1;
 }
 
 static int detect_vm_hypervisor(void) {
@@ -317,6 +337,7 @@ static int detect_vm_zvm(void) {
 int detect_vm(void) {
         static thread_local int cached_found = _VIRTUALIZATION_INVALID;
         int r, dmi;
+        bool other = false;
 
         if (cached_found >= 0)
                 return cached_found;
@@ -337,45 +358,68 @@ int detect_vm(void) {
         r = detect_vm_cpuid();
         if (r < 0)
                 return r;
-        if (r != VIRTUALIZATION_NONE)
-                goto finish;
+        if (r != VIRTUALIZATION_NONE) {
+                if (r == VIRTUALIZATION_VM_OTHER)
+                        other = true;
+                else
+                        goto finish;
+        }
 
         r = dmi;
         if (r < 0)
                 return r;
-        if (r != VIRTUALIZATION_NONE)
-                goto finish;
+        if (r != VIRTUALIZATION_NONE) {
+                if (r == VIRTUALIZATION_VM_OTHER)
+                        other = true;
+                else
+                        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 xen capabilities
-         * file next. If that's not found, then we check for the high-level
-         * hypervisor sysfs file:
-         *
-         * https://bugs.freedesktop.org/show_bug.cgi?id=77271 */
+         * 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_NONE)
-                goto finish;
+        if (r != VIRTUALIZATION_NONE) {
+                if (r == VIRTUALIZATION_VM_OTHER)
+                        other = true;
+                else
+                        goto finish;
+        }
 
         r = detect_vm_hypervisor();
         if (r < 0)
                 return r;
-        if (r != VIRTUALIZATION_NONE)
-                goto finish;
+        if (r != VIRTUALIZATION_NONE) {
+                if (r == VIRTUALIZATION_VM_OTHER)
+                        other = true;
+                else
+                        goto finish;
+        }
 
         r = detect_vm_device_tree();
         if (r < 0)
                 return r;
-        if (r != VIRTUALIZATION_NONE)
-                goto finish;
+        if (r != VIRTUALIZATION_NONE) {
+                if (r == VIRTUALIZATION_VM_OTHER)
+                        other = true;
+                else
+                        goto finish;
+        }
 
         r = detect_vm_uml();
         if (r < 0)
                 return r;
-        if (r != VIRTUALIZATION_NONE)
-                goto finish;
+        if (r != VIRTUALIZATION_NONE) {
+                if (r == VIRTUALIZATION_VM_OTHER)
+                        other = true;
+                else
+                        goto finish;
+        }
 
         r = detect_vm_zvm();
         if (r < 0)
@@ -385,8 +429,14 @@ 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 && detect_vm_xen_dom0())
-                r = VIRTUALIZATION_NONE;
+        if (r == VIRTUALIZATION_XEN) {
+                int ret = detect_vm_xen_dom0();
+                if (ret < 0)
+                        return ret;
+                if (ret > 0)
+                        r = VIRTUALIZATION_NONE;
+        } else if (r == VIRTUALIZATION_NONE && other)
+                r = VIRTUALIZATION_VM_OTHER;
 
         cached_found = r;
         log_debug("Found VM virtualization %s", virtualization_to_string(r));
index 7d15169..d9badd8 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 595688e..d721b02 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index e6bb6b5..ad8c850 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index e086376..12d04ee 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -104,7 +105,7 @@ int fgetxattr_malloc(int fd, const char *name, char **value) {
 }
 
 ssize_t fgetxattrat_fake(int dirfd, const char *filename, const char *attribute, void *value, size_t size, int flags) {
-        char fn[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(int) + 1];
+        char fn[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int) + 1];
         _cleanup_close_ int fd = -1;
         ssize_t l;
 
index 6fa097b..1a78027 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index a4337f4..639c343 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 41cb69f..d00b527 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 17af233..eb888e8 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 85f3b42..59c1af7 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -37,6 +38,7 @@
 
 #include "alloc-util.h"
 #include "blkid-util.h"
+#include "bootspec.h"
 #include "copy.h"
 #include "dirent-util.h"
 #include "efivars.h"
 #include "stat-util.h"
 #include "string-util.h"
 #include "strv.h"
+#include "terminal-util.h"
 #include "umask-util.h"
 #include "util.h"
 #include "verbs.h"
 #include "virt.h"
 
 static char *arg_path = NULL;
+static bool arg_print_path = false;
 static bool arg_touch_variables = true;
 
-static int verify_esp(
-                bool searching,
-                const char *p,
+static int acquire_esp(
+                bool unprivileged_mode,
                 uint32_t *ret_part,
                 uint64_t *ret_pstart,
                 uint64_t *ret_psize,
                 sd_id128_t *ret_uuid) {
 
-        _cleanup_blkid_free_probe_ blkid_probe b = NULL;
-        _cleanup_free_ char *t = NULL;
-        uint64_t pstart = 0, psize = 0;
-        struct stat st, st2;
-        const char *v, *t2;
-        struct statfs sfs;
-        sd_id128_t uuid = SD_ID128_NULL;
-        uint32_t part = 0;
-        bool quiet;
+        char *np;
         int r;
 
-        assert(p);
-
-        /* Non-root user can run only `bootctl status`, then if error occured in the following, it does not cause any issues.
-         * So, let's silence the error messages. */
-        quiet = (geteuid() != 0);
-
-        if (statfs(p, &sfs) < 0) {
-
-                /* If we are searching for the mount point, don't generate a log message if we can't find the path */
-                if (errno == ENOENT && searching)
-                        return -ENOENT;
-
-                return log_full_errno(quiet && errno == EACCES ? LOG_DEBUG : LOG_ERR, errno,
-                                      "Failed to check file system type of \"%s\": %m", p);
-        }
-
-        if (!F_TYPE_EQUAL(sfs.f_type, MSDOS_SUPER_MAGIC)) {
-
-                if (searching)
-                        return -EADDRNOTAVAIL;
-
-                log_error("File system \"%s\" is not a FAT EFI System Partition (ESP) file system.", p);
-                return -ENODEV;
-        }
-
-        if (stat(p, &st) < 0)
-                return log_full_errno(quiet && errno == EACCES ? LOG_DEBUG : LOG_ERR, errno,
-                                      "Failed to determine block device node of \"%s\": %m", p);
-
-        if (major(st.st_dev) == 0) {
-                log_error("Block device node of %p is invalid.", p);
-                return -ENODEV;
-        }
-
-        t2 = strjoina(p, "/..");
-        r = stat(t2, &st2);
-        if (r < 0)
-                return log_full_errno(quiet && errno == EACCES ? LOG_DEBUG : LOG_ERR, errno,
-                                      "Failed to determine block device node of parent of \"%s\": %m", p);
-
-        if (st.st_dev == st2.st_dev) {
-                log_error("Directory \"%s\" is not the root of the EFI System Partition (ESP) file system.", p);
-                return -ENODEV;
-        }
-
-        /* In a container we don't have access to block devices, skip this part of the verification, we trust the
-         * container manager set everything up correctly on its own. Also skip the following verification for non-root user. */
-        if (detect_container() > 0 || geteuid() != 0)
-                goto finish;
-
-        r = asprintf(&t, "/dev/block/%u:%u", major(st.st_dev), minor(st.st_dev));
-        if (r < 0)
-                return log_oom();
-
-        errno = 0;
-        b = blkid_new_probe_from_filename(t);
-        if (!b)
-                return log_error_errno(errno ?: ENOMEM, "Failed to open file system \"%s\": %m", p);
-
-        blkid_probe_enable_superblocks(b, 1);
-        blkid_probe_set_superblocks_flags(b, BLKID_SUBLKS_TYPE);
-        blkid_probe_enable_partitions(b, 1);
-        blkid_probe_set_partitions_flags(b, BLKID_PARTS_ENTRY_DETAILS);
-
-        errno = 0;
-        r = blkid_do_safeprobe(b);
-        if (r == -2) {
-                log_error("File system \"%s\" is ambiguous.", p);
-                return -ENODEV;
-        } else if (r == 1) {
-                log_error("File system \"%s\" does not contain a label.", p);
-                return -ENODEV;
-        } else if (r != 0)
-                return log_error_errno(errno ?: EIO, "Failed to probe file system \"%s\": %m", p);
-
-        errno = 0;
-        r = blkid_probe_lookup_value(b, "TYPE", &v, NULL);
-        if (r != 0)
-                return log_error_errno(errno ?: EIO, "Failed to probe file system type \"%s\": %m", p);
-        if (!streq(v, "vfat")) {
-                log_error("File system \"%s\" is not FAT.", p);
-                return -ENODEV;
-        }
-
-        errno = 0;
-        r = blkid_probe_lookup_value(b, "PART_ENTRY_SCHEME", &v, NULL);
-        if (r != 0)
-                return log_error_errno(errno ?: EIO, "Failed to probe partition scheme \"%s\": %m", p);
-        if (!streq(v, "gpt")) {
-                log_error("File system \"%s\" is not on a GPT partition table.", p);
-                return -ENODEV;
-        }
-
-        errno = 0;
-        r = blkid_probe_lookup_value(b, "PART_ENTRY_TYPE", &v, NULL);
-        if (r != 0)
-                return log_error_errno(errno ?: EIO, "Failed to probe partition type UUID \"%s\": %m", p);
-        if (!streq(v, "c12a7328-f81f-11d2-ba4b-00a0c93ec93b")) {
-                log_error("File system \"%s\" has wrong type for an EFI System Partition (ESP).", p);
-                return -ENODEV;
-        }
+        /* Find the ESP, and log about errors. Note that find_esp_and_warn() will log in all error cases on its own,
+         * except for ENOKEY (which is good, we want to show our own message in that case, suggesting use of --path=)
+         * and EACCESS (only when we request unprivileged mode; in this case we simply eat up the error here, so that
+         * --list and --status work too, without noise about this). */
 
-        errno = 0;
-        r = blkid_probe_lookup_value(b, "PART_ENTRY_UUID", &v, NULL);
-        if (r != 0)
-                return log_error_errno(errno ?: EIO, "Failed to probe partition entry UUID \"%s\": %m", p);
-        r = sd_id128_from_string(v, &uuid);
-        if (r < 0) {
-                log_error("Partition \"%s\" has invalid UUID \"%s\".", p, v);
-                return -EIO;
-        }
-
-        errno = 0;
-        r = blkid_probe_lookup_value(b, "PART_ENTRY_NUMBER", &v, NULL);
-        if (r != 0)
-                return log_error_errno(errno ?: EIO, "Failed to probe partition number \"%s\": m", p);
-        r = safe_atou32(v, &part);
+        r = find_esp_and_warn(arg_path, unprivileged_mode, &np, ret_part, ret_pstart, ret_psize, ret_uuid);
+        if (r == -ENOKEY)
+                return log_error_errno(r,
+                                       "Couldn't find EFI system partition. It is recommended to mount it to /boot or /efi.\n"
+                                       "Alternatively, use --path= to specify path to mount point.");
         if (r < 0)
-                return log_error_errno(r, "Failed to parse PART_ENTRY_NUMBER field.");
+                return r;
 
-        errno = 0;
-        r = blkid_probe_lookup_value(b, "PART_ENTRY_OFFSET", &v, NULL);
-        if (r != 0)
-                return log_error_errno(errno ?: EIO, "Failed to probe partition offset \"%s\": %m", p);
-        r = safe_atou64(v, &pstart);
-        if (r < 0)
-                return log_error_errno(r, "Failed to parse PART_ENTRY_OFFSET field.");
+        free_and_replace(arg_path, np);
 
-        errno = 0;
-        r = blkid_probe_lookup_value(b, "PART_ENTRY_SIZE", &v, NULL);
-        if (r != 0)
-                return log_error_errno(errno ?: EIO, "Failed to probe partition size \"%s\": %m", p);
-        r = safe_atou64(v, &psize);
-        if (r < 0)
-                return log_error_errno(r, "Failed to parse PART_ENTRY_SIZE field.");
-
-finish:
-        if (ret_part)
-                *ret_part = part;
-        if (ret_pstart)
-                *ret_pstart = pstart;
-        if (ret_psize)
-                *ret_psize = psize;
-        if (ret_uuid)
-                *ret_uuid = uuid;
+        log_debug("Using EFI System Partition at %s.", arg_path);
 
         return 0;
 }
 
-static int find_esp(uint32_t *part, uint64_t *pstart, uint64_t *psize, sd_id128_t *uuid) {
-        const char *path;
-        int r;
-
-        if (arg_path)
-                return verify_esp(false, arg_path, part, pstart, psize, uuid);
-
-        FOREACH_STRING(path, "/efi", "/boot", "/boot/efi") {
-
-                r = verify_esp(true, path, part, pstart, psize, uuid);
-                if (IN_SET(r, -ENOENT, -EADDRNOTAVAIL)) /* This one is not it */
-                        continue;
-                if (r < 0)
-                        return r;
-
-                arg_path = strdup(path);
-                if (!arg_path)
-                        return log_oom();
-
-                log_info("Using EFI System Partition at %s.", path);
-                return 0;
-        }
-
-        log_error("Couldn't find EFI system partition. It is recommended to mount it to /boot. Alternatively, use --path= to specify path to mount point.");
-        return -ENOENT;
-}
-
 /* search for "#### LoaderInfo: systemd-boot 218 ####" string inside the binary */
 static int get_file_version(int fd, char **v) {
         struct stat st;
@@ -442,6 +281,54 @@ static int status_variables(void) {
         return 0;
 }
 
+static int status_entries(const char *esp_path, sd_id128_t partition) {
+        int r;
+
+        _cleanup_(boot_config_free) BootConfig config = {};
+
+        printf("Default Boot Entry:\n");
+
+        r = boot_entries_load_config(esp_path, &config);
+        if (r < 0)
+                return log_error_errno(r, "Failed to load bootspec config from \"%s/loader\": %m",
+                                       esp_path);
+
+        if (config.default_entry < 0)
+                printf("%zu entries, no entry suitable as default", config.n_entries);
+        else {
+                const BootEntry *e = &config.entries[config.default_entry];
+
+                printf("        title: %s\n", boot_entry_title(e));
+                if (e->version)
+                        printf("      version: %s\n", e->version);
+                if (e->kernel)
+                        printf("        linux: %s\n", e->kernel);
+                if (!strv_isempty(e->initrd)) {
+                        _cleanup_free_ char *t;
+
+                        t = strv_join(e->initrd, " ");
+                        if (!t)
+                                return log_oom();
+
+                        printf("       initrd: %s\n", t);
+                }
+                if (!strv_isempty(e->options)) {
+                        _cleanup_free_ char *t;
+
+                        t = strv_join(e->options, " ");
+                        if (!t)
+                                return log_oom();
+
+                        printf("      options: %s\n", t);
+                }
+                if (e->device_tree)
+                        printf("   devicetree: %s\n", e->device_tree);
+                puts("");
+        }
+
+        return 0;
+}
+
 static int compare_product(const char *a, const char *b) {
         size_t x, y;
 
@@ -610,7 +497,8 @@ static int copy_one_file(const char *esp_path, const char *name, bool force) {
                 char *v;
 
                 /* Create the EFI default boot loader name (specified for removable devices) */
-                v = strjoina(esp_path, "/EFI/BOOT/BOOT", name + strlen("systemd-boot"));
+                v = strjoina(esp_path, "/EFI/BOOT/BOOT",
+                             name + STRLEN("systemd-boot"));
                 ascii_strupper(strrchr(v, '/') + 1);
 
                 k = copy_file_with_version_check(p, v, force);
@@ -961,10 +849,12 @@ static int help(int argc, char *argv[], void *userdata) {
                "  -h --help          Show this help\n"
                "     --version       Print version\n"
                "     --path=PATH     Path to the EFI System Partition (ESP)\n"
+               "  -p --print-path    Print path to the EFI partition\n"
                "     --no-variables  Don't touch EFI variables\n"
                "\n"
                "Commands:\n"
                "     status          Show status of installed systemd-boot and EFI variables\n"
+               "     list            List boot entries\n"
                "     install         Install systemd-boot to the ESP and EFI variables\n"
                "     update          Update systemd-boot in the ESP and EFI variables\n"
                "     remove          Remove systemd-boot from the ESP and EFI variables\n",
@@ -984,6 +874,7 @@ static int parse_argv(int argc, char *argv[]) {
                 { "help",         no_argument,       NULL, 'h'              },
                 { "version",      no_argument,       NULL, ARG_VERSION      },
                 { "path",         required_argument, NULL, ARG_PATH         },
+                { "print-path",   no_argument,       NULL, 'p'              },
                 { "no-variables", no_argument,       NULL, ARG_NO_VARIABLES },
                 { NULL,           0,                 NULL, 0                }
         };
@@ -993,7 +884,7 @@ static int parse_argv(int argc, char *argv[]) {
         assert(argc >= 0);
         assert(argv);
 
-        while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
+        while ((c = getopt_long(argc, argv, "hp", options, NULL)) >= 0)
                 switch (c) {
 
                 case 'h':
@@ -1009,6 +900,10 @@ static int parse_argv(int argc, char *argv[]) {
                                 return log_oom();
                         break;
 
+                case 'p':
+                        arg_print_path = true;
+                        break;
+
                 case ARG_NO_VARIABLES:
                         arg_touch_variables = false;
                         break;
@@ -1031,21 +926,26 @@ static void read_loader_efi_var(const char *name, char **var) {
                 log_warning_errno(r, "Failed to read EFI variable %s: %m", name);
 }
 
-static int must_be_root(void) {
+static int verb_status(int argc, char *argv[], void *userdata) {
 
-        if (geteuid() == 0)
-                return 0;
+        sd_id128_t uuid = SD_ID128_NULL;
+        int r, k;
 
-        log_error("Need to be root.");
-        return -EPERM;
-}
+        r = acquire_esp(geteuid() != 0, NULL, NULL, NULL, &uuid);
 
-static int verb_status(int argc, char *argv[], void *userdata) {
+        if (arg_print_path) {
+                if (r == -EACCES) /* If we couldn't acquire the ESP path, log about access errors (which is the only
+                                   * error the find_esp_and_warn() won't log on its own) */
+                        return log_error_errno(r, "Failed to determine ESP: %m");
+                if (r < 0)
+                        return r;
 
-        sd_id128_t uuid = SD_ID128_NULL;
-        int r, r2;
+                puts(arg_path);
+                return 0;
+        }
 
-        r2 = find_esp(NULL, NULL, NULL, &uuid);
+        r = 0; /* If we couldn't determine the path, then don't consider that a problem from here on, just show what we
+                * can show */
 
         if (is_efi_boot()) {
                 _cleanup_free_ char *fw_type = NULL, *fw_info = NULL, *loader = NULL, *loader_path = NULL;
@@ -1059,24 +959,24 @@ static int verb_status(int argc, char *argv[], void *userdata) {
                 if (loader_path)
                         efi_tilt_backslashes(loader_path);
 
-                r = efi_loader_get_device_part_uuid(&loader_part_uuid);
-                if (r < 0 && r != -ENOENT)
-                        r2 = log_warning_errno(r, "Failed to read EFI variable LoaderDevicePartUUID: %m");
+                k = efi_loader_get_device_part_uuid(&loader_part_uuid);
+                if (k < 0 && k != -ENOENT)
+                        r = log_warning_errno(k, "Failed to read EFI variable LoaderDevicePartUUID: %m");
 
                 printf("System:\n");
                 printf("     Firmware: %s (%s)\n", strna(fw_type), strna(fw_info));
 
-                r = is_efi_secure_boot();
-                if (r < 0)
-                        r2 = log_warning_errno(r, "Failed to query secure boot status: %m");
+                k = is_efi_secure_boot();
+                if (k < 0)
+                        r = log_warning_errno(k, "Failed to query secure boot status: %m");
                 else
-                        printf("  Secure Boot: %sd\n", enable_disable(r));
+                        printf("  Secure Boot: %sd\n", enable_disable(k));
 
-                r = is_efi_secure_boot_setup_mode();
-                if (r < 0)
-                        r2 = log_warning_errno(r, "Failed to query secure boot mode: %m");
+                k = is_efi_secure_boot_setup_mode();
+                if (k < 0)
+                        r = log_warning_errno(k, "Failed to query secure boot mode: %m");
                 else
-                        printf("   Setup Mode: %s\n", r ? "setup" : "user");
+                        printf("   Setup Mode: %s\n", k ? "setup" : "user");
                 printf("\n");
 
                 printf("Current Loader:\n");
@@ -1091,17 +991,93 @@ static int verb_status(int argc, char *argv[], void *userdata) {
         } else
                 printf("System:\n    Not booted with EFI\n\n");
 
-        r = status_binaries(arg_path, uuid);
-        if (r < 0)
-                r2 = r;
+        if (arg_path) {
+                k = status_binaries(arg_path, uuid);
+                if (k < 0)
+                        r = k;
+        }
 
         if (is_efi_boot()) {
-                r = status_variables();
-                if (r < 0)
-                        r2 = r;
+                k = status_variables();
+                if (k < 0)
+                        r = k;
+        }
+
+        if (arg_path) {
+                k = status_entries(arg_path, uuid);
+                if (k < 0)
+                        r = k;
+        }
+
+        return r;
+}
+
+static int verb_list(int argc, char *argv[], void *userdata) {
+        _cleanup_(boot_config_free) BootConfig config = {};
+        sd_id128_t uuid = SD_ID128_NULL;
+        unsigned n;
+        int r;
+
+        /* If we lack privileges we invoke find_esp_and_warn() in "unprivileged mode" here, which does two things: turn
+         * off logging about access errors and turn off potentially privileged device probing. Here we're interested in
+         * the latter but not the former, hence request the mode, and log about EACCES. */
+
+        r = acquire_esp(geteuid() != 0, NULL, NULL, NULL, &uuid);
+        if (r == -EACCES) /* We really need the ESP path for this call, hence also log about access errors */
+                return log_error_errno(r, "Failed to determine ESP: %m");
+        if (r < 0)
+                return r;
+
+        r = boot_entries_load_config(arg_path, &config);
+        if (r < 0)
+                return log_error_errno(r, "Failed to load bootspec config from \"%s/loader\": %m",
+                                       arg_path);
+
+        printf("Available boot entries:\n");
+
+        for (n = 0; n < config.n_entries; n++) {
+                const BootEntry *e = &config.entries[n];
+
+                printf("        title: %s%s%s%s%s%s\n",
+                       ansi_highlight(),
+                       boot_entry_title(e),
+                       ansi_normal(),
+                       ansi_highlight_green(),
+                       n == config.default_entry ? " (default)" : "",
+                       ansi_normal());
+                if (e->version)
+                        printf("      version: %s\n", e->version);
+                if (e->machine_id)
+                        printf("   machine-id: %s\n", e->machine_id);
+                if (e->architecture)
+                        printf(" architecture: %s\n", e->architecture);
+                if (e->kernel)
+                        printf("        linux: %s\n", e->kernel);
+                if (!strv_isempty(e->initrd)) {
+                        _cleanup_free_ char *t;
+
+                        t = strv_join(e->initrd, " ");
+                        if (!t)
+                                return log_oom();
+
+                        printf("       initrd: %s\n", t);
+                }
+                if (!strv_isempty(e->options)) {
+                        _cleanup_free_ char *t;
+
+                        t = strv_join(e->options, " ");
+                        if (!t)
+                                return log_oom();
+
+                        printf("      options: %s\n", t);
+                }
+                if (e->device_tree)
+                        printf("   devicetree: %s\n", e->device_tree);
+
+                puts("");
         }
 
-        return r2;
+        return 0;
 }
 
 static int verb_install(int argc, char *argv[], void *userdata) {
@@ -1112,11 +1088,7 @@ static int verb_install(int argc, char *argv[], void *userdata) {
         bool install;
         int r;
 
-        r = must_be_root();
-        if (r < 0)
-                return r;
-
-        r = find_esp(&part, &pstart, &psize, &uuid);
+        r = acquire_esp(false, &part, &pstart, &psize, &uuid);
         if (r < 0)
                 return r;
 
@@ -1147,11 +1119,7 @@ static int verb_remove(int argc, char *argv[], void *userdata) {
         sd_id128_t uuid = SD_ID128_NULL;
         int r;
 
-        r = must_be_root();
-        if (r < 0)
-                return r;
-
-        r = find_esp(NULL, NULL, NULL, &uuid);
+        r = acquire_esp(false, NULL, NULL, NULL, &uuid);
         if (r < 0)
                 return r;
 
@@ -1171,11 +1139,12 @@ static int verb_remove(int argc, char *argv[], void *userdata) {
 static int bootctl_main(int argc, char *argv[]) {
 
         static const Verb verbs[] = {
-                { "help",            VERB_ANY, VERB_ANY, 0,            help         },
-                { "status",          VERB_ANY, 1,        VERB_DEFAULT, verb_status  },
-                { "install",         VERB_ANY, 1,        0,            verb_install },
-                { "update",          VERB_ANY, 1,        0,            verb_install },
-                { "remove",          VERB_ANY, 1,        0,            verb_remove  },
+                { "help",            VERB_ANY, VERB_ANY, 0,               help         },
+                { "status",          VERB_ANY, 1,        VERB_DEFAULT,    verb_status  },
+                { "list",            VERB_ANY, 1,        0,               verb_list    },
+                { "install",         VERB_ANY, 1,        VERB_MUSTBEROOT, verb_install },
+                { "update",          VERB_ANY, 1,        VERB_MUSTBEROOT, verb_install },
+                { "remove",          VERB_ANY, 1,        VERB_MUSTBEROOT, verb_remove  },
                 {}
         };
 
index 12176f1..ea9f39a 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /*
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
@@ -1305,10 +1306,29 @@ static VOID config_default_entry_select(Config *config) {
         config->idx_default = -1;
 }
 
+static BOOLEAN find_nonunique(ConfigEntry **entries, UINTN entry_count) {
+        BOOLEAN non_unique = FALSE;
+        UINTN i, k;
+
+        for (i = 0; i < entry_count; i++)
+                entries[i]->non_unique = FALSE;
+
+        for (i = 0; i < entry_count; i++)
+                for (k = 0; k < entry_count; k++) {
+                        if (i == k)
+                                continue;
+                        if (StrCmp(entries[i]->title_show, entries[k]->title_show) != 0)
+                                continue;
+
+                        non_unique = entries[i]->non_unique = entries[k]->non_unique = TRUE;
+                }
+
+        return non_unique;
+}
+
 /* generate a unique title, avoiding non-distinguishable menu entries */
 static VOID config_title_generate(Config *config) {
-        UINTN i, k;
-        BOOLEAN unique;
+        UINTN i;
 
         /* set title */
         for (i = 0; i < config->entry_count; i++) {
@@ -1321,20 +1341,7 @@ static VOID config_title_generate(Config *config) {
                 config->entries[i]->title_show = StrDuplicate(title);
         }
 
-        unique = TRUE;
-        for (i = 0; i < config->entry_count; i++) {
-                for (k = 0; k < config->entry_count; k++) {
-                        if (i == k)
-                                continue;
-                        if (StrCmp(config->entries[i]->title_show, config->entries[k]->title_show) != 0)
-                                continue;
-
-                        unique = FALSE;
-                        config->entries[i]->non_unique = TRUE;
-                        config->entries[k]->non_unique = TRUE;
-                }
-        }
-        if (unique)
+        if (!find_nonunique(config->entries, config->entry_count))
                 return;
 
         /* add version to non-unique titles */
@@ -1349,23 +1356,9 @@ static VOID config_title_generate(Config *config) {
                 s = PoolPrint(L"%s (%s)", config->entries[i]->title_show, config->entries[i]->version);
                 FreePool(config->entries[i]->title_show);
                 config->entries[i]->title_show = s;
-                config->entries[i]->non_unique = FALSE;
         }
 
-        unique = TRUE;
-        for (i = 0; i < config->entry_count; i++) {
-                for (k = 0; k < config->entry_count; k++) {
-                        if (i == k)
-                                continue;
-                        if (StrCmp(config->entries[i]->title_show, config->entries[k]->title_show) != 0)
-                                continue;
-
-                        unique = FALSE;
-                        config->entries[i]->non_unique = TRUE;
-                        config->entries[k]->non_unique = TRUE;
-                }
-        }
-        if (unique)
+        if (!find_nonunique(config->entries, config->entry_count))
                 return;
 
         /* add machine-id to non-unique titles */
@@ -1383,24 +1376,10 @@ static VOID config_title_generate(Config *config) {
                 s = PoolPrint(L"%s (%s)", config->entries[i]->title_show, m);
                 FreePool(config->entries[i]->title_show);
                 config->entries[i]->title_show = s;
-                config->entries[i]->non_unique = FALSE;
                 FreePool(m);
         }
 
-        unique = TRUE;
-        for (i = 0; i < config->entry_count; i++) {
-                for (k = 0; k < config->entry_count; k++) {
-                        if (i == k)
-                                continue;
-                        if (StrCmp(config->entries[i]->title_show, config->entries[k]->title_show) != 0)
-                                continue;
-
-                        unique = FALSE;
-                        config->entries[i]->non_unique = TRUE;
-                        config->entries[k]->non_unique = TRUE;
-                }
-        }
-        if (unique)
+        if (!find_nonunique(config->entries, config->entry_count))
                 return;
 
         /* add file name to non-unique titles */
index 2b797c9..4487ed0 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /*
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
index 3fe0ce5..5664a4e 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /*
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
index 3e3b5b2..af0f05c 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /*
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
index af91a9c..c5894f8 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /*
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
index 4854baf..29577c8 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /*
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
index cf48e64..10e0c26 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /*
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
index 0dc99a6..e8f7651 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /*
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
@@ -84,7 +85,7 @@ static inline VOID linux_efi_handover(EFI_HANDLE image, struct SetupHeader *setu
 EFI_STATUS linux_exec(EFI_HANDLE *image,
                       CHAR8 *cmdline, UINTN cmdline_len,
                       UINTN linux_addr,
-                      UINTN initrd_addr, UINTN initrd_size) {
+                      UINTN initrd_addr, UINTN initrd_size, BOOLEAN secure) {
         struct SetupHeader *image_setup;
         struct SetupHeader *boot_setup;
         EFI_PHYSICAL_ADDRESS addr;
@@ -107,6 +108,17 @@ EFI_STATUS linux_exec(EFI_HANDLE *image,
         CopyMem(boot_setup, image_setup, sizeof(struct SetupHeader));
         boot_setup->loader_id = 0xff;
 
+        if (secure) {
+                /* set secure boot flag in linux kernel zero page, see
+                   - Documentation/x86/zero-page.txt
+                   - arch/x86/include/uapi/asm/bootparam.h
+                   - drivers/firmware/efi/libstub/secureboot.c
+                   in the linux kernel source tree
+                   Possible values: 0 (unassigned), 1 (undetected), 2 (disabled), 3 (enabled)
+                */
+                boot_setup->boot_sector[0x1ec] = 3;
+        }
+
         boot_setup->code32_start = (UINT32)linux_addr + (image_setup->setup_secs+1) * 512;
 
         if (cmdline) {
index d9e6ed7..3c11423 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /*
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
@@ -18,5 +19,5 @@
 EFI_STATUS linux_exec(EFI_HANDLE *image,
                       CHAR8 *cmdline, UINTN cmdline_size,
                       UINTN linux_addr,
-                      UINTN initrd_addr, UINTN initrd_size);
+                      UINTN initrd_addr, UINTN initrd_size, BOOLEAN secure);
 #endif
index 324d1c8..be4fea8 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /*
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
@@ -26,6 +27,11 @@ typedef struct _TCG_VERSION {
         UINT8 RevMinor;
 } TCG_VERSION;
 
+typedef struct tdEFI_TCG2_VERSION {
+        UINT8 Major;
+        UINT8 Minor;
+} EFI_TCG2_VERSION;
+
 typedef struct _TCG_BOOT_SERVICE_CAPABILITY {
         UINT8 Size;
         struct _TCG_VERSION StructureVersion;
@@ -35,6 +41,18 @@ typedef struct _TCG_BOOT_SERVICE_CAPABILITY {
         BOOLEAN TPMDeactivatedFlag;
 } TCG_BOOT_SERVICE_CAPABILITY;
 
+typedef struct tdTREE_BOOT_SERVICE_CAPABILITY {
+        UINT8 Size;
+        EFI_TCG2_VERSION StructureVersion;
+        EFI_TCG2_VERSION ProtocolVersion;
+        UINT32 HashAlgorithmBitmap;
+        UINT32 SupportedEventLogs;
+        BOOLEAN TrEEPresentFlag;
+        UINT16 MaxCommandSize;
+        UINT16 MaxResponseSize;
+        UINT32 ManufacturerID;
+} TREE_BOOT_SERVICE_CAPABILITY;
+
 typedef UINT32 TCG_ALGORITHM_ID;
 #define TCG_ALG_SHA 0x00000004  // The SHA1 algorithm
 
@@ -98,11 +116,6 @@ typedef struct _EFI_TCG {
 
 typedef struct tdEFI_TCG2_PROTOCOL EFI_TCG2_PROTOCOL;
 
-typedef struct tdEFI_TCG2_VERSION {
-        UINT8 Major;
-        UINT8 Minor;
-} EFI_TCG2_VERSION;
-
 typedef UINT32 EFI_TCG2_EVENT_LOG_BITMAP;
 typedef UINT32 EFI_TCG2_EVENT_LOG_FORMAT;
 typedef UINT32 EFI_TCG2_EVENT_ALGORITHM_BITMAP;
@@ -131,13 +144,13 @@ typedef struct {
         UINT16 HeaderVersion;
         UINT32 PCRIndex;
         UINT32 EventType;
-} EFI_TCG2_EVENT_HEADER;
+} __attribute__ ((packed)) EFI_TCG2_EVENT_HEADER;
 
 typedef struct tdEFI_TCG2_EVENT {
         UINT32 Size;
         EFI_TCG2_EVENT_HEADER Header;
         UINT8 Event[1];
-} EFI_TCG2_EVENT;
+} __attribute__ ((packed)) EFI_TCG2_EVENT;
 
 typedef EFI_STATUS(EFIAPI * EFI_TCG2_GET_CAPABILITY) (IN EFI_TCG2_PROTOCOL * This,
                                                       IN OUT EFI_TCG2_BOOT_SERVICE_CAPABILITY * ProtocolCapability);
@@ -188,7 +201,7 @@ static EFI_STATUS tpm1_measure_to_pcr_and_event_log(const EFI_TCG *tcg, UINT32 p
 
         tcg_event = AllocateZeroPool(desc_len + sizeof(TCG_PCR_EVENT));
 
-        if (tcg_event == NULL)
+        if (!tcg_event)
                 return EFI_OUT_OF_RESOURCES;
 
         tcg_event->EventSize = desc_len;
@@ -217,22 +230,21 @@ static EFI_STATUS tpm1_measure_to_pcr_and_event_log(const EFI_TCG *tcg, UINT32 p
  * internal switch through calling get_event_log() in order to allow
  * to retrieve the logs from OS runtime.
  */
-static EFI_STATUS trigger_tcg2_final_events_table(const EFI_TCG2 *tcg)
+static EFI_STATUS trigger_tcg2_final_events_table(const EFI_TCG2 *tcg, EFI_TCG2_EVENT_LOG_FORMAT log_fmt)
 {
         return uefi_call_wrapper(tcg->GetEventLog, 5, (EFI_TCG2 *) tcg,
-                                 EFI_TCG2_EVENT_LOG_FORMAT_TCG_2, NULL,
-                                 NULL, NULL);
+                                 log_fmt, 0, 0, 0);
 }
 
 static EFI_STATUS tpm2_measure_to_pcr_and_event_log(const EFI_TCG2 *tcg, UINT32 pcrindex, const EFI_PHYSICAL_ADDRESS buffer,
-                                                    UINT64 buffer_size, const CHAR16 *description) {
+                                                    UINT64 buffer_size, const CHAR16 *description, EFI_TCG2_EVENT_LOG_FORMAT log_fmt) {
         EFI_STATUS status;
         EFI_TCG2_EVENT *tcg_event;
         UINTN desc_len;
         static BOOLEAN triggered = FALSE;
 
         if (triggered == FALSE) {
-                status = trigger_tcg2_final_events_table(tcg);
+                status = trigger_tcg2_final_events_table(tcg, log_fmt);
                 if (EFI_ERROR(status))
                         return status;
 
@@ -243,10 +255,10 @@ static EFI_STATUS tpm2_measure_to_pcr_and_event_log(const EFI_TCG2 *tcg, UINT32
 
         tcg_event = AllocateZeroPool(sizeof(*tcg_event) - sizeof(tcg_event->Event) + desc_len + 1);
 
-        if (tcg_event == NULL)
+        if (!tcg_event)
                 return EFI_OUT_OF_RESOURCES;
 
-        tcg_event->Size = sizeof(EFI_TCG2_EVENT) - sizeof(tcg_event->Event) + desc_len + 1;
+        tcg_event->Size = sizeof(*tcg_event) - sizeof(tcg_event->Event) + desc_len + 1;
         tcg_event->Header.HeaderSize = sizeof(EFI_TCG2_EVENT_HEADER);
         tcg_event->Header.HeaderVersion = EFI_TCG2_EVENT_HEADER_VERSION;
         tcg_event->Header.PCRIndex = pcrindex;
@@ -254,7 +266,7 @@ static EFI_STATUS tpm2_measure_to_pcr_and_event_log(const EFI_TCG2 *tcg, UINT32
 
         CopyMem((VOID *) tcg_event->Event, (VOID *) description, desc_len);
 
-        status = uefi_call_wrapper(tcg->HashLogExtendEvent, 5, (EFI_TCG2 *) tcg, 0, buffer, buffer_size, tcg_event);
+        status = uefi_call_wrapper(tcg->HashLogExtendEvent, 5, (EFI_TCG2 *) tcg, 0, buffer, (UINT64) buffer_size, tcg_event);
 
         uefi_call_wrapper(BS->FreePool, 1, tcg_event);
 
@@ -293,24 +305,31 @@ static EFI_TCG * tcg1_interface_check(void) {
         return tcg;
 }
 
-static EFI_TCG2 * tcg2_interface_check(void) {
+static EFI_TCG2 * tcg2_interface_check(EFI_TCG2_BOOT_SERVICE_CAPABILITY *caps) {
         EFI_GUID tpm2_guid = EFI_TCG2_PROTOCOL_GUID;
         EFI_STATUS status;
         EFI_TCG2 *tcg;
-        EFI_TCG2_BOOT_SERVICE_CAPABILITY capability;
 
         status = LibLocateProtocol(&tpm2_guid, (void **) &tcg);
 
         if (EFI_ERROR(status))
                 return NULL;
 
-        capability.Size = (UINT8) sizeof(capability);
-        status = uefi_call_wrapper(tcg->GetCapability, 2, tcg, &capability);
+        caps->Size = (UINT8) sizeof(EFI_TCG2_BOOT_SERVICE_CAPABILITY);
+        status = uefi_call_wrapper(tcg->GetCapability, 2, tcg, caps);
 
         if (EFI_ERROR(status))
                 return NULL;
 
-        if (!capability.TPMPresentFlag)
+        if (caps->StructureVersion.Major == 1 &&
+            caps->StructureVersion.Minor == 0) {
+                TCG_BOOT_SERVICE_CAPABILITY *caps_1_0;
+                caps_1_0 = (TCG_BOOT_SERVICE_CAPABILITY *)caps;
+                if (caps_1_0->TPMPresentFlag)
+                        return tcg;
+        }
+
+        if (!caps->TPMPresentFlag)
                 return NULL;
 
         return tcg;
@@ -319,10 +338,27 @@ static EFI_TCG2 * tcg2_interface_check(void) {
 EFI_STATUS tpm_log_event(UINT32 pcrindex, const EFI_PHYSICAL_ADDRESS buffer, UINTN buffer_size, const CHAR16 *description) {
         EFI_TCG *tpm1;
         EFI_TCG2 *tpm2;
-
-        tpm2 = tcg2_interface_check();
-        if (tpm2)
-                return tpm2_measure_to_pcr_and_event_log(tpm2, pcrindex, buffer, buffer_size, description);
+        EFI_TCG2_BOOT_SERVICE_CAPABILITY caps;
+
+        tpm2 = tcg2_interface_check(&caps);
+        if (tpm2) {
+                EFI_TCG2_EVENT_LOG_BITMAP supported_logs;
+                EFI_TCG2_EVENT_LOG_FORMAT log_fmt;
+
+                if (caps.StructureVersion.Major == 1 &&
+                    caps.StructureVersion.Minor == 0)
+                        supported_logs = ((TREE_BOOT_SERVICE_CAPABILITY *)&caps)->SupportedEventLogs;
+                else
+                        supported_logs = caps.SupportedEventLogs;
+
+                if (supported_logs & EFI_TCG2_EVENT_LOG_FORMAT_TCG_2)
+                        log_fmt = EFI_TCG2_EVENT_LOG_FORMAT_TCG_2;
+                else
+                        log_fmt = EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2;
+
+                uefi_call_wrapper(BS->Stall, 1, 2000 * 1000);
+                return tpm2_measure_to_pcr_and_event_log(tpm2, pcrindex, buffer, buffer_size, description, log_fmt);
+        }
 
         tpm1 = tcg1_interface_check();
         if (tpm1)
index 43aa8a0..63e0a73 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /*
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
index eb0be02..992a3ba 100644 (file)
@@ -1,3 +1,20 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
+# Copyright 2017 Zbigniew Jędrzejewski-Szmek
+#
+# 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.
+#
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
 efi_headers = files('''
         console.h
         disk.h
index 054e8ed..3755a36 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /*
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
index fa8feea..4a411f5 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /*
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
index 0f73be9..6d7d814 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /*
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
@@ -61,10 +62,7 @@ static BOOLEAN shim_validate(VOID *data, UINT32 size) {
         if (!shim_lock)
                 return FALSE;
 
-        if (shim_lock->shim_verify(data, size) == EFI_SUCCESS)
-                return TRUE;
-
-        return FALSE;
+        return shim_lock->shim_verify(data, size) == EFI_SUCCESS;
 }
 
 BOOLEAN secure_boot_enabled(void) {
@@ -161,7 +159,7 @@ static EFIAPI EFI_STATUS security_policy_authentication (const EFI_SECURITY_PROT
         EFI_DEVICE_PATH *dev_path;
         EFI_HANDLE h;
         EFI_FILE *root;
-        VOID *file_buffer = NULL;
+        CHAR8 *file_buffer = NULL;
         UINTN file_size;
         CHAR16 *dev_path_str;
 
@@ -181,18 +179,16 @@ static EFIAPI EFI_STATUS security_policy_authentication (const EFI_SECURITY_PROT
         dev_path_str = DevicePathToStr(dev_path);
         FreePool(dev_path);
 
-        file_size = file_read(root, dev_path_str, 0, 0, file_buffer);
+        file_size = file_read(root, dev_path_str, 0, 0, &file_buffer);
         FreePool(dev_path_str);
         uefi_call_wrapper(root->Close, 1, root);
 
         if (shim_validate(file_buffer, file_size))
                 status = EFI_SUCCESS;
-
-        FreePool(file_buffer);
-
-        /* Try using the platform's native policy.... */
-        if (status != EFI_SUCCESS)
+        else
+                /* Try using the platform's native policy.... */
                 status = uefi_call_wrapper(esfas, 3, this, authentication_status, device_path_const);
+        FreePool(file_buffer);
 
         return status;
 }
@@ -207,9 +203,9 @@ EFI_STATUS security_policy_install(void) {
                 return EFI_ALREADY_STARTED;
 
         /*
-         * Don't bother with status here.  The call is allowed
-         * to fail, since SECURITY2 was introduced in PI 1.2.1
-         * If it fails, use security2_protocol == NULL as indicator
+         * Don't bother with status here. The call is allowed
+         * to fail, since SECURITY2 was introduced in PI 1.2.1.
+         * Use security2_protocol == NULL as indicator.
          */
         uefi_call_wrapper(BS->LocateProtocol, 3, (EFI_GUID*) &security2_protocol_guid, NULL, (VOID**) &security2_protocol);
 
@@ -218,14 +214,14 @@ EFI_STATUS security_policy_install(void) {
         if (status != EFI_SUCCESS)
                 return status;
 
-        if (!security2_protocol) {
+        esfas = security_protocol->FileAuthenticationState;
+        security_protocol->FileAuthenticationState = security_policy_authentication;
+
+        if (security2_protocol) {
                 es2fa = security2_protocol->FileAuthentication;
                 security2_protocol->FileAuthentication = security2_policy_authentication;
         }
 
-        esfas = security_protocol->FileAuthenticationState;
-        security_protocol->FileAuthenticationState = security_policy_authentication;
-
         return EFI_SUCCESS;
 }
 
index 2dcf48d..d9ab135 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /*
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
index c0ef7f6..32186d4 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /*
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
index 09b543f..c7e9c7a 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /*
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
index e85ebf2..e917019 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /* This program 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
@@ -108,7 +109,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
 
         err = linux_exec(image, cmdline, cmdline_len,
                          (UINTN)loaded_image->ImageBase + addrs[1],
-                         (UINTN)loaded_image->ImageBase + addrs[2], szs[2]);
+                         (UINTN)loaded_image->ImageBase + addrs[2], szs[2], secure);
 
         graphics_mode(FALSE);
         Print(L"Execution of embedded linux image failed: %r\n", err);
index 98c5be7..b165f31 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /*
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
index e673cdf..35150ae 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /*
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
index a057949..54d6e07 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index d922e35..a27a1c8 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 0d4bb8e..0ef1893 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -18,6 +19,8 @@
 ***/
 
 #include <getopt.h>
+#include <stdio_ext.h>
+
 #include <hashmap.h>
 
 #include "sd-bus.h"
@@ -699,12 +702,7 @@ static void member_free(Member *m) {
 DEFINE_TRIVIAL_CLEANUP_FUNC(Member*, member_free);
 
 static void member_set_free(Set *s) {
-        Member *m;
-
-        while ((m = set_steal_first(s)))
-                member_free(m);
-
-        set_free(s);
+        set_free_with_destructor(s, member_free);
 }
 
 DEFINE_TRIVIAL_CLEANUP_FUNC(Set*, member_set_free);
@@ -871,7 +869,7 @@ static int introspect(sd_bus *bus, char **argv) {
                 .on_property = on_property,
         };
 
-        _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
+        _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply_xml = NULL;
         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
         _cleanup_(member_set_freep) Set *members = NULL;
         Iterator i;
@@ -897,13 +895,11 @@ static int introspect(sd_bus *bus, char **argv) {
         if (!members)
                 return log_oom();
 
-        r = sd_bus_call_method(bus, argv[1], argv[2], "org.freedesktop.DBus.Introspectable", "Introspect", &error, &reply, "");
-        if (r < 0) {
-                log_error("Failed to introspect object %s of service %s: %s", argv[2], argv[1], bus_error_message(&error, r));
-                return r;
-        }
+        r = sd_bus_call_method(bus, argv[1], argv[2], "org.freedesktop.DBus.Introspectable", "Introspect", &error, &reply_xml, "");
+        if (r < 0)
+                return log_error_errno(r, "Failed to introspect object %s of service %s: %s", argv[2], argv[1], bus_error_message(&error, r));
 
-        r = sd_bus_message_read(reply, "s", &xml);
+        r = sd_bus_message_read(reply_xml, "s", &xml);
         if (r < 0)
                 return bus_log_parse_error(r);
 
@@ -914,6 +910,7 @@ static int introspect(sd_bus *bus, char **argv) {
 
         /* Second, find the current values for them */
         SET_FOREACH(m, members, i) {
+                _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
 
                 if (!streq(m->type, "property"))
                         continue;
@@ -925,10 +922,8 @@ static int introspect(sd_bus *bus, char **argv) {
                         continue;
 
                 r = sd_bus_call_method(bus, argv[1], argv[2], "org.freedesktop.DBus.Properties", "GetAll", &error, &reply, "s", m->interface);
-                if (r < 0) {
-                        log_error("%s", bus_error_message(&error, r));
-                        return r;
-                }
+                if (r < 0)
+                        return log_error_errno(r, "%s", bus_error_message(&error, r));
 
                 r = sd_bus_message_enter_container(reply, 'a', "{sv}");
                 if (r < 0)
@@ -960,22 +955,20 @@ static int introspect(sd_bus *bus, char **argv) {
                         if (!mf)
                                 return log_oom();
 
+                        (void) __fsetlocking(mf, FSETLOCKING_BYCALLER);
+
                         r = format_cmdline(reply, mf, false);
                         if (r < 0)
                                 return bus_log_parse_error(r);
 
-                        fclose(mf);
-                        mf = NULL;
+                        mf = safe_fclose(mf);
 
                         z = set_get(members, &((Member) {
                                                 .type = "property",
                                                 .interface = m->interface,
                                                 .name = (char*) name }));
-                        if (z) {
-                                free(z->value);
-                                z->value = buf;
-                                buf = NULL;
-                        }
+                        if (z)
+                                free_and_replace(z->value, buf);
 
                         r = sd_bus_message_exit_container(reply);
                         if (r < 0)
@@ -993,10 +986,10 @@ static int introspect(sd_bus *bus, char **argv) {
 
         pager_open(arg_no_pager, false);
 
-        name_width = strlen("NAME");
-        type_width = strlen("TYPE");
-        signature_width = strlen("SIGNATURE");
-        result_width = strlen("RESULT/VALUE");
+        name_width = STRLEN("NAME");
+        type_width = STRLEN("TYPE");
+        signature_width = STRLEN("SIGNATURE");
+        result_width = STRLEN("RESULT/VALUE");
 
         sorted = newa(Member*, set_size(members));
 
@@ -1804,7 +1797,7 @@ static int help(void) {
                "     --match=MATCH        Only show matching messages\n"
                "     --size=SIZE          Maximum length of captured packet\n"
                "     --list               Don't show tree, but simple object path list\n"
-               "     --quiet              Don't show method call reply\n"
+               "  -q --quiet              Don't show method call reply\n"
                "     --verbose            Show result values in long format\n"
                "     --expect-reply=BOOL  Expect a method call reply\n"
                "     --auto-start=BOOL    Auto-start destination service\n"
@@ -2141,7 +2134,7 @@ static int busctl_main(sd_bus *bus, int argc, char *argv[]) {
 }
 
 int main(int argc, char *argv[]) {
-        sd_bus *bus = NULL;
+        _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
         int r;
 
         log_parse_environment();
@@ -2231,7 +2224,6 @@ int main(int argc, char *argv[]) {
         r = busctl_main(bus, argc, argv);
 
 finish:
-        sd_bus_flush_close_unref(bus);
         pager_close();
 
         strv_free(arg_matches);
index 1b746a0..fb44b9f 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index d7c722a..05d12eb 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 7ebb02f..fe339eb 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -104,10 +105,7 @@ static void group_free(Group *g) {
 }
 
 static void group_hashmap_clear(Hashmap *h) {
-        Group *g;
-
-        while ((g = hashmap_steal_first(h)))
-                group_free(g);
+        hashmap_clear_with_destructor(h, group_free);
 }
 
 static void group_hashmap_free(Hashmap *h) {
index 6207f81..60e7903 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 0eccb59..43f4f19 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 9b0d1ca..28d5cc3 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -130,7 +131,20 @@ static void automount_done(Unit *u) {
         a->expire_event_source = sd_event_source_unref(a->expire_event_source);
 }
 
-static int automount_add_mount_links(Automount *a) {
+static int automount_add_trigger_dependencies(Automount *a) {
+        Unit *x;
+        int r;
+
+        assert(a);
+
+        r = unit_load_related_unit(UNIT(a), ".mount", &x);
+        if (r < 0)
+                return r;
+
+        return unit_add_two_dependencies(UNIT(a), UNIT_BEFORE, UNIT_TRIGGERS, x, true, UNIT_DEPENDENCY_IMPLICIT);
+}
+
+static int automount_add_mount_dependencies(Automount *a) {
         _cleanup_free_ char *parent = NULL;
 
         assert(a);
@@ -139,7 +153,7 @@ static int automount_add_mount_links(Automount *a) {
         if (!parent)
                 return -ENOMEM;
 
-        return unit_require_mounts_for(UNIT(a), parent);
+        return unit_require_mounts_for(UNIT(a), parent, UNIT_DEPENDENCY_IMPLICIT);
 }
 
 static int automount_add_default_dependencies(Automount *a) {
@@ -153,7 +167,7 @@ static int automount_add_default_dependencies(Automount *a) {
         if (!MANAGER_IS_SYSTEM(UNIT(a)->manager))
                 return 0;
 
-        r = unit_add_two_dependencies_by_name(UNIT(a), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
+        r = unit_add_two_dependencies_by_name(UNIT(a), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true, UNIT_DEPENDENCY_DEFAULT);
         if (r < 0)
                 return r;
 
@@ -210,26 +224,20 @@ static int automount_load(Unit *u) {
         assert(u->load_state == UNIT_STUB);
 
         /* Load a .automount file */
-        r = unit_load_fragment_and_dropin_optional(u);
+        r = unit_load_fragment_and_dropin(u);
         if (r < 0)
                 return r;
 
         if (u->load_state == UNIT_LOADED) {
-                Unit *x;
-
                 r = automount_set_where(a);
                 if (r < 0)
                         return r;
 
-                r = unit_load_related_unit(u, ".mount", &x);
-                if (r < 0)
-                        return r;
-
-                r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, x, true);
+                r = automount_add_trigger_dependencies(a);
                 if (r < 0)
                         return r;
 
-                r = automount_add_mount_links(a);
+                r = automount_add_mount_dependencies(a);
                 if (r < 0)
                         return r;
 
@@ -557,8 +565,8 @@ static void automount_trigger_notify(Unit *u, Unit *other) {
 static void automount_enter_waiting(Automount *a) {
         _cleanup_close_ int ioctl_fd = -1;
         int p[2] = { -1, -1 };
-        char name[sizeof("systemd-")-1 + DECIMAL_STR_MAX(pid_t) + 1];
-        char options[sizeof("fd=,pgrp=,minproto=5,maxproto=5,direct")-1
+        char name[STRLEN("systemd-") + DECIMAL_STR_MAX(pid_t) + 1];
+        char options[STRLEN("fd=,pgrp=,minproto=5,maxproto=5,direct")
                      + DECIMAL_STR_MAX(int) + DECIMAL_STR_MAX(gid_t) + 1];
         bool mounted = false;
         int r, dev_autofs_fd;
index 76a2011..b8be4d3 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 909c1c8..f3f40fb 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -641,28 +642,41 @@ int bpf_firewall_reset_accounting(int map_fd) {
 
 
 int bpf_firewall_supported(void) {
+        struct bpf_insn trivial[] = {
+                BPF_MOV64_IMM(BPF_REG_0, 1),
+                BPF_EXIT_INSN()
+        };
+
+        _cleanup_(bpf_program_unrefp) BPFProgram *program = NULL;
         static int supported = -1;
+        union bpf_attr attr;
         int fd, r;
 
-        /* Checks whether BPF firewalling is supported. For this, we check three things:
+        /* Checks whether BPF firewalling is supported. For this, we check five things:
          *
          * a) whether we are privileged
          * b) whether the unified hierarchy is being used
          * c) the BPF implementation in the kernel supports BPF LPM TRIE maps, which we require
+         * d) the BPF implementation in the kernel supports BPF_PROG_TYPE_CGROUP_SKB programs, which we require
+         * e) the BPF implementation in the kernel supports the BPF_PROG_ATTACH call, which we require
          *
          */
 
         if (supported >= 0)
                 return supported;
 
-        if (geteuid() != 0)
+        if (geteuid() != 0) {
+                log_debug("Not enough privileges, BPF firewalling is not supported.");
                 return supported = false;
+        }
 
         r = cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER);
         if (r < 0)
                 return log_error_errno(r, "Can't determine whether the unified hierarchy is used: %m");
-        if (r == 0)
+        if (r == 0) {
+                log_debug("Not running with unified cgroups, BPF firewalling is not supported.");
                 return supported = false;
+        }
 
         fd = bpf_map_new(BPF_MAP_TYPE_LPM_TRIE,
                          offsetof(struct bpf_lpm_trie_key, data) + sizeof(uint64_t),
@@ -676,5 +690,45 @@ int bpf_firewall_supported(void) {
 
         safe_close(fd);
 
-        return supported = true;
+        if (bpf_program_new(BPF_PROG_TYPE_CGROUP_SKB, &program) < 0) {
+                log_debug_errno(r, "Can't allocate CGROUP SKB BPF program, BPF firewalling is not supported: %m");
+                return supported = false;
+        }
+
+        r = bpf_program_add_instructions(program, trivial, ELEMENTSOF(trivial));
+        if (r < 0) {
+                log_debug_errno(r, "Can't add trivial instructions to CGROUP SKB BPF program, BPF firewalling is not supported: %m");
+                return supported = false;
+        }
+
+        r = bpf_program_load_kernel(program, NULL, 0);
+        if (r < 0) {
+                log_debug_errno(r, "Can't load kernel CGROUP SKB BPF program, BPF firewalling is not supported: %m");
+                return supported = false;
+        }
+
+        /* Unfortunately the kernel allows us to create BPF_PROG_TYPE_CGROUP_SKB programs even when CONFIG_CGROUP_BPF
+         * is turned off at kernel compilation time. This sucks of course: why does it allow us to create a cgroup BPF
+         * program if we can't do a thing with it later?
+         *
+         * We detect this case by issuing the BPF_PROG_ATTACH bpf() call with invalid file descriptors: if
+         * CONFIG_CGROUP_BPF is turned off, then the call will fail early with EINVAL. If it is turned on the
+         * parameters are validated however, and that'll fail with EBADF then. */
+
+        attr = (union bpf_attr) {
+                .attach_type = BPF_CGROUP_INET_EGRESS,
+                .target_fd = -1,
+                .attach_bpf_fd = -1,
+        };
+
+        r = bpf(BPF_PROG_ATTACH, &attr, sizeof(attr));
+        if (r < 0) {
+                if (errno == EBADF) /* YAY! */
+                        return supported = true;
+
+                log_debug_errno(errno, "Didn't get EBADF from BPF_PROG_ATTACH, BPF firewalling is not supported: %m");
+        } else
+                log_debug("Wut? kernel accepted our invalid BPF_PROG_ATTACH call? Something is weird, assuming BPF firewalling is broken and hence not supported.");
+
+        return supported = false;
 }
index 870e314..37a1f2e 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 4e74e7b..9769a17 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -211,6 +212,16 @@ void cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix) {
                 prefix, cgroup_device_policy_to_string(c->device_policy),
                 prefix, yes_no(c->delegate));
 
+        if (c->delegate) {
+                _cleanup_free_ char *t = NULL;
+
+                (void) cg_mask_to_string(c->delegate_controllers, &t);
+
+                fprintf(f, "%sDelegateControllers=%s\n",
+                        prefix,
+                        strempty(t));
+        }
+
         LIST_FOREACH(device_allow, a, c->device_allow)
                 fprintf(f,
                         "%sDeviceAllow=%s %s%s%s\n",
@@ -668,9 +679,11 @@ static void cgroup_apply_unified_memory_limit(Unit *u, const char *file, uint64_
                               "Failed to set %s: %m", file);
 }
 
-static void cgroup_apply_firewall(Unit *u, CGroupContext *c) {
+static void cgroup_apply_firewall(Unit *u) {
         int r;
 
+        assert(u);
+
         if (u->type == UNIT_SLICE) /* Skip this for slice units, they are inner cgroup nodes, and since bpf/cgroup is
                                     * not recursive we don't ever touch the bpf on them */
                 return;
@@ -1022,7 +1035,7 @@ static void cgroup_context_apply(
         }
 
         if (apply_bpf)
-                cgroup_apply_firewall(u, c);
+                cgroup_apply_firewall(u);
 }
 
 CGroupMask cgroup_context_get_mask(CGroupContext *c) {
@@ -1064,32 +1077,42 @@ CGroupMask unit_get_own_mask(Unit *u) {
         if (!c)
                 return 0;
 
-        /* If delegation is turned on, then turn on all cgroups,
-         * unless we are on the legacy hierarchy and the process we
-         * fork into it is known to drop privileges, and hence
-         * shouldn't get access to the controllers.
+        return cgroup_context_get_mask(c) | unit_get_delegate_mask(u);
+}
+
+CGroupMask unit_get_delegate_mask(Unit *u) {
+        CGroupContext *c;
+
+        /* If delegation is turned on, then turn on selected controllers, unless we are on the legacy hierarchy and the
+         * process we fork into is known to drop privileges, and hence shouldn't get access to the controllers.
          *
-         * Note that on the unified hierarchy it is safe to delegate
-         * controllers to unprivileged services. */
+         * Note that on the unified hierarchy it is safe to delegate controllers to unprivileged services. */
 
-        if (c->delegate) {
+        if (u->type == UNIT_SLICE)
+                return 0;
+
+        c = unit_get_cgroup_context(u);
+        if (!c)
+                return 0;
+
+        if (!c->delegate)
+                return 0;
+
+        if (cg_all_unified() <= 0) {
                 ExecContext *e;
 
                 e = unit_get_exec_context(u);
-                if (!e ||
-                    exec_context_maintains_privileges(e) ||
-                    cg_all_unified() > 0)
-                        return _CGROUP_MASK_ALL;
+                if (e && !exec_context_maintains_privileges(e))
+                        return 0;
         }
 
-        return cgroup_context_get_mask(c);
+        return c->delegate_controllers;
 }
 
 CGroupMask unit_get_members_mask(Unit *u) {
         assert(u);
 
-        /* Returns the mask of controllers all of the unit's children
-         * require, merged */
+        /* Returns the mask of controllers all of the unit's children require, merged */
 
         if (u->cgroup_members_mask_valid)
                 return u->cgroup_members_mask;
@@ -1097,10 +1120,11 @@ CGroupMask unit_get_members_mask(Unit *u) {
         u->cgroup_members_mask = 0;
 
         if (u->type == UNIT_SLICE) {
+                void *v;
                 Unit *member;
                 Iterator i;
 
-                SET_FOREACH(member, u->dependencies[UNIT_BEFORE], i) {
+                HASHMAP_FOREACH_KEY(v, member, u->dependencies[UNIT_BEFORE], i) {
 
                         if (member == u)
                                 continue;
@@ -1108,9 +1132,7 @@ CGroupMask unit_get_members_mask(Unit *u) {
                         if (UNIT_DEREF(member->slice) != u)
                                 continue;
 
-                        u->cgroup_members_mask |=
-                                unit_get_own_mask(member) |
-                                unit_get_members_mask(member);
+                        u->cgroup_members_mask |= unit_get_subtree_mask(member); /* note that this calls ourselves again, for the children */
                 }
         }
 
@@ -1128,7 +1150,7 @@ CGroupMask unit_get_siblings_mask(Unit *u) {
         if (UNIT_ISSET(u->slice))
                 return unit_get_members_mask(UNIT_DEREF(u->slice));
 
-        return unit_get_own_mask(u) | unit_get_members_mask(u);
+        return unit_get_subtree_mask(u); /* we are the top-level slice */
 }
 
 CGroupMask unit_get_subtree_mask(Unit *u) {
@@ -1374,6 +1396,31 @@ int unit_watch_cgroup(Unit *u) {
         return 0;
 }
 
+int unit_pick_cgroup_path(Unit *u) {
+        _cleanup_free_ char *path = NULL;
+        int r;
+
+        assert(u);
+
+        if (u->cgroup_path)
+                return 0;
+
+        if (!UNIT_HAS_CGROUP_CONTEXT(u))
+                return -EINVAL;
+
+        path = unit_default_cgroup_path(u);
+        if (!path)
+                return log_oom();
+
+        r = unit_set_cgroup_path(u, path);
+        if (r == -EEXIST)
+                return log_unit_error_errno(u, r, "Control group %s exists already.", path);
+        if (r < 0)
+                return log_unit_error_errno(u, r, "Failed to set unit's control group path to %s: %m", path);
+
+        return 0;
+}
+
 static int unit_create_cgroup(
                 Unit *u,
                 CGroupMask target_mask,
@@ -1389,19 +1436,10 @@ static int unit_create_cgroup(
         if (!c)
                 return 0;
 
-        if (!u->cgroup_path) {
-                _cleanup_free_ char *path = NULL;
-
-                path = unit_default_cgroup_path(u);
-                if (!path)
-                        return log_oom();
-
-                r = unit_set_cgroup_path(u, path);
-                if (r == -EEXIST)
-                        return log_unit_error_errno(u, r, "Control group %s exists already.", path);
-                if (r < 0)
-                        return log_unit_error_errno(u, r, "Failed to set unit's control group path to %s: %m", path);
-        }
+        /* Figure out our cgroup path */
+        r = unit_pick_cgroup_path(u);
+        if (r < 0)
+                return r;
 
         /* First, create our own group */
         r = cg_create_everywhere(u->manager->cgroup_supported, target_mask, u->cgroup_path);
@@ -1467,7 +1505,7 @@ static void cgroup_xattr_apply(Unit *u) {
                          sd_id128_to_string(u->invocation_id, ids), 32,
                          0);
         if (r < 0)
-                log_unit_warning_errno(u, r, "Failed to set invocation ID on control group %s, ignoring: %m", u->cgroup_path);
+                log_unit_debug_errno(u, r, "Failed to set invocation ID on control group %s, ignoring: %m", u->cgroup_path);
 }
 
 static bool unit_has_mask_realized(
@@ -1485,6 +1523,27 @@ static bool unit_has_mask_realized(
                  (!needs_bpf && u->cgroup_bpf_state == UNIT_CGROUP_BPF_OFF));
 }
 
+static void unit_add_to_cgroup_realize_queue(Unit *u) {
+        assert(u);
+
+        if (u->in_cgroup_realize_queue)
+                return;
+
+        LIST_PREPEND(cgroup_realize_queue, u->manager->cgroup_realize_queue, u);
+        u->in_cgroup_realize_queue = true;
+}
+
+static void unit_remove_from_cgroup_realize_queue(Unit *u) {
+        assert(u);
+
+        if (!u->in_cgroup_realize_queue)
+                return;
+
+        LIST_REMOVE(cgroup_realize_queue, u->manager->cgroup_realize_queue, u);
+        u->in_cgroup_realize_queue = false;
+}
+
+
 /* Check if necessary controllers and attributes for a unit are in place.
  *
  * If so, do nothing.
@@ -1498,10 +1557,7 @@ static int unit_realize_cgroup_now(Unit *u, ManagerState state) {
 
         assert(u);
 
-        if (u->in_cgroup_realize_queue) {
-                LIST_REMOVE(cgroup_realize_queue, u->manager->cgroup_realize_queue, u);
-                u->in_cgroup_realize_queue = false;
-        }
+        unit_remove_from_cgroup_realize_queue(u);
 
         target_mask = unit_get_target_mask(u);
         enable_mask = unit_get_enable_mask(u);
@@ -1534,16 +1590,6 @@ static int unit_realize_cgroup_now(Unit *u, ManagerState state) {
         return 0;
 }
 
-static void unit_add_to_cgroup_realize_queue(Unit *u) {
-        assert(u);
-
-        if (u->in_cgroup_realize_queue)
-                return;
-
-        LIST_PREPEND(cgroup_realize_queue, u->manager->cgroup_realize_queue, u);
-        u->in_cgroup_realize_queue = true;
-}
-
 unsigned manager_dispatch_cgroup_realize_queue(Manager *m) {
         ManagerState state;
         unsigned n = 0;
@@ -1557,6 +1603,12 @@ unsigned manager_dispatch_cgroup_realize_queue(Manager *m) {
         while ((i = m->cgroup_realize_queue)) {
                 assert(i->in_cgroup_realize_queue);
 
+                if (UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(i))) {
+                        /* Maybe things changed, and the unit is not actually active anymore? */
+                        unit_remove_from_cgroup_realize_queue(i);
+                        continue;
+                }
+
                 r = unit_realize_cgroup_now(i, state);
                 if (r < 0)
                         log_warning_errno(r, "Failed to realize cgroups for queued unit %s, ignoring: %m", i->id);
@@ -1577,8 +1629,9 @@ static void unit_add_siblings_to_cgroup_realize_queue(Unit *u) {
         while ((slice = UNIT_DEREF(u->slice))) {
                 Iterator i;
                 Unit *m;
+                void *v;
 
-                SET_FOREACH(m, slice->dependencies[UNIT_BEFORE], i) {
+                HASHMAP_FOREACH_KEY(v, m, u->dependencies[UNIT_BEFORE], i) {
                         if (m == u)
                                 continue;
 
@@ -1954,11 +2007,9 @@ int manager_setup_cgroup(Manager *m) {
         if (e)
                 *e = 0;
 
-        /* And make sure to store away the root value without trailing
-         * slash, even for the root dir, so that we can easily prepend
-         * it everywhere. */
-        while ((e = endswith(m->cgroup_root, "/")))
-                *e = 0;
+        /* And make sure to store away the root value without trailing slash, even for the root dir, so that we can
+         * easily prepend it everywhere. */
+        delete_trailing_chars(m->cgroup_root, "/");
 
         /* 2. Show data */
         r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_root, NULL, &path);
@@ -1970,9 +2021,9 @@ int manager_setup_cgroup(Manager *m) {
                 return log_error_errno(r, "Couldn't determine if we are running in the unified hierarchy: %m");
 
         all_unified = cg_all_unified();
-        if (r < 0)
-                return log_error_errno(r, "Couldn't determine whether we are in all unified mode: %m");
-        if (r > 0)
+        if (all_unified < 0)
+                return log_error_errno(all_unified, "Couldn't determine whether we are in all unified mode: %m");
+        if (all_unified > 0)
                 log_debug("Unified cgroup hierarchy is located at %s.", path);
         else {
                 r = cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER);
@@ -2342,7 +2393,6 @@ int unit_get_ip_accounting(
         fd = IN_SET(metric, CGROUP_IP_INGRESS_BYTES, CGROUP_IP_INGRESS_PACKETS) ?
                 u->ip_accounting_ingress_map_fd :
                 u->ip_accounting_egress_map_fd;
-
         if (fd < 0)
                 return -ENODATA;
 
@@ -2412,7 +2462,7 @@ void unit_invalidate_cgroup(Unit *u, CGroupMask m) {
         if (m & (CGROUP_MASK_CPU | CGROUP_MASK_CPUACCT))
                 m |= CGROUP_MASK_CPU | CGROUP_MASK_CPUACCT;
 
-        if ((u->cgroup_realized_mask & m) == 0)
+        if ((u->cgroup_realized_mask & m) == 0) /* NOP? */
                 return;
 
         u->cgroup_realized_mask &= ~m;
@@ -2425,7 +2475,7 @@ void unit_invalidate_cgroup_bpf(Unit *u) {
         if (!UNIT_HAS_CGROUP_CONTEXT(u))
                 return;
 
-        if (u->cgroup_bpf_state == UNIT_CGROUP_BPF_INVALIDATED)
+        if (u->cgroup_bpf_state == UNIT_CGROUP_BPF_INVALIDATED) /* NOP? */
                 return;
 
         u->cgroup_bpf_state = UNIT_CGROUP_BPF_INVALIDATED;
@@ -2436,8 +2486,9 @@ void unit_invalidate_cgroup_bpf(Unit *u) {
         if (u->type == UNIT_SLICE) {
                 Unit *member;
                 Iterator i;
+                void *v;
 
-                SET_FOREACH(member, u->dependencies[UNIT_BEFORE], i) {
+                HASHMAP_FOREACH_KEY(v, member, u->dependencies[UNIT_BEFORE], i) {
                         if (member == u)
                                 continue;
 
index 65245fb..0c5bb4a 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -126,6 +127,7 @@ struct CGroupContext {
         uint64_t tasks_max;
 
         bool delegate;
+        CGroupMask delegate_controllers;
 };
 
 /* Used when querying IP accounting data */
@@ -153,8 +155,9 @@ void cgroup_context_free_blockio_device_weight(CGroupContext *c, CGroupBlockIODe
 void cgroup_context_free_blockio_device_bandwidth(CGroupContext *c, CGroupBlockIODeviceBandwidth *b);
 
 CGroupMask unit_get_own_mask(Unit *u);
-CGroupMask unit_get_siblings_mask(Unit *u);
+CGroupMask unit_get_delegate_mask(Unit *u);
 CGroupMask unit_get_members_mask(Unit *u);
+CGroupMask unit_get_siblings_mask(Unit *u);
 CGroupMask unit_get_subtree_mask(Unit *u);
 
 CGroupMask unit_get_target_mask(Unit *u);
@@ -166,6 +169,7 @@ void unit_update_cgroup_members_masks(Unit *u);
 
 char *unit_default_cgroup_path(Unit *u);
 int unit_set_cgroup_path(Unit *u, const char *path);
+int unit_pick_cgroup_path(Unit *u);
 
 int unit_realize_cgroup(Unit *u);
 void unit_release_cgroup(Unit *u);
index 2a3a070..f021f03 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 6531698..7540a8d 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 26212b3..4b1b86f 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -37,7 +38,7 @@ static int bus_automount_set_transient_property(
                 Automount *a,
                 const char *name,
                 sd_bus_message *message,
-                UnitSetPropertiesMode mode,
+                UnitWriteFlags flags,
                 sd_bus_error *error) {
 
         int r;
@@ -46,18 +47,21 @@ static int bus_automount_set_transient_property(
         assert(name);
         assert(message);
 
+        flags |= UNIT_PRIVATE;
+
         if (streq(name, "TimeoutIdleUSec")) {
                 usec_t timeout_idle_usec;
+
                 r = sd_bus_message_read(message, "t", &timeout_idle_usec);
                 if (r < 0)
                         return r;
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         char time[FORMAT_TIMESPAN_MAX];
 
                         a->timeout_idle_usec = timeout_idle_usec;
-                        unit_write_drop_in_format(UNIT(a), mode, name, "[Automount]\nTimeoutIdleSec=%s\n",
-                                format_timespan(time, sizeof(time), timeout_idle_usec, USEC_PER_MSEC));
+                        unit_write_settingf(UNIT(a), flags, name, "TimeoutIdleSec=%s\n",
+                                            format_timespan(time, sizeof(time), timeout_idle_usec, USEC_PER_MSEC));
                 }
         } else
                 return 0;
@@ -69,20 +73,17 @@ int bus_automount_set_property(
                 Unit *u,
                 const char *name,
                 sd_bus_message *message,
-                UnitSetPropertiesMode mode,
+                UnitWriteFlags flags,
                 sd_bus_error *error) {
 
         Automount *a = AUTOMOUNT(u);
-        int r = 0;
 
         assert(a);
         assert(name);
         assert(message);
 
-        if (u->transient && u->load_state == UNIT_STUB)
-                /* This is a transient unit, let's load a little more */
-
-                r = bus_automount_set_transient_property(a, name, message, mode, error);
+        if (u->transient && u->load_state == UNIT_STUB) /* This is a transient unit? let's load a little more */
+                return bus_automount_set_transient_property(a, name, message, flags, error);
 
-        return r;
+        return 0;
 }
index f41adda..3781194 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -22,4 +23,4 @@
 
 extern const sd_bus_vtable bus_automount_vtable[];
 
-int bus_automount_set_property(Unit *u, const char *name, sd_bus_message *message, UnitSetPropertiesMode mode, sd_bus_error *error);
+int bus_automount_set_property(Unit *u, const char *name, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
index a99d727..abca4e1 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -18,6 +19,7 @@
 ***/
 
 #include <arpa/inet.h>
+#include <stdio_ext.h>
 
 #include "af-list.h"
 #include "alloc-util.h"
 
 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_cgroup_device_policy, cgroup_device_policy, CGroupDevicePolicy);
 
+static int property_get_delegate_controllers(
+                sd_bus *bus,
+                const char *path,
+                const char *interface,
+                const char *property,
+                sd_bus_message *reply,
+                void *userdata,
+                sd_bus_error *error) {
+
+        CGroupContext *c = userdata;
+        CGroupController cc;
+        int r;
+
+        assert(bus);
+        assert(reply);
+        assert(c);
+
+        if (!c->delegate)
+                return sd_bus_message_append(reply, "as", 0);
+
+        r = sd_bus_message_open_container(reply, 'a', "s");
+        if (r < 0)
+                return r;
+
+        for (cc = 0; cc < _CGROUP_CONTROLLER_MAX; cc++) {
+                if ((c->delegate_controllers & CGROUP_CONTROLLER_TO_MASK(cc)) == 0)
+                        continue;
+
+                r = sd_bus_message_append(reply, "s", cgroup_controller_to_string(cc));
+                if (r < 0)
+                        return r;
+        }
+
+        return sd_bus_message_close_container(reply);
+}
+
 static int property_get_io_device_weight(
                 sd_bus *bus,
                 const char *path,
@@ -255,6 +293,7 @@ static int property_get_ip_address_access(
 const sd_bus_vtable bus_cgroup_vtable[] = {
         SD_BUS_VTABLE_START(0),
         SD_BUS_PROPERTY("Delegate", "b", bus_property_get_bool, offsetof(CGroupContext, delegate), 0),
+        SD_BUS_PROPERTY("DelegateControllers", "as", property_get_delegate_controllers, 0, 0),
         SD_BUS_PROPERTY("CPUAccounting", "b", bus_property_get_bool, offsetof(CGroupContext, cpu_accounting), 0),
         SD_BUS_PROPERTY("CPUWeight", "t", NULL, offsetof(CGroupContext, cpu_weight), 0),
         SD_BUS_PROPERTY("StartupCPUWeight", "t", NULL, offsetof(CGroupContext, startup_cpu_weight), 0),
@@ -296,7 +335,7 @@ static int bus_cgroup_set_transient_property(
                 CGroupContext *c,
                 const char *name,
                 sd_bus_message *message,
-                UnitSetPropertiesMode mode,
+                UnitWriteFlags flags,
                 sd_bus_error *error) {
 
         int r;
@@ -306,6 +345,8 @@ static int bus_cgroup_set_transient_property(
         assert(name);
         assert(message);
 
+        flags |= UNIT_PRIVATE;
+
         if (streq(name, "Delegate")) {
                 int b;
 
@@ -313,9 +354,57 @@ static int bus_cgroup_set_transient_property(
                 if (r < 0)
                         return r;
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         c->delegate = b;
-                        unit_write_drop_in_private(u, mode, name, b ? "Delegate=yes" : "Delegate=no");
+                        c->delegate_controllers = b ? _CGROUP_MASK_ALL : 0;
+
+                        unit_write_settingf(u, flags, name, "Delegate=%s", yes_no(b));
+                }
+
+                return 1;
+
+        } else if (streq(name, "DelegateControllers")) {
+                CGroupMask mask = 0;
+
+                r = sd_bus_message_enter_container(message, 'a', "s");
+                if (r < 0)
+                        return r;
+
+                for (;;) {
+                        CGroupController cc;
+                        const char *t;
+
+                        r = sd_bus_message_read(message, "s", &t);
+                        if (r < 0)
+                                return r;
+                        if (r == 0)
+                                break;
+
+                        cc = cgroup_controller_from_string(t);
+                        if (cc < 0)
+                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown cgroup contoller '%s'", t);
+
+                        mask |= CGROUP_CONTROLLER_TO_MASK(cc);
+                }
+
+                r = sd_bus_message_exit_container(message);
+                if (r < 0)
+                        return r;
+
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
+                        _cleanup_free_ char *t = NULL;
+
+                        r = cg_mask_to_string(mask, &t);
+                        if (r < 0)
+                                return r;
+
+                        c->delegate = true;
+                        if (mask == 0)
+                                c->delegate_controllers = 0;
+                        else
+                                c->delegate_controllers |= mask;
+
+                        unit_write_settingf(u, flags, name, "Delegate=%s", strempty(t));
                 }
 
                 return 1;
@@ -329,7 +418,7 @@ int bus_cgroup_set_property(
                 CGroupContext *c,
                 const char *name,
                 sd_bus_message *message,
-                UnitSetPropertiesMode mode,
+                UnitWriteFlags flags,
                 sd_bus_error *error) {
 
         CGroupIOLimitType iol_type;
@@ -340,6 +429,8 @@ int bus_cgroup_set_property(
         assert(name);
         assert(message);
 
+        flags |= UNIT_PRIVATE;
+
         if (streq(name, "CPUAccounting")) {
                 int b;
 
@@ -347,10 +438,10 @@ int bus_cgroup_set_property(
                 if (r < 0)
                         return r;
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         c->cpu_accounting = b;
                         unit_invalidate_cgroup(u, CGROUP_MASK_CPUACCT|CGROUP_MASK_CPU);
-                        unit_write_drop_in_private(u, mode, name, b ? "CPUAccounting=yes" : "CPUAccounting=no");
+                        unit_write_settingf(u, flags, name, "CPUAccounting=%s", yes_no(b));
                 }
 
                 return 1;
@@ -363,16 +454,16 @@ int bus_cgroup_set_property(
                         return r;
 
                 if (!CGROUP_WEIGHT_IS_OK(weight))
-                        return sd_bus_error_set_errnof(error, EINVAL, "CPUWeight value out of range");
+                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "CPUWeight= value out of range");
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         c->cpu_weight = weight;
                         unit_invalidate_cgroup(u, CGROUP_MASK_CPU);
 
                         if (weight == CGROUP_WEIGHT_INVALID)
-                                unit_write_drop_in_private(u, mode, name, "CPUWeight=");
+                                unit_write_setting(u, flags, name, "CPUWeight=");
                         else
-                                unit_write_drop_in_private_format(u, mode, name, "CPUWeight=%" PRIu64, weight);
+                                unit_write_settingf(u, flags, name, "CPUWeight=%" PRIu64, weight);
                 }
 
                 return 1;
@@ -385,16 +476,16 @@ int bus_cgroup_set_property(
                         return r;
 
                 if (!CGROUP_WEIGHT_IS_OK(weight))
-                        return sd_bus_error_set_errnof(error, EINVAL, "StartupCPUWeight value out of range");
+                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "StartupCPUWeight= value out of range");
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         c->startup_cpu_weight = weight;
                         unit_invalidate_cgroup(u, CGROUP_MASK_CPU);
 
                         if (weight == CGROUP_CPU_SHARES_INVALID)
-                                unit_write_drop_in_private(u, mode, name, "StartupCPUWeight=");
+                                unit_write_setting(u, flags, name, "StartupCPUWeight=");
                         else
-                                unit_write_drop_in_private_format(u, mode, name, "StartupCPUWeight=%" PRIu64, weight);
+                                unit_write_settingf(u, flags, name, "StartupCPUWeight=%" PRIu64, weight);
                 }
 
                 return 1;
@@ -407,16 +498,16 @@ int bus_cgroup_set_property(
                         return r;
 
                 if (!CGROUP_CPU_SHARES_IS_OK(shares))
-                        return sd_bus_error_set_errnof(error, EINVAL, "CPUShares value out of range");
+                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "CPUShares= value out of range");
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         c->cpu_shares = shares;
                         unit_invalidate_cgroup(u, CGROUP_MASK_CPU);
 
                         if (shares == CGROUP_CPU_SHARES_INVALID)
-                                unit_write_drop_in_private(u, mode, name, "CPUShares=");
+                                unit_write_setting(u, flags, name, "CPUShares=");
                         else
-                                unit_write_drop_in_private_format(u, mode, name, "CPUShares=%" PRIu64, shares);
+                                unit_write_settingf(u, flags, name, "CPUShares=%" PRIu64, shares);
                 }
 
                 return 1;
@@ -429,16 +520,16 @@ int bus_cgroup_set_property(
                         return r;
 
                 if (!CGROUP_CPU_SHARES_IS_OK(shares))
-                        return sd_bus_error_set_errnof(error, EINVAL, "StartupCPUShares value out of range");
+                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "StartupCPUShares= value out of range");
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         c->startup_cpu_shares = shares;
                         unit_invalidate_cgroup(u, CGROUP_MASK_CPU);
 
                         if (shares == CGROUP_CPU_SHARES_INVALID)
-                                unit_write_drop_in_private(u, mode, name, "StartupCPUShares=");
+                                unit_write_setting(u, flags, name, "StartupCPUShares=");
                         else
-                                unit_write_drop_in_private_format(u, mode, name, "StartupCPUShares=%" PRIu64, shares);
+                                unit_write_settingf(u, flags, name, "StartupCPUShares=%" PRIu64, shares);
                 }
 
                 return 1;
@@ -451,20 +542,20 @@ int bus_cgroup_set_property(
                         return r;
 
                 if (u64 <= 0)
-                        return sd_bus_error_set_errnof(error, EINVAL, "CPUQuotaPerSecUSec value out of range");
+                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "CPUQuotaPerSecUSec= value out of range");
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         c->cpu_quota_per_sec_usec = u64;
                         unit_invalidate_cgroup(u, CGROUP_MASK_CPU);
+
                         if (c->cpu_quota_per_sec_usec == USEC_INFINITY)
-                                unit_write_drop_in_private_format(u, mode, "CPUQuota",
-                                                                  "CPUQuota=");
+                                unit_write_setting(u, flags, "CPUQuota", "CPUQuota=");
                         else
-                                /* config_parse_cpu_quota() requires an integer, so
-                                 * truncating division is used on purpose here. */
-                                unit_write_drop_in_private_format(u, mode, "CPUQuota",
-                                                                  "CPUQuota=%0.f%%",
-                                                                  (double) (c->cpu_quota_per_sec_usec / 10000));
+                                /* config_parse_cpu_quota() requires an integer, so truncating division is used on
+                                 * purpose here. */
+                                unit_write_settingf(u, flags, "CPUQuota",
+                                                    "CPUQuota=%0.f%%",
+                                                    (double) (c->cpu_quota_per_sec_usec / 10000));
                 }
 
                 return 1;
@@ -476,10 +567,10 @@ int bus_cgroup_set_property(
                 if (r < 0)
                         return r;
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         c->io_accounting = b;
                         unit_invalidate_cgroup(u, CGROUP_MASK_IO);
-                        unit_write_drop_in_private(u, mode, name, b ? "IOAccounting=yes" : "IOAccounting=no");
+                        unit_write_settingf(u, flags, name, "IOAccounting=%s", yes_no(b));
                 }
 
                 return 1;
@@ -492,16 +583,16 @@ int bus_cgroup_set_property(
                         return r;
 
                 if (!CGROUP_WEIGHT_IS_OK(weight))
-                        return sd_bus_error_set_errnof(error, EINVAL, "IOWeight value out of range");
+                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "IOWeight= value out of range");
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         c->io_weight = weight;
                         unit_invalidate_cgroup(u, CGROUP_MASK_IO);
 
                         if (weight == CGROUP_WEIGHT_INVALID)
-                                unit_write_drop_in_private(u, mode, name, "IOWeight=");
+                                unit_write_setting(u, flags, name, "IOWeight=");
                         else
-                                unit_write_drop_in_private_format(u, mode, name, "IOWeight=%" PRIu64, weight);
+                                unit_write_settingf(u, flags, name, "IOWeight=%" PRIu64, weight);
                 }
 
                 return 1;
@@ -514,16 +605,16 @@ int bus_cgroup_set_property(
                         return r;
 
                 if (CGROUP_WEIGHT_IS_OK(weight))
-                        return sd_bus_error_set_errnof(error, EINVAL, "StartupIOWeight value out of range");
+                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "StartupIOWeight= value out of range");
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         c->startup_io_weight = weight;
                         unit_invalidate_cgroup(u, CGROUP_MASK_IO);
 
                         if (weight == CGROUP_WEIGHT_INVALID)
-                                unit_write_drop_in_private(u, mode, name, "StartupIOWeight=");
+                                unit_write_setting(u, flags, name, "StartupIOWeight=");
                         else
-                                unit_write_drop_in_private_format(u, mode, name, "StartupIOWeight=%" PRIu64, weight);
+                                unit_write_settingf(u, flags, name, "StartupIOWeight=%" PRIu64, weight);
                 }
 
                 return 1;
@@ -539,7 +630,7 @@ int bus_cgroup_set_property(
 
                 while ((r = sd_bus_message_read(message, "(st)", &path, &u64)) > 0) {
 
-                        if (mode != UNIT_CHECK) {
+                        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                                 CGroupIODeviceLimit *a = NULL, *b;
 
                                 LIST_FOREACH(device_limits, b, c->io_device_limits) {
@@ -580,7 +671,7 @@ int bus_cgroup_set_property(
                 if (r < 0)
                         return r;
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         CGroupIODeviceLimit *a;
                         _cleanup_free_ char *buf = NULL;
                         _cleanup_fclose_ FILE *f = NULL;
@@ -597,6 +688,8 @@ int bus_cgroup_set_property(
                         if (!f)
                                 return -ENOMEM;
 
+                        (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
+
                         fprintf(f, "%s=\n", name);
                         LIST_FOREACH(device_limits, a, c->io_device_limits)
                                         if (a->limits[iol_type] != cgroup_io_limit_defaults[iol_type])
@@ -605,7 +698,7 @@ int bus_cgroup_set_property(
                         r = fflush_and_check(f);
                         if (r < 0)
                                 return r;
-                        unit_write_drop_in_private(u, mode, name, buf);
+                        unit_write_setting(u, flags, name, buf);
                 }
 
                 return 1;
@@ -622,9 +715,9 @@ int bus_cgroup_set_property(
                 while ((r = sd_bus_message_read(message, "(st)", &path, &weight)) > 0) {
 
                         if (!CGROUP_WEIGHT_IS_OK(weight) || weight == CGROUP_WEIGHT_INVALID)
-                                return sd_bus_error_set_errnof(error, EINVAL, "IODeviceWeight out of range");
+                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "IODeviceWeight= value out of range");
 
-                        if (mode != UNIT_CHECK) {
+                        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                                 CGroupIODeviceWeight *a = NULL, *b;
 
                                 LIST_FOREACH(device_weights, b, c->io_device_weights) {
@@ -657,7 +750,7 @@ int bus_cgroup_set_property(
                 if (r < 0)
                         return r;
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         _cleanup_free_ char *buf = NULL;
                         _cleanup_fclose_ FILE *f = NULL;
                         CGroupIODeviceWeight *a;
@@ -674,14 +767,16 @@ int bus_cgroup_set_property(
                         if (!f)
                                 return -ENOMEM;
 
-                        fputs_unlocked("IODeviceWeight=\n", f);
+                        (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
+
+                        fputs("IODeviceWeight=\n", f);
                         LIST_FOREACH(device_weights, a, c->io_device_weights)
                                 fprintf(f, "IODeviceWeight=%s %" PRIu64 "\n", a->path, a->weight);
 
                         r = fflush_and_check(f);
                         if (r < 0)
                                 return r;
-                        unit_write_drop_in_private(u, mode, name, buf);
+                        unit_write_setting(u, flags, name, buf);
                 }
 
                 return 1;
@@ -693,10 +788,10 @@ int bus_cgroup_set_property(
                 if (r < 0)
                         return r;
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         c->blockio_accounting = b;
                         unit_invalidate_cgroup(u, CGROUP_MASK_BLKIO);
-                        unit_write_drop_in_private(u, mode, name, b ? "BlockIOAccounting=yes" : "BlockIOAccounting=no");
+                        unit_write_settingf(u, flags, name, "BlockIOAccounting=%s", yes_no(b));
                 }
 
                 return 1;
@@ -709,16 +804,16 @@ int bus_cgroup_set_property(
                         return r;
 
                 if (!CGROUP_BLKIO_WEIGHT_IS_OK(weight))
-                        return sd_bus_error_set_errnof(error, EINVAL, "BlockIOWeight value out of range");
+                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "BlockIOWeight= value out of range");
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         c->blockio_weight = weight;
                         unit_invalidate_cgroup(u, CGROUP_MASK_BLKIO);
 
                         if (weight == CGROUP_BLKIO_WEIGHT_INVALID)
-                                unit_write_drop_in_private(u, mode, name, "BlockIOWeight=");
+                                unit_write_setting(u, flags, name, "BlockIOWeight=");
                         else
-                                unit_write_drop_in_private_format(u, mode, name, "BlockIOWeight=%" PRIu64, weight);
+                                unit_write_settingf(u, flags, name, "BlockIOWeight=%" PRIu64, weight);
                 }
 
                 return 1;
@@ -731,16 +826,16 @@ int bus_cgroup_set_property(
                         return r;
 
                 if (!CGROUP_BLKIO_WEIGHT_IS_OK(weight))
-                        return sd_bus_error_set_errnof(error, EINVAL, "StartupBlockIOWeight value out of range");
+                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "StartupBlockIOWeight= value out of range");
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         c->startup_blockio_weight = weight;
                         unit_invalidate_cgroup(u, CGROUP_MASK_BLKIO);
 
                         if (weight == CGROUP_BLKIO_WEIGHT_INVALID)
-                                unit_write_drop_in_private(u, mode, name, "StartupBlockIOWeight=");
+                                unit_write_setting(u, flags, name, "StartupBlockIOWeight=");
                         else
-                                unit_write_drop_in_private_format(u, mode, name, "StartupBlockIOWeight=%" PRIu64, weight);
+                                unit_write_settingf(u, flags, name, "StartupBlockIOWeight=%" PRIu64, weight);
                 }
 
                 return 1;
@@ -760,7 +855,7 @@ int bus_cgroup_set_property(
 
                 while ((r = sd_bus_message_read(message, "(st)", &path, &u64)) > 0) {
 
-                        if (mode != UNIT_CHECK) {
+                        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                                 CGroupBlockIODeviceBandwidth *a = NULL, *b;
 
                                 LIST_FOREACH(device_bandwidths, b, c->blockio_device_bandwidths) {
@@ -801,7 +896,7 @@ int bus_cgroup_set_property(
                 if (r < 0)
                         return r;
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         CGroupBlockIODeviceBandwidth *a;
                         _cleanup_free_ char *buf = NULL;
                         _cleanup_fclose_ FILE *f = NULL;
@@ -822,13 +917,15 @@ int bus_cgroup_set_property(
                         if (!f)
                                 return -ENOMEM;
 
+                        (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
+
                         if (read) {
-                                fputs_unlocked("BlockIOReadBandwidth=\n", f);
+                                fputs("BlockIOReadBandwidth=\n", f);
                                 LIST_FOREACH(device_bandwidths, a, c->blockio_device_bandwidths)
                                         if (a->rbps != CGROUP_LIMIT_MAX)
                                                 fprintf(f, "BlockIOReadBandwidth=%s %" PRIu64 "\n", a->path, a->rbps);
                         } else {
-                                fputs_unlocked("BlockIOWriteBandwidth=\n", f);
+                                fputs("BlockIOWriteBandwidth=\n", f);
                                 LIST_FOREACH(device_bandwidths, a, c->blockio_device_bandwidths)
                                         if (a->wbps != CGROUP_LIMIT_MAX)
                                                 fprintf(f, "BlockIOWriteBandwidth=%s %" PRIu64 "\n", a->path, a->wbps);
@@ -837,7 +934,8 @@ int bus_cgroup_set_property(
                         r = fflush_and_check(f);
                         if (r < 0)
                                 return r;
-                        unit_write_drop_in_private(u, mode, name, buf);
+
+                        unit_write_setting(u, flags, name, buf);
                 }
 
                 return 1;
@@ -854,9 +952,9 @@ int bus_cgroup_set_property(
                 while ((r = sd_bus_message_read(message, "(st)", &path, &weight)) > 0) {
 
                         if (!CGROUP_BLKIO_WEIGHT_IS_OK(weight) || weight == CGROUP_BLKIO_WEIGHT_INVALID)
-                                return sd_bus_error_set_errnof(error, EINVAL, "BlockIODeviceWeight out of range");
+                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "BlockIODeviceWeight= out of range");
 
-                        if (mode != UNIT_CHECK) {
+                        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                                 CGroupBlockIODeviceWeight *a = NULL, *b;
 
                                 LIST_FOREACH(device_weights, b, c->blockio_device_weights) {
@@ -889,7 +987,7 @@ int bus_cgroup_set_property(
                 if (r < 0)
                         return r;
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         _cleanup_free_ char *buf = NULL;
                         _cleanup_fclose_ FILE *f = NULL;
                         CGroupBlockIODeviceWeight *a;
@@ -906,14 +1004,17 @@ int bus_cgroup_set_property(
                         if (!f)
                                 return -ENOMEM;
 
-                        fputs_unlocked("BlockIODeviceWeight=\n", f);
+                        (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
+
+                        fputs("BlockIODeviceWeight=\n", f);
                         LIST_FOREACH(device_weights, a, c->blockio_device_weights)
                                 fprintf(f, "BlockIODeviceWeight=%s %" PRIu64 "\n", a->path, a->weight);
 
                         r = fflush_and_check(f);
                         if (r < 0)
                                 return r;
-                        unit_write_drop_in_private(u, mode, name, buf);
+
+                        unit_write_setting(u, flags, name, buf);
                 }
 
                 return 1;
@@ -925,10 +1026,10 @@ int bus_cgroup_set_property(
                 if (r < 0)
                         return r;
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         c->memory_accounting = b;
                         unit_invalidate_cgroup(u, CGROUP_MASK_MEMORY);
-                        unit_write_drop_in_private(u, mode, name, b ? "MemoryAccounting=yes" : "MemoryAccounting=no");
+                        unit_write_settingf(u, flags, name, "MemoryAccounting=%s", yes_no(b));
                 }
 
                 return 1;
@@ -940,9 +1041,9 @@ int bus_cgroup_set_property(
                 if (r < 0)
                         return r;
                 if (v <= 0)
-                        return sd_bus_error_set_errnof(error, EINVAL, "%s= is too small", name);
+                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= is too small", name);
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         if (streq(name, "MemoryLow"))
                                 c->memory_low = v;
                         else if (streq(name, "MemoryHigh"))
@@ -955,14 +1056,14 @@ int bus_cgroup_set_property(
                         unit_invalidate_cgroup(u, CGROUP_MASK_MEMORY);
 
                         if (v == CGROUP_LIMIT_MAX)
-                                unit_write_drop_in_private_format(u, mode, name, "%s=infinity", name);
+                                unit_write_settingf(u, flags, name, "%s=infinity", name);
                         else
-                                unit_write_drop_in_private_format(u, mode, name, "%s=%" PRIu64, name, v);
+                                unit_write_settingf(u, flags, name, "%s=%" PRIu64, name, v);
                 }
 
                 return 1;
 
-        } else if (STR_IN_SET(name, "MemoryLowScale", "MemoryHighScale", "MemoryMaxScale")) {
+        } else if (STR_IN_SET(name, "MemoryLowScale", "MemoryHighScale", "MemoryMaxScale", "MemorySwapMaxScale")) {
                 uint32_t raw;
                 uint64_t v;
 
@@ -972,9 +1073,9 @@ int bus_cgroup_set_property(
 
                 v = physical_memory_scale(raw, UINT32_MAX);
                 if (v <= 0 || v == UINT64_MAX)
-                        return sd_bus_error_set_errnof(error, EINVAL, "%s= is out of range", name);
+                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= is out of range", name);
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         const char *e;
 
                         /* Chop off suffix */
@@ -985,12 +1086,14 @@ int bus_cgroup_set_property(
                                 c->memory_low = v;
                         else if (streq(name, "MemoryHigh"))
                                 c->memory_high = v;
-                        else
+                        else if (streq(name, "MemorySwapMaxScale"))
+                                c->memory_swap_max = v;
+                        else /* MemoryMax */
                                 c->memory_max = v;
 
                         unit_invalidate_cgroup(u, CGROUP_MASK_MEMORY);
-                        unit_write_drop_in_private_format(u, mode, name, "%s=%" PRIu32 "%%", name,
-                                                          (uint32_t) (DIV_ROUND_UP((uint64_t) raw * 100U, (uint64_t) UINT32_MAX)));
+                        unit_write_settingf(u, flags, name, "%s=%" PRIu32 "%%", name,
+                                            (uint32_t) (DIV_ROUND_UP((uint64_t) raw * 100U, (uint64_t) UINT32_MAX)));
                 }
 
                 return 1;
@@ -1002,16 +1105,16 @@ int bus_cgroup_set_property(
                 if (r < 0)
                         return r;
                 if (limit <= 0)
-                        return sd_bus_error_set_errnof(error, EINVAL, "%s= is too small", name);
+                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= is too small", name);
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         c->memory_limit = limit;
                         unit_invalidate_cgroup(u, CGROUP_MASK_MEMORY);
 
-                        if (limit == (uint64_t) -1)
-                                unit_write_drop_in_private(u, mode, name, "MemoryLimit=infinity");
+                        if (limit == CGROUP_LIMIT_MAX)
+                                unit_write_setting(u, flags, name, "MemoryLimit=infinity");
                         else
-                                unit_write_drop_in_private_format(u, mode, name, "MemoryLimit=%" PRIu64, limit);
+                                unit_write_settingf(u, flags, name, "MemoryLimit=%" PRIu64, limit);
                 }
 
                 return 1;
@@ -1026,12 +1129,12 @@ int bus_cgroup_set_property(
 
                 limit = physical_memory_scale(raw, UINT32_MAX);
                 if (limit <= 0 || limit == UINT64_MAX)
-                        return sd_bus_error_set_errnof(error, EINVAL, "%s= is out of range", name);
+                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= is out of range", name);
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         c->memory_limit = limit;
                         unit_invalidate_cgroup(u, CGROUP_MASK_MEMORY);
-                        unit_write_drop_in_private_format(u, mode, "MemoryLimit", "MemoryLimit=%" PRIu32 "%%",
+                        unit_write_settingf(u, flags, "MemoryLimit", "MemoryLimit=%" PRIu32 "%%",
                                                           (uint32_t) (DIV_ROUND_UP((uint64_t) raw * 100U, (uint64_t) UINT32_MAX)));
                 }
 
@@ -1049,10 +1152,10 @@ int bus_cgroup_set_property(
                 if (p < 0)
                         return -EINVAL;
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         c->device_policy = p;
                         unit_invalidate_cgroup(u, CGROUP_MASK_DEVICES);
-                        unit_write_drop_in_private_format(u, mode, name, "DevicePolicy=%s", policy);
+                        unit_write_settingf(u, flags, name, "DevicePolicy=%s", policy);
                 }
 
                 return 1;
@@ -1072,15 +1175,15 @@ int bus_cgroup_set_property(
                              !startswith(path, "block-") &&
                              !startswith(path, "char-")) ||
                             strpbrk(path, WHITESPACE))
-                            return sd_bus_error_set_errnof(error, EINVAL, "DeviceAllow= requires device node");
+                            return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "DeviceAllow= requires device node");
 
                         if (isempty(rwm))
                                 rwm = "rwm";
 
                         if (!in_charset(rwm, "rwm"))
-                                return sd_bus_error_set_errnof(error, EINVAL, "DeviceAllow= requires combination of rwm flags");
+                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "DeviceAllow= requires combination of rwm flags");
 
-                        if (mode != UNIT_CHECK) {
+                        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                                 CGroupDeviceAllow *a = NULL, *b;
 
                                 LIST_FOREACH(device_allow, b, c->device_allow) {
@@ -1118,7 +1221,7 @@ int bus_cgroup_set_property(
                 if (r < 0)
                         return r;
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         _cleanup_free_ char *buf = NULL;
                         _cleanup_fclose_ FILE *f = NULL;
                         CGroupDeviceAllow *a;
@@ -1135,14 +1238,16 @@ int bus_cgroup_set_property(
                         if (!f)
                                 return -ENOMEM;
 
-                        fputs_unlocked("DeviceAllow=\n", f);
+                        (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
+
+                        fputs("DeviceAllow=\n", f);
                         LIST_FOREACH(device_allow, a, c->device_allow)
                                 fprintf(f, "DeviceAllow=%s %s%s%s\n", a->path, a->r ? "r" : "", a->w ? "w" : "", a->m ? "m" : "");
 
                         r = fflush_and_check(f);
                         if (r < 0)
                                 return r;
-                        unit_write_drop_in_private(u, mode, name, buf);
+                        unit_write_setting(u, flags, name, buf);
                 }
 
                 return 1;
@@ -1154,10 +1259,10 @@ int bus_cgroup_set_property(
                 if (r < 0)
                         return r;
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         c->tasks_accounting = b;
                         unit_invalidate_cgroup(u, CGROUP_MASK_PIDS);
-                        unit_write_drop_in_private(u, mode, name, b ? "TasksAccounting=yes" : "TasksAccounting=no");
+                        unit_write_settingf(u, flags, name, "TasksAccounting=%s", yes_no(b));
                 }
 
                 return 1;
@@ -1169,16 +1274,16 @@ int bus_cgroup_set_property(
                 if (r < 0)
                         return r;
                 if (limit <= 0)
-                        return sd_bus_error_set_errnof(error, EINVAL, "%s= is too small", name);
+                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= is too small", name);
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         c->tasks_max = limit;
                         unit_invalidate_cgroup(u, CGROUP_MASK_PIDS);
 
                         if (limit == (uint64_t) -1)
-                                unit_write_drop_in_private(u, mode, name, "TasksMax=infinity");
+                                unit_write_setting(u, flags, name, "TasksMax=infinity");
                         else
-                                unit_write_drop_in_private_format(u, mode, name, "TasksMax=%" PRIu64, limit);
+                                unit_write_settingf(u, flags, name, "TasksMax=%" PRIu64, limit);
                 }
 
                 return 1;
@@ -1193,13 +1298,13 @@ int bus_cgroup_set_property(
 
                 limit = system_tasks_max_scale(raw, UINT32_MAX);
                 if (limit <= 0 || limit >= UINT64_MAX)
-                        return sd_bus_error_set_errnof(error, EINVAL, "%s= is out of range", name);
+                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= is out of range", name);
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         c->tasks_max = limit;
                         unit_invalidate_cgroup(u, CGROUP_MASK_PIDS);
-                        unit_write_drop_in_private_format(u, mode, name, "TasksMax=%" PRIu32 "%%",
-                                                          (uint32_t) (DIV_ROUND_UP((uint64_t) raw * 100U, (uint64_t) UINT32_MAX)));
+                        unit_write_settingf(u, flags, name, "TasksMax=%" PRIu32 "%%",
+                                            (uint32_t) (DIV_ROUND_UP((uint64_t) raw * 100U, (uint64_t) UINT32_MAX)));
                 }
 
                 return 1;
@@ -1211,11 +1316,11 @@ int bus_cgroup_set_property(
                 if (r < 0)
                         return r;
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         c->ip_accounting = b;
 
                         unit_invalidate_cgroup_bpf(u);
-                        unit_write_drop_in_private(u, mode, name, b ? "IPAccounting=yes" : "IPAccounting=no");
+                        unit_write_settingf(u, flags, name, "IPAccounting=%s", yes_no(b));
                 }
 
                 return 1;
@@ -1247,14 +1352,14 @@ int bus_cgroup_set_property(
                                 return r;
 
                         if (!IN_SET(family, AF_INET, AF_INET6))
-                                return sd_bus_error_set_errnof(error, EINVAL, "%s= expects IPv4 or IPv6 addresses only.", name);
+                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= expects IPv4 or IPv6 addresses only.", name);
 
                         r = sd_bus_message_read_array(message, 'y', &ap, &an);
                         if (r < 0)
                                 return r;
 
                         if (an != FAMILY_ADDRESS_SIZE(family))
-                                return sd_bus_error_set_errnof(error, EINVAL, "IP address has wrong size for family (%s, expected %zu, got %zu)",
+                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "IP address has wrong size for family (%s, expected %zu, got %zu)",
                                                                af_to_name(family), FAMILY_ADDRESS_SIZE(family), an);
 
                         r = sd_bus_message_read(message, "u", &prefixlen);
@@ -1262,9 +1367,9 @@ int bus_cgroup_set_property(
                                 return r;
 
                         if (prefixlen > FAMILY_ADDRESS_SIZE(family)*8)
-                                return sd_bus_error_set_errnof(error, EINVAL, "Prefix length %" PRIu32 " too large for address family %s.", prefixlen, af_to_name(family));
+                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Prefix length %" PRIu32 " too large for address family %s.", prefixlen, af_to_name(family));
 
-                        if (mode != UNIT_CHECK) {
+                        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                                 IPAddressAccessItem *item;
 
                                 item = new0(IPAddressAccessItem, 1);
@@ -1291,7 +1396,7 @@ int bus_cgroup_set_property(
 
                 *list = ip_address_access_reduce(*list);
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         _cleanup_free_ char *buf = NULL;
                         _cleanup_fclose_ FILE *f = NULL;
                         IPAddressAccessItem *item;
@@ -1305,8 +1410,10 @@ int bus_cgroup_set_property(
                         if (!f)
                                 return -ENOMEM;
 
-                        fputs_unlocked(name, f);
-                        fputs_unlocked("=\n", f);
+                        (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
+
+                        fputs(name, f);
+                        fputs("=\n", f);
 
                         LIST_FOREACH(items, item, *list) {
                                 char buffer[CONST_MAX(INET_ADDRSTRLEN, INET6_ADDRSTRLEN)];
@@ -1321,15 +1428,22 @@ int bus_cgroup_set_property(
                         r = fflush_and_check(f);
                         if (r < 0)
                                 return r;
-                        unit_write_drop_in_private(u, mode, name, buf);
+
+                        unit_write_setting(u, flags, name, buf);
 
                         if (*list) {
                                 r = bpf_firewall_supported();
                                 if (r < 0)
                                         return r;
-                                if (r == 0)
-                                        log_warning("Transient unit %s configures an IP firewall, but the local system does not support BPF/cgroup firewalling.\n"
-                                                    "Proceeding WITHOUT firewalling in effect!", u->id);
+                                if (r == 0) {
+                                        static bool warned = false;
+
+                                        log_full(warned ? LOG_DEBUG : LOG_WARNING,
+                                                 "Transient unit %s configures an IP firewall, but the local system does not support BPF/cgroup firewalling.\n"
+                                                 "Proceeding WITHOUT firewalling in effect! (This warning is only shown for the first started transient unit using IP firewalling.)", u->id);
+
+                                        warned = true;
+                                }
                         }
                 }
 
@@ -1337,7 +1451,7 @@ int bus_cgroup_set_property(
         }
 
         if (u->transient && u->load_state == UNIT_STUB) {
-                r = bus_cgroup_set_transient_property(u, c, name, message, mode, error);
+                r = bus_cgroup_set_transient_property(u, c, name, message, flags, error);
                 if (r != 0)
                         return r;
 
index b2212fe..0588370 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -25,4 +26,4 @@
 
 extern const sd_bus_vtable bus_cgroup_vtable[];
 
-int bus_cgroup_set_property(Unit *u, CGroupContext *c, const char *name, sd_bus_message *message, UnitSetPropertiesMode mode, sd_bus_error *error);
+int bus_cgroup_set_property(Unit *u, CGroupContext *c, const char *name, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
index e1a1222..fbb60d8 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index eb1d8c3..c809870 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index d211ff1..a33a48f 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -18,6 +19,7 @@
 ***/
 
 #include <sys/prctl.h>
+#include <stdio_ext.h>
 
 #if HAVE_SECCOMP
 #include <seccomp.h>
 #include "af-list.h"
 #include "alloc-util.h"
 #include "bus-util.h"
-#include "capability-util.h"
 #include "cap-list.h"
+#include "capability-util.h"
+#include "cpu-set-util.h"
 #include "dbus-execute.h"
 #include "env-util.h"
 #include "errno-list.h"
+#include "escape.h"
 #include "execute.h"
 #include "fd-util.h"
 #include "fileio.h"
+#include "hexdecoct.h"
+#include "io-util.h"
 #include "ioprio.h"
+#include "journal-util.h"
 #include "missing.h"
 #include "mount-util.h"
 #include "namespace.h"
@@ -46,6 +53,7 @@
 #include "seccomp-util.h"
 #endif
 #include "securebits-util.h"
+#include "specifier.h"
 #include "strv.h"
 #include "syslog-util.h"
 #include "unit-printf.h"
@@ -408,7 +416,7 @@ static int property_get_syscall_filter(
 
 #if HAVE_SECCOMP
         Iterator i;
-        void *id;
+        void *id, *val;
 #endif
 
         assert(bus);
@@ -424,14 +432,33 @@ static int property_get_syscall_filter(
                 return r;
 
 #if HAVE_SECCOMP
-        SET_FOREACH(id, c->syscall_filter, i) {
-                char *name;
+        HASHMAP_FOREACH_KEY(val, id, c->syscall_filter, i) {
+                _cleanup_free_ char *name = NULL;
+                const char *e = NULL;
+                char *s;
+                int num = PTR_TO_INT(val);
 
                 name = seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE, PTR_TO_INT(id) - 1);
                 if (!name)
                         continue;
 
-                r = strv_consume(&l, name);
+                if (num >= 0) {
+                        e = errno_to_name(num);
+                        if (e) {
+                                s = strjoin(name, ":", e);
+                                if (!s)
+                                        return -ENOMEM;
+                        } else {
+                                r = asprintf(&s, "%s:%d", name, num);
+                                if (r < 0)
+                                        return -ENOMEM;
+                        }
+                } else {
+                        s = name;
+                        name = NULL;
+                }
+
+                r = strv_consume(&l, s);
                 if (r < 0)
                         return r;
         }
@@ -692,7 +719,7 @@ static int property_get_syslog_facility(
         return sd_bus_message_append(reply, "i", LOG_FAC(c->syslog_priority));
 }
 
-static int property_get_input_fdname(
+static int property_get_stdio_fdname(
                 sd_bus *bus,
                 const char *path,
                 const char *interface,
@@ -702,19 +729,26 @@ static int property_get_input_fdname(
                 sd_bus_error *error) {
 
         ExecContext *c = userdata;
-        const char *name;
+        int fileno;
 
         assert(bus);
         assert(c);
         assert(property);
         assert(reply);
 
-        name = exec_context_fdname(c, STDIN_FILENO);
+        if (streq(property, "StandardInputFileDescriptorName"))
+                fileno = STDIN_FILENO;
+        else if (streq(property, "StandardOutputFileDescriptorName"))
+                fileno = STDOUT_FILENO;
+        else {
+                assert(streq(property, "StandardErrorFileDescriptorName"));
+                fileno = STDERR_FILENO;
+        }
 
-        return sd_bus_message_append(reply, "s", name);
+        return sd_bus_message_append(reply, "s", exec_context_fdname(c, fileno));
 }
 
-static int property_get_output_fdname(
+static int property_get_input_data(
                 sd_bus *bus,
                 const char *path,
                 const char *interface,
@@ -724,19 +758,13 @@ static int property_get_output_fdname(
                 sd_bus_error *error) {
 
         ExecContext *c = userdata;
-        const char *name = NULL;
 
         assert(bus);
         assert(c);
         assert(property);
         assert(reply);
 
-        if (c->std_output == EXEC_OUTPUT_NAMED_FD && streq(property, "StandardOutputFileDescriptorName"))
-                name = exec_context_fdname(c, STDOUT_FILENO);
-        else if (c->std_error == EXEC_OUTPUT_NAMED_FD && streq(property, "StandardErrorFileDescriptorName"))
-                name = exec_context_fdname(c, STDERR_FILENO);
-
-        return sd_bus_message_append(reply, "s", name);
+        return sd_bus_message_append_array(reply, 'y', c->stdin_data, c->stdin_data_size);
 }
 
 static int property_get_bind_paths(
@@ -782,6 +810,37 @@ static int property_get_bind_paths(
         return sd_bus_message_close_container(reply);
 }
 
+static int property_get_log_extra_fields(
+                sd_bus *bus,
+                const char *path,
+                const char *interface,
+                const char *property,
+                sd_bus_message *reply,
+                void *userdata,
+                sd_bus_error *error) {
+
+        ExecContext *c = userdata;
+        size_t i;
+        int r;
+
+        assert(bus);
+        assert(c);
+        assert(property);
+        assert(reply);
+
+        r = sd_bus_message_open_container(reply, 'a', "ay");
+        if (r < 0)
+                return r;
+
+        for (i = 0; i < c->n_log_extra_fields; i++) {
+                r = sd_bus_message_append_array(reply, 'y', c->log_extra_fields[i].iov_base, c->log_extra_fields[i].iov_len);
+                if (r < 0)
+                        return r;
+        }
+
+        return sd_bus_message_close_container(reply);
+}
+
 const sd_bus_vtable bus_exec_vtable[] = {
         SD_BUS_VTABLE_START(0),
         SD_BUS_PROPERTY("Environment", "as", NULL, offsetof(ExecContext, environment), SD_BUS_VTABLE_PROPERTY_CONST),
@@ -835,11 +894,12 @@ const sd_bus_vtable bus_exec_vtable[] = {
         SD_BUS_PROPERTY("CPUSchedulingResetOnFork", "b", bus_property_get_bool, offsetof(ExecContext, cpu_sched_reset_on_fork), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("NonBlocking", "b", bus_property_get_bool, offsetof(ExecContext, non_blocking), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("StandardInput", "s", property_get_exec_input, offsetof(ExecContext, std_input), SD_BUS_VTABLE_PROPERTY_CONST),
-        SD_BUS_PROPERTY("StandardInputFileDescriptorName", "s", property_get_input_fdname, 0, SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("StandardInputFileDescriptorName", "s", property_get_stdio_fdname, 0, SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("StandardInputData", "ay", property_get_input_data, 0, SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("StandardOutput", "s", bus_property_get_exec_output, offsetof(ExecContext, std_output), SD_BUS_VTABLE_PROPERTY_CONST),
-        SD_BUS_PROPERTY("StandardOutputFileDescriptorName", "s", property_get_output_fdname, 0, SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("StandardOutputFileDescriptorName", "s", property_get_stdio_fdname, 0, SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("StandardError", "s", bus_property_get_exec_output, offsetof(ExecContext, std_error), SD_BUS_VTABLE_PROPERTY_CONST),
-        SD_BUS_PROPERTY("StandardErrorFileDescriptorName", "s", property_get_output_fdname, 0, SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("StandardErrorFileDescriptorName", "s", property_get_stdio_fdname, 0, SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("TTYPath", "s", NULL, offsetof(ExecContext, tty_path), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("TTYReset", "b", bus_property_get_bool, offsetof(ExecContext, tty_reset), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("TTYVHangup", "b", bus_property_get_bool, offsetof(ExecContext, tty_vhangup), SD_BUS_VTABLE_PROPERTY_CONST),
@@ -849,6 +909,8 @@ const sd_bus_vtable bus_exec_vtable[] = {
         SD_BUS_PROPERTY("SyslogLevelPrefix", "b", bus_property_get_bool, offsetof(ExecContext, syslog_level_prefix), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("SyslogLevel", "i", property_get_syslog_level, 0, SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("SyslogFacility", "i", property_get_syslog_facility, 0, SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("LogLevelMax", "i", bus_property_get_int, offsetof(ExecContext, log_level_max), SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("LogExtraFields", "aay", property_get_log_extra_fields, 0, SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("SecureBits", "i", bus_property_get_int, offsetof(ExecContext, secure_bits), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("CapabilityBoundingSet", "t", property_get_capability_bounding_set, 0, SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("AmbientCapabilities", "t", property_get_ambient_capabilities, 0, SD_BUS_VTABLE_PROPERTY_CONST),
@@ -1009,7 +1071,7 @@ int bus_exec_context_set_transient_property(
                 ExecContext *c,
                 const char *name,
                 sd_bus_message *message,
-                UnitSetPropertiesMode mode,
+                UnitWriteFlags flags,
                 sd_bus_error *error) {
 
         const char *soft = NULL;
@@ -1020,6 +1082,8 @@ int bus_exec_context_set_transient_property(
         assert(name);
         assert(message);
 
+        flags |= UNIT_PRIVATE;
+
         if (streq(name, "User")) {
                 const char *uu;
 
@@ -1030,14 +1094,13 @@ int bus_exec_context_set_transient_property(
                 if (!isempty(uu) && !valid_user_group_name_or_id(uu))
                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid user name: %s", uu);
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
 
-                        if (isempty(uu))
-                                c->user = mfree(c->user);
-                        else if (free_and_strdup(&c->user, uu) < 0)
-                                return -ENOMEM;
+                        r = free_and_strdup(&c->user, empty_to_null(uu));
+                        if (r < 0)
+                                return r;
 
-                        unit_write_drop_in_private_format(u, mode, name, "User=%s", uu);
+                        unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "User=%s", uu);
                 }
 
                 return 1;
@@ -1052,14 +1115,13 @@ int bus_exec_context_set_transient_property(
                 if (!isempty(gg) && !valid_user_group_name_or_id(gg))
                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid group name: %s", gg);
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
 
-                        if (isempty(gg))
-                                c->group = mfree(c->group);
-                        else if (free_and_strdup(&c->group, gg) < 0)
-                                return -ENOMEM;
+                        r = free_and_strdup(&c->group, empty_to_null(gg));
+                        if (r < 0)
+                                return r;
 
-                        unit_write_drop_in_private_format(u, mode, name, "Group=%s", gg);
+                        unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "Group=%s", gg);
                 }
 
                 return 1;
@@ -1077,10 +1139,10 @@ int bus_exec_context_set_transient_property(
                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid supplementary group names");
                 }
 
-                if (mode != UNIT_CHECK) {
-                        if (strv_length(l) == 0) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
+                        if (strv_isempty(l)) {
                                 c->supplementary_groups = strv_free(c->supplementary_groups);
-                                unit_write_drop_in_private_format(u, mode, name, "%s=", name);
+                                unit_write_settingf(u, flags, name, "%s=", name);
                         } else {
                                 _cleanup_free_ char *joined = NULL;
 
@@ -1092,7 +1154,7 @@ int bus_exec_context_set_transient_property(
                                 if (!joined)
                                         return -ENOMEM;
 
-                                unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, joined);
+                                unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s", name, joined);
                         }
                 }
 
@@ -1105,14 +1167,14 @@ int bus_exec_context_set_transient_property(
                 if (r < 0)
                         return r;
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
 
                         if (isempty(id))
                                 c->syslog_identifier = mfree(c->syslog_identifier);
                         else if (free_and_strdup(&c->syslog_identifier, id) < 0)
                                 return -ENOMEM;
 
-                        unit_write_drop_in_private_format(u, mode, name, "SyslogIdentifier=%s", id);
+                        unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "SyslogIdentifier=%s", id);
                 }
 
                 return 1;
@@ -1126,9 +1188,9 @@ int bus_exec_context_set_transient_property(
                 if (!log_level_is_valid(level))
                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Log level value out of range");
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         c->syslog_priority = (c->syslog_priority & LOG_FACMASK) | level;
-                        unit_write_drop_in_private_format(u, mode, name, "SyslogLevel=%i", level);
+                        unit_write_settingf(u, flags, name, "SyslogLevel=%i", level);
                 }
 
                 return 1;
@@ -1142,12 +1204,104 @@ int bus_exec_context_set_transient_property(
                 if (!log_facility_unshifted_is_valid(facility))
                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Log facility value out of range");
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         c->syslog_priority = (facility << 3) | LOG_PRI(c->syslog_priority);
-                        unit_write_drop_in_private_format(u, mode, name, "SyslogFacility=%i", facility);
+                        unit_write_settingf(u, flags, name, "SyslogFacility=%i", facility);
+                }
+
+                return 1;
+
+        } else if (streq(name, "LogLevelMax")) {
+                int32_t level;
+
+                r = sd_bus_message_read(message, "i", &level);
+                if (r < 0)
+                        return r;
+
+                if (!log_level_is_valid(level))
+                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Maximum log level value out of range");
+
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
+                        c->log_level_max = level;
+                        unit_write_settingf(u, flags, name, "LogLevelMax=%i", level);
                 }
 
                 return 1;
+
+        } else if (streq(name, "LogExtraFields")) {
+                size_t n = 0;
+
+                r = sd_bus_message_enter_container(message, 'a', "ay");
+                if (r < 0)
+                        return r;
+
+                for (;;) {
+                        _cleanup_free_ void *copy = NULL;
+                        struct iovec *t;
+                        const char *eq;
+                        const void *p;
+                        size_t sz;
+
+                        /* Note that we expect a byte array for each field, instead of a string. That's because on the
+                         * lower-level journal fields can actually contain binary data and are not restricted to text,
+                         * and we should not "lose precision" in our types on the way. That said, I am pretty sure
+                         * actually encoding binary data as unit metadata is not a good idea. Hence we actually refuse
+                         * any actual binary data, and only accept UTF-8. This allows us to eventually lift this
+                         * limitation, should a good, valid usecase arise. */
+
+                        r = sd_bus_message_read_array(message, 'y', &p, &sz);
+                        if (r < 0)
+                                return r;
+                        if (r == 0)
+                                break;
+
+                        if (memchr(p, 0, sz))
+                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Journal field contains zero byte");
+
+                        eq = memchr(p, '=', sz);
+                        if (!eq)
+                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Journal field contains no '=' character");
+                        if (!journal_field_valid(p, eq - (const char*) p, false))
+                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Journal field invalid");
+
+                        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
+                                t = realloc_multiply(c->log_extra_fields, sizeof(struct iovec), c->n_log_extra_fields+1);
+                                if (!t)
+                                        return -ENOMEM;
+                                c->log_extra_fields = t;
+                        }
+
+                        copy = malloc(sz + 1);
+                        if (!copy)
+                                return -ENOMEM;
+
+                        memcpy(copy, p, sz);
+                        ((uint8_t*) copy)[sz] = 0;
+
+                        if (!utf8_is_valid(copy))
+                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Journal field is not valid UTF-8");
+
+                        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
+                                c->log_extra_fields[c->n_log_extra_fields++] = IOVEC_MAKE(copy, sz);
+                                unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS|UNIT_ESCAPE_C, name, "LogExtraFields=%s", (char*) copy);
+
+                                copy = NULL;
+                        }
+
+                        n++;
+                }
+
+                r = sd_bus_message_exit_container(message);
+                if (r < 0)
+                        return r;
+
+                if (!UNIT_WRITE_FLAGS_NOOP(flags) && n == 0) {
+                        exec_context_free_log_extra_fields(c);
+                        unit_write_setting(u, flags, name, "LogExtraFields=");
+                }
+
+                return 1;
+
         } else if (streq(name, "SecureBits")) {
                 int n;
 
@@ -1158,7 +1312,7 @@ int bus_exec_context_set_transient_property(
                 if (!secure_bits_is_valid(n))
                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid secure bits");
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         _cleanup_free_ char *str = NULL;
 
                         c->secure_bits = n;
@@ -1166,7 +1320,7 @@ int bus_exec_context_set_transient_property(
                         if (r < 0)
                                 return r;
 
-                        unit_write_drop_in_private_format(u, mode, name, "SecureBits=%s", str);
+                        unit_write_settingf(u, flags, name, "SecureBits=%s", str);
                 }
 
                 return 1;
@@ -1177,7 +1331,7 @@ int bus_exec_context_set_transient_property(
                 if (r < 0)
                         return r;
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         _cleanup_free_ char *str = NULL;
 
                         if (streq(name, "CapabilityBoundingSet"))
@@ -1189,7 +1343,7 @@ int bus_exec_context_set_transient_property(
                         if (r < 0)
                                 return r;
 
-                        unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, str);
+                        unit_write_settingf(u, flags, name, "%s=%s", name, str);
                 }
 
                 return 1;
@@ -1206,11 +1360,9 @@ int bus_exec_context_set_transient_property(
                 if (p == PERSONALITY_INVALID)
                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid personality");
 
-                if (mode != UNIT_CHECK) {
-                        _cleanup_free_ char *str = NULL;
-
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         c->personality = p;
-                        unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, s);
+                        unit_write_settingf(u, flags, name, "%s=%s", name, s);
                 }
 
                 return 1;
@@ -1219,7 +1371,7 @@ int bus_exec_context_set_transient_property(
 
         } else if (streq(name, "SystemCallFilter")) {
                 int whitelist;
-                _cleanup_strv_free_ char **l;
+                _cleanup_strv_free_ char **l = NULL;
 
                 r = sd_bus_message_enter_container(message, 'r', "bas");
                 if (r < 0)
@@ -1237,27 +1389,34 @@ int bus_exec_context_set_transient_property(
                 if (r < 0)
                         return r;
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         _cleanup_free_ char *joined = NULL;
 
-                        if (strv_length(l) == 0) {
+                        if (strv_isempty(l)) {
                                 c->syscall_whitelist = false;
-                                c->syscall_filter = set_free(c->syscall_filter);
+                                c->syscall_filter = hashmap_free(c->syscall_filter);
                         } else {
                                 char **s;
 
                                 c->syscall_whitelist = whitelist;
 
-                                r = set_ensure_allocated(&c->syscall_filter, NULL);
+                                r = hashmap_ensure_allocated(&c->syscall_filter, NULL);
                                 if (r < 0)
                                         return r;
 
                                 STRV_FOREACH(s, l) {
-                                        if (**s == '@') {
+                                        _cleanup_free_ char *n = NULL;
+                                        int e;
+
+                                        r = parse_syscall_and_errno(*s, &n, &e);
+                                        if (r < 0)
+                                                return r;
+
+                                        if (*n == '@') {
                                                 const SyscallFilterSet *set;
                                                 const char *i;
 
-                                                set = syscall_filter_set_find(*s);
+                                                set = syscall_filter_set_find(n);
                                                 if (!set)
                                                         return -EINVAL;
 
@@ -1268,7 +1427,7 @@ int bus_exec_context_set_transient_property(
                                                         if (id == __NR_SCMP_ERROR)
                                                                 return -EINVAL;
 
-                                                        r = set_put(c->address_families, INT_TO_PTR(id + 1));
+                                                        r = hashmap_put(c->syscall_filter, INT_TO_PTR(id + 1), INT_TO_PTR(e));
                                                         if (r < 0)
                                                                 return r;
                                                 }
@@ -1276,11 +1435,11 @@ int bus_exec_context_set_transient_property(
                                         } else {
                                                 int id;
 
-                                                id = seccomp_syscall_resolve_name(*s);
+                                                id = seccomp_syscall_resolve_name(n);
                                                 if (id == __NR_SCMP_ERROR)
                                                         return -EINVAL;
 
-                                                r = set_put(c->address_families, INT_TO_PTR(id + 1));
+                                                r = hashmap_put(c->syscall_filter, INT_TO_PTR(id + 1), INT_TO_PTR(e));
                                                 if (r < 0)
                                                         return r;
                                         }
@@ -1291,7 +1450,7 @@ int bus_exec_context_set_transient_property(
                         if (!joined)
                                 return -ENOMEM;
 
-                        unit_write_drop_in_private_format(u, mode, name, "SystemCallFilter=%s%s", whitelist ? "" : "~", joined);
+                        unit_write_settingf(u, flags, name, "SystemCallFilter=%s%s", whitelist ? "" : "~", joined);
                 }
 
                 return 1;
@@ -1303,10 +1462,10 @@ int bus_exec_context_set_transient_property(
                 if (r < 0)
                         return r;
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         _cleanup_free_ char *joined = NULL;
 
-                        if (strv_length(l) == 0)
+                        if (strv_isempty(l))
                                 c->syscall_archs = set_free(c->syscall_archs);
                         else {
                                 char **s;
@@ -1333,34 +1492,32 @@ int bus_exec_context_set_transient_property(
                         if (!joined)
                                 return -ENOMEM;
 
-                        unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, joined);
+                        unit_write_settingf(u, flags, name, "%s=%s", name, joined);
                 }
 
                 return 1;
 
         } else if (streq(name, "SystemCallErrorNumber")) {
                 int32_t n;
-                const char *str;
 
                 r = sd_bus_message_read(message, "i", &n);
                 if (r < 0)
                         return r;
 
-                str = errno_to_name(n);
-                if (!str)
+                if (n <= 0 || n > ERRNO_MAX)
                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid SystemCallErrorNumber");
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         c->syscall_errno = n;
 
-                        unit_write_drop_in_private_format(u, mode, name, "SystemCallErrorNumber=%s", str);
+                        unit_write_settingf(u, flags, name, "SystemCallErrorNumber=%d", n);
                 }
 
                 return 1;
 
         } else if (streq(name, "RestrictAddressFamilies")) {
                 int whitelist;
-                _cleanup_strv_free_ char **l;
+                _cleanup_strv_free_ char **l = NULL;
 
                 r = sd_bus_message_enter_container(message, 'r', "bas");
                 if (r < 0)
@@ -1378,10 +1535,10 @@ int bus_exec_context_set_transient_property(
                 if (r < 0)
                         return r;
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         _cleanup_free_ char *joined = NULL;
 
-                        if (strv_length(l) == 0) {
+                        if (strv_isempty(l)) {
                                 c->address_families_whitelist = false;
                                 c->address_families = set_free(c->address_families);
                         } else {
@@ -1410,7 +1567,7 @@ int bus_exec_context_set_transient_property(
                         if (!joined)
                                 return -ENOMEM;
 
-                        unit_write_drop_in_private_format(u, mode, name, "RestrictAddressFamilies=%s%s", whitelist ? "" : "~", joined);
+                        unit_write_settingf(u, flags, name, "RestrictAddressFamilies=%s%s", whitelist ? "" : "~", joined);
                 }
 
                 return 1;
@@ -1426,7 +1583,7 @@ int bus_exec_context_set_transient_property(
                 if (!sched_policy_is_valid(n))
                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid CPU scheduling policy");
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         _cleanup_free_ char *str = NULL;
 
                         c->cpu_sched_policy = n;
@@ -1434,7 +1591,7 @@ int bus_exec_context_set_transient_property(
                         if (r < 0)
                                 return r;
 
-                        unit_write_drop_in_private_format(u, mode, name, "CPUSchedulingPolicy=%s", str);
+                        unit_write_settingf(u, flags, name, "CPUSchedulingPolicy=%s", str);
                 }
 
                 return 1;
@@ -1449,9 +1606,9 @@ int bus_exec_context_set_transient_property(
                 if (!ioprio_priority_is_valid(n))
                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid CPU scheduling priority");
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         c->cpu_sched_priority = n;
-                        unit_write_drop_in_private_format(u, mode, name, "CPUSchedulingPriority=%i", n);
+                        unit_write_settingf(u, flags, name, "CPUSchedulingPriority=%i", n);
                 }
 
                 return 1;
@@ -1464,31 +1621,31 @@ int bus_exec_context_set_transient_property(
                 if (r < 0)
                         return r;
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         if (n == 0) {
-                                c->cpuset = mfree(c->cpuset);
-                                unit_write_drop_in_private_format(u, mode, name, "%s=", name);
+                                c->cpuset = cpu_set_mfree(c->cpuset);
+                                c->cpuset_ncpus = 0;
+                                unit_write_settingf(u, flags, name, "%s=", name);
                         } else {
                                 _cleanup_free_ char *str = NULL;
-                                uint8_t *l;
-                                size_t allocated = 0, len = 0, i;
+                                size_t allocated = 0, len = 0, i, ncpus;
 
-                                c->cpuset = (cpu_set_t*) memdup(a, sizeof(cpu_set_t) * n);
-                                if (c->cpuset)
-                                        return -ENOMEM;
+                                ncpus = CPU_SIZE_TO_NUM(n);
 
-                                l = (uint8_t*) a;
-                                for (i = 0; i < n; i++) {
+                                for (i = 0; i < ncpus; i++) {
                                         _cleanup_free_ char *p = NULL;
                                         size_t add;
 
-                                        r = asprintf(&p, "%hhi", l[i]);
+                                        if (!CPU_ISSET_S(i, n, (cpu_set_t*) a))
+                                                continue;
+
+                                        r = asprintf(&p, "%zu", i);
                                         if (r < 0)
                                                 return -ENOMEM;
 
                                         add = strlen(p);
 
-                                        if (GREEDY_REALLOC(str, allocated, len + add + 2))
+                                        if (!GREEDY_REALLOC(str, allocated, len + add + 2))
                                                 return -ENOMEM;
 
                                         strcpy(mempcpy(str + len, p, add), " ");
@@ -1498,7 +1655,26 @@ int bus_exec_context_set_transient_property(
                                 if (len != 0)
                                         str[len - 1] = '\0';
 
-                                unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, str);
+                                if (!c->cpuset || c->cpuset_ncpus < ncpus) {
+                                        cpu_set_t *cpuset;
+
+                                        cpuset = CPU_ALLOC(ncpus);
+                                        if (!cpuset)
+                                                return -ENOMEM;
+
+                                        CPU_ZERO_S(n, cpuset);
+                                        if (c->cpuset) {
+                                                CPU_OR_S(CPU_ALLOC_SIZE(c->cpuset_ncpus), cpuset, c->cpuset, (cpu_set_t*) a);
+                                                CPU_FREE(c->cpuset);
+                                        } else
+                                                CPU_OR_S(n, cpuset, cpuset, (cpu_set_t*) a);
+
+                                        c->cpuset = cpuset;
+                                        c->cpuset_ncpus = ncpus;
+                                } else
+                                        CPU_OR_S(n, c->cpuset, c->cpuset, (cpu_set_t*) a);
+
+                                unit_write_settingf(u, flags, name, "%s=%s", name, str);
                         }
                 }
 
@@ -1513,9 +1689,9 @@ int bus_exec_context_set_transient_property(
                 if (!nice_is_valid(n))
                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Nice value out of range");
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         c->nice = n;
-                        unit_write_drop_in_private_format(u, mode, name, "Nice=%i", n);
+                        unit_write_settingf(u, flags, name, "Nice=%i", n);
                 }
 
                 return 1;
@@ -1530,7 +1706,7 @@ int bus_exec_context_set_transient_property(
                 if (!ioprio_class_is_valid(q))
                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid IO scheduling class: %i", q);
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         _cleanup_free_ char *s = NULL;
 
                         r = ioprio_class_to_string_alloc(q, &s);
@@ -1540,7 +1716,7 @@ int bus_exec_context_set_transient_property(
                         c->ioprio = IOPRIO_PRIO_VALUE(q, IOPRIO_PRIO_DATA(c->ioprio));
                         c->ioprio_set = true;
 
-                        unit_write_drop_in_private_format(u, mode, name, "IOSchedulingClass=%s", s);
+                        unit_write_settingf(u, flags, name, "IOSchedulingClass=%s", s);
                 }
 
                 return 1;
@@ -1555,11 +1731,11 @@ int bus_exec_context_set_transient_property(
                 if (!ioprio_priority_is_valid(p))
                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid IO scheduling priority: %i", p);
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         c->ioprio = IOPRIO_PRIO_VALUE(IOPRIO_PRIO_CLASS(c->ioprio), p);
                         c->ioprio_set = true;
 
-                        unit_write_drop_in_private_format(u, mode, name, "IOSchedulingPriority=%i", p);
+                        unit_write_settingf(u, flags, name, "IOSchedulingPriority=%i", p);
                 }
 
                 return 1;
@@ -1574,7 +1750,7 @@ int bus_exec_context_set_transient_property(
                 if (!path_is_absolute(s))
                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s takes an absolute path", name);
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         if (streq(name, "TTYPath"))
                                 r = free_and_strdup(&c->tty_path, s);
                         else if (streq(name, "RootImage"))
@@ -1586,7 +1762,7 @@ int bus_exec_context_set_transient_property(
                         if (r < 0)
                                 return r;
 
-                        unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, s);
+                        unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s", name, s);
                 }
 
                 return 1;
@@ -1608,7 +1784,7 @@ int bus_exec_context_set_transient_property(
                 if (!streq(s, "~") && !path_is_absolute(s))
                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "WorkingDirectory= expects an absolute path or '~'");
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         if (streq(s, "~")) {
                                 c->working_directory = mfree(c->working_directory);
                                 c->working_directory_home = true;
@@ -1621,7 +1797,7 @@ int bus_exec_context_set_transient_property(
                         }
 
                         c->working_directory_missing_ok = missing_ok;
-                        unit_write_drop_in_private_format(u, mode, name, "WorkingDirectory=%s%s", missing_ok ? "-" : "", s);
+                        unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "WorkingDirectory=%s%s", missing_ok ? "-" : "", s);
                 }
 
                 return 1;
@@ -1638,10 +1814,10 @@ int bus_exec_context_set_transient_property(
                 if (p < 0)
                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid standard input name");
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         c->std_input = p;
 
-                        unit_write_drop_in_private_format(u, mode, name, "StandardInput=%s", exec_input_to_string(p));
+                        unit_write_settingf(u, flags, name, "StandardInput=%s", exec_input_to_string(p));
                 }
 
                 return 1;
@@ -1658,10 +1834,10 @@ int bus_exec_context_set_transient_property(
                 if (p < 0)
                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid standard output name");
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         c->std_output = p;
 
-                        unit_write_drop_in_private_format(u, mode, name, "StandardOutput=%s", exec_output_to_string(p));
+                        unit_write_settingf(u, flags, name, "StandardOutput=%s", exec_output_to_string(p));
                 }
 
                 return 1;
@@ -1678,10 +1854,10 @@ int bus_exec_context_set_transient_property(
                 if (p < 0)
                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid standard error name");
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         c->std_error = p;
 
-                        unit_write_drop_in_private_format(u, mode, name, "StandardError=%s", exec_output_to_string(p));
+                        unit_write_settingf(u, flags, name, "StandardError=%s", exec_output_to_string(p));
                 }
 
                 return 1;
@@ -1694,28 +1870,125 @@ int bus_exec_context_set_transient_property(
                 if (r < 0)
                         return r;
 
-                if (!fdname_is_valid(s))
+                if (isempty(s))
+                        s = NULL;
+                else if (!fdname_is_valid(s))
                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid file descriptor name");
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
+
                         if (streq(name, "StandardInputFileDescriptorName")) {
-                                c->std_input = EXEC_INPUT_NAMED_FD;
-                                r = free_and_strdup(&c->stdio_fdname[STDIN_FILENO], s);
+                                r = free_and_strdup(c->stdio_fdname + STDIN_FILENO, s);
                                 if (r < 0)
                                         return r;
-                                unit_write_drop_in_private_format(u, mode, name, "StandardInput=fd:%s", s);
+
+                                c->std_input = EXEC_INPUT_NAMED_FD;
+                                unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardInput=fd:%s", exec_context_fdname(c, STDIN_FILENO));
+
                         } else if (streq(name, "StandardOutputFileDescriptorName")) {
+                                r = free_and_strdup(c->stdio_fdname + STDOUT_FILENO, s);
+                                if (r < 0)
+                                        return r;
+
                                 c->std_output = EXEC_OUTPUT_NAMED_FD;
-                                r = free_and_strdup(&c->stdio_fdname[STDOUT_FILENO], s);
+                                unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardOutput=fd:%s", exec_context_fdname(c, STDOUT_FILENO));
+
+                        } else {
+                                assert(streq(name, "StandardErrorFileDescriptorName"));
+
+                                r = free_and_strdup(&c->stdio_fdname[STDERR_FILENO], s);
                                 if (r < 0)
                                         return r;
-                                unit_write_drop_in_private_format(u, mode, name, "StandardOutput=fd:%s", s);
-                        } else if (streq(name, "StandardErrorFileDescriptorName")) {
+
                                 c->std_error = EXEC_OUTPUT_NAMED_FD;
-                                r = free_and_strdup(&c->stdio_fdname[STDERR_FILENO], s);
+                                unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardError=fd:%s", exec_context_fdname(c, STDERR_FILENO));
+                        }
+                }
+
+                return 1;
+
+        } else if (STR_IN_SET(name, "StandardInputFile", "StandardOutputFile", "StandardErrorFile")) {
+                const char *s;
+
+                r = sd_bus_message_read(message, "s", &s);
+                if (r < 0)
+                        return r;
+
+                if (!path_is_absolute(s))
+                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not absolute", s);
+                if (!path_is_normalized(s))
+                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not normalized", s);
+
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
+
+                        if (streq(name, "StandardInputFile")) {
+                                r = free_and_strdup(&c->stdio_file[STDIN_FILENO], s);
                                 if (r < 0)
                                         return r;
-                                unit_write_drop_in_private_format(u, mode, name, "StandardError=fd:%s", s);
+
+                                c->std_input = EXEC_INPUT_FILE;
+                                unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardInput=file:%s", s);
+
+                        } else if (streq(name, "StandardOutputFile")) {
+                                r = free_and_strdup(&c->stdio_file[STDOUT_FILENO], s);
+                                if (r < 0)
+                                        return r;
+
+                                c->std_output = EXEC_OUTPUT_FILE;
+                                unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardOutput=file:%s", s);
+
+                        } else {
+                                assert(streq(name, "StandardErrorFile"));
+
+                                r = free_and_strdup(&c->stdio_file[STDERR_FILENO], s);
+                                if (r < 0)
+                                        return r;
+
+                                c->std_error = EXEC_OUTPUT_FILE;
+                                unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardError=file:%s", s);
+                        }
+                }
+
+                return 1;
+
+        } else if (streq(name, "StandardInputData")) {
+                const void *p;
+                size_t sz;
+
+                r = sd_bus_message_read_array(message, 'y', &p, &sz);
+                if (r < 0)
+                        return r;
+
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
+                        _cleanup_free_ char *encoded = NULL;
+
+                        if (sz == 0) {
+                                c->stdin_data = mfree(c->stdin_data);
+                                c->stdin_data_size = 0;
+
+                                unit_write_settingf(u, flags, name, "StandardInputData=");
+                        } else {
+                                void *q;
+                                ssize_t n;
+
+                                if (c->stdin_data_size + sz < c->stdin_data_size || /* check for overflow */
+                                    c->stdin_data_size + sz > EXEC_STDIN_DATA_MAX)
+                                        return -E2BIG;
+
+                                n = base64mem(p, sz, &encoded);
+                                if (n < 0)
+                                        return (int) n;
+
+                                q = realloc(c->stdin_data, c->stdin_data_size + sz);
+                                if (!q)
+                                        return -ENOMEM;
+
+                                memcpy((uint8_t*) q + c->stdin_data_size, p, sz);
+
+                                c->stdin_data = q;
+                                c->stdin_data_size += sz;
+
+                                unit_write_settingf(u, flags, name, "StandardInputData=%s", encoded);
                         }
                 }
 
@@ -1734,7 +2007,7 @@ int bus_exec_context_set_transient_property(
                 if (r < 0)
                         return r;
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         if (streq(name, "IgnoreSIGPIPE"))
                                 c->ignore_sigpipe = b;
                         else if (streq(name, "TTYVHangup"))
@@ -1778,7 +2051,7 @@ int bus_exec_context_set_transient_property(
                         else if (streq(name, "LockPersonality"))
                                 c->lock_personality = b;
 
-                        unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, yes_no(b));
+                        unit_write_settingf(u, flags, name, "%s=%s", name, yes_no(b));
                 }
 
                 return 1;
@@ -1790,13 +2063,13 @@ int bus_exec_context_set_transient_property(
                 if (r < 0)
                         return r;
 
-                if (mode != UNIT_CHECK) {
-                        if (isempty(id))
-                                c->utmp_id = mfree(c->utmp_id);
-                        else if (free_and_strdup(&c->utmp_id, id) < 0)
-                                return -ENOMEM;
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
 
-                        unit_write_drop_in_private_format(u, mode, name, "UtmpIdentifier=%s", strempty(id));
+                        r = free_and_strdup(&c->utmp_id, empty_to_null(id));
+                        if (r < 0)
+                                return r;
+
+                        unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "UtmpIdentifier=%s", strempty(id));
                 }
 
                 return 1;
@@ -1813,10 +2086,10 @@ int bus_exec_context_set_transient_property(
                 if (m < 0)
                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid utmp mode");
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         c->utmp_mode = m;
 
-                        unit_write_drop_in_private_format(u, mode, name, "UtmpMode=%s", exec_utmp_mode_to_string(m));
+                        unit_write_settingf(u, flags, name, "UtmpMode=%s", exec_utmp_mode_to_string(m));
                 }
 
                 return 1;
@@ -1828,53 +2101,48 @@ int bus_exec_context_set_transient_property(
                 if (r < 0)
                         return r;
 
-                if (mode != UNIT_CHECK) {
-                        if (isempty(n))
-                                c->pam_name = mfree(c->pam_name);
-                        else if (free_and_strdup(&c->pam_name, n) < 0)
-                                return -ENOMEM;
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
 
-                        unit_write_drop_in_private_format(u, mode, name, "PAMName=%s", strempty(n));
+                        r = free_and_strdup(&c->pam_name, empty_to_null(n));
+                        if (r < 0)
+                                return r;
+
+                        unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "PAMName=%s", strempty(n));
                 }
 
                 return 1;
 
         } else if (streq(name, "Environment")) {
 
-                _cleanup_strv_free_ char **l = NULL, **q = NULL;
+                _cleanup_strv_free_ char **l = NULL;
 
                 r = sd_bus_message_read_strv(message, &l);
                 if (r < 0)
                         return r;
 
-                r = unit_full_printf_strv(u, l, &q);
-                if (r < 0)
-                        return r;
-
-                if (!strv_env_is_valid(q))
+                if (!strv_env_is_valid(l))
                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment block.");
 
-                if (mode != UNIT_CHECK) {
-                        if (strv_length(q) == 0) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
+                        if (strv_isempty(l)) {
                                 c->environment = strv_free(c->environment);
-                                unit_write_drop_in_private_format(u, mode, name, "Environment=");
+                                unit_write_setting(u, flags, name, "Environment=");
                         } else {
                                 _cleanup_free_ char *joined = NULL;
                                 char **e;
 
-                                e = strv_env_merge(2, c->environment, q);
+                                joined = unit_concat_strv(l, UNIT_ESCAPE_SPECIFIERS|UNIT_ESCAPE_C);
+                                if (!joined)
+                                        return -ENOMEM;
+
+                                e = strv_env_merge(2, c->environment, l);
                                 if (!e)
                                         return -ENOMEM;
 
                                 strv_free(c->environment);
                                 c->environment = e;
 
-                                /* We write just the new settings out to file, with unresolved specifiers */
-                                joined = strv_join_quoted(l);
-                                if (!joined)
-                                        return -ENOMEM;
-
-                                unit_write_drop_in_private_format(u, mode, name, "Environment=%s", joined);
+                                unit_write_settingf(u, flags, name, "Environment=%s", joined);
                         }
                 }
 
@@ -1882,40 +2150,35 @@ int bus_exec_context_set_transient_property(
 
         } else if (streq(name, "UnsetEnvironment")) {
 
-                _cleanup_strv_free_ char **l = NULL, **q = NULL;
+                _cleanup_strv_free_ char **l = NULL;
 
                 r = sd_bus_message_read_strv(message, &l);
                 if (r < 0)
                         return r;
 
-                r = unit_full_printf_strv(u, l, &q);
-                if (r < 0)
-                        return r;
-
-                if (!strv_env_name_or_assignment_is_valid(q))
+                if (!strv_env_name_or_assignment_is_valid(l))
                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid UnsetEnvironment= list.");
 
-                if (mode != UNIT_CHECK) {
-                        if (strv_length(q) == 0) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
+                        if (strv_isempty(l)) {
                                 c->unset_environment = strv_free(c->unset_environment);
-                                unit_write_drop_in_private_format(u, mode, name, "UnsetEnvironment=");
+                                unit_write_setting(u, flags, name, "UnsetEnvironment=");
                         } else {
                                 _cleanup_free_ char *joined = NULL;
                                 char **e;
 
-                                e = strv_env_merge(2, c->unset_environment, q);
+                                joined = unit_concat_strv(l, UNIT_ESCAPE_SPECIFIERS|UNIT_ESCAPE_C);
+                                if (!joined)
+                                        return -ENOMEM;
+
+                                e = strv_env_merge(2, c->unset_environment, l);
                                 if (!e)
                                         return -ENOMEM;
 
                                 strv_free(c->unset_environment);
                                 c->unset_environment = e;
 
-                                /* We write just the new settings out to file, with unresolved specifiers */
-                                joined = strv_join_quoted(l);
-                                if (!joined)
-                                        return -ENOMEM;
-
-                                unit_write_drop_in_private_format(u, mode, name, "UnsetEnvironment=%s", joined);
+                                unit_write_settingf(u, flags, name, "UnsetEnvironment=%s", joined);
                         }
                 }
 
@@ -1929,9 +2192,9 @@ int bus_exec_context_set_transient_property(
                 if (r < 0)
                         return r;
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         c->timer_slack_nsec = n;
-                        unit_write_drop_in_private_format(u, mode, name, "TimerSlackNSec=" NSEC_FMT, n);
+                        unit_write_settingf(u, flags, name, "TimerSlackNSec=" NSEC_FMT, n);
                 }
 
                 return 1;
@@ -1946,10 +2209,10 @@ int bus_exec_context_set_transient_property(
                 if (!oom_score_adjust_is_valid(oa))
                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "OOM score adjust value out of range");
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         c->oom_score_adjust = oa;
                         c->oom_score_adjust_set = true;
-                        unit_write_drop_in_private_format(u, mode, name, "OOMScoreAdjust=%i", oa);
+                        unit_write_settingf(u, flags, name, "OOMScoreAdjust=%i", oa);
                 }
 
                 return 1;
@@ -1970,8 +2233,19 @@ int bus_exec_context_set_transient_property(
                 if (!f)
                         return -ENOMEM;
 
-                STRV_FOREACH(i, c->environment_files)
-                        fprintf(f, "EnvironmentFile=%s", *i);
+                (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
+
+                fputs("EnvironmentFile=\n", f);
+
+                STRV_FOREACH(i, c->environment_files) {
+                        _cleanup_free_ char *q = NULL;
+
+                        q = specifier_escape(*i);
+                        if (!q)
+                                return -ENOMEM;
+
+                        fprintf(f, "EnvironmentFile=%s\n", q);
+                }
 
                 while ((r = sd_bus_message_enter_container(message, 'r', "sb")) > 0) {
                         const char *path;
@@ -1988,14 +2262,21 @@ int bus_exec_context_set_transient_property(
                         if (!path_is_absolute(path))
                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not absolute.", path);
 
-                        if (mode != UNIT_CHECK) {
+                        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
+                                _cleanup_free_ char *q = NULL;
                                 char *buf;
 
                                 buf = strjoin(b ? "-" : "", path);
                                 if (!buf)
                                         return -ENOMEM;
 
-                                fprintf(f, "EnvironmentFile=%s", buf);
+                                q = specifier_escape(buf);
+                                if (!q) {
+                                        free(buf);
+                                        return -ENOMEM;
+                                }
+
+                                fprintf(f, "EnvironmentFile=%s\n", q);
 
                                 r = strv_consume(&l, buf);
                                 if (r < 0)
@@ -2013,16 +2294,16 @@ int bus_exec_context_set_transient_property(
                 if (r < 0)
                         return r;
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         if (strv_isempty(l)) {
                                 c->environment_files = strv_free(c->environment_files);
-                                unit_write_drop_in_private(u, mode, name, "EnvironmentFile=");
+                                unit_write_setting(u, flags, name, "EnvironmentFile=");
                         } else {
                                 r = strv_extend_strv(&c->environment_files, l, true);
                                 if (r < 0)
                                         return r;
 
-                                unit_write_drop_in_private(u, mode, name, joined);
+                                unit_write_setting(u, flags, name, joined);
                         }
                 }
 
@@ -2030,36 +2311,32 @@ int bus_exec_context_set_transient_property(
 
         } else if (streq(name, "PassEnvironment")) {
 
-                _cleanup_strv_free_ char **l = NULL, **q = NULL;
+                _cleanup_strv_free_ char **l = NULL;
 
                 r = sd_bus_message_read_strv(message, &l);
                 if (r < 0)
                         return r;
 
-                r = unit_full_printf_strv(u, l, &q);
-                if (r < 0)
-                        return r;
-
-                if (!strv_env_name_is_valid(q))
+                if (!strv_env_name_is_valid(l))
                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid PassEnvironment= block.");
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         if (strv_isempty(l)) {
                                 c->pass_environment = strv_free(c->pass_environment);
-                                unit_write_drop_in_private_format(u, mode, name, "PassEnvironment=");
+                                unit_write_setting(u, flags, name, "PassEnvironment=");
                         } else {
                                 _cleanup_free_ char *joined = NULL;
 
-                                r = strv_extend_strv(&c->pass_environment, q, true);
+                                r = strv_extend_strv(&c->pass_environment, l, true);
                                 if (r < 0)
                                         return r;
 
                                 /* We write just the new settings out to file, with unresolved specifiers. */
-                                joined = strv_join_quoted(l);
+                                joined = unit_concat_strv(l, UNIT_ESCAPE_SPECIFIERS);
                                 if (!joined)
                                         return -ENOMEM;
 
-                                unit_write_drop_in_private_format(u, mode, name, "PassEnvironment=%s", joined);
+                                unit_write_settingf(u, flags, name, "PassEnvironment=%s", joined);
                         }
                 }
 
@@ -2088,9 +2365,7 @@ int bus_exec_context_set_transient_property(
                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s", name);
                 }
 
-                if (mode != UNIT_CHECK) {
-                        _cleanup_free_ char *joined = NULL;
-
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         if (STR_IN_SET(name, "ReadWriteDirectories", "ReadWritePaths"))
                                 dirs = &c->read_write_paths;
                         else if (STR_IN_SET(name, "ReadOnlyDirectories", "ReadOnlyPaths"))
@@ -2098,21 +2373,22 @@ int bus_exec_context_set_transient_property(
                         else /* "InaccessiblePaths" */
                                 dirs = &c->inaccessible_paths;
 
-                        if (strv_length(l) == 0) {
+                        if (strv_isempty(l)) {
                                 *dirs = strv_free(*dirs);
-                                unit_write_drop_in_private_format(u, mode, name, "%s=", name);
+                                unit_write_settingf(u, flags, name, "%s=", name);
                         } else {
-                                r = strv_extend_strv(dirs, l, true);
-                                if (r < 0)
-                                        return -ENOMEM;
+                                _cleanup_free_ char *joined = NULL;
 
-                                joined = strv_join_quoted(*dirs);
+                                joined = unit_concat_strv(l, UNIT_ESCAPE_SPECIFIERS);
                                 if (!joined)
                                         return -ENOMEM;
 
-                                unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, joined);
-                        }
+                                r = strv_extend_strv(dirs, l, true);
+                                if (r < 0)
+                                        return -ENOMEM;
 
+                                unit_write_settingf(u, flags, name, "%s=%s", name, joined);
+                        }
                 }
 
                 return 1;
@@ -2136,9 +2412,9 @@ int bus_exec_context_set_transient_property(
                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Failed to parse protect system value");
                 }
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         c->protect_system = ps;
-                        unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, s);
+                        unit_write_settingf(u, flags, name, "%s=%s", name, s);
                 }
 
                 return 1;
@@ -2162,9 +2438,9 @@ int bus_exec_context_set_transient_property(
                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Failed to parse protect home value");
                 }
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         c->protect_home = ph;
-                        unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, s);
+                        unit_write_settingf(u, flags, name, "%s=%s", name, s);
                 }
 
                 return 1;
@@ -2182,10 +2458,10 @@ int bus_exec_context_set_transient_property(
                 if (m < 0)
                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid keyring mode");
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         c->keyring_mode = m;
 
-                        unit_write_drop_in_private_format(u, mode, name, "KeyringMode=%s", exec_keyring_mode_to_string(m));
+                        unit_write_settingf(u, flags, name, "KeyringMode=%s", exec_keyring_mode_to_string(m));
                 }
 
                 return 1;
@@ -2202,10 +2478,10 @@ int bus_exec_context_set_transient_property(
                 if (m < 0)
                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid preserve mode");
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         c->runtime_directory_preserve_mode = m;
 
-                        unit_write_drop_in_private_format(u, mode, name, "RuntimeDirectoryPreserve=%s", exec_preserve_mode_to_string(m));
+                        unit_write_settingf(u, flags, name, "RuntimeDirectoryPreserve=%s", exec_preserve_mode_to_string(m));
                 }
 
                 return 1;
@@ -2217,7 +2493,7 @@ int bus_exec_context_set_transient_property(
                 if (r < 0)
                         return r;
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         ExecDirectoryType i;
 
                         if (streq(name, "UMask"))
@@ -2229,7 +2505,7 @@ int bus_exec_context_set_transient_property(
                                                 break;
                                         }
 
-                        unit_write_drop_in_private_format(u, mode, name, "%s=%040o", name, m);
+                        unit_write_settingf(u, flags, name, "%s=%040o", name, m);
                 }
 
                 return 1;
@@ -2243,12 +2519,11 @@ int bus_exec_context_set_transient_property(
                         return r;
 
                 STRV_FOREACH(p, l) {
-                        if (!path_is_safe(*p) || path_is_absolute(*p))
+                        if (!path_is_normalized(*p) || path_is_absolute(*p))
                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= path is not valid: %s", name, *p);
                 }
 
-                if (mode != UNIT_CHECK) {
-                        _cleanup_free_ char *joined = NULL;
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         char ***dirs = NULL;
                         ExecDirectoryType i;
 
@@ -2262,17 +2537,19 @@ int bus_exec_context_set_transient_property(
 
                         if (strv_isempty(l)) {
                                 *dirs = strv_free(*dirs);
-                                unit_write_drop_in_private_format(u, mode, name, "%s=", name);
+                                unit_write_settingf(u, flags, name, "%s=", name);
                         } else {
+                                _cleanup_free_ char *joined = NULL;
+
                                 r = strv_extend_strv(dirs, l, true);
                                 if (r < 0)
                                         return -ENOMEM;
 
-                                joined = strv_join_quoted(*dirs);
+                                joined = unit_concat_strv(l, UNIT_ESCAPE_SPECIFIERS);
                                 if (!joined)
                                         return -ENOMEM;
 
-                                unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, joined);
+                                unit_write_settingf(u, flags, name, "%s=%s", name, joined);
                         }
                 }
 
@@ -2284,13 +2561,13 @@ int bus_exec_context_set_transient_property(
                 if (r < 0)
                         return r;
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         if (isempty(s))
                                 c->selinux_context = mfree(c->selinux_context);
                         else if (free_and_strdup(&c->selinux_context, s) < 0)
                                 return -ENOMEM;
 
-                        unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, strempty(s));
+                        unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s", name, strempty(s));
                 }
 
                 return 1;
@@ -2307,7 +2584,7 @@ int bus_exec_context_set_transient_property(
                 if (r < 0)
                         return r;
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         char **p;
                         bool *b;
 
@@ -2328,45 +2605,45 @@ int bus_exec_context_set_transient_property(
                                 *b = ignore;
                         }
 
-                        unit_write_drop_in_private_format(u, mode, name, "%s=%s%s", name, ignore ? "-" : "", strempty(s));
+                        unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s%s", name, ignore ? "-" : "", strempty(s));
                 }
 
                 return 1;
 
         } else if (streq(name, "RestrictNamespaces")) {
-                uint64_t flags;
+                uint64_t rf;
 
-                r = sd_bus_message_read(message, "t", &flags);
+                r = sd_bus_message_read(message, "t", &rf);
                 if (r < 0)
                         return r;
-                if ((flags & NAMESPACE_FLAGS_ALL) != flags)
+                if ((rf & NAMESPACE_FLAGS_ALL) != rf)
                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown namespace types");
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         _cleanup_free_ char *s = NULL;
 
-                        r = namespace_flag_to_string_many(flags, &s);
+                        r = namespace_flag_to_string_many(rf, &s);
                         if (r < 0)
                                 return r;
 
-                        c->restrict_namespaces = flags;
-                        unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, s);
+                        c->restrict_namespaces = rf;
+                        unit_write_settingf(u, flags, name, "%s=%s", name, s);
                 }
 
                 return 1;
         } else if (streq(name, "MountFlags")) {
-                uint64_t flags;
+                uint64_t fl;
 
-                r = sd_bus_message_read(message, "t", &flags);
+                r = sd_bus_message_read(message, "t", &fl);
                 if (r < 0)
                         return r;
-                if (!IN_SET(flags, 0, MS_SHARED, MS_PRIVATE, MS_SLAVE))
+                if (!IN_SET(fl, 0, MS_SHARED, MS_PRIVATE, MS_SLAVE))
                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown mount propagation flags");
 
-                if (mode != UNIT_CHECK) {
-                        c->mount_flags = flags;
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
+                        c->mount_flags = fl;
 
-                        unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, mount_propagation_flags_to_string(flags));
+                        unit_write_settingf(u, flags, name, "%s=%s", name, mount_propagation_flags_to_string(fl));
                 }
 
                 return 1;
@@ -2397,7 +2674,7 @@ int bus_exec_context_set_transient_property(
                         if (!IN_SET(mount_flags, 0, MS_REC))
                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown mount flags.");
 
-                        if (mode != UNIT_CHECK) {
+                        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                                 r = bind_mount_add(&c->bind_mounts, &c->n_bind_mounts,
                                                    &(BindMount) {
                                                            .source = strdup(source),
@@ -2409,8 +2686,8 @@ int bus_exec_context_set_transient_property(
                                 if (r < 0)
                                         return r;
 
-                                unit_write_drop_in_private_format(
-                                                u, mode, name,
+                                unit_write_settingf(
+                                                u, flags|UNIT_ESCAPE_SPECIFIERS, name,
                                                 "%s=%s%s:%s:%s",
                                                 name,
                                                 ignore_enoent ? "-" : "",
@@ -2432,6 +2709,8 @@ int bus_exec_context_set_transient_property(
                         bind_mount_free_many(c->bind_mounts, c->n_bind_mounts);
                         c->bind_mounts = NULL;
                         c->n_bind_mounts = 0;
+
+                        unit_write_settingf(u, flags, name, "%s=", name);
                 }
 
                 return 1;
@@ -2468,7 +2747,7 @@ int bus_exec_context_set_transient_property(
                                 return -ERANGE;
                 }
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         _cleanup_free_ char *f = NULL;
                         struct rlimit nl;
 
@@ -2498,7 +2777,7 @@ int bus_exec_context_set_transient_property(
                                         return -ENOMEM;
                         }
 
-                        unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, f);
+                        unit_write_settingf(u, flags, name, "%s=%s", name, f);
                 }
 
                 return 1;
index d0aa8e1..f30f077 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -42,4 +43,4 @@ int bus_property_get_exec_output(sd_bus *bus, const char *path, const char *inte
 int bus_property_get_exec_command(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *ret_error);
 int bus_property_get_exec_command_list(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *ret_error);
 
-int bus_exec_context_set_transient_property(Unit *u, ExecContext *c, const char *name, sd_bus_message *message, UnitSetPropertiesMode mode, sd_bus_error *error);
+int bus_exec_context_set_transient_property(Unit *u, ExecContext *c, const char *name, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
index effc45d..0802fc9 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index a4366a0..65d8781 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 8c65be6..bf3bbb2 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -38,7 +39,7 @@ int bus_kill_context_set_transient_property(
                 KillContext *c,
                 const char *name,
                 sd_bus_message *message,
-                UnitSetPropertiesMode mode,
+                UnitWriteFlags flags,
                 sd_bus_error *error) {
 
         int r;
@@ -48,6 +49,8 @@ int bus_kill_context_set_transient_property(
         assert(name);
         assert(message);
 
+        flags |= UNIT_PRIVATE;
+
         if (streq(name, "KillMode")) {
                 const char *m;
                 KillMode k;
@@ -60,10 +63,10 @@ int bus_kill_context_set_transient_property(
                 if (k < 0)
                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Kill mode '%s' not known.", m);
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         c->kill_mode = k;
 
-                        unit_write_drop_in_private_format(u, mode, name, "KillMode=%s", kill_mode_to_string(k));
+                        unit_write_settingf(u, flags, name, "KillMode=%s", kill_mode_to_string(k));
                 }
 
                 return 1;
@@ -78,10 +81,10 @@ int bus_kill_context_set_transient_property(
                 if (!SIGNAL_VALID(sig))
                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Signal %i out of range", sig);
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         c->kill_signal = sig;
 
-                        unit_write_drop_in_private_format(u, mode, name, "KillSignal=%s", signal_to_string(sig));
+                        unit_write_settingf(u, flags, name, "KillSignal=%s", signal_to_string(sig));
                 }
 
                 return 1;
@@ -93,10 +96,10 @@ int bus_kill_context_set_transient_property(
                 if (r < 0)
                         return r;
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         c->send_sighup = b;
 
-                        unit_write_drop_in_private_format(u, mode, name, "SendSIGHUP=%s", yes_no(b));
+                        unit_write_settingf(u, flags, name, "SendSIGHUP=%s", yes_no(b));
                 }
 
                 return 1;
@@ -108,10 +111,10 @@ int bus_kill_context_set_transient_property(
                 if (r < 0)
                         return r;
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         c->send_sigkill = b;
 
-                        unit_write_drop_in_private_format(u, mode, name, "SendSIGKILL=%s", yes_no(b));
+                        unit_write_settingf(u, flags, name, "SendSIGKILL=%s", yes_no(b));
                 }
 
                 return 1;
index b9b1881..1df3b37 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -26,4 +27,4 @@
 
 extern const sd_bus_vtable bus_kill_vtable[];
 
-int bus_kill_context_set_transient_property(Unit *u, KillContext *c, const char *name, sd_bus_message *message, UnitSetPropertiesMode mode, sd_bus_error *error);
+int bus_kill_context_set_transient_property(Unit *u, KillContext *c, const char *name, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
index 9b5e184..131b5ea 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -26,7 +27,6 @@
 #include "architecture.h"
 #include "build.h"
 #include "bus-common-errors.h"
-#include "clock-util.h"
 #include "dbus-execute.h"
 #include "dbus-job.h"
 #include "dbus-manager.h"
@@ -139,27 +139,18 @@ static int property_get_tainted(
                 void *userdata,
                 sd_bus_error *error) {
 
-        char buf[sizeof("split-usr:cgroups-missing:local-hwclock:")] = "", *e = buf;
+        _cleanup_free_ char *s = NULL;
         Manager *m = userdata;
 
         assert(bus);
         assert(reply);
         assert(m);
 
-        if (m->taint_usr)
-                e = stpcpy(e, "split-usr:");
+        s = manager_taint_string(m);
+        if (!s)
+                return log_oom();
 
-        if (access("/proc/cgroups", F_OK) < 0)
-                e = stpcpy(e, "cgroups-missing:");
-
-        if (clock_is_localtime(NULL) > 0)
-                e = stpcpy(e, "local-hwclock:");
-
-        /* remove the last ':' */
-        if (e != buf)
-                e[-1] = 0;
-
-        return sd_bus_message_append(reply, "s", buf);
+        return sd_bus_message_append(reply, "s", s);
 }
 
 static int property_get_log_target(
@@ -316,7 +307,7 @@ static int property_get_progress(
         assert(reply);
         assert(m);
 
-        if (dual_timestamp_is_set(&m->finish_timestamp))
+        if (MANAGER_IS_FINISHED(m))
                 d = 1.0;
         else
                 d = 1.0 - ((double) hashmap_size(m->jobs) / (double) m->n_installed_jobs);
@@ -1282,9 +1273,7 @@ static int method_unsubscribe(sd_bus_message *message, void *userdata, sd_bus_er
 
 static int method_dump(sd_bus_message *message, void *userdata, sd_bus_error *error) {
         _cleanup_free_ char *dump = NULL;
-        _cleanup_fclose_ FILE *f = NULL;
         Manager *m = userdata;
-        size_t size;
         int r;
 
         assert(message);
@@ -1296,14 +1285,7 @@ static int method_dump(sd_bus_message *message, void *userdata, sd_bus_error *er
         if (r < 0)
                 return r;
 
-        f = open_memstream(&dump, &size);
-        if (!f)
-                return -ENOMEM;
-
-        manager_dump_units(m, f, NULL);
-        manager_dump_jobs(m, f, NULL);
-
-        r = fflush_and_check(f);
+        r = manager_get_dump_string(m, &dump);
         if (r < 0)
                 return r;
 
@@ -2406,18 +2388,18 @@ const sd_bus_vtable bus_manager_vtable[] = {
         SD_BUS_PROPERTY("Virtualization", "s", property_get_virtualization, 0, SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("Architecture", "s", property_get_architecture, 0, SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("Tainted", "s", property_get_tainted, 0, SD_BUS_VTABLE_PROPERTY_CONST),
-        BUS_PROPERTY_DUAL_TIMESTAMP("FirmwareTimestamp", offsetof(Manager, firmware_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
-        BUS_PROPERTY_DUAL_TIMESTAMP("LoaderTimestamp", offsetof(Manager, loader_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
-        BUS_PROPERTY_DUAL_TIMESTAMP("KernelTimestamp", offsetof(Manager, kernel_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
-        BUS_PROPERTY_DUAL_TIMESTAMP("InitRDTimestamp", offsetof(Manager, initrd_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
-        BUS_PROPERTY_DUAL_TIMESTAMP("UserspaceTimestamp", offsetof(Manager, userspace_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
-        BUS_PROPERTY_DUAL_TIMESTAMP("FinishTimestamp", offsetof(Manager, finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
-        BUS_PROPERTY_DUAL_TIMESTAMP("SecurityStartTimestamp", offsetof(Manager, security_start_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
-        BUS_PROPERTY_DUAL_TIMESTAMP("SecurityFinishTimestamp", offsetof(Manager, security_finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
-        BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsStartTimestamp", offsetof(Manager, generators_start_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
-        BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsFinishTimestamp", offsetof(Manager, generators_finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
-        BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadStartTimestamp", offsetof(Manager, units_load_start_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
-        BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadFinishTimestamp", offsetof(Manager, units_load_finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
+        BUS_PROPERTY_DUAL_TIMESTAMP("FirmwareTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_FIRMWARE]), SD_BUS_VTABLE_PROPERTY_CONST),
+        BUS_PROPERTY_DUAL_TIMESTAMP("LoaderTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_LOADER]), SD_BUS_VTABLE_PROPERTY_CONST),
+        BUS_PROPERTY_DUAL_TIMESTAMP("KernelTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_KERNEL]), SD_BUS_VTABLE_PROPERTY_CONST),
+        BUS_PROPERTY_DUAL_TIMESTAMP("InitRDTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_INITRD]), SD_BUS_VTABLE_PROPERTY_CONST),
+        BUS_PROPERTY_DUAL_TIMESTAMP("UserspaceTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_USERSPACE]), SD_BUS_VTABLE_PROPERTY_CONST),
+        BUS_PROPERTY_DUAL_TIMESTAMP("FinishTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_FINISH]), SD_BUS_VTABLE_PROPERTY_CONST),
+        BUS_PROPERTY_DUAL_TIMESTAMP("SecurityStartTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_SECURITY_START]), SD_BUS_VTABLE_PROPERTY_CONST),
+        BUS_PROPERTY_DUAL_TIMESTAMP("SecurityFinishTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_SECURITY_FINISH]), SD_BUS_VTABLE_PROPERTY_CONST),
+        BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsStartTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_GENERATORS_START]), SD_BUS_VTABLE_PROPERTY_CONST),
+        BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsFinishTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_GENERATORS_FINISH]), SD_BUS_VTABLE_PROPERTY_CONST),
+        BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadStartTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_UNITS_LOAD_START]), SD_BUS_VTABLE_PROPERTY_CONST),
+        BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadFinishTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_UNITS_LOAD_FINISH]), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_WRITABLE_PROPERTY("LogLevel", "s", property_get_log_level, property_set_log_level, 0, 0),
         SD_BUS_WRITABLE_PROPERTY("LogTarget", "s", property_get_log_target, property_set_log_target, 0, 0),
         SD_BUS_PROPERTY("NNames", "u", property_get_n_names, 0, 0),
index 5d37c88..afc9e1d 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 76a7a7c..628bce0 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -36,7 +37,7 @@ static int property_get_what(
                 sd_bus_error *error) {
 
         Mount *m = userdata;
-        const char *d;
+        const char *d = NULL;
 
         assert(bus);
         assert(reply);
@@ -46,8 +47,6 @@ static int property_get_what(
                 d = m->parameters_proc_self_mountinfo.what;
         else if (m->from_fragment && m->parameters_fragment.what)
                 d = m->parameters_fragment.what;
-        else
-                d = "";
 
         return sd_bus_message_append(reply, "s", d);
 }
@@ -62,7 +61,7 @@ static int property_get_options(
                 sd_bus_error *error) {
 
         Mount *m = userdata;
-        const char *d;
+        const char *d = NULL;
 
         assert(bus);
         assert(reply);
@@ -72,8 +71,6 @@ static int property_get_options(
                 d = m->parameters_proc_self_mountinfo.options;
         else if (m->from_fragment && m->parameters_fragment.options)
                 d = m->parameters_fragment.options;
-        else
-                d = "";
 
         return sd_bus_message_append(reply, "s", d);
 }
@@ -87,21 +84,19 @@ static int property_get_type(
                 void *userdata,
                 sd_bus_error *error) {
 
+        const char *fstype = NULL;
         Mount *m = userdata;
-        const char *d;
 
         assert(bus);
         assert(reply);
         assert(m);
 
         if (m->from_proc_self_mountinfo && m->parameters_proc_self_mountinfo.fstype)
-                d = m->parameters_proc_self_mountinfo.fstype;
+                fstype = m->parameters_proc_self_mountinfo.fstype;
         else if (m->from_fragment && m->parameters_fragment.fstype)
-                d = m->parameters_fragment.fstype;
-        else
-                d = "";
+                fstype = m->parameters_fragment.fstype;
 
-        return sd_bus_message_append(reply, "s", d);
+        return sd_bus_message_append(reply, "s", fstype);
 }
 
 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result, mount_result, MountResult);
@@ -131,18 +126,19 @@ static int bus_mount_set_transient_property(
                 Mount *m,
                 const char *name,
                 sd_bus_message *message,
-                UnitSetPropertiesMode mode,
+                UnitWriteFlags flags,
                 sd_bus_error *error) {
 
         const char *new_property;
         char **property;
-        char *p;
         int r;
 
         assert(m);
         assert(name);
         assert(message);
 
+        flags |= UNIT_PRIVATE;
+
         if (streq(name, "What"))
                 property = &m->parameters_fragment.what;
         else if (streq(name, "Options"))
@@ -156,16 +152,13 @@ static int bus_mount_set_transient_property(
         if (r < 0)
                 return r;
 
-        if (mode != UNIT_CHECK) {
-                p = strdup(new_property);
-                if (!p)
-                        return -ENOMEM;
+        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
 
-                unit_write_drop_in_format(UNIT(m), mode, name, "[Mount]\n%s=%s\n",
-                        name, new_property);
+                r = free_and_strdup(property, new_property);
+                if (r < 0)
+                        return r;
 
-                free(*property);
-                *property = p;
+                unit_write_settingf(UNIT(m), flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s", name, new_property);
         }
 
         return 1;
@@ -175,7 +168,7 @@ int bus_mount_set_property(
                 Unit *u,
                 const char *name,
                 sd_bus_message *message,
-                UnitSetPropertiesMode mode,
+                UnitWriteFlags flags,
                 sd_bus_error *error) {
 
         Mount *m = MOUNT(u);
@@ -185,22 +178,22 @@ int bus_mount_set_property(
         assert(name);
         assert(message);
 
-        r = bus_cgroup_set_property(u, &m->cgroup_context, name, message, mode, error);
+        r = bus_cgroup_set_property(u, &m->cgroup_context, name, message, flags, error);
         if (r != 0)
                 return r;
 
         if (u->transient && u->load_state == UNIT_STUB) {
                 /* This is a transient unit, let's load a little more */
 
-                r = bus_mount_set_transient_property(m, name, message, mode, error);
+                r = bus_mount_set_transient_property(m, name, message, flags, error);
                 if (r != 0)
                         return r;
 
-                r = bus_exec_context_set_transient_property(u, &m->exec_context, name, message, mode, error);
+                r = bus_exec_context_set_transient_property(u, &m->exec_context, name, message, flags, error);
                 if (r != 0)
                         return r;
 
-                r = bus_kill_context_set_transient_property(u, &m->kill_context, name, message, mode, error);
+                r = bus_kill_context_set_transient_property(u, &m->kill_context, name, message, flags, error);
                 if (r != 0)
                         return r;
         }
index ec16166..5d5e1f6 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -25,5 +26,5 @@
 
 extern const sd_bus_vtable bus_mount_vtable[];
 
-int bus_mount_set_property(Unit *u, const char *name, sd_bus_message *message, UnitSetPropertiesMode mode, sd_bus_error *error);
+int bus_mount_set_property(Unit *u, const char *name, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
 int bus_mount_commit_properties(Unit *u);
index 1e153e5..0f54b04 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index d3c19e0..5e7e859 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 1abaf9f..9195ad3 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -60,7 +61,7 @@ static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result, scope_result, ScopeResu
 
 const sd_bus_vtable bus_scope_vtable[] = {
         SD_BUS_VTABLE_START(0),
-        SD_BUS_PROPERTY("Controller", "s", NULL, offsetof(Scope, controller), SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("Controller", "s", NULL, offsetof(Scope, controller), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
         SD_BUS_PROPERTY("TimeoutStopUSec", "t", bus_property_get_usec, offsetof(Scope, timeout_stop_usec), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("Result", "s", property_get_result, offsetof(Scope, result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
         SD_BUS_SIGNAL("RequestStop", NULL, 0),
@@ -72,7 +73,7 @@ static int bus_scope_set_transient_property(
                 Scope *s,
                 const char *name,
                 sd_bus_message *message,
-                UnitSetPropertiesMode mode,
+                UnitWriteFlags flags,
                 sd_bus_error *error) {
 
         int r;
@@ -81,6 +82,8 @@ static int bus_scope_set_transient_property(
         assert(name);
         assert(message);
 
+        flags |= UNIT_PRIVATE;
+
         if (streq(name, "PIDs")) {
                 unsigned n = 0;
                 uint32_t pid;
@@ -94,7 +97,7 @@ static int bus_scope_set_transient_property(
                         if (pid <= 1)
                                 return -EINVAL;
 
-                        if (mode != UNIT_CHECK) {
+                        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                                 r = unit_watch_pid(UNIT(s), pid);
                                 if (r < 0 && r != -EEXIST)
                                         return r;
@@ -116,7 +119,11 @@ static int bus_scope_set_transient_property(
 
         } else if (streq(name, "Controller")) {
                 const char *controller;
-                char *c;
+
+                /* We can't support direct connections with this, as direct connections know no service or unique name
+                 * concept, but the Controller field stores exactly that. */
+                if (sd_bus_message_get_bus(message) != UNIT(s)->manager->api_bus)
+                        return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Sorry, Controller= logic only supported via the bus.");
 
                 r = sd_bus_message_read(message, "s", &controller);
                 if (r < 0)
@@ -125,33 +132,25 @@ static int bus_scope_set_transient_property(
                 if (!isempty(controller) && !service_name_is_valid(controller))
                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Controller '%s' is not a valid bus name.", controller);
 
-                if (mode != UNIT_CHECK) {
-                        if (isempty(controller))
-                                c = NULL;
-                        else {
-                                c = strdup(controller);
-                                if (!c)
-                                        return -ENOMEM;
-                        }
-
-                        free(s->controller);
-                        s->controller = c;
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
+                        r = free_and_strdup(&s->controller, empty_to_null(controller));
+                        if (r < 0)
+                                return r;
                 }
 
                 return 1;
 
         } else if (streq(name, "TimeoutStopUSec")) {
+                uint64_t t;
 
-                if (mode != UNIT_CHECK) {
-                        r = sd_bus_message_read(message, "t", &s->timeout_stop_usec);
-                        if (r < 0)
-                                return r;
+                r = sd_bus_message_read(message, "t", &t);
+                if (r < 0)
+                        return r;
 
-                        unit_write_drop_in_private_format(UNIT(s), mode, name, "TimeoutStopSec="USEC_FMT"us", s->timeout_stop_usec);
-                } else {
-                        r = sd_bus_message_skip(message, "t");
-                        if (r < 0)
-                                return r;
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
+                        s->timeout_stop_usec = t;
+
+                        unit_write_settingf(UNIT(s), flags, name, "TimeoutStopSec=" USEC_FMT "us", t);
                 }
 
                 return 1;
@@ -164,7 +163,7 @@ int bus_scope_set_property(
                 Unit *u,
                 const char *name,
                 sd_bus_message *message,
-                UnitSetPropertiesMode mode,
+                UnitWriteFlags flags,
                 sd_bus_error *error) {
 
         Scope *s = SCOPE(u);
@@ -174,18 +173,18 @@ int bus_scope_set_property(
         assert(name);
         assert(message);
 
-        r = bus_cgroup_set_property(u, &s->cgroup_context, name, message, mode, error);
+        r = bus_cgroup_set_property(u, &s->cgroup_context, name, message, flags, error);
         if (r != 0)
                 return r;
 
         if (u->load_state == UNIT_STUB) {
                 /* While we are created we still accept PIDs */
 
-                r = bus_scope_set_transient_property(s, name, message, mode, error);
+                r = bus_scope_set_transient_property(s, name, message, flags, error);
                 if (r != 0)
                         return r;
 
-                r = bus_kill_context_set_transient_property(u, &s->kill_context, name, message, mode, error);
+                r = bus_kill_context_set_transient_property(u, &s->kill_context, name, message, flags, error);
                 if (r != 0)
                         return r;
         }
@@ -227,3 +226,40 @@ int bus_scope_send_request_stop(Scope *s) {
 
         return sd_bus_send_to(UNIT(s)->manager->api_bus, m, s->controller, NULL);
 }
+
+static int on_controller_gone(sd_bus_track *track, void *userdata) {
+        Scope *s = userdata;
+
+        assert(track);
+
+        if (s->controller) {
+                log_unit_debug(UNIT(s), "Controller %s disappeared from bus.", s->controller);
+                unit_add_to_dbus_queue(UNIT(s));
+                s->controller = mfree(s->controller);
+        }
+
+        s->controller_track = sd_bus_track_unref(s->controller_track);
+
+        return 0;
+}
+
+int bus_scope_track_controller(Scope *s) {
+        int r;
+
+        assert(s);
+
+        if (!s->controller || s->controller_track)
+                return 0;
+
+        r = sd_bus_track_new(UNIT(s)->manager->api_bus, &s->controller_track, on_controller_gone, s);
+        if (r < 0)
+                return r;
+
+        r = sd_bus_track_add_name(s->controller_track, s->controller);
+        if (r < 0) {
+                s->controller_track = sd_bus_track_unref(s->controller_track);
+                return r;
+        }
+
+        return 0;
+}
index 270306f..aa60489 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -25,7 +26,9 @@
 
 extern const sd_bus_vtable bus_scope_vtable[];
 
-int bus_scope_set_property(Unit *u, const char *name, sd_bus_message *i, UnitSetPropertiesMode mode, sd_bus_error *error);
+int bus_scope_set_property(Unit *u, const char *name, sd_bus_message *i, UnitWriteFlags flags, sd_bus_error *error);
 int bus_scope_commit_properties(Unit *u);
 
 int bus_scope_send_request_stop(Scope *s);
+
+int bus_scope_track_controller(Scope *s);
index 05bdc0a..0189952 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -17,6 +18,8 @@
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
+#include <stdio_ext.h>
+
 #include "alloc-util.h"
 #include "async.h"
 #include "bus-util.h"
@@ -50,7 +53,6 @@ const sd_bus_vtable bus_service_vtable[] = {
         SD_BUS_PROPERTY("RuntimeMaxUSec", "t", bus_property_get_usec, offsetof(Service, runtime_max_usec), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("WatchdogUSec", "t", bus_property_get_usec, offsetof(Service, watchdog_usec), SD_BUS_VTABLE_PROPERTY_CONST),
         BUS_PROPERTY_DUAL_TIMESTAMP("WatchdogTimestamp", offsetof(Service, watchdog_timestamp), 0),
-        SD_BUS_PROPERTY("FailureAction", "s", property_get_emergency_action, offsetof(Service, emergency_action), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("PermissionsStartOnly", "b", bus_property_get_bool, offsetof(Service, permissions_start_only), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("RootDirectoryStartOnly", "b", bus_property_get_bool, offsetof(Service, root_directory_start_only), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("RemainAfterExit", "b", bus_property_get_bool, offsetof(Service, remain_after_exit), SD_BUS_VTABLE_PROPERTY_CONST),
@@ -81,6 +83,7 @@ const sd_bus_vtable bus_service_vtable[] = {
         SD_BUS_PROPERTY("StartLimitInterval", "t", bus_property_get_usec, offsetof(Unit, start_limit.interval), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
         SD_BUS_PROPERTY("StartLimitBurst", "u", bus_property_get_unsigned, offsetof(Unit, start_limit.burst), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
         SD_BUS_PROPERTY("StartLimitAction", "s", property_get_emergency_action, offsetof(Unit, start_limit_action), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
+        SD_BUS_PROPERTY("FailureAction", "s", property_get_emergency_action, offsetof(Unit, failure_action), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
         SD_BUS_PROPERTY("RebootArgument", "s", NULL, offsetof(Unit, reboot_arg), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
         SD_BUS_VTABLE_END
 };
@@ -89,15 +92,18 @@ static int bus_service_set_transient_property(
                 Service *s,
                 const char *name,
                 sd_bus_message *message,
-                UnitSetPropertiesMode mode,
+                UnitWriteFlags flags,
                 sd_bus_error *error) {
 
+        ServiceExecCommand ci;
         int r;
 
         assert(s);
         assert(name);
         assert(message);
 
+        flags |= UNIT_PRIVATE;
+
         if (streq(name, "RemainAfterExit")) {
                 int b;
 
@@ -105,9 +111,9 @@ static int bus_service_set_transient_property(
                 if (r < 0)
                         return r;
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         s->remain_after_exit = b;
-                        unit_write_drop_in_private_format(UNIT(s), mode, name, "RemainAfterExit=%s", yes_no(b));
+                        unit_write_settingf(UNIT(s), flags, name, "RemainAfterExit=%s", yes_no(b));
                 }
 
                 return 1;
@@ -124,9 +130,9 @@ static int bus_service_set_transient_property(
                 if (k < 0)
                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid service type %s", t);
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         s->type = k;
-                        unit_write_drop_in_private_format(UNIT(s), mode, name, "Type=%s", service_type_to_string(s->type));
+                        unit_write_settingf(UNIT(s), flags, name, "Type=%s", service_type_to_string(s->type));
                 }
 
                 return 1;
@@ -137,9 +143,9 @@ static int bus_service_set_transient_property(
                 if (r < 0)
                         return r;
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         s->runtime_max_usec = u;
-                        unit_write_drop_in_private_format(UNIT(s), mode, name, "RuntimeMaxSec=" USEC_FMT "us", u);
+                        unit_write_settingf(UNIT(s), flags, name, "RuntimeMaxSec=" USEC_FMT "us", u);
                 }
 
                 return 1;
@@ -160,9 +166,9 @@ static int bus_service_set_transient_property(
                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid restart setting: %s", v);
                 }
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         s->restart = sr;
-                        unit_write_drop_in_private_format(UNIT(s), mode, name, "Restart=%s", service_restart_to_string(sr));
+                        unit_write_settingf(UNIT(s), flags, name, "Restart=%s", service_restart_to_string(sr));
                 }
 
                 return 1;
@@ -177,7 +183,7 @@ static int bus_service_set_transient_property(
                 if (r < 0)
                         return r;
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         int copy;
 
                         copy = fcntl(fd, F_DUPFD_CLOEXEC, 3);
@@ -207,9 +213,9 @@ static int bus_service_set_transient_property(
                 if (r < 0)
                         return r;
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         s->n_fd_store_max = (unsigned) u;
-                        unit_write_drop_in_private_format(UNIT(s), mode, name, "FileDescriptorStoreMax=%" PRIu32, u);
+                        unit_write_settingf(UNIT(s), flags, name, "FileDescriptorStoreMax=%" PRIu32, u);
                 }
 
                 return 1;
@@ -226,14 +232,14 @@ static int bus_service_set_transient_property(
                 if (k < 0)
                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid notify access setting %s", t);
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         s->notify_access = k;
-                        unit_write_drop_in_private_format(UNIT(s), mode, name, "NotifyAccess=%s", notify_access_to_string(s->notify_access));
+                        unit_write_settingf(UNIT(s), flags, name, "NotifyAccess=%s", notify_access_to_string(s->notify_access));
                 }
 
                 return 1;
 
-        } else if (streq(name, "ExecStart")) {
+        } else if ((ci = service_exec_command_from_string(name)) >= 0) {
                 unsigned n = 0;
 
                 r = sd_bus_message_enter_container(message, 'a', "(sasb)");
@@ -250,7 +256,7 @@ static int bus_service_set_transient_property(
                                 return r;
 
                         if (!path_is_absolute(path))
-                                return sd_bus_error_set_errnof(error, EINVAL, "Path %s is not absolute.", path);
+                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not absolute.", path);
 
                         r = sd_bus_message_read_strv(message, &argv);
                         if (r < 0)
@@ -264,7 +270,7 @@ static int bus_service_set_transient_property(
                         if (r < 0)
                                 return r;
 
-                        if (mode != UNIT_CHECK) {
+                        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                                 ExecCommand *c;
 
                                 c = new0(ExecCommand, 1);
@@ -283,7 +289,7 @@ static int bus_service_set_transient_property(
                                 c->flags = b ? EXEC_COMMAND_IGNORE_FAILURE : 0;
 
                                 path_kill_slashes(c->path);
-                                exec_command_append_list(&s->exec_command[SERVICE_EXEC_START], c);
+                                exec_command_append_list(&s->exec_command[ci], c);
                         }
 
                         n++;
@@ -296,38 +302,47 @@ static int bus_service_set_transient_property(
                 if (r < 0)
                         return r;
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         _cleanup_free_ char *buf = NULL;
                         _cleanup_fclose_ FILE *f = NULL;
                         ExecCommand *c;
                         size_t size = 0;
 
                         if (n == 0)
-                                s->exec_command[SERVICE_EXEC_START] = exec_command_free_list(s->exec_command[SERVICE_EXEC_START]);
+                                s->exec_command[ci] = exec_command_free_list(s->exec_command[ci]);
 
                         f = open_memstream(&buf, &size);
                         if (!f)
                                 return -ENOMEM;
 
-                        fputs_unlocked("ExecStart=\n", f);
+                        (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
+
+                        fputs("ExecStart=\n", f);
 
-                        LIST_FOREACH(command, c, s->exec_command[SERVICE_EXEC_START]) {
-                                _cleanup_free_ char *a;
+                        LIST_FOREACH(command, c, s->exec_command[ci]) {
+                                _cleanup_free_ char *a = NULL, *t = NULL;
+                                const char *p;
 
-                                a = strv_join_quoted(c->argv);
+                                p = unit_escape_setting(c->path, UNIT_ESCAPE_C|UNIT_ESCAPE_SPECIFIERS, &t);
+                                if (!p)
+                                        return -ENOMEM;
+
+                                a = unit_concat_strv(c->argv, UNIT_ESCAPE_C|UNIT_ESCAPE_SPECIFIERS);
                                 if (!a)
                                         return -ENOMEM;
 
-                                fprintf(f, "ExecStart=%s@%s %s\n",
+                                fprintf(f, "%s=%s@%s %s\n",
+                                        name,
                                         c->flags & EXEC_COMMAND_IGNORE_FAILURE ? "-" : "",
-                                        c->path,
+                                        p,
                                         a);
                         }
 
                         r = fflush_and_check(f);
                         if (r < 0)
                                 return r;
-                        unit_write_drop_in_private(UNIT(s), mode, name, buf);
+
+                        unit_write_setting(UNIT(s), flags, name, buf);
                 }
 
                 return 1;
@@ -340,7 +355,7 @@ int bus_service_set_property(
                 Unit *u,
                 const char *name,
                 sd_bus_message *message,
-                UnitSetPropertiesMode mode,
+                UnitWriteFlags flags,
                 sd_bus_error *error) {
 
         Service *s = SERVICE(u);
@@ -350,22 +365,22 @@ int bus_service_set_property(
         assert(name);
         assert(message);
 
-        r = bus_cgroup_set_property(u, &s->cgroup_context, name, message, mode, error);
+        r = bus_cgroup_set_property(u, &s->cgroup_context, name, message, flags, error);
         if (r != 0)
                 return r;
 
         if (u->transient && u->load_state == UNIT_STUB) {
                 /* This is a transient unit, let's load a little more */
 
-                r = bus_service_set_transient_property(s, name, message, mode, error);
+                r = bus_service_set_transient_property(s, name, message, flags, error);
                 if (r != 0)
                         return r;
 
-                r = bus_exec_context_set_transient_property(u, &s->exec_context, name, message, mode, error);
+                r = bus_exec_context_set_transient_property(u, &s->exec_context, name, message, flags, error);
                 if (r != 0)
                         return r;
 
-                r = bus_kill_context_set_transient_property(u, &s->kill_context, name, message, mode, error);
+                r = bus_kill_context_set_transient_property(u, &s->kill_context, name, message, flags, error);
                 if (r != 0)
                         return r;
         }
index 769a537..2da29ec 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -25,5 +26,5 @@
 
 extern const sd_bus_vtable bus_service_vtable[];
 
-int bus_service_set_property(Unit *u, const char *name, sd_bus_message *i, UnitSetPropertiesMode mode, sd_bus_error *error);
+int bus_service_set_property(Unit *u, const char *name, sd_bus_message *i, UnitWriteFlags flags, sd_bus_error *error);
 int bus_service_commit_properties(Unit *u);
index e37f50b..fa2ff72 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -31,7 +32,7 @@ int bus_slice_set_property(
                 Unit *u,
                 const char *name,
                 sd_bus_message *message,
-                UnitSetPropertiesMode mode,
+                UnitWriteFlags flags,
                 sd_bus_error *error) {
 
         Slice *s = SLICE(u);
@@ -39,7 +40,7 @@ int bus_slice_set_property(
         assert(name);
         assert(u);
 
-        return bus_cgroup_set_property(u, &s->cgroup_context, name, message, mode, error);
+        return bus_cgroup_set_property(u, &s->cgroup_context, name, message, flags, error);
 }
 
 int bus_slice_commit_properties(Unit *u) {
index 52ceebb..0c21919 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -25,5 +26,5 @@
 
 extern const sd_bus_vtable bus_slice_vtable[];
 
-int bus_slice_set_property(Unit *u, const char *name, sd_bus_message *message, UnitSetPropertiesMode mode, sd_bus_error *error);
+int bus_slice_set_property(Unit *u, const char *name, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
 int bus_slice_commit_properties(Unit *u);
index 21adb64..930b7fa 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -165,7 +166,7 @@ int bus_socket_set_property(
                 Unit *u,
                 const char *name,
                 sd_bus_message *message,
-                UnitSetPropertiesMode mode,
+                UnitWriteFlags flags,
                 sd_bus_error *error) {
 
         Socket *s = SOCKET(u);
@@ -174,7 +175,7 @@ int bus_socket_set_property(
         assert(name);
         assert(message);
 
-        return bus_cgroup_set_property(u, &s->cgroup_context, name, message, mode, error);
+        return bus_cgroup_set_property(u, &s->cgroup_context, name, message, flags, error);
 }
 
 int bus_socket_commit_properties(Unit *u) {
index 7a792c7..e6db2d0 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -25,5 +26,5 @@
 
 extern const sd_bus_vtable bus_socket_vtable[];
 
-int bus_socket_set_property(Unit *u, const char *name, sd_bus_message *message, UnitSetPropertiesMode mode, sd_bus_error *error);
+int bus_socket_set_property(Unit *u, const char *name, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
 int bus_socket_commit_properties(Unit *u);
index 85a2c26..795aaa9 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -95,7 +96,7 @@ int bus_swap_set_property(
                 Unit *u,
                 const char *name,
                 sd_bus_message *message,
-                UnitSetPropertiesMode mode,
+                UnitWriteFlags flags,
                 sd_bus_error *error) {
 
         Swap *s = SWAP(u);
@@ -104,7 +105,7 @@ int bus_swap_set_property(
         assert(name);
         assert(message);
 
-        return bus_cgroup_set_property(u, &s->cgroup_context, name, message, mode, error);
+        return bus_cgroup_set_property(u, &s->cgroup_context, name, message, flags, error);
 }
 
 int bus_swap_commit_properties(Unit *u) {
index 5238471..6cca748 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -26,5 +27,5 @@
 
 extern const sd_bus_vtable bus_swap_vtable[];
 
-int bus_swap_set_property(Unit *u, const char *name, sd_bus_message *message, UnitSetPropertiesMode mode, sd_bus_error *error);
+int bus_swap_set_property(Unit *u, const char *name, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
 int bus_swap_commit_properties(Unit *u);
index 6858b1c..7060b65 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 9be5ce0..7852917 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index c98282a..3e64536 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -175,7 +176,7 @@ static int bus_timer_set_transient_property(
                 Timer *t,
                 const char *name,
                 sd_bus_message *message,
-                UnitSetPropertiesMode mode,
+                UnitWriteFlags flags,
                 sd_bus_error *error) {
 
         int r;
@@ -184,6 +185,8 @@ static int bus_timer_set_transient_property(
         assert(name);
         assert(message);
 
+        flags |= UNIT_PRIVATE;
+
         if (STR_IN_SET(name,
                        "OnActiveSec",
                        "OnBootSec",
@@ -203,10 +206,10 @@ static int bus_timer_set_transient_property(
                 if (r < 0)
                         return r;
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         char time[FORMAT_TIMESPAN_MAX];
 
-                        unit_write_drop_in_private_format(UNIT(t), mode, name, "%s=%s", name, format_timespan(time, sizeof(time), u, USEC_PER_MSEC));
+                        unit_write_settingf(UNIT(t), flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s", name, format_timespan(time, sizeof(time), u, USEC_PER_MSEC));
 
                         v = new0(TimerValue, 1);
                         if (!v)
@@ -230,12 +233,12 @@ static int bus_timer_set_transient_property(
                 if (r < 0)
                         return r;
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         r = calendar_spec_from_string(str, &c);
                         if (r < 0)
                                 return r;
 
-                        unit_write_drop_in_private_format(UNIT(t), mode, name, "%s=%s", name, str);
+                        unit_write_settingf(UNIT(t), flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s", name, str);
 
                         v = new0(TimerValue, 1);
                         if (!v) {
@@ -261,9 +264,9 @@ static int bus_timer_set_transient_property(
                 if (r < 0)
                         return r;
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         t->accuracy_usec = u;
-                        unit_write_drop_in_private_format(UNIT(t), mode, name, "AccuracySec=" USEC_FMT "us", u);
+                        unit_write_settingf(UNIT(t), flags, name, "AccuracySec=" USEC_FMT "us", u);
                 }
 
                 return 1;
@@ -275,37 +278,29 @@ static int bus_timer_set_transient_property(
                 if (r < 0)
                         return r;
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         t->random_usec = u;
-                        unit_write_drop_in_private_format(UNIT(t), mode, name, "RandomizedDelaySec=" USEC_FMT "us", u);
+                        unit_write_settingf(UNIT(t), flags, name, "RandomizedDelaySec=" USEC_FMT "us", u);
                 }
 
                 return 1;
 
-        } else if (streq(name, "WakeSystem")) {
+        } else if (STR_IN_SET(name, "WakeSystem", "Persistent", "RemainAfterElapse")) {
                 int b;
 
                 r = sd_bus_message_read(message, "b", &b);
                 if (r < 0)
                         return r;
 
-                if (mode != UNIT_CHECK) {
-                        t->wake_system = b;
-                        unit_write_drop_in_private_format(UNIT(t), mode, name, "%s=%s", name, yes_no(b));
-                }
-
-                return 1;
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
+                        if (streq(name, "WakeSystem"))
+                                t->wake_system = b;
+                        else if (streq(name, "Persistent"))
+                                t->persistent = b;
+                        else /* RemainAfterElapse */
+                                t->remain_after_elapse = b;
 
-        } else if (streq(name, "RemainAfterElapse")) {
-                int b;
-
-                r = sd_bus_message_read(message, "b", &b);
-                if (r < 0)
-                        return r;
-
-                if (mode != UNIT_CHECK) {
-                        t->remain_after_elapse = b;
-                        unit_write_drop_in_private_format(UNIT(t), mode, name, "%s=%s", name, yes_no(b));
+                        unit_write_settingf(UNIT(t), flags, name, "%s=%s", name, yes_no(b));
                 }
 
                 return 1;
@@ -318,21 +313,17 @@ int bus_timer_set_property(
                 Unit *u,
                 const char *name,
                 sd_bus_message *message,
-                UnitSetPropertiesMode mode,
+                UnitWriteFlags mode,
                 sd_bus_error *error) {
 
         Timer *t = TIMER(u);
-        int r;
 
         assert(t);
         assert(name);
         assert(message);
 
-        if (u->transient && u->load_state == UNIT_STUB) {
-                r = bus_timer_set_transient_property(t, name, message, mode, error);
-                if (r != 0)
-                        return r;
-        }
+        if (u->transient && u->load_state == UNIT_STUB)
+                return bus_timer_set_transient_property(t, name, message, mode, error);
 
         return 0;
 }
index 39053dc..d810b04 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -25,4 +26,4 @@
 
 extern const sd_bus_vtable bus_timer_vtable[];
 
-int bus_timer_set_property(Unit *u, const char *name, sd_bus_message *i, UnitSetPropertiesMode mode, sd_bus_error *error);
+int bus_timer_set_property(Unit *u, const char *name, sd_bus_message *i, UnitWriteFlags flags, sd_bus_error *error);
index a9a6882..cdab461 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -37,6 +38,7 @@
 #include "strv.h"
 #include "user-util.h"
 
+static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_collect_mode, collect_mode, CollectMode);
 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_load_state, unit_load_state, UnitLoadState);
 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_job_mode, job_mode, JobMode);
 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_emergency_action, emergency_action, EmergencyAction);
@@ -100,9 +102,10 @@ static int property_get_dependencies(
                 void *userdata,
                 sd_bus_error *error) {
 
-        Set *s = *(Set**) userdata;
+        Hashmap *h = *(Hashmap**) userdata;
         Iterator j;
         Unit *u;
+        void *v;
         int r;
 
         assert(bus);
@@ -112,7 +115,7 @@ static int property_get_dependencies(
         if (r < 0)
                 return r;
 
-        SET_FOREACH(u, s, j) {
+        HASHMAP_FOREACH_KEY(v, u, h, j) {
                 r = sd_bus_message_append(reply, "s", u->id);
                 if (r < 0)
                         return r;
@@ -137,6 +140,37 @@ static int property_get_obsolete_dependencies(
         return sd_bus_message_append(reply, "as", 0);
 }
 
+static int property_get_requires_mounts_for(
+                sd_bus *bus,
+                const char *path,
+                const char *interface,
+                const char *property,
+                sd_bus_message *reply,
+                void *userdata,
+                sd_bus_error *error) {
+
+        Hashmap *h = *(Hashmap**) userdata;
+        const char *p;
+        Iterator j;
+        void *v;
+        int r;
+
+        assert(bus);
+        assert(reply);
+
+        r = sd_bus_message_open_container(reply, 'a', "s");
+        if (r < 0)
+                return r;
+
+        HASHMAP_FOREACH_KEY(v, p, h, j) {
+                r = sd_bus_message_append(reply, "s", p);
+                if (r < 0)
+                        return r;
+        }
+
+        return sd_bus_message_close_container(reply);
+}
+
 static int property_get_description(
                 sd_bus *bus,
                 const char *path,
@@ -719,7 +753,7 @@ const sd_bus_vtable bus_unit_vtable[] = {
         SD_BUS_PROPERTY("PropagatesReloadTo", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_PROPAGATES_RELOAD_TO]), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("ReloadPropagatedFrom", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_RELOAD_PROPAGATED_FROM]), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("JoinsNamespaceOf", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_JOINS_NAMESPACE_OF]), SD_BUS_VTABLE_PROPERTY_CONST),
-        SD_BUS_PROPERTY("RequiresMountsFor", "as", NULL, offsetof(Unit, requires_mounts_for), SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("RequiresMountsFor", "as", property_get_requires_mounts_for, offsetof(Unit, requires_mounts_for), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("Documentation", "as", NULL, offsetof(Unit, documentation), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("Description", "s", property_get_description, 0, SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("LoadState", "s", property_get_load_state, offsetof(Unit, load_state), SD_BUS_VTABLE_PROPERTY_CONST),
@@ -764,8 +798,11 @@ const sd_bus_vtable bus_unit_vtable[] = {
         SD_BUS_PROPERTY("StartLimitIntervalSec", "t", bus_property_get_usec, offsetof(Unit, start_limit.interval), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("StartLimitBurst", "u", bus_property_get_unsigned, offsetof(Unit, start_limit.burst), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("StartLimitAction", "s", property_get_emergency_action, offsetof(Unit, start_limit_action), SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("FailureAction", "s", property_get_emergency_action, offsetof(Unit, failure_action), SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("SuccessAction", "s", property_get_emergency_action, offsetof(Unit, success_action), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("RebootArgument", "s", NULL, offsetof(Unit, reboot_arg), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("InvocationID", "ay", bus_property_get_id128, offsetof(Unit, invocation_id), 0),
+        SD_BUS_PROPERTY("CollectMode", "s", property_get_collect_mode, offsetof(Unit, collect_mode), 0),
 
         SD_BUS_METHOD("Start", "s", "o", method_start, SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD("Stop", "s", "o", method_stop, SD_BUS_VTABLE_UNPRIVILEGED),
@@ -1278,11 +1315,11 @@ int bus_unit_queue_job(
         return sd_bus_reply_method_return(message, "o", path);
 }
 
-static int bus_unit_set_transient_property(
+static int bus_unit_set_live_property(
                 Unit *u,
                 const char *name,
                 sd_bus_message *message,
-                UnitSetPropertiesMode mode,
+                UnitWriteFlags flags,
                 sd_bus_error *error) {
 
         int r;
@@ -1291,6 +1328,9 @@ static int bus_unit_set_transient_property(
         assert(name);
         assert(message);
 
+        /* Handles setting properties both "live" (i.e. at any time during runtime), and during creation (for transient
+         * units that are being created). */
+
         if (streq(name, "Description")) {
                 const char *d;
 
@@ -1298,26 +1338,65 @@ static int bus_unit_set_transient_property(
                 if (r < 0)
                         return r;
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         r = unit_set_description(u, d);
                         if (r < 0)
                                 return r;
 
-                        unit_write_drop_in_format(u, mode, name, "[Unit]\nDescription=%s", d);
+                        unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "Description=%s", d);
                 }
 
                 return 1;
+        }
 
-        } else if (streq(name, "DefaultDependencies")) {
+        return 0;
+}
+
+static int bus_unit_set_transient_property(
+                Unit *u,
+                const char *name,
+                sd_bus_message *message,
+                UnitWriteFlags flags,
+                sd_bus_error *error) {
+
+        int r;
+
+        assert(u);
+        assert(name);
+        assert(message);
+
+        /* Handles settings when transient units are created. This settings cannot be altered anymore after the unit
+         * has been created. */
+
+        if (streq(name, "DefaultDependencies")) {
                 int b;
 
                 r = sd_bus_message_read(message, "b", &b);
                 if (r < 0)
                         return r;
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         u->default_dependencies = b;
-                        unit_write_drop_in_format(u, mode, name, "[Unit]\nDefaultDependencies=%s", yes_no(b));
+                        unit_write_settingf(u, flags, name, "DefaultDependencies=%s", yes_no(b));
+                }
+
+                return 1;
+
+        } else if (streq(name, "CollectMode")) {
+                const char *s;
+                CollectMode m;
+
+                r = sd_bus_message_read(message, "s", &s);
+                if (r < 0)
+                        return r;
+
+                m = collect_mode_from_string(s);
+                if (m < 0)
+                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown garbage collection mode: %s", s);
+
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
+                        u->collect_mode = m;
+                        unit_write_settingf(u, flags, name, "CollectMode=%s", collect_mode_to_string(m));
                 }
 
                 return 1;
@@ -1350,12 +1429,12 @@ static int bus_unit_set_transient_property(
                 if (slice->type != UNIT_SLICE)
                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unit name '%s' is not a slice", s);
 
-                if (mode != UNIT_CHECK) {
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         r = unit_set_slice(u, slice);
                         if (r < 0)
                                 return r;
 
-                        unit_write_drop_in_private_format(u, mode, name, "Slice=%s", s);
+                        unit_write_settingf(u, flags|UNIT_PRIVATE, name, "Slice=%s", s);
                 }
 
                 return 1;
@@ -1392,10 +1471,10 @@ static int bus_unit_set_transient_property(
                         if (!unit_name_is_valid(other, UNIT_NAME_PLAIN|UNIT_NAME_INSTANCE))
                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid unit name %s", other);
 
-                        if (mode != UNIT_CHECK) {
+                        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                                 _cleanup_free_ char *label = NULL;
 
-                                r = unit_add_dependency_by_name(u, d, other, NULL, true);
+                                r = unit_add_dependency_by_name(u, d, other, NULL, true, UNIT_DEPENDENCY_FILE);
                                 if (r < 0)
                                         return r;
 
@@ -1403,7 +1482,7 @@ static int bus_unit_set_transient_property(
                                 if (!label)
                                         return -ENOMEM;
 
-                                unit_write_drop_in_format(u, mode, label, "[Unit]\n%s=%s", name, other);
+                                unit_write_settingf(u, flags, label, "%s=%s", name, other);
                         }
 
                 }
@@ -1416,6 +1495,30 @@ static int bus_unit_set_transient_property(
 
                 return 1;
 
+        } else if (STR_IN_SET(name, "FailureAction", "SuccessAction")) {
+                EmergencyAction action;
+                const char *s;
+
+                r = sd_bus_message_read(message, "s", &s);
+                if (r < 0)
+                        return r;
+
+                action = emergency_action_from_string(s);
+                if (action < 0)
+                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid emergency action: %s", s);
+
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
+
+                        if (streq(name, "FailureAction"))
+                                u->failure_action = action;
+                        else
+                                u->success_action = action;
+
+                        unit_write_settingf(u, flags, name, "%s=%s", name, emergency_action_to_string(action));
+                }
+
+                return 1;
+
         } else if (streq(name, "AddRef")) {
 
                 int b;
@@ -1434,7 +1537,7 @@ static int bus_unit_set_transient_property(
                 if (r < 0)
                         return r;
 
-                if (mode != UNIT_CHECK)
+                if (!UNIT_WRITE_FLAGS_NOOP(flags))
                         u->bus_track_add = b;
 
                 return 1;
@@ -1446,7 +1549,7 @@ static int bus_unit_set_transient_property(
 int bus_unit_set_properties(
                 Unit *u,
                 sd_bus_message *message,
-                UnitSetPropertiesMode mode,
+                UnitWriteFlags flags,
                 bool commit,
                 sd_bus_error *error) {
 
@@ -1468,12 +1571,13 @@ int bus_unit_set_properties(
 
         for (;;) {
                 const char *name;
+                UnitWriteFlags f;
 
                 r = sd_bus_message_enter_container(message, 'r', "sv");
                 if (r < 0)
                         return r;
                 if (r == 0) {
-                        if (for_real || mode == UNIT_CHECK)
+                        if (for_real || UNIT_WRITE_FLAGS_NOOP(flags))
                                 break;
 
                         /* Reached EOF. Let's try again, and this time for realz... */
@@ -1496,11 +1600,17 @@ int bus_unit_set_properties(
                 if (r < 0)
                         return r;
 
-                r = UNIT_VTABLE(u)->bus_set_property(u, name, message, for_real ? mode : UNIT_CHECK, error);
+                /* If not for real, then mask out the two target flags */
+                f = for_real ? flags : (flags & ~(UNIT_RUNTIME|UNIT_PERSISTENT));
+
+                r = UNIT_VTABLE(u)->bus_set_property(u, name, message, f, error);
                 if (r == 0 && u->transient && u->load_state == UNIT_STUB)
-                        r = bus_unit_set_transient_property(u, name, message, for_real ? mode : UNIT_CHECK, error);
+                        r = bus_unit_set_transient_property(u, name, message, f, error);
+                if (r == 0)
+                        r = bus_unit_set_live_property(u, name, message, f, error);
                 if (r < 0)
                         return r;
+
                 if (r == 0)
                         return sd_bus_error_setf(error, SD_BUS_ERROR_PROPERTY_READ_ONLY, "Cannot set property %s, or unknown property.", name);
 
index b280de7..d7066ee 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -33,7 +34,7 @@ int bus_unit_method_start_generic(sd_bus_message *message, Unit *u, JobType job_
 int bus_unit_method_kill(sd_bus_message *message, void *userdata, sd_bus_error *error);
 int bus_unit_method_reset_failed(sd_bus_message *message, void *userdata, sd_bus_error *error);
 
-int bus_unit_set_properties(Unit *u, sd_bus_message *message, UnitSetPropertiesMode mode, bool commit, sd_bus_error *error);
+int bus_unit_set_properties(Unit *u, sd_bus_message *message, UnitWriteFlags flags, bool commit, sd_bus_error *error);
 int bus_unit_method_set_properties(sd_bus_message *message, void *userdata, sd_bus_error *error);
 int bus_unit_method_get_processes(sd_bus_message *message, void *userdata, sd_bus_error *error);
 int bus_unit_method_ref(sd_bus_message *message, void *userdata, sd_bus_error *error);
index 210b344..b7d8af9 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index a092ed9..fe50fdd 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index a5d701f..b538b06 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -256,60 +257,89 @@ static int device_update_description(Unit *u, struct udev_device *dev, const cha
 }
 
 static int device_add_udev_wants(Unit *u, struct udev_device *dev) {
-        const char *wants, *property, *p;
+        const char *wants, *property;
         int r;
 
         assert(u);
         assert(dev);
 
         property = MANAGER_IS_USER(u->manager) ? "SYSTEMD_USER_WANTS" : "SYSTEMD_WANTS";
+
         wants = udev_device_get_property_value(dev, property);
-        for (p = wants;;) {
+        if (!wants)
+                return 0;
+
+        for (;;) {
                 _cleanup_free_ char *word = NULL, *k = NULL;
 
-                r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES);
+                r = extract_first_word(&wants, &word, NULL, EXTRACT_QUOTES);
                 if (r == 0)
                         return 0;
                 if (r == -ENOMEM)
                         return log_oom();
                 if (r < 0)
-                        return log_unit_error_errno(u, r, "Failed to add parse %s: %m", property);
+                        return log_unit_error_errno(u, r, "Failed to parse property %s with value %s: %m", property, wants);
 
-                r = unit_name_mangle(word, UNIT_NAME_NOGLOB, &k);
-                if (r < 0)
-                        return log_unit_error_errno(u, r, "Failed to mangle unit name \"%s\": %m", word);
+                if (unit_name_is_valid(word, UNIT_NAME_TEMPLATE) && DEVICE(u)->sysfs) {
+                        _cleanup_free_ char *escaped = NULL;
+
+                        /* If the unit name is specified as template, then automatically fill in the sysfs path of the
+                         * device as instance name, properly escaped. */
+
+                        r = unit_name_path_escape(DEVICE(u)->sysfs, &escaped);
+                        if (r < 0)
+                                return log_unit_error_errno(u, r, "Failed to escape %s: %m", DEVICE(u)->sysfs);
+
+                        r = unit_name_replace_instance(word, escaped, &k);
+                        if (r < 0)
+                                return log_unit_error_errno(u, r, "Failed to build %s instance of template %s: %m", escaped, word);
+                } else {
+                        /* If this is not a template, then let's mangle it so, that it becomes a valid unit name. */
 
-                r = unit_add_dependency_by_name(u, UNIT_WANTS, k, NULL, true);
+                        r = unit_name_mangle(word, UNIT_NAME_NOGLOB, &k);
+                        if (r < 0)
+                                return log_unit_error_errno(u, r, "Failed to mangle unit name \"%s\": %m", word);
+                }
+
+                r = unit_add_dependency_by_name(u, UNIT_WANTS, k, NULL, true, UNIT_DEPENDENCY_UDEV);
                 if (r < 0)
-                        return log_unit_error_errno(u, r, "Failed to add wants dependency: %m");
+                        return log_unit_error_errno(u, r, "Failed to add Wants= dependency: %m");
         }
 }
 
-static bool device_is_bound_by_mounts(Unit *d, struct udev_device *dev) {
+static bool device_is_bound_by_mounts(Device *d, struct udev_device *dev) {
         const char *bound_by;
-        int r = false;
+        int r;
 
         assert(d);
         assert(dev);
 
         bound_by = udev_device_get_property_value(dev, "SYSTEMD_MOUNT_DEVICE_BOUND");
-        if (bound_by)
-                r = parse_boolean(bound_by) > 0;
+        if (bound_by) {
+                r = parse_boolean(bound_by);
+                if (r < 0)
+                        log_warning_errno(r, "Failed to parse SYSTEMD_MOUNT_DEVICE_BOUND='%s' udev property of %s, ignoring: %m", bound_by, strna(d->sysfs));
 
-        DEVICE(d)->bind_mounts = r;
-        return r;
+                d->bind_mounts = r > 0;
+        } else
+                d->bind_mounts = false;
+
+        return d->bind_mounts;
 }
 
 static int device_upgrade_mount_deps(Unit *u) {
         Unit *other;
         Iterator i;
+        void *v;
         int r;
 
-        SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY], i) {
+        /* Let's upgrade Requires= to BindsTo= on us. (Used when SYSTEMD_MOUNT_DEVICE_BOUND is set) */
+
+        HASHMAP_FOREACH_KEY(v, other, u->dependencies[UNIT_REQUIRED_BY], i) {
                 if (other->type != UNIT_MOUNT)
                         continue;
 
-                r = unit_add_dependency(other, UNIT_BINDS_TO, u, true);
+                r = unit_add_dependency(other, UNIT_BINDS_TO, u, true, UNIT_DEPENDENCY_UDEV);
                 if (r < 0)
                         return r;
         }
@@ -337,23 +367,26 @@ static int device_setup_unit(Manager *m, struct udev_device *dev, const char *pa
                 return log_error_errno(r, "Failed to generate unit name from device path: %m");
 
         u = manager_get_unit(m, e);
-
-        /* The device unit can still be present even if the device was
-         * unplugged: a mount unit can reference it hence preventing
-         * the GC to have garbaged it. That's desired since the device
-         * unit may have a dependency on the mount unit which was
-         * added during the loading of the later. */
-        if (dev && u && DEVICE(u)->state == DEVICE_PLUGGED) {
-                /* This unit is in plugged state: we're sure it's
-                 * attached to a device. */
-                if (!path_equal(DEVICE(u)->sysfs, sysfs)) {
-                        log_unit_debug(u, "Dev %s appeared twice with different sysfs paths %s and %s",
-                                       e, DEVICE(u)->sysfs, sysfs);
-                        return -EEXIST;
+        if (u) {
+                /* The device unit can still be present even if the device was unplugged: a mount unit can reference it hence
+                 * preventing the GC to have garbaged it. That's desired since the device unit may have a dependency on the
+                 * mount unit which was added during the loading of the later. */
+                if (dev && DEVICE(u)->state == DEVICE_PLUGGED) {
+
+                        /* This unit is in plugged state: we're sure it's attached to a device. */
+                        if (!path_equal(DEVICE(u)->sysfs, sysfs)) {
+                                log_unit_debug(u, "Dev %s appeared twice with different sysfs paths %s and %s",
+                                               e, DEVICE(u)->sysfs, sysfs);
+                                return -EEXIST;
+                        }
                 }
-        }
 
-        if (!u) {
+                delete = false;
+
+                /* Let's remove all dependencies generated due to udev properties. We'll readd whatever is configured
+                 * now below. */
+                unit_remove_dependencies(u, UNIT_DEPENDENCY_UDEV);
+        } else {
                 delete = true;
 
                 r = unit_new_for_name(m, sizeof(Device), e, &u);
@@ -361,8 +394,7 @@ static int device_setup_unit(Manager *m, struct udev_device *dev, const char *pa
                         goto fail;
 
                 unit_add_to_load_queue(u);
-        } else
-                delete = false;
+        }
 
         /* If this was created via some dependency and has not
          * actually been seen yet ->sysfs will not be
@@ -380,16 +412,13 @@ static int device_setup_unit(Manager *m, struct udev_device *dev, const char *pa
                         (void) device_add_udev_wants(u, dev);
         }
 
-        /* So the user wants the mount units to be bound to the device but a
-         * mount unit might has been seen by systemd before the device appears
-         * on its radar. In this case the device unit is partially initialized
-         * and includes the deps on the mount unit but at that time the "bind
-         * mounts" flag wasn't not present. Fix this up now. */
-        if (dev && device_is_bound_by_mounts(u, dev))
+        /* So the user wants the mount units to be bound to the device but a mount unit might has been seen by systemd
+         * before the device appears on its radar. In this case the device unit is partially initialized and includes
+         * the deps on the mount unit but at that time the "bind mounts" flag wasn't not present. Fix this up now. */
+        if (dev && device_is_bound_by_mounts(DEVICE(u), dev))
                 device_upgrade_mount_deps(u);
 
-        /* Note that this won't dispatch the load queue, the caller
-         * has to do that if needed and appropriate */
+        /* Note that this won't dispatch the load queue, the caller has to do that if needed and appropriate */
 
         unit_add_to_dbus_queue(u);
         return 0;
@@ -772,6 +801,26 @@ static int device_dispatch_io(sd_event_source *source, int fd, uint32_t revents,
                 return 0;
         }
 
+        if (streq(action, "change"))  {
+                _cleanup_free_ char *e = NULL;
+                Unit *u;
+
+                r = unit_name_from_path(sysfs, ".device", &e);
+                if (r < 0)
+                        log_error_errno(r, "Failed to generate unit name from device path: %m");
+                else {
+                        u = manager_get_unit(m, e);
+                        if (u && UNIT_VTABLE(u)->active_state(u) == UNIT_ACTIVE) {
+                                r = manager_propagate_reload(m, u, JOB_REPLACE, NULL);
+                                if (r < 0)
+                                        log_error_errno(r, "Failed to propagate reload: %m");
+                        }
+                }
+        }
+
+        /* A change event can signal that a device is becoming ready, in particular if
+         * the device is using the SYSTEMD_READY logic in udev
+         * so we need to reach the else block of the follwing if, even for change events */
         if (streq(action, "remove"))  {
                 r = swap_process_device_remove(m, dev);
                 if (r < 0)
index dd372fb..a551e77 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index f1b5ee7..3da31bf 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -82,7 +83,7 @@ static int dynamic_user_add(Manager *m, const char *name, int storage_socket[2],
         return 0;
 }
 
-int dynamic_user_acquire(Manager *m, const char *name, DynamicUser** ret) {
+static int dynamic_user_acquire(Manager *m, const char *name, DynamicUser** ret) {
         _cleanup_close_pair_ int storage_socket[2] = { -1, -1 };
         DynamicUser *d;
         int r;
@@ -146,7 +147,7 @@ int dynamic_user_acquire(Manager *m, const char *name, DynamicUser** ret) {
 
 static int make_uid_symlinks(uid_t uid, const char *name, bool b) {
 
-        char path1[strlen("/run/systemd/dynamic-uid/direct:") + DECIMAL_STR_MAX(uid_t) + 1];
+        char path1[STRLEN("/run/systemd/dynamic-uid/direct:") + DECIMAL_STR_MAX(uid_t) + 1];
         const char *path2;
         int r = 0, k;
 
@@ -174,7 +175,7 @@ static int make_uid_symlinks(uid_t uid, const char *name, bool b) {
                         r = k;
         }
 
-        if (b && symlink(path1 + strlen("/run/systemd/dynamic-uid/direct:"), path2) < 0) {
+        if (b && symlink(path1 + STRLEN("/run/systemd/dynamic-uid/direct:"), path2) < 0) {
                 k = log_warning_errno(errno,  "Failed to symlink \"%s\": %m", path2);
                 if (r == 0)
                         r = k;
@@ -217,7 +218,7 @@ static int pick_uid(char **suggested_paths, const char *name, uid_t *ret_uid) {
         (void) mkdir("/run/systemd/dynamic-uid", 0755);
 
         for (;;) {
-                char lock_path[strlen("/run/systemd/dynamic-uid/") + DECIMAL_STR_MAX(uid_t) + 1];
+                char lock_path[STRLEN("/run/systemd/dynamic-uid/") + DECIMAL_STR_MAX(uid_t) + 1];
                 _cleanup_close_ int lock_fd = -1;
                 uid_t candidate;
                 ssize_t l;
@@ -410,7 +411,7 @@ static int dynamic_user_push(DynamicUser *d, uid_t uid, int lock_fd) {
 }
 
 static void unlink_uid_lock(int lock_fd, uid_t uid, const char *name) {
-        char lock_path[strlen("/run/systemd/dynamic-uid/") + DECIMAL_STR_MAX(uid_t) + 1];
+        char lock_path[STRLEN("/run/systemd/dynamic-uid/") + DECIMAL_STR_MAX(uid_t) + 1];
 
         if (lock_fd < 0)
                 return;
@@ -421,31 +422,55 @@ static void unlink_uid_lock(int lock_fd, uid_t uid, const char *name) {
         (void) make_uid_symlinks(uid, name, false); /* remove direct lookup symlinks */
 }
 
-int dynamic_user_realize(DynamicUser *d, char **suggested_dirs, uid_t *ret) {
+static int lockfp(int fd, int *fd_lock) {
+        if (lockf(fd, F_LOCK, 0) < 0)
+                return -errno;
+        *fd_lock = fd;
+        return 0;
+}
 
-        _cleanup_close_ int etc_passwd_lock_fd = -1, uid_lock_fd = -1;
-        uid_t uid = UID_INVALID;
+static void unlockfp(int *fd_lock) {
+        if (*fd_lock < 0)
+                return;
+        lockf(*fd_lock, F_ULOCK, 0);
+        *fd_lock = -1;
+}
+
+static int dynamic_user_realize(
+                DynamicUser *d,
+                char **suggested_dirs,
+                uid_t *ret_uid, gid_t *ret_gid,
+                bool is_user) {
+
+        _cleanup_(unlockfp) int storage_socket0_lock = -1;
+        _cleanup_close_ int uid_lock_fd = -1;
+        _cleanup_close_ int etc_passwd_lock_fd = -1;
+        uid_t num = UID_INVALID; /* a uid if is_user, and a gid otherwise */
+        gid_t gid = GID_INVALID; /* a gid if is_user, ignored otherwise */
         int r;
 
         assert(d);
+        assert(is_user == !!ret_uid);
+        assert(ret_gid);
 
         /* Acquire a UID for the user name. This will allocate a UID for the user name if the user doesn't exist
          * yet. If it already exists its existing UID/GID will be reused. */
 
-        if (lockf(d->storage_socket[0], F_LOCK, 0) < 0)
-                return -errno;
+        r = lockfp(d->storage_socket[0], &storage_socket0_lock);
+        if (r < 0)
+                return r;
 
-        r = dynamic_user_pop(d, &uid, &uid_lock_fd);
+        r = dynamic_user_pop(d, &num, &uid_lock_fd);
         if (r < 0) {
                 int new_uid_lock_fd;
                 uid_t new_uid;
 
                 if (r != -EAGAIN)
-                        goto finish;
+                        return r;
 
                 /* OK, nothing stored yet, let's try to find something useful. While we are working on this release the
                  * lock however, so that nobody else blocks on our NSS lookups. */
-                (void) lockf(d->storage_socket[0], F_ULOCK, 0);
+                unlockfp(&storage_socket0_lock);
 
                 /* Let's see if a proper, static user or group by this name exists. Try to take the lock on
                  * /etc/passwd, if that fails with EROFS then /etc is read-only. In that case it's fine if we don't
@@ -455,47 +480,58 @@ int dynamic_user_realize(DynamicUser *d, char **suggested_dirs, uid_t *ret) {
                         return etc_passwd_lock_fd;
 
                 /* First, let's parse this as numeric UID */
-                r = parse_uid(d->name, &uid);
+                r = parse_uid(d->name, &num);
                 if (r < 0) {
                         struct passwd *p;
                         struct group *g;
 
-                        /* OK, this is not a numeric UID. Let's see if there's a user by this name */
-                        p = getpwnam(d->name);
-                        if (p)
-                                uid = p->pw_uid;
-
-                        /* Let's see if there's a group by this name */
-                        g = getgrnam(d->name);
-                        if (g) {
-                                /* If the UID/GID of the user/group of the same don't match, refuse operation */
-                                if (uid != UID_INVALID && uid != (uid_t) g->gr_gid)
-                                        return -EILSEQ;
-
-                                uid = (uid_t) g->gr_gid;
+                        if (is_user) {
+                                /* OK, this is not a numeric UID. Let's see if there's a user by this name */
+                                p = getpwnam(d->name);
+                                if (p) {
+                                        num = p->pw_uid;
+                                        gid = p->pw_gid;
+                                } else {
+                                        /* if the user does not exist but the group with the same name exists, refuse operation */
+                                        g = getgrnam(d->name);
+                                        if (g)
+                                                return -EILSEQ;
+                                }
+                        } else {
+                                /* Let's see if there's a group by this name */
+                                g = getgrnam(d->name);
+                                if (g)
+                                        num = (uid_t) g->gr_gid;
+                                else {
+                                        /* if the group does not exist but the user with the same name exists, refuse operation */
+                                        p = getpwnam(d->name);
+                                        if (p)
+                                                return -EILSEQ;
+                                }
                         }
                 }
 
-                if (uid == UID_INVALID) {
+                if (num == UID_INVALID) {
                         /* No static UID assigned yet, excellent. Let's pick a new dynamic one, and lock it. */
 
-                        uid_lock_fd = pick_uid(suggested_dirs, d->name, &uid);
+                        uid_lock_fd = pick_uid(suggested_dirs, d->name, &num);
                         if (uid_lock_fd < 0)
                                 return uid_lock_fd;
                 }
 
                 /* So, we found a working UID/lock combination. Let's see if we actually still need it. */
-                if (lockf(d->storage_socket[0], F_LOCK, 0) < 0) {
-                        unlink_uid_lock(uid_lock_fd, uid, d->name);
-                        return -errno;
+                r = lockfp(d->storage_socket[0], &storage_socket0_lock);
+                if (r < 0) {
+                        unlink_uid_lock(uid_lock_fd, num, d->name);
+                        return r;
                 }
 
                 r = dynamic_user_pop(d, &new_uid, &new_uid_lock_fd);
                 if (r < 0) {
                         if (r != -EAGAIN) {
                                 /* OK, something bad happened, let's get rid of the bits we acquired. */
-                                unlink_uid_lock(uid_lock_fd, uid, d->name);
-                                goto finish;
+                                unlink_uid_lock(uid_lock_fd, num, d->name);
+                                return r;
                         }
 
                         /* Great! Nothing is stored here, still. Store our newly acquired data. */
@@ -503,10 +539,10 @@ int dynamic_user_realize(DynamicUser *d, char **suggested_dirs, uid_t *ret) {
                         /* Hmm, so as it appears there's now something stored in the storage socket. Throw away what we
                          * acquired, and use what's stored now. */
 
-                        unlink_uid_lock(uid_lock_fd, uid, d->name);
+                        unlink_uid_lock(uid_lock_fd, num, d->name);
                         safe_close(uid_lock_fd);
 
-                        uid = new_uid;
+                        num = new_uid;
                         uid_lock_fd = new_uid_lock_fd;
                 }
         }
@@ -514,19 +550,21 @@ int dynamic_user_realize(DynamicUser *d, char **suggested_dirs, uid_t *ret) {
         /* If the UID/GID was already allocated dynamically, push the data we popped out back in. If it was already
          * allocated statically, push the UID back too, but do not push the lock fd in. If we allocated the UID
          * dynamically right here, push that in along with the lock fd for it. */
-        r = dynamic_user_push(d, uid, uid_lock_fd);
+        r = dynamic_user_push(d, num, uid_lock_fd);
         if (r < 0)
-                goto finish;
+                return r;
 
-        *ret = uid;
-        r = 0;
+        if (is_user) {
+                *ret_uid = num;
+                *ret_gid = gid != GID_INVALID ? gid : num;
+        } else
+                *ret_gid = num;
 
-finish:
-        (void) lockf(d->storage_socket[0], F_ULOCK, 0);
-        return r;
+        return 0;
 }
 
-int dynamic_user_current(DynamicUser *d, uid_t *ret) {
+static int dynamic_user_current(DynamicUser *d, uid_t *ret) {
+        _cleanup_(unlockfp) int storage_socket0_lock = -1;
         _cleanup_close_ int lock_fd = -1;
         uid_t uid;
         int r;
@@ -536,26 +574,23 @@ int dynamic_user_current(DynamicUser *d, uid_t *ret) {
 
         /* Get the currently assigned UID for the user, if there's any. This simply pops the data from the storage socket, and pushes it back in right-away. */
 
-        if (lockf(d->storage_socket[0], F_LOCK, 0) < 0)
-                return -errno;
+        r = lockfp(d->storage_socket[0], &storage_socket0_lock);
+        if (r < 0)
+                return r;
 
         r = dynamic_user_pop(d, &uid, &lock_fd);
         if (r < 0)
-                goto finish;
+                return r;
 
         r = dynamic_user_push(d, uid, lock_fd);
         if (r < 0)
-                goto finish;
+                return r;
 
         *ret = uid;
-        r = 0;
-
-finish:
-        (void) lockf(d->storage_socket[0], F_ULOCK, 0);
-        return r;
+        return 0;
 }
 
-DynamicUser* dynamic_user_ref(DynamicUser *d) {
+static DynamicUser* dynamic_user_ref(DynamicUser *d) {
         if (!d)
                 return NULL;
 
@@ -565,7 +600,7 @@ DynamicUser* dynamic_user_ref(DynamicUser *d) {
         return d;
 }
 
-DynamicUser* dynamic_user_unref(DynamicUser *d) {
+static DynamicUser* dynamic_user_unref(DynamicUser *d) {
         if (!d)
                 return NULL;
 
@@ -580,6 +615,7 @@ DynamicUser* dynamic_user_unref(DynamicUser *d) {
 }
 
 static int dynamic_user_close(DynamicUser *d) {
+        _cleanup_(unlockfp) int storage_socket0_lock = -1;
         _cleanup_close_ int lock_fd = -1;
         uid_t uid;
         int r;
@@ -587,28 +623,23 @@ static int dynamic_user_close(DynamicUser *d) {
         /* Release the user ID, by releasing the lock on it, and emptying the storage socket. After this the user is
          * unrealized again, much like it was after it the DynamicUser object was first allocated. */
 
-        if (lockf(d->storage_socket[0], F_LOCK, 0) < 0)
-                return -errno;
+        r = lockfp(d->storage_socket[0], &storage_socket0_lock);
+        if (r < 0)
+                return r;
 
         r = dynamic_user_pop(d, &uid, &lock_fd);
-        if (r == -EAGAIN) {
+        if (r == -EAGAIN)
                 /* User wasn't realized yet, nothing to do. */
-                r = 0;
-                goto finish;
-        }
+                return 0;
         if (r < 0)
-                goto finish;
+                return r;
 
         /* This dynamic user was realized and dynamically allocated. In this case, let's remove the lock file. */
         unlink_uid_lock(lock_fd, uid, d->name);
-        r = 1;
-
-finish:
-        (void) lockf(d->storage_socket[0], F_ULOCK, 0);
-        return r;
+        return 1;
 }
 
-DynamicUser* dynamic_user_destroy(DynamicUser *d) {
+static DynamicUser* dynamic_user_destroy(DynamicUser *d) {
         if (!d)
                 return NULL;
 
@@ -713,7 +744,7 @@ void dynamic_user_vacuum(Manager *m, bool close_user) {
 }
 
 int dynamic_user_lookup_uid(Manager *m, uid_t uid, char **ret) {
-        char lock_path[strlen("/run/systemd/dynamic-uid/") + DECIMAL_STR_MAX(uid_t) + 1];
+        char lock_path[STRLEN("/run/systemd/dynamic-uid/") + DECIMAL_STR_MAX(uid_t) + 1];
         _cleanup_free_ char *user = NULL;
         uid_t check_uid;
         int r;
@@ -814,21 +845,19 @@ int dynamic_creds_realize(DynamicCreds *creds, char **suggested_paths, uid_t *ui
         /* Realize both the referenced user and group */
 
         if (creds->user) {
-                r = dynamic_user_realize(creds->user, suggested_paths, &u);
+                r = dynamic_user_realize(creds->user, suggested_paths, &u, &g, true);
                 if (r < 0)
                         return r;
         }
 
         if (creds->group && creds->group != creds->user) {
-                r = dynamic_user_realize(creds->group, suggested_paths, &g);
+                r = dynamic_user_realize(creds->group, suggested_paths, NULL, &g, false);
                 if (r < 0)
                         return r;
-        } else
-                g = u;
+        }
 
         *uid = u;
         *gid = g;
-
         return 0;
 }
 
index e7de4f4..b073c65 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -43,15 +44,6 @@ struct DynamicUser {
         char name[];
 };
 
-int dynamic_user_acquire(Manager *m, const char *name, DynamicUser **ret);
-
-int dynamic_user_realize(DynamicUser *d, char **suggested_paths, uid_t *ret);
-int dynamic_user_current(DynamicUser *d, uid_t *ret);
-
-DynamicUser* dynamic_user_ref(DynamicUser *d);
-DynamicUser* dynamic_user_unref(DynamicUser *d);
-DynamicUser* dynamic_user_destroy(DynamicUser *d);
-
 int dynamic_user_serialize(Manager *m, FILE *f, FDSet *fds);
 void dynamic_user_deserialize_one(Manager *m, const char *value, FDSet *fds);
 void dynamic_user_vacuum(Manager *m, bool close_user);
index 90232bc..308608e 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -31,7 +32,7 @@
 static void log_and_status(Manager *m, const char *message, const char *reason) {
         log_warning("%s: %s", message, reason);
         manager_status_printf(m, STATUS_TYPE_EMERGENCY,
-                              ANSI_HIGHLIGHT_RED " !!  " ANSI_NORMAL,
+                              ANSI_HIGHLIGHT_RED "  !!  " ANSI_NORMAL,
                               "%s: %s", message, reason);
 }
 
index 8804b59..4079e84 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 2697132..01ec5b3 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -65,6 +66,7 @@
 #include "cap-list.h"
 #include "capability-util.h"
 #include "chown-recursive.h"
+#include "cpu-set-util.h"
 #include "def.h"
 #include "env-util.h"
 #include "errno-list.h"
@@ -97,6 +99,7 @@
 #include "signal-util.h"
 #include "smack-util.h"
 #include "special.h"
+#include "stat-util.h"
 #include "string-table.h"
 #include "string-util.h"
 #include "strv.h"
@@ -275,7 +278,7 @@ static bool exec_context_needs_term(const ExecContext *c) {
 }
 
 static int open_null_as(int flags, int nfd) {
-        int fd, r;
+        int fd;
 
         assert(nfd >= 0);
 
@@ -283,13 +286,7 @@ static int open_null_as(int flags, int nfd) {
         if (fd < 0)
                 return -errno;
 
-        if (fd != nfd) {
-                r = dup2(fd, nfd) < 0 ? -errno : nfd;
-                safe_close(fd);
-        } else
-                r = nfd;
-
-        return r;
+        return move_fd(fd, nfd, false);
 }
 
 static int connect_journal_socket(int fd, uid_t uid, gid_t gid) {
@@ -381,34 +378,78 @@ static int connect_logger_as(
                 is_kmsg_output(output),
                 is_terminal_output(output));
 
-        if (fd == nfd)
-                return nfd;
+        return move_fd(fd, nfd, false);
+}
+static int open_terminal_as(const char *path, int flags, int nfd) {
+        int fd;
 
-        r = dup2(fd, nfd) < 0 ? -errno : nfd;
-        safe_close(fd);
+        assert(path);
+        assert(nfd >= 0);
 
-        return r;
+        fd = open_terminal(path, flags | O_NOCTTY);
+        if (fd < 0)
+                return fd;
+
+        return move_fd(fd, nfd, false);
 }
-static int open_terminal_as(const char *path, mode_t mode, int nfd) {
+
+static int acquire_path(const char *path, int flags, mode_t mode) {
+        union sockaddr_union sa = {
+                .sa.sa_family = AF_UNIX,
+        };
         int fd, r;
 
         assert(path);
-        assert(nfd >= 0);
 
-        fd = open_terminal(path, mode | O_NOCTTY);
-        if (fd < 0)
+        if (IN_SET(flags & O_ACCMODE, O_WRONLY, O_RDWR))
+                flags |= O_CREAT;
+
+        fd = open(path, flags|O_NOCTTY, mode);
+        if (fd >= 0)
                 return fd;
 
-        if (fd != nfd) {
-                r = dup2(fd, nfd) < 0 ? -errno : nfd;
+        if (errno != ENXIO) /* ENXIO is returned when we try to open() an AF_UNIX file system socket on Linux */
+                return -errno;
+        if (strlen(path) > sizeof(sa.un.sun_path)) /* Too long, can't be a UNIX socket */
+                return -ENXIO;
+
+        /* So, it appears the specified path could be an AF_UNIX socket. Let's see if we can connect to it. */
+
+        fd = socket(AF_UNIX, SOCK_STREAM, 0);
+        if (fd < 0)
+                return -errno;
+
+        strncpy(sa.un.sun_path, path, sizeof(sa.un.sun_path));
+        if (connect(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) {
                 safe_close(fd);
-        } else
-                r = nfd;
+                return errno == EINVAL ? -ENXIO : -errno; /* Propagate initial error if we get EINVAL, i.e. we have
+                                                           * indication that his wasn't an AF_UNIX socket after all */
+        }
 
-        return r;
+        if ((flags & O_ACCMODE) == O_RDONLY)
+                r = shutdown(fd, SHUT_WR);
+        else if ((flags & O_ACCMODE) == O_WRONLY)
+                r = shutdown(fd, SHUT_RD);
+        else
+                return fd;
+        if (r < 0) {
+                safe_close(fd);
+                return -errno;
+        }
+
+        return fd;
 }
 
-static int fixup_input(ExecInput std_input, int socket_fd, bool apply_tty_stdin) {
+static int fixup_input(
+                const ExecContext *context,
+                int socket_fd,
+                bool apply_tty_stdin) {
+
+        ExecInput std_input;
+
+        assert(context);
+
+        std_input = context->std_input;
 
         if (is_terminal_input(std_input) && !apply_tty_stdin)
                 return EXEC_INPUT_NULL;
@@ -416,6 +457,9 @@ static int fixup_input(ExecInput std_input, int socket_fd, bool apply_tty_stdin)
         if (std_input == EXEC_INPUT_SOCKET && socket_fd < 0)
                 return EXEC_INPUT_NULL;
 
+        if (std_input == EXEC_INPUT_DATA && context->stdin_data_size == 0)
+                return EXEC_INPUT_NULL;
+
         return std_input;
 }
 
@@ -443,13 +487,15 @@ static int setup_input(
                         return -errno;
 
                 /* Try to make this the controlling tty, if it is a tty, and reset it */
-                (void) ioctl(STDIN_FILENO, TIOCSCTTY, context->std_input == EXEC_INPUT_TTY_FORCE);
-                (void) reset_terminal_fd(STDIN_FILENO, true);
+                if (isatty(STDIN_FILENO)) {
+                        (void) ioctl(STDIN_FILENO, TIOCSCTTY, context->std_input == EXEC_INPUT_TTY_FORCE);
+                        (void) reset_terminal_fd(STDIN_FILENO, true);
+                }
 
                 return STDIN_FILENO;
         }
 
-        i = fixup_input(context->std_input, socket_fd, params->flags & EXEC_APPLY_TTY_STDIN);
+        i = fixup_input(context, socket_fd, params->flags & EXEC_APPLY_TTY_STDIN);
 
         switch (i) {
 
@@ -459,7 +505,7 @@ static int setup_input(
         case EXEC_INPUT_TTY:
         case EXEC_INPUT_TTY_FORCE:
         case EXEC_INPUT_TTY_FAIL: {
-                int fd, r;
+                int fd;
 
                 fd = acquire_terminal(exec_context_tty_path(context),
                                       i == EXEC_INPUT_TTY_FAIL,
@@ -469,22 +515,46 @@ static int setup_input(
                 if (fd < 0)
                         return fd;
 
-                if (fd != STDIN_FILENO) {
-                        r = dup2(fd, STDIN_FILENO) < 0 ? -errno : STDIN_FILENO;
-                        safe_close(fd);
-                } else
-                        r = STDIN_FILENO;
-
-                return r;
+                return move_fd(fd, STDIN_FILENO, false);
         }
 
         case EXEC_INPUT_SOCKET:
+                assert(socket_fd >= 0);
+
                 return dup2(socket_fd, STDIN_FILENO) < 0 ? -errno : STDIN_FILENO;
 
         case EXEC_INPUT_NAMED_FD:
+                assert(named_iofds[STDIN_FILENO] >= 0);
+
                 (void) fd_nonblock(named_iofds[STDIN_FILENO], false);
                 return dup2(named_iofds[STDIN_FILENO], STDIN_FILENO) < 0 ? -errno : STDIN_FILENO;
 
+        case EXEC_INPUT_DATA: {
+                int fd;
+
+                fd = acquire_data_fd(context->stdin_data, context->stdin_data_size, 0);
+                if (fd < 0)
+                        return fd;
+
+                return move_fd(fd, STDIN_FILENO, false);
+        }
+
+        case EXEC_INPUT_FILE: {
+                bool rw;
+                int fd;
+
+                assert(context->stdio_file[STDIN_FILENO]);
+
+                rw = (context->std_output == EXEC_OUTPUT_FILE && streq_ptr(context->stdio_file[STDIN_FILENO], context->stdio_file[STDOUT_FILENO])) ||
+                        (context->std_error == EXEC_OUTPUT_FILE && streq_ptr(context->stdio_file[STDIN_FILENO], context->stdio_file[STDERR_FILENO]));
+
+                fd = acquire_path(context->stdio_file[STDIN_FILENO], rw ? O_RDWR : O_RDONLY, 0666 & ~context->umask);
+                if (fd < 0)
+                        return fd;
+
+                return move_fd(fd, STDIN_FILENO, false);
+        }
+
         default:
                 assert_not_reached("Unknown input type");
         }
@@ -529,7 +599,7 @@ static int setup_output(
                 return STDERR_FILENO;
         }
 
-        i = fixup_input(context->std_input, socket_fd, params->flags & EXEC_APPLY_TTY_STDIN);
+        i = fixup_input(context, socket_fd, params->flags & EXEC_APPLY_TTY_STDIN);
         o = fixup_output(context->std_output, socket_fd);
 
         if (fileno == STDERR_FILENO) {
@@ -558,8 +628,8 @@ static int setup_output(
                 if (i == EXEC_INPUT_NULL && is_terminal_input(context->std_input))
                         return open_terminal_as(exec_context_tty_path(context), O_WRONLY, fileno);
 
-                /* If the input is connected to anything that's not a /dev/null, inherit that... */
-                if (i != EXEC_INPUT_NULL)
+                /* If the input is connected to anything that's not a /dev/null or a data fd, inherit that... */
+                if (!IN_SET(i, EXEC_INPUT_NULL, EXEC_INPUT_DATA))
                         return dup2(STDIN_FILENO, fileno) < 0 ? -errno : fileno;
 
                 /* If we are not started from PID 1 we just inherit STDOUT from our parent process. */
@@ -612,12 +682,34 @@ static int setup_output(
 
         case EXEC_OUTPUT_SOCKET:
                 assert(socket_fd >= 0);
+
                 return dup2(socket_fd, fileno) < 0 ? -errno : fileno;
 
         case EXEC_OUTPUT_NAMED_FD:
+                assert(named_iofds[fileno] >= 0);
+
                 (void) fd_nonblock(named_iofds[fileno], false);
                 return dup2(named_iofds[fileno], fileno) < 0 ? -errno : fileno;
 
+        case EXEC_OUTPUT_FILE: {
+                bool rw;
+                int fd;
+
+                assert(context->stdio_file[fileno]);
+
+                rw = context->std_input == EXEC_INPUT_FILE &&
+                        streq_ptr(context->stdio_file[fileno], context->stdio_file[STDIN_FILENO]);
+
+                if (rw)
+                        return dup2(STDIN_FILENO, fileno) < 0 ? -errno : fileno;
+
+                fd = acquire_path(context->stdio_file[fileno], O_WRONLY, 0666 & ~context->umask);
+                if (fd < 0)
+                        return fd;
+
+                return move_fd(fd, fileno, false);
+        }
+
         default:
                 assert_not_reached("Unknown error type");
         }
@@ -962,14 +1054,11 @@ static int get_supplementary_groups(const ExecContext *c, const char *user,
         return 0;
 }
 
-static int enforce_groups(const ExecContext *context, gid_t gid,
-                          gid_t *supplementary_gids, int ngids) {
+static int enforce_groups(gid_t gid, gid_t *supplementary_gids, int ngids) {
         int r;
 
-        assert(context);
-
-        /* Handle SupplementaryGroups= even if it is empty */
-        if (!strv_isempty(context->supplementary_groups)) {
+        /* Handle SupplementaryGroups= if it is not empty */
+        if (ngids > 0) {
                 r = maybe_setgroups(ngids, supplementary_gids);
                 if (r < 0)
                         return r;
@@ -1314,7 +1403,7 @@ static bool context_has_syscall_filters(const ExecContext *c) {
         assert(c);
 
         return c->syscall_whitelist ||
-                !set_isempty(c->syscall_filter);
+                !hashmap_isempty(c->syscall_filter);
 }
 
 static bool context_has_no_new_privileges(const ExecContext *c) {
@@ -1729,7 +1818,12 @@ static bool exec_needs_mount_namespace(
             !strv_isempty(context->inaccessible_paths))
                 return true;
 
-        if (context->n_bind_mounts > 0)
+        if (context->n_bind_mounts > 0 ||
+            !strv_isempty(context->directories[EXEC_DIRECTORY_RUNTIME].paths) ||
+            !strv_isempty(context->directories[EXEC_DIRECTORY_STATE].paths) ||
+            !strv_isempty(context->directories[EXEC_DIRECTORY_CACHE].paths) ||
+            !strv_isempty(context->directories[EXEC_DIRECTORY_LOGS].paths) ||
+            !strv_isempty(context->directories[EXEC_DIRECTORY_CONFIGURATION].paths))
                 return true;
 
         if (context->mount_flags != 0)
@@ -1749,13 +1843,6 @@ static bool exec_needs_mount_namespace(
         if (context->mount_apivfs && (context->root_image || context->root_directory))
                 return true;
 
-        if (context->dynamic_user &&
-            (!strv_isempty(context->directories[EXEC_DIRECTORY_RUNTIME].paths) ||
-             !strv_isempty(context->directories[EXEC_DIRECTORY_STATE].paths) ||
-             !strv_isempty(context->directories[EXEC_DIRECTORY_CACHE].paths) ||
-             !strv_isempty(context->directories[EXEC_DIRECTORY_LOGS].paths)))
-                return true;
-
         return false;
 }
 
@@ -1965,7 +2052,8 @@ static int setup_exec_directory(
                 if (r < 0)
                         goto fail;
 
-                if (context->dynamic_user && type != EXEC_DIRECTORY_CONFIGURATION) {
+                if (context->dynamic_user &&
+                    !IN_SET(type, EXEC_DIRECTORY_RUNTIME, EXEC_DIRECTORY_CONFIGURATION)) {
                         _cleanup_free_ char *private_root = NULL, *relative = NULL, *parent = NULL;
 
                         /* So, here's one extra complication when dealing with DynamicUser=1 units. In that case we
@@ -1986,7 +2074,9 @@ static int setup_exec_directory(
                          * dirs it needs but no others. Tricky? Yes, absolutely, but it works!
                          *
                          * Note that we don't do this for EXEC_DIRECTORY_CONFIGURATION as that's assumed not to be
-                         * owned by the service itself. */
+                         * owned by the service itself.
+                         * Also, note that we don't do this for EXEC_DIRECTORY_RUNTIME as that's often used for sharing
+                         * files or sockets with other services. */
 
                         private_root = strjoin(params->prefix[type], "/private");
                         if (!private_root) {
@@ -1995,7 +2085,7 @@ static int setup_exec_directory(
                         }
 
                         /* First set up private root if it doesn't exist yet, with access mode 0700 and owned by root:root */
-                        r = mkdir_safe_label(private_root, 0700, 0, 0);
+                        r = mkdir_safe_label(private_root, 0700, 0, 0, false);
                         if (r < 0)
                                 goto fail;
 
@@ -2010,10 +2100,24 @@ static int setup_exec_directory(
                         if (r < 0)
                                 goto fail;
 
-                        /* Finally, create the actual directory for the service */
-                        r = mkdir_label(pp, context->directories[type].mode);
-                        if (r < 0 && r != -EEXIST)
-                                goto fail;
+                        if (is_dir(p, false) > 0 &&
+                            (laccess(pp, F_OK) < 0 && errno == ENOENT)) {
+
+                                /* Hmm, the private directory doesn't exist yet, but the normal one exists? If so, move
+                                 * it over. Most likely the service has been upgraded from one that didn't use
+                                 * DynamicUser=1, to one that does. */
+
+                                if (rename(p, pp) < 0) {
+                                        r = -errno;
+                                        goto fail;
+                                }
+                        } else {
+                                /* Otherwise, create the actual directory for the service */
+
+                                r = mkdir_label(pp, context->directories[type].mode);
+                                if (r < 0 && r != -EEXIST)
+                                        goto fail;
+                        }
 
                         parent = dirname_malloc(p);
                         if (!parent) {
@@ -2064,6 +2168,7 @@ fail:
         return r;
 }
 
+#if ENABLE_SMACK
 static int setup_smack(
                 const ExecContext *context,
                 const ExecCommand *command) {
@@ -2094,55 +2199,7 @@ static int setup_smack(
 
         return 0;
 }
-
-static int compile_read_write_paths(
-                const ExecContext *context,
-                const ExecParameters *params,
-                char ***ret) {
-
-        _cleanup_strv_free_ char **l = NULL;
-        char **rt;
-        ExecDirectoryType i;
-
-        /* Compile the list of writable paths. This is the combination of
-         * the explicitly configured paths, plus all runtime directories. */
-
-        if (strv_isempty(context->read_write_paths)) {
-                for (i = 0; i < _EXEC_DIRECTORY_TYPE_MAX; i++)
-                        if (!strv_isempty(context->directories[i].paths))
-                                break;
-
-                if (i == _EXEC_DIRECTORY_TYPE_MAX) {
-                        *ret = NULL; /* NOP if neither is set */
-                        return 0;
-                }
-        }
-
-        l = strv_copy(context->read_write_paths);
-        if (!l)
-                return -ENOMEM;
-
-        for (i = 0; i < _EXEC_DIRECTORY_TYPE_MAX; i++) {
-                if (!params->prefix[i])
-                        continue;
-
-                STRV_FOREACH(rt, context->directories[i].paths) {
-                        char *s;
-
-                        s = strjoin(params->prefix[i], "/", *rt);
-                        if (!s)
-                                return -ENOMEM;
-
-                        if (strv_consume(&l, s) < 0)
-                                return -ENOMEM;
-                }
-        }
-
-        *ret = l;
-        l = NULL;
-
-        return 0;
-}
+#endif
 
 static int compile_bind_mounts(
                 const ExecContext *context,
@@ -2182,7 +2239,7 @@ static int compile_bind_mounts(
         if (!bind_mounts)
                 return -ENOMEM;
 
-        for (i = 0; context->n_bind_mounts; i++) {
+        for (i = 0; i < context->n_bind_mounts; i++) {
                 BindMount *item = context->bind_mounts + i;
                 char *s, *d;
 
@@ -2217,7 +2274,8 @@ static int compile_bind_mounts(
                 if (strv_isempty(context->directories[t].paths))
                         continue;
 
-                if (context->dynamic_user && t != EXEC_DIRECTORY_CONFIGURATION) {
+                if (context->dynamic_user &&
+                    !IN_SET(t, EXEC_DIRECTORY_RUNTIME, EXEC_DIRECTORY_CONFIGURATION)) {
                         char *private_root;
 
                         /* So this is for a dynamic user, and we need to make sure the process can access its own
@@ -2240,7 +2298,8 @@ static int compile_bind_mounts(
                 STRV_FOREACH(suffix, context->directories[t].paths) {
                         char *s, *d;
 
-                        if (context->dynamic_user && t != EXEC_DIRECTORY_CONFIGURATION)
+                        if (context->dynamic_user &&
+                            !IN_SET(t, EXEC_DIRECTORY_RUNTIME, EXEC_DIRECTORY_CONFIGURATION))
                                 s = strjoin(params->prefix[t], "/private/", *suffix);
                         else
                                 s = strjoin(params->prefix[t], "/", *suffix);
@@ -2288,10 +2347,10 @@ static int apply_mount_namespace(
                 const ExecParameters *params,
                 ExecRuntime *runtime) {
 
-        _cleanup_strv_free_ char **rw = NULL, **empty_directories = NULL;
+        _cleanup_strv_free_ char **empty_directories = NULL;
         char *tmp = NULL, *var = NULL;
         const char *root_dir = NULL, *root_image = NULL;
-        NameSpaceInfo ns_info = {
+        NamespaceInfo ns_info = {
                 .ignore_protect_paths = false,
                 .private_dev = context->private_devices,
                 .protect_control_groups = context->protect_control_groups,
@@ -2317,10 +2376,6 @@ static int apply_mount_namespace(
                         var = strjoina(runtime->var_tmp_dir, "/tmp");
         }
 
-        r = compile_read_write_paths(context, params, &rw);
-        if (r < 0)
-                return r;
-
         if (params->flags & EXEC_APPLY_CHROOT) {
                 root_image = context->root_image;
 
@@ -2343,7 +2398,7 @@ static int apply_mount_namespace(
         needs_sandboxing = (params->flags & EXEC_APPLY_SANDBOXING) && !(command->flags & EXEC_COMMAND_FULLY_PRIVILEGED);
 
         r = setup_namespace(root_dir, root_image,
-                            &ns_info, rw,
+                            &ns_info, context->read_write_paths,
                             needs_sandboxing ? context->read_only_paths : NULL,
                             needs_sandboxing ? context->inaccessible_paths : NULL,
                             empty_directories,
@@ -2665,7 +2720,10 @@ static int compile_suggested_paths(const ExecContext *c, const ExecParameters *p
                 STRV_FOREACH(i, c->directories[t].paths) {
                         char *e;
 
-                        e = strjoin(p->prefix[t], "/private/", *i);
+                        if (t == EXEC_DIRECTORY_RUNTIME)
+                                e = strjoin(p->prefix[t], "/", *i);
+                        else
+                                e = strjoin(p->prefix[t], "/private/", *i);
                         if (!e)
                                 return -ENOMEM;
 
@@ -2699,7 +2757,7 @@ static int exec_child(
                 int *exit_status) {
 
         _cleanup_strv_free_ char **our_env = NULL, **pass_env = NULL, **accum_env = NULL, **final_argv = NULL;
-        _cleanup_free_ char *mac_selinux_context_net = NULL, *home_buffer = NULL;
+        _cleanup_free_ char *home_buffer = NULL;
         _cleanup_free_ gid_t *supplementary_gids = NULL;
         const char *username = NULL, *groupname = NULL;
         const char *home = NULL, *shell = NULL;
@@ -2710,6 +2768,7 @@ static int exec_child(
                 needs_mount_namespace,  /* Do we need to set up a mount namespace for this kernel? */
                 needs_ambient_hack;     /* Do we need to apply the ambient capabilities hack? */
 #if HAVE_SELINUX
+        _cleanup_free_ char *mac_selinux_context_net = NULL;
         bool use_selinux = false;
 #endif
 #if ENABLE_SMACK
@@ -2819,6 +2878,10 @@ static int exec_child(
                 r = dynamic_creds_realize(dcreds, suggested_paths, &uid, &gid);
                 if (r < 0) {
                         *exit_status = EXIT_USER;
+                        if (r == -EILSEQ) {
+                                log_unit_error(unit, "Failed to update dynamic user credentials: User or group with specified name already exists.");
+                                return -EOPNOTSUPP;
+                        }
                         return log_unit_error_errno(unit, r, "Failed to update dynamic user credentials: %m");
                 }
 
@@ -2986,17 +3049,12 @@ static int exec_child(
                 }
         }
 
-        /* If delegation is enabled we'll pass ownership of the cgroup
-         * (but only in systemd's own controller hierarchy!) to the
-         * user of the new process. */
+        /* If delegation is enabled we'll pass ownership of the cgroup to the user of the new process. On cgroupsv1
+         * this is only about systemd's own hierarchy, i.e. not the controller hierarchies, simply because that's not
+         * safe. On cgroupsv2 there's only one hierarchy anyway, and delegation is safe there, hence in that case only
+         * touch a single hierarchy too. */
         if (params->cgroup_path && context->user && (params->flags & EXEC_CGROUP_DELEGATE)) {
-                r = cg_set_task_access(SYSTEMD_CGROUP_CONTROLLER, params->cgroup_path, 0644, uid, gid);
-                if (r < 0) {
-                        *exit_status = EXIT_CGROUP;
-                        return log_unit_error_errno(unit, r, "Failed to adjust control group access: %m");
-                }
-
-                r = cg_set_group_access(SYSTEMD_CGROUP_CONTROLLER, params->cgroup_path, 0755, uid, gid);
+                r = cg_set_access(SYSTEMD_CGROUP_CONTROLLER, params->cgroup_path, uid, gid);
                 if (r < 0) {
                         *exit_status = EXIT_CGROUP;
                         return log_unit_error_errno(unit, r, "Failed to adjust control group access: %m");
@@ -3091,11 +3149,14 @@ static int exec_child(
         }
 
         if (context->private_network && runtime && runtime->netns_storage_socket[0] >= 0) {
-                r = setup_netns(runtime->netns_storage_socket);
-                if (r < 0) {
-                        *exit_status = EXIT_NETWORK;
-                        return log_unit_error_errno(unit, r, "Failed to set up network namespacing: %m");
-                }
+                if (ns_type_supported(NAMESPACE_NET)) {
+                        r = setup_netns(runtime->netns_storage_socket);
+                        if (r < 0) {
+                                *exit_status = EXIT_NETWORK;
+                                return log_unit_error_errno(unit, r, "Failed to set up network namespacing: %m");
+                        }
+                } else
+                        log_unit_warning(unit, "PrivateNetwork=yes is configured, but the kernel does not support network namespaces, ignoring.");
         }
 
         needs_mount_namespace = exec_needs_mount_namespace(context, params, runtime);
@@ -3114,7 +3175,7 @@ static int exec_child(
 
         /* Drop groups as early as possbile */
         if (needs_setuid) {
-                r = enforce_groups(context, gid, supplementary_gids, ngids);
+                r = enforce_groups(gid, supplementary_gids, ngids);
                 if (r < 0) {
                         *exit_status = EXIT_GROUP;
                         return log_unit_error_errno(unit, r, "Changing group credentials failed: %m");
@@ -3179,6 +3240,18 @@ static int exec_child(
                         }
                 }
 
+#if ENABLE_SMACK
+                /* LSM Smack needs the capability CAP_MAC_ADMIN to change the current execution security context of the
+                 * process. This is the latest place before dropping capabilities. Other MAC context are set later. */
+                if (use_smack) {
+                        r = setup_smack(context, command);
+                        if (r < 0) {
+                                *exit_status = EXIT_SMACK_PROCESS_LABEL;
+                                return log_unit_error_errno(unit, r, "Failed to set SMACK process label: %m");
+                        }
+                }
+#endif
+
                 bset = context->capability_bounding_set;
                 /* If the ambient caps hack is enabled (which means the kernel can't do them, and the user asked for
                  * our magic fallback), then let's add some extra caps, so that the service can drop privs of its own,
@@ -3255,7 +3328,7 @@ static int exec_child(
         }
 
         if (needs_sandboxing) {
-                /* Apply the MAC contexts late, but before seccomp syscall filtering, as those should really be last to
+                /* Apply other MAC contexts late, but before seccomp syscall filtering, as those should really be last to
                  * influence our own codepaths as little as possible. Moreover, applying MAC contexts usually requires
                  * syscalls that are subject to seccomp filtering, hence should probably be applied before the syscalls
                  * are restricted. */
@@ -3274,16 +3347,6 @@ static int exec_child(
                 }
 #endif
 
-#if ENABLE_SMACK
-                if (use_smack) {
-                        r = setup_smack(context, command);
-                        if (r < 0) {
-                                *exit_status = EXIT_SMACK_PROCESS_LABEL;
-                                return log_unit_error_errno(unit, r, "Failed to set SMACK process label: %m");
-                        }
-                }
-#endif
-
 #if HAVE_APPARMOR
                 if (use_apparmor && context->apparmor_profile) {
                         r = aa_change_onexec(context->apparmor_profile);
@@ -3569,11 +3632,12 @@ void exec_context_init(ExecContext *c) {
                 c->directories[i].mode = 0755;
         c->capability_bounding_set = CAP_ALL;
         c->restrict_namespaces = NAMESPACE_FLAGS_ALL;
+        c->log_level_max = -1;
 }
 
 void exec_context_done(ExecContext *c) {
-        unsigned l;
         ExecDirectoryType i;
+        size_t l;
 
         assert(c);
 
@@ -3585,8 +3649,10 @@ void exec_context_done(ExecContext *c) {
         for (l = 0; l < ELEMENTSOF(c->rlimit); l++)
                 c->rlimit[l] = mfree(c->rlimit[l]);
 
-        for (l = 0; l < 3; l++)
+        for (l = 0; l < 3; l++) {
                 c->stdio_fdname[l] = mfree(c->stdio_fdname[l]);
+                c->stdio_file[l] = mfree(c->stdio_file[l]);
+        }
 
         c->working_directory = mfree(c->working_directory);
         c->root_directory = mfree(c->root_directory);
@@ -3611,20 +3677,26 @@ void exec_context_done(ExecContext *c) {
 
         bind_mount_free_many(c->bind_mounts, c->n_bind_mounts);
 
-        if (c->cpuset)
-                CPU_FREE(c->cpuset);
+        c->cpuset = cpu_set_mfree(c->cpuset);
 
         c->utmp_id = mfree(c->utmp_id);
         c->selinux_context = mfree(c->selinux_context);
         c->apparmor_profile = mfree(c->apparmor_profile);
         c->smack_process_label = mfree(c->smack_process_label);
 
-        c->syscall_filter = set_free(c->syscall_filter);
+        c->syscall_filter = hashmap_free(c->syscall_filter);
         c->syscall_archs = set_free(c->syscall_archs);
         c->address_families = set_free(c->address_families);
 
         for (i = 0; i < _EXEC_DIRECTORY_TYPE_MAX; i++)
                 c->directories[i].paths = strv_free(c->directories[i].paths);
+
+        c->log_level_max = -1;
+
+        exec_context_free_log_extra_fields(c);
+
+        c->stdin_data = mfree(c->stdin_data);
+        c->stdin_data_size = 0;
 }
 
 int exec_context_destroy_runtime_directory(ExecContext *c, const char *runtime_prefix) {
@@ -3645,18 +3717,6 @@ int exec_context_destroy_runtime_directory(ExecContext *c, const char *runtime_p
                 /* We execute this synchronously, since we need to be sure this is gone when we start the service
                  * next. */
                 (void) rm_rf(p, REMOVE_ROOT);
-
-                /* Also destroy any matching subdirectory below /private/. This is done to support DynamicUser=1
-                 * setups. Note that we don't conditionalize here on that though, as the namespace is same way, and it
-                 * makes us a bit more robust towards changing unit settings. Or to say this differently: in the worst
-                 * case this is a NOP. */
-
-                free(p);
-                p = strjoin(runtime_prefix, "/private/", *i);
-                if (!p)
-                        return -ENOMEM;
-
-                (void) rm_rf(p, REMOVE_ROOT);
         }
 
         return 0;
@@ -3711,18 +3771,25 @@ const char* exec_context_fdname(const ExecContext *c, int fd_index) {
         assert(c);
 
         switch (fd_index) {
+
         case STDIN_FILENO:
                 if (c->std_input != EXEC_INPUT_NAMED_FD)
                         return NULL;
+
                 return c->stdio_fdname[STDIN_FILENO] ?: "stdin";
+
         case STDOUT_FILENO:
                 if (c->std_output != EXEC_OUTPUT_NAMED_FD)
                         return NULL;
+
                 return c->stdio_fdname[STDOUT_FILENO] ?: "stdout";
+
         case STDERR_FILENO:
                 if (c->std_error != EXEC_OUTPUT_NAMED_FD)
                         return NULL;
+
                 return c->stdio_fdname[STDERR_FILENO] ?: "stderr";
+
         default:
                 return NULL;
         }
@@ -3835,7 +3902,7 @@ int exec_context_load_environment(Unit *unit, const ExecContext *c, char ***l) {
                                 p = strv_env_clean_with_callback(p, invalid_env, &info);
                         }
 
-                        if (r == NULL)
+                        if (!r)
                                 r = p;
                         else {
                                 char **m;
@@ -3899,9 +3966,9 @@ static void strv_fprintf(FILE *f, char **l) {
 }
 
 void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) {
+        ExecDirectoryType dt;
         char **e, **d;
         unsigned i;
-        ExecDirectoryType dt;
         int r;
 
         assert(c);
@@ -4032,6 +4099,20 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) {
                 prefix, exec_output_to_string(c->std_output),
                 prefix, exec_output_to_string(c->std_error));
 
+        if (c->std_input == EXEC_INPUT_NAMED_FD)
+                fprintf(f, "%sStandardInputFileDescriptorName: %s\n", prefix, c->stdio_fdname[STDIN_FILENO]);
+        if (c->std_output == EXEC_OUTPUT_NAMED_FD)
+                fprintf(f, "%sStandardOutputFileDescriptorName: %s\n", prefix, c->stdio_fdname[STDOUT_FILENO]);
+        if (c->std_error == EXEC_OUTPUT_NAMED_FD)
+                fprintf(f, "%sStandardErrorFileDescriptorName: %s\n", prefix, c->stdio_fdname[STDERR_FILENO]);
+
+        if (c->std_input == EXEC_INPUT_FILE)
+                fprintf(f, "%sStandardInputFile: %s\n", prefix, c->stdio_file[STDIN_FILENO]);
+        if (c->std_output == EXEC_OUTPUT_FILE)
+                fprintf(f, "%sStandardOutputFile: %s\n", prefix, c->stdio_file[STDOUT_FILENO]);
+        if (c->std_error == EXEC_OUTPUT_FILE)
+                fprintf(f, "%sStandardErrorFile: %s\n", prefix, c->stdio_file[STDERR_FILENO]);
+
         if (c->tty_path)
                 fprintf(f,
                         "%sTTYPath: %s\n"
@@ -4077,6 +4158,26 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) {
                         fprintf(f, "%sCapabilities: %s\n", prefix, t);
         }
 
+        if (c->log_level_max >= 0) {
+                _cleanup_free_ char *t = NULL;
+
+                (void) log_level_to_string_alloc(c->log_level_max, &t);
+
+                fprintf(f, "%sLogLevelMax: %s\n", prefix, strna(t));
+        }
+
+        if (c->n_log_extra_fields > 0) {
+                size_t j;
+
+                for (j = 0; j < c->n_log_extra_fields; j++) {
+                        fprintf(f, "%sLogExtraFields: ", prefix);
+                        fwrite(c->log_extra_fields[j].iov_base,
+                               1, c->log_extra_fields[j].iov_len,
+                               f);
+                        fputc('\n', f);
+                }
+        }
+
         if (c->secure_bits) {
                 _cleanup_free_ char *str = NULL;
 
@@ -4176,7 +4277,7 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) {
         if (c->syscall_filter) {
 #if HAVE_SECCOMP
                 Iterator j;
-                void *id;
+                void *id, *val;
                 bool first = true;
 #endif
 
@@ -4188,8 +4289,10 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) {
                         fputc('~', f);
 
 #if HAVE_SECCOMP
-                SET_FOREACH(id, c->syscall_filter, j) {
+                HASHMAP_FOREACH_KEY(val, id, c->syscall_filter, j) {
                         _cleanup_free_ char *name = NULL;
+                        const char *errno_name = NULL;
+                        int num = PTR_TO_INT(val);
 
                         if (first)
                                 first = false;
@@ -4198,6 +4301,14 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) {
 
                         name = seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE, PTR_TO_INT(id) - 1);
                         fputs(strna(name), f);
+
+                        if (num >= 0) {
+                                errno_name = errno_to_name(num);
+                                if (errno_name)
+                                        fprintf(f, ":%s", errno_name);
+                                else
+                                        fprintf(f, ":%d", num);
+                        }
                 }
 #endif
 
@@ -4230,10 +4341,17 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) {
                                 prefix, s);
         }
 
-        if (c->syscall_errno > 0)
-                fprintf(f,
-                        "%sSystemCallErrorNumber: %s\n",
-                        prefix, strna(errno_to_name(c->syscall_errno)));
+        if (c->syscall_errno > 0) {
+                const char *errno_name;
+
+                fprintf(f, "%sSystemCallErrorNumber: ", prefix);
+
+                errno_name = errno_to_name(c->syscall_errno);
+                if (errno_name)
+                        fprintf(f, "%s\n", errno_name);
+                else
+                        fprintf(f, "%d\n", c->syscall_errno);
+        }
 
         if (c->apparmor_profile)
                 fprintf(f,
@@ -4271,6 +4389,17 @@ int exec_context_get_effective_ioprio(ExecContext *c) {
         return p;
 }
 
+void exec_context_free_log_extra_fields(ExecContext *c) {
+        size_t l;
+
+        assert(c);
+
+        for (l = 0; l < c->n_log_extra_fields; l++)
+                free(c->log_extra_fields[l].iov_base);
+        c->log_extra_fields = mfree(c->log_extra_fields);
+        c->n_log_extra_fields = 0;
+}
+
 void exec_status_start(ExecStatus *s, pid_t pid) {
         assert(s);
 
@@ -4688,6 +4817,8 @@ static const char* const exec_input_table[_EXEC_INPUT_MAX] = {
         [EXEC_INPUT_TTY_FAIL] = "tty-fail",
         [EXEC_INPUT_SOCKET] = "socket",
         [EXEC_INPUT_NAMED_FD] = "fd",
+        [EXEC_INPUT_DATA] = "data",
+        [EXEC_INPUT_FILE] = "file",
 };
 
 DEFINE_STRING_TABLE_LOOKUP(exec_input, ExecInput);
@@ -4704,6 +4835,7 @@ static const char* const exec_output_table[_EXEC_OUTPUT_MAX] = {
         [EXEC_OUTPUT_JOURNAL_AND_CONSOLE] = "journal+console",
         [EXEC_OUTPUT_SOCKET] = "socket",
         [EXEC_OUTPUT_NAMED_FD] = "fd",
+        [EXEC_OUTPUT_FILE] = "file",
 };
 
 DEFINE_STRING_TABLE_LOOKUP(exec_output, ExecOutput);
index fceed3f..8d9e0de 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -37,6 +38,8 @@ typedef struct ExecParameters ExecParameters;
 #include "namespace.h"
 #include "nsflags.h"
 
+#define EXEC_STDIN_DATA_MAX (64U*1024U*1024U)
+
 typedef enum ExecUtmpMode {
         EXEC_UTMP_INIT,
         EXEC_UTMP_LOGIN,
@@ -52,6 +55,8 @@ typedef enum ExecInput {
         EXEC_INPUT_TTY_FAIL,
         EXEC_INPUT_SOCKET,
         EXEC_INPUT_NAMED_FD,
+        EXEC_INPUT_DATA,
+        EXEC_INPUT_FILE,
         _EXEC_INPUT_MAX,
         _EXEC_INPUT_INVALID = -1
 } ExecInput;
@@ -68,6 +73,7 @@ typedef enum ExecOutput {
         EXEC_OUTPUT_JOURNAL_AND_CONSOLE,
         EXEC_OUTPUT_SOCKET,
         EXEC_OUTPUT_NAMED_FD,
+        EXEC_OUTPUT_FILE,
         _EXEC_OUTPUT_MAX,
         _EXEC_OUTPUT_INVALID = -1
 } ExecOutput;
@@ -162,6 +168,10 @@ struct ExecContext {
         ExecOutput std_output;
         ExecOutput std_error;
         char *stdio_fdname[3];
+        char *stdio_file[3];
+
+        void *stdin_data;
+        size_t stdin_data_size;
 
         nsec_t timer_slack_nsec;
 
@@ -214,6 +224,11 @@ struct ExecContext {
         char *syslog_identifier;
         bool syslog_level_prefix;
 
+        int log_level_max;
+
+        struct iovec* log_extra_fields;
+        size_t n_log_extra_fields;
+
         bool cpu_sched_reset_on_fork;
         bool non_blocking;
         bool private_tmp;
@@ -244,7 +259,7 @@ struct ExecContext {
 
         unsigned long restrict_namespaces; /* The CLONE_NEWxyz flags permitted to the unit's processes */
 
-        Set *syscall_filter;
+        Hashmap *syscall_filter;
         Set *syscall_archs;
         int syscall_errno;
         bool syscall_whitelist:1;
@@ -355,6 +370,8 @@ bool exec_context_maintains_privileges(ExecContext *c);
 
 int exec_context_get_effective_ioprio(ExecContext *c);
 
+void exec_context_free_log_extra_fields(ExecContext *c);
+
 void exec_status_start(ExecStatus *s, pid_t pid);
 void exec_status_exit(ExecStatus *s, ExecContext *context, pid_t pid, int code, int status);
 void exec_status_dump(ExecStatus *s, FILE *f, const char *prefix);
index 845e31e..1929991 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -36,7 +37,7 @@ int hostname_setup(void) {
         const char *hn;
         int r;
 
-        r = read_hostname_config("/etc/hostname", &b);
+        r = read_etc_hostname(NULL, &b);
         if (r < 0) {
                 if (r == -ENOENT)
                         enoent = true;
index 73e8c75..8bf8769 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 6c7b209..8031962 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -61,7 +62,7 @@ int ima_setup(void) {
         }
 
         /* attempt to write the name of the policy file into sysfs file */
-        if (write(imafd, IMA_POLICY_PATH, strlen(IMA_POLICY_PATH)) > 0)
+        if (write(imafd, IMA_POLICY_PATH, STRLEN(IMA_POLICY_PATH)) > 0)
                 goto done;
 
         /* fall back to copying the policy line-by-line */
index 472b58c..1eae74b 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index cfb7d51..8d72fc0 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -114,7 +115,7 @@ int config_parse_ip_address_access(
 
                         a->family = AF_INET6;
                         a->address.in6 = (struct in6_addr) {
-                                .__in6_u.__u6_addr32[0] = htobe32(0xfe800000)
+                                .s6_addr32[0] = htobe32(0xfe800000)
                         };
                         a->prefixlen = 64;
 
@@ -133,7 +134,7 @@ int config_parse_ip_address_access(
 
                         a->family = AF_INET6;
                         a->address.in6 = (struct in6_addr) {
-                                .__in6_u.__u6_addr32[0] = htobe32(0xff000000)
+                                .s6_addr32[0] = htobe32(0xff000000)
                         };
                         a->prefixlen = 8;
 
@@ -155,9 +156,15 @@ int config_parse_ip_address_access(
                 r = bpf_firewall_supported();
                 if (r < 0)
                         return r;
-                if (r == 0)
-                        log_warning("File %s:%u configures an IP firewall (%s=%s), but the local system does not support BPF/cgroup based firewalling.\n"
-                                    "Proceeding WITHOUT firewalling in effect!", filename, line, lvalue, rvalue);
+                if (r == 0) {
+                        static bool warned = false;
+
+                        log_full(warned ? LOG_DEBUG : LOG_WARNING,
+                                 "File %s:%u configures an IP firewall (%s=%s), but the local system does not support BPF/cgroup based firewalling.\n"
+                                 "Proceeding WITHOUT firewalling in effect! (This warning is only shown for the first loaded unit using IP firewalling.)", filename, line, lvalue, rvalue);
+
+                        warned = true;
+                }
         }
 
         return 0;
index 9aeab1f..536142e 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index fb57f19..2ea7834 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -437,6 +438,7 @@ int job_type_merge_and_collapse(JobType *a, JobType b, Unit *u) {
 static bool job_is_runnable(Job *j) {
         Iterator i;
         Unit *other;
+        void *v;
 
         assert(j);
         assert(j->installed);
@@ -459,13 +461,12 @@ static bool job_is_runnable(Job *j) {
                 return true;
 
         if (IN_SET(j->type, JOB_START, JOB_VERIFY_ACTIVE, JOB_RELOAD)) {
-
                 /* Immediate result is that the job is or might be
                  * started. In this case let's wait for the
                  * dependencies, regardless whether they are
                  * starting or stopping something. */
 
-                SET_FOREACH(other, j->unit->dependencies[UNIT_AFTER], i)
+                HASHMAP_FOREACH_KEY(v, other, j->unit->dependencies[UNIT_AFTER], i)
                         if (other->job)
                                 return false;
         }
@@ -473,7 +474,7 @@ static bool job_is_runnable(Job *j) {
         /* Also, if something else is being stopped and we should
          * change state after it, then let's wait. */
 
-        SET_FOREACH(other, j->unit->dependencies[UNIT_BEFORE], i)
+        HASHMAP_FOREACH_KEY(v, other, j->unit->dependencies[UNIT_BEFORE], i)
                 if (other->job &&
                     IN_SET(other->job->type, JOB_STOP, JOB_RESTART))
                         return false;
@@ -531,7 +532,7 @@ static int job_perform_on_unit(Job **j) {
 
                 case JOB_RESTART:
                         t = JOB_STOP;
-                        /* fall through */
+                        _fallthrough_;
                 case JOB_STOP:
                         r = unit_stop(u);
                         break;
@@ -776,7 +777,7 @@ static void job_log_status_message(Unit *u, JobType t, JobResult result) {
 
         /* The description might be longer than the buffer, but that's OK, we'll just truncate it here */
         DISABLE_WARNING_FORMAT_NONLITERAL;
-        snprintf(buf, sizeof(buf), format, unit_description(u));
+        xsprintf(buf, format, unit_description(u));
         REENABLE_WARNING;
 
         switch (t) {
@@ -832,10 +833,11 @@ static void job_emit_status_message(Unit *u, JobType t, JobResult result) {
 static void job_fail_dependencies(Unit *u, UnitDependency d) {
         Unit *other;
         Iterator i;
+        void *v;
 
         assert(u);
 
-        SET_FOREACH(other, u->dependencies[d], i) {
+        HASHMAP_FOREACH_KEY(v, other, u->dependencies[d], i) {
                 Job *j = other->job;
 
                 if (!j)
@@ -852,6 +854,7 @@ int job_finish_and_invalidate(Job *j, JobResult result, bool recursive, bool alr
         Unit *other;
         JobType t;
         Iterator i;
+        void *v;
 
         assert(j);
         assert(j->installed);
@@ -868,14 +871,13 @@ int job_finish_and_invalidate(Job *j, JobResult result, bool recursive, bool alr
         if (!already)
                 job_emit_status_message(u, t, result);
 
-        job_add_to_dbus_queue(j);
-
         /* Patch restart jobs so that they become normal start jobs */
         if (result == JOB_DONE && t == JOB_RESTART) {
 
                 job_change_type(j, JOB_START);
                 job_set_state(j, JOB_WAITING);
 
+                job_add_to_dbus_queue(j);
                 job_add_to_run_queue(j);
                 job_add_to_gc_queue(j);
 
@@ -920,12 +922,12 @@ int job_finish_and_invalidate(Job *j, JobResult result, bool recursive, bool alr
 
 finish:
         /* Try to start the next jobs that can be started */
-        SET_FOREACH(other, u->dependencies[UNIT_AFTER], i)
+        HASHMAP_FOREACH_KEY(v, other, u->dependencies[UNIT_AFTER], i)
                 if (other->job) {
                         job_add_to_run_queue(other->job);
                         job_add_to_gc_queue(other->job);
                 }
-        SET_FOREACH(other, u->dependencies[UNIT_BEFORE], i)
+        HASHMAP_FOREACH_KEY(v, other, u->dependencies[UNIT_BEFORE], i)
                 if (other->job) {
                         job_add_to_run_queue(other->job);
                         job_add_to_gc_queue(other->job);
@@ -1274,6 +1276,7 @@ int job_get_timeout(Job *j, usec_t *timeout) {
 bool job_check_gc(Job *j) {
         Unit *other;
         Iterator i;
+        void *v;
 
         assert(j);
 
@@ -1302,7 +1305,7 @@ bool job_check_gc(Job *j) {
 
         /* If a job is ordered after ours, and is to be started, then it needs to wait for us, regardless if we stop or
          * start, hence let's not GC in that case. */
-        SET_FOREACH(other, j->unit->dependencies[UNIT_BEFORE], i) {
+        HASHMAP_FOREACH_KEY(v, other, j->unit->dependencies[UNIT_BEFORE], i) {
                 if (!other->job)
                         continue;
 
@@ -1315,7 +1318,7 @@ bool job_check_gc(Job *j) {
 
         /* If we are going down, but something else is ordered After= us, then it needs to wait for us */
         if (IN_SET(j->type, JOB_STOP, JOB_RESTART))
-                SET_FOREACH(other, j->unit->dependencies[UNIT_AFTER], i) {
+                HASHMAP_FOREACH_KEY(v, other, j->unit->dependencies[UNIT_AFTER], i) {
                         if (!other->job)
                                 continue;
 
@@ -1393,6 +1396,7 @@ int job_get_before(Job *j, Job*** ret) {
         size_t n = 0, n_allocated = 0;
         Unit *other = NULL;
         Iterator i;
+        void *v;
 
         /* Returns a list of all pending jobs that need to finish before this job may be started. */
 
@@ -1406,7 +1410,7 @@ int job_get_before(Job *j, Job*** ret) {
 
         if (IN_SET(j->type, JOB_START, JOB_VERIFY_ACTIVE, JOB_RELOAD)) {
 
-                SET_FOREACH(other, j->unit->dependencies[UNIT_AFTER], i) {
+                HASHMAP_FOREACH_KEY(v, other, j->unit->dependencies[UNIT_AFTER], i) {
                         if (!other->job)
                                 continue;
 
@@ -1416,7 +1420,7 @@ int job_get_before(Job *j, Job*** ret) {
                 }
         }
 
-        SET_FOREACH(other, j->unit->dependencies[UNIT_BEFORE], i) {
+        HASHMAP_FOREACH_KEY(v, other, j->unit->dependencies[UNIT_BEFORE], i) {
                 if (!other->job)
                         continue;
 
@@ -1440,6 +1444,7 @@ int job_get_after(Job *j, Job*** ret) {
         _cleanup_free_ Job** list = NULL;
         size_t n = 0, n_allocated = 0;
         Unit *other = NULL;
+        void *v;
         Iterator i;
 
         assert(j);
@@ -1447,7 +1452,7 @@ int job_get_after(Job *j, Job*** ret) {
 
         /* Returns a list of all pending jobs that are waiting for this job to finish. */
 
-        SET_FOREACH(other, j->unit->dependencies[UNIT_BEFORE], i) {
+        HASHMAP_FOREACH_KEY(v, other, j->unit->dependencies[UNIT_BEFORE], i) {
                 if (!other->job)
                         continue;
 
@@ -1464,7 +1469,7 @@ int job_get_after(Job *j, Job*** ret) {
 
         if (IN_SET(j->type, JOB_STOP, JOB_RESTART)) {
 
-                SET_FOREACH(other, j->unit->dependencies[UNIT_AFTER], i) {
+                HASHMAP_FOREACH_KEY(v, other, j->unit->dependencies[UNIT_AFTER], i) {
                         if (!other->job)
                                 continue;
 
index b170018..a2f3b7b 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 6854587..f438c4d 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index b3d2056..f0d6ec4 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 5e914e4..e77763e 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -129,9 +130,9 @@ static void wait_for_children(Set *pids, sigset_t *mask) {
                  * might not be our child. */
                 SET_FOREACH(p, pids, i) {
 
-                        /* We misuse getpgid as a check whether a
-                         * process still exists. */
-                        if (getpgid(PTR_TO_PID(p)) >= 0)
+                        /* kill(pid, 0) sends no signal, but it tells
+                         * us whether the process still exists. */
+                        if (kill(PTR_TO_PID(p), 0) == 0)
                                 continue;
 
                         if (errno != ESRCH)
index acc2439..01bd6e5 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 066b959..a2809d0 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
 #include <string.h>
 #include <unistd.h>
 
-#if HAVE_KMOD
-#include <libkmod.h>
-#endif
-
 #include "alloc-util.h"
 #include "bus-util.h"
 #include "capability-util.h"
@@ -34,6 +31,9 @@
 #include "string-util.h"
 
 #if HAVE_KMOD
+#include <libkmod.h>
+#include "module-util.h"
+
 static void systemd_kmod_log(
                 void *data,
                 int priority,
@@ -110,7 +110,7 @@ int kmod_setup(void) {
                 /* virtio_rng would be loaded by udev later, but real entropy might be needed very early */
                 { "virtio_rng", NULL,                       false,  false,   has_virtio_rng },
         };
-        struct kmod_ctx *ctx = NULL;
+        _cleanup_(kmod_unrefp) struct kmod_ctx *ctx = NULL;
         unsigned int i;
         int r;
 
@@ -118,7 +118,7 @@ int kmod_setup(void) {
                 return 0;
 
         for (i = 0; i < ELEMENTSOF(kmod_table); i++) {
-                struct kmod_module *mod;
+                _cleanup_(kmod_module_unrefp) struct kmod_module *mod = NULL;
 
                 if (kmod_table[i].path && access(kmod_table[i].path, F_OK) >= 0)
                         continue;
@@ -157,13 +157,8 @@ int kmod_setup(void) {
                         log_full_errno(print_warning ? LOG_WARNING : LOG_DEBUG, r,
                                        "Failed to insert module '%s': %m", kmod_module_get_name(mod));
                 }
-
-                kmod_module_unref(mod);
         }
 
-        if (ctx)
-                kmod_unref(ctx);
-
 #endif
         return 0;
 }
index 685f4df..b5ea6b5 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 00f09ce..57ed686 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -115,10 +116,10 @@ static int process_deps(Unit *u, UnitDependency dependency, const char *dir_suff
                         log_unit_warning(u, "%s dependency dropin %s target %s has different name",
                                          unit_dependency_to_string(dependency), *p, target);
 
-                r = unit_add_dependency_by_name(u, dependency, entry, *p, true);
+                r = unit_add_dependency_by_name(u, dependency, entry, *p, true, UNIT_DEPENDENCY_FILE);
                 if (r < 0)
-                        log_unit_error_errno(u, r, "cannot add %s dependency on %s, ignoring: %m",
-                                             unit_dependency_to_string(dependency), entry);
+                        log_unit_warning_errno(u, r, "Cannot add %s dependency on %s, ignoring: %m",
+                                               unit_dependency_to_string(dependency), entry);
         }
 
         return 0;
@@ -154,12 +155,11 @@ int unit_load_dropin(Unit *u) {
                         return log_oom();
         }
 
-        STRV_FOREACH(f, u->dropin_paths) {
-                config_parse(u->id, *f, NULL,
-                             UNIT_VTABLE(u)->sections,
-                             config_item_perf_lookup, load_fragment_gperf_lookup,
-                             false, false, false, u);
-        }
+        STRV_FOREACH(f, u->dropin_paths)
+                (void) config_parse(u->id, *f, NULL,
+                                    UNIT_VTABLE(u)->sections,
+                                    config_item_perf_lookup, load_fragment_gperf_lookup,
+                                    0, u);
 
         u->dropin_mtime = now(CLOCK_REALTIME);
 
index 5828a22..4c8ab48 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 0e87e8d..ef3cbc3 100644 (file)
@@ -1,4 +1,7 @@
 %{
+#if __GNUC__ >= 7
+_Pragma("GCC diagnostic ignored \"-Wimplicit-fallthrough\"")
+#endif
 #include <stddef.h>
 #include "conf-parser.h"
 #include "load-fragment.h"
@@ -37,9 +40,12 @@ $1.EnvironmentFile,              config_parse_unit_env_file,         0,
 $1.PassEnvironment,              config_parse_pass_environ,          0,                             offsetof($1, exec_context.pass_environment)
 $1.UnsetEnvironment,             config_parse_unset_environ,         0,                             offsetof($1, exec_context.unset_environment)
 $1.DynamicUser,                  config_parse_bool,                  true,                          offsetof($1, exec_context.dynamic_user)
+$1.RemoveIPC,                    config_parse_bool,                  0,                             offsetof($1, exec_context.remove_ipc)
 $1.StandardInput,                config_parse_exec_input,            0,                             offsetof($1, exec_context)
 $1.StandardOutput,               config_parse_exec_output,           0,                             offsetof($1, exec_context)
 $1.StandardError,                config_parse_exec_output,           0,                             offsetof($1, exec_context)
+$1.StandardInputText,            config_parse_exec_input_text,       0,                             offsetof($1, exec_context)
+$1.StandardInputData,            config_parse_exec_input_data,       0,                             offsetof($1, exec_context)
 $1.TTYPath,                      config_parse_unit_path_printf,      0,                             offsetof($1, exec_context.tty_path)
 $1.TTYReset,                     config_parse_bool,                  0,                             offsetof($1, exec_context.tty_reset)
 $1.TTYVHangup,                   config_parse_bool,                  0,                             offsetof($1, exec_context.tty_vhangup)
@@ -48,6 +54,8 @@ $1.SyslogIdentifier,             config_parse_unit_string_printf,    0,
 $1.SyslogFacility,               config_parse_log_facility,          0,                             offsetof($1, exec_context.syslog_priority)
 $1.SyslogLevel,                  config_parse_log_level,             0,                             offsetof($1, exec_context.syslog_priority)
 $1.SyslogLevelPrefix,            config_parse_bool,                  0,                             offsetof($1, exec_context.syslog_level_prefix)
+$1.LogLevelMax,                  config_parse_log_level,             0,                             offsetof($1, exec_context.log_level_max)
+$1.LogExtraFields,               config_parse_log_extra_fields,      0,                             offsetof($1, exec_context)
 $1.Capabilities,                 config_parse_exec_capabilities,     0,                             offsetof($1, exec_context)
 $1.SecureBits,                   config_parse_exec_secure_bits,      0,                             offsetof($1, exec_context)
 $1.CapabilityBoundingSet,        config_parse_capability_set,        0,                             offsetof($1, exec_context.capability_bounding_set)
@@ -173,7 +181,7 @@ $1.BlockIOReadBandwidth,         config_parse_blockio_bandwidth,     0,
 $1.BlockIOWriteBandwidth,        config_parse_blockio_bandwidth,     0,                             offsetof($1, cgroup_context)
 $1.TasksAccounting,              config_parse_bool,                  0,                             offsetof($1, cgroup_context.tasks_accounting)
 $1.TasksMax,                     config_parse_tasks_max,             0,                             offsetof($1, cgroup_context.tasks_max)
-$1.Delegate,                     config_parse_bool,                  0,                             offsetof($1, cgroup_context.delegate)
+$1.Delegate,                     config_parse_delegate,              0,                             offsetof($1, cgroup_context)
 $1.IPAccounting,                 config_parse_bool,                  0,                             offsetof($1, cgroup_context.ip_accounting)
 $1.IPAddressAllow,               config_parse_ip_address_access,     0,                             offsetof($1, cgroup_context.ip_address_allow)
 $1.IPAddressDeny,                config_parse_ip_address_access,     0,                             offsetof($1, cgroup_context.ip_address_deny)
@@ -181,7 +189,7 @@ $1.NetClass,                     config_parse_warn_compat,           DISABLED_LE
 )m4_dnl
 Unit.Description,                config_parse_unit_string_printf,    0,                             offsetof(Unit, description)
 Unit.Documentation,              config_parse_documentation,         0,                             offsetof(Unit, documentation)
-Unit.SourcePath,                 config_parse_path,                  0,                             offsetof(Unit, source_path)
+Unit.SourcePath,                 config_parse_unit_path_printf,      0,                             offsetof(Unit, source_path)
 Unit.Requires,                   config_parse_unit_deps,             UNIT_REQUIRES,                 0
 Unit.Requisite,                  config_parse_unit_deps,             UNIT_REQUISITE,                0
 Unit.Wants,                      config_parse_unit_deps,             UNIT_WANTS,                    0
@@ -198,7 +206,7 @@ Unit.PropagateReloadFrom,        config_parse_unit_deps,             UNIT_RELOAD
 Unit.PartOf,                     config_parse_unit_deps,             UNIT_PART_OF,                  0
 Unit.JoinsNamespaceOf,           config_parse_unit_deps,             UNIT_JOINS_NAMESPACE_OF,       0
 Unit.RequiresOverridable,        config_parse_obsolete_unit_deps,    UNIT_REQUIRES,                 0
-Unit.RequisiteOverridable,       config_parse_obsolete_unit_deps,    UNIT_REQUISITE,    0
+Unit.RequisiteOverridable,       config_parse_obsolete_unit_deps,    UNIT_REQUISITE,                0
 Unit.RequiresMountsFor,          config_parse_unit_requires_mounts_for, 0,                          0
 Unit.StopWhenUnneeded,           config_parse_bool,                  0,                             offsetof(Unit, stop_when_unneeded)
 Unit.RefuseManualStart,          config_parse_bool,                  0,                             offsetof(Unit, refuse_manual_start)
@@ -218,6 +226,8 @@ m4_dnl The following is a legacy alias name for compatibility
 Unit.StartLimitInterval,         config_parse_sec,                   0,                             offsetof(Unit, start_limit.interval)
 Unit.StartLimitBurst,            config_parse_unsigned,              0,                             offsetof(Unit, start_limit.burst)
 Unit.StartLimitAction,           config_parse_emergency_action,      0,                             offsetof(Unit, start_limit_action)
+Unit.FailureAction,              config_parse_emergency_action,      0,                             offsetof(Unit, failure_action)
+Unit.SuccessAction,              config_parse_emergency_action,      0,                             offsetof(Unit, success_action)
 Unit.RebootArgument,             config_parse_unit_string_printf,    0,                             offsetof(Unit, reboot_arg)
 Unit.ConditionPathExists,        config_parse_unit_condition_path,   CONDITION_PATH_EXISTS,         offsetof(Unit, conditions)
 Unit.ConditionPathExistsGlob,    config_parse_unit_condition_path,   CONDITION_PATH_EXISTS_GLOB,    offsetof(Unit, conditions)
@@ -261,6 +271,7 @@ Unit.AssertACPower,              config_parse_unit_condition_string, CONDITION_A
 Unit.AssertUser,                 config_parse_unit_condition_string, CONDITION_USER,                offsetof(Unit, asserts)
 Unit.AssertGroup,                config_parse_unit_condition_string, CONDITION_GROUP,               offsetof(Unit, asserts)
 Unit.AssertNull,                 config_parse_unit_condition_null,   0,                             offsetof(Unit, asserts)
+Unit.CollectMode,                config_parse_collect_mode,          0,                             offsetof(Unit, collect_mode)
 m4_dnl
 Service.PIDFile,                 config_parse_unit_path_printf,      0,                             offsetof(Service, pid_file)
 Service.ExecStartPre,            config_parse_exec,                  SERVICE_EXEC_START_PRE,        offsetof(Service, exec_command)
@@ -275,12 +286,12 @@ Service.TimeoutStartSec,         config_parse_service_timeout,       0,
 Service.TimeoutStopSec,          config_parse_service_timeout,       0,                             0
 Service.RuntimeMaxSec,           config_parse_sec,                   0,                             offsetof(Service, runtime_max_usec)
 Service.WatchdogSec,             config_parse_sec,                   0,                             offsetof(Service, watchdog_usec)
-m4_dnl The following three only exist for compatibility, they moved into Unit, see above
+m4_dnl The following five only exist for compatibility, they moved into Unit, see above
 Service.StartLimitInterval,      config_parse_sec,                   0,                             offsetof(Unit, start_limit.interval)
 Service.StartLimitBurst,         config_parse_unsigned,              0,                             offsetof(Unit, start_limit.burst)
 Service.StartLimitAction,        config_parse_emergency_action,      0,                             offsetof(Unit, start_limit_action)
-Service.RebootArgument,          config_parse_unit_path_printf,      0,                             offsetof(Unit, reboot_arg)
-Service.FailureAction,           config_parse_emergency_action,      0,                             offsetof(Service, emergency_action)
+Service.FailureAction,           config_parse_emergency_action,      0,                             offsetof(Unit, failure_action)
+Service.RebootArgument,          config_parse_unit_string_printf,    0,                             offsetof(Unit, reboot_arg)
 Service.Type,                    config_parse_service_type,          0,                             offsetof(Service, type)
 Service.Restart,                 config_parse_service_restart,       0,                             offsetof(Service, restart)
 Service.PermissionsStartOnly,    config_parse_bool,                  0,                             offsetof(Service, permissions_start_only)
@@ -371,9 +382,9 @@ CGROUP_CONTEXT_CONFIG_ITEMS(Socket)m4_dnl
 KILL_CONTEXT_CONFIG_ITEMS(Socket)m4_dnl
 m4_dnl
 Mount.What,                      config_parse_unit_string_printf,    0,                             offsetof(Mount, parameters_fragment.what)
-Mount.Where,                     config_parse_path,                  0,                             offsetof(Mount, where)
+Mount.Where,                     config_parse_unit_path_printf,      0,                             offsetof(Mount, where)
 Mount.Options,                   config_parse_unit_string_printf,    0,                             offsetof(Mount, parameters_fragment.options)
-Mount.Type,                      config_parse_string,                0,                             offsetof(Mount, parameters_fragment.fstype)
+Mount.Type,                      config_parse_unit_string_printf,    0,                             offsetof(Mount, parameters_fragment.fstype)
 Mount.TimeoutSec,                config_parse_sec_fix_0,             0,                             offsetof(Mount, timeout_usec)
 Mount.DirectoryMode,             config_parse_mode,                  0,                             offsetof(Mount, directory_mode)
 Mount.SloppyOptions,             config_parse_bool,                  0,                             offsetof(Mount, sloppy_options)
@@ -383,11 +394,11 @@ EXEC_CONTEXT_CONFIG_ITEMS(Mount)m4_dnl
 CGROUP_CONTEXT_CONFIG_ITEMS(Mount)m4_dnl
 KILL_CONTEXT_CONFIG_ITEMS(Mount)m4_dnl
 m4_dnl
-Automount.Where,                 config_parse_path,                  0,                             offsetof(Automount, where)
+Automount.Where,                 config_parse_unit_path_printf,      0,                             offsetof(Automount, where)
 Automount.DirectoryMode,         config_parse_mode,                  0,                             offsetof(Automount, directory_mode)
 Automount.TimeoutIdleSec,        config_parse_sec_fix_0,             0,                             offsetof(Automount, timeout_idle_usec)
 m4_dnl
-Swap.What,                       config_parse_path,                  0,                             offsetof(Swap, parameters_fragment.what)
+Swap.What,                       config_parse_unit_path_printf,      0,                             offsetof(Swap, parameters_fragment.what)
 Swap.Priority,                   config_parse_int,                   0,                             offsetof(Swap, parameters_fragment.priority)
 Swap.Options,                    config_parse_unit_string_printf,    0,                             offsetof(Swap, parameters_fragment.options)
 Swap.TimeoutSec,                 config_parse_sec_fix_0,             0,                             offsetof(Swap, timeout_usec)
index 61dd1d6..db42c7e 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
 #include "escape.h"
 #include "fd-util.h"
 #include "fs-util.h"
+#include "hexdecoct.h"
+#include "io-util.h"
 #include "ioprio.h"
+#include "journal-util.h"
 #include "load-fragment.h"
 #include "log.h"
 #include "missing.h"
@@ -101,6 +105,8 @@ int config_parse_warn_compat(
         return 0;
 }
 
+DEFINE_CONFIG_PARSE_ENUM(config_parse_collect_mode, collect_mode, CollectMode, "Failed to parse garbage collection mode");
+
 int config_parse_unit_deps(
                 const char *unit,
                 const char *filename,
@@ -142,7 +148,7 @@ int config_parse_unit_deps(
                         continue;
                 }
 
-                r = unit_add_dependency_by_name(u, d, k, NULL, true);
+                r = unit_add_dependency_by_name(u, d, k, NULL, true, UNIT_DEPENDENCY_FILE);
                 if (r < 0)
                         log_syntax(unit, LOG_ERR, filename, line, r, "Failed to add dependency on %s, ignoring: %m", k);
         }
@@ -827,21 +833,22 @@ int config_parse_socket_bindtodevice(
         return 0;
 }
 
-DEFINE_CONFIG_PARSE_ENUM(config_parse_input, exec_input, ExecInput, "Failed to parse input literal specifier");
-DEFINE_CONFIG_PARSE_ENUM(config_parse_output, exec_output, ExecOutput, "Failed to parse output literal specifier");
-
-int config_parse_exec_input(const char *unit,
-                            const char *filename,
-                            unsigned line,
-                            const char *section,
-                            unsigned section_line,
-                            const char *lvalue,
-                            int ltype,
-                            const char *rvalue,
-                            void *data,
-                            void *userdata) {
+int config_parse_exec_input(
+                const char *unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
         ExecContext *c = data;
-        const char *name;
+        Unit *u = userdata;
+        const char *n;
+        ExecInput ei;
         int r;
 
         assert(data);
@@ -849,41 +856,187 @@ int config_parse_exec_input(const char *unit,
         assert(line);
         assert(rvalue);
 
-        name = startswith(rvalue, "fd:");
-        if (name) {
-                /* Strip prefix and validate fd name */
-                if (!fdname_is_valid(name)) {
-                        log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid file descriptor name, ignoring: %s", name);
-                        return 0;
+        n = startswith(rvalue, "fd:");
+        if (n) {
+                _cleanup_free_ char *resolved = NULL;
+
+                r = unit_full_printf(u, n, &resolved);
+                if (r < 0)
+                        return log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers on %s: %m", n);
+
+                if (isempty(resolved))
+                        resolved = mfree(resolved);
+                else if (!fdname_is_valid(resolved)) {
+                        log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid file descriptor name: %s", resolved);
+                        return -EINVAL;
                 }
-                c->std_input = EXEC_INPUT_NAMED_FD;
-                r = free_and_strdup(&c->stdio_fdname[STDIN_FILENO], name);
+
+                free_and_replace(c->stdio_fdname[STDIN_FILENO], resolved);
+
+                ei = EXEC_INPUT_NAMED_FD;
+
+        } else if ((n = startswith(rvalue, "file:"))) {
+                _cleanup_free_ char *resolved = NULL;
+
+                r = unit_full_printf(u, n, &resolved);
                 if (r < 0)
-                        log_oom();
-                return r;
+                        return log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers on %s: %m", n);
+
+                if (!path_is_absolute(resolved)) {
+                        log_syntax(unit, LOG_ERR, filename, line, 0, "file: requires an absolute path name: %s", resolved);
+                        return -EINVAL;
+                }
+
+                if (!path_is_normalized(resolved)) {
+                        log_syntax(unit, LOG_ERR, filename, line, 0, "file: requires a normalized path name: %s", resolved);
+                        return -EINVAL;
+                }
+
+                free_and_replace(c->stdio_file[STDIN_FILENO], resolved);
+
+                ei = EXEC_INPUT_FILE;
+
         } else {
-                ExecInput ei = exec_input_from_string(rvalue);
-                if (ei == _EXEC_INPUT_INVALID)
+                ei = exec_input_from_string(rvalue);
+                if (ei < 0) {
                         log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse input specifier, ignoring: %s", rvalue);
-                else
-                        c->std_input = ei;
+                        return 0;
+                }
+        }
+
+        c->std_input = ei;
+        return 0;
+}
+
+int config_parse_exec_input_text(
+                const char *unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        _cleanup_free_ char *unescaped = NULL, *resolved = NULL;
+        ExecContext *c = data;
+        Unit *u = userdata;
+        size_t sz;
+        void *p;
+        int r;
+
+        assert(data);
+        assert(filename);
+        assert(line);
+        assert(rvalue);
+
+        if (isempty(rvalue)) {
+                /* Reset if the empty string is assigned */
+                c->stdin_data = mfree(c->stdin_data);
+                c->stdin_data_size = 0;
                 return 0;
         }
+
+        r = cunescape(rvalue, 0, &unescaped);
+        if (r < 0)
+                return log_syntax(unit, LOG_ERR, filename, line, r, "Failed to decode C escaped text: %s", rvalue);
+
+        r = unit_full_printf(u, unescaped, &resolved);
+        if (r < 0)
+                return log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers: %s", unescaped);
+
+        sz = strlen(resolved);
+        if (c->stdin_data_size + sz + 1 < c->stdin_data_size || /* check for overflow */
+            c->stdin_data_size + sz + 1 > EXEC_STDIN_DATA_MAX) {
+                log_syntax(unit, LOG_ERR, filename, line, 0, "Standard input data too large (%zu), maximum of %zu permitted, ignoring.", c->stdin_data_size + sz, (size_t) EXEC_STDIN_DATA_MAX);
+                return -E2BIG;
+        }
+
+        p = realloc(c->stdin_data, c->stdin_data_size + sz + 1);
+        if (!p)
+                return log_oom();
+
+        *((char*) mempcpy((char*) p + c->stdin_data_size, resolved, sz)) = '\n';
+
+        c->stdin_data = p;
+        c->stdin_data_size += sz + 1;
+
+        return 0;
 }
 
-int config_parse_exec_output(const char *unit,
-                             const char *filename,
-                             unsigned line,
-                             const char *section,
-                             unsigned section_line,
-                             const char *lvalue,
-                             int ltype,
-                             const char *rvalue,
-                             void *data,
-                             void *userdata) {
+int config_parse_exec_input_data(
+                const char *unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        _cleanup_free_ void *p = NULL;
+        ExecContext *c = data;
+        size_t sz;
+        void *q;
+        int r;
+
+        assert(data);
+        assert(filename);
+        assert(line);
+        assert(rvalue);
+
+        if (isempty(rvalue)) {
+                /* Reset if the empty string is assigned */
+                c->stdin_data = mfree(c->stdin_data);
+                c->stdin_data_size = 0;
+                return 0;
+        }
+
+        r = unbase64mem(rvalue, (size_t) -1, &p, &sz);
+        if (r < 0)
+                return log_syntax(unit, LOG_ERR, filename, line, r, "Failed to decode base64 data, ignoring: %s", rvalue);
+
+        assert(sz > 0);
+
+        if (c->stdin_data_size + sz < c->stdin_data_size || /* check for overflow */
+            c->stdin_data_size + sz > EXEC_STDIN_DATA_MAX) {
+                log_syntax(unit, LOG_ERR, filename, line, 0, "Standard input data too large (%zu), maximum of %zu permitted, ignoring.", c->stdin_data_size + sz, (size_t) EXEC_STDIN_DATA_MAX);
+                return -E2BIG;
+        }
+
+        q = realloc(c->stdin_data, c->stdin_data_size + sz);
+        if (!q)
+                return log_oom();
+
+        memcpy((uint8_t*) q + c->stdin_data_size, p, sz);
+
+        c->stdin_data = q;
+        c->stdin_data_size += sz;
+
+        return 0;
+}
+
+int config_parse_exec_output(
+                const char *unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        _cleanup_free_ char *resolved = NULL;
+        const char *n;
         ExecContext *c = data;
+        Unit *u = userdata;
         ExecOutput eo;
-        const char *name;
         int r;
 
         assert(data);
@@ -892,38 +1045,67 @@ int config_parse_exec_output(const char *unit,
         assert(lvalue);
         assert(rvalue);
 
-        name = startswith(rvalue, "fd:");
-        if (name) {
-                /* Strip prefix and validate fd name */
-                if (!fdname_is_valid(name)) {
-                        log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid file descriptor name, ignoring: %s", name);
-                        return 0;
+        n = startswith(rvalue, "fd:");
+        if (n) {
+                r = unit_full_printf(u, n, &resolved);
+                if (r < 0)
+                        return log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers on %s: %m", n);
+
+                if (isempty(resolved))
+                        resolved = mfree(resolved);
+                else if (!fdname_is_valid(resolved)) {
+                        log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid file descriptor name: %s", resolved);
+                        return -EINVAL;
                 }
+
                 eo = EXEC_OUTPUT_NAMED_FD;
+
+        } else if ((n = startswith(rvalue, "file:"))) {
+
+                r = unit_full_printf(u, n, &resolved);
+                if (r < 0)
+                        return log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers on %s: %m", n);
+
+                if (!path_is_absolute(resolved)) {
+                        log_syntax(unit, LOG_ERR, filename, line, 0, "file: requires an absolute path name: %s", resolved);
+                        return -EINVAL;
+                }
+
+                if (!path_is_normalized(resolved)) {
+                        log_syntax(unit, LOG_ERR, filename, line, 0, "file: requires a normalized path name, ignoring: %s", resolved);
+                        return -EINVAL;
+                }
+
+                eo = EXEC_OUTPUT_FILE;
+
         } else {
                 eo = exec_output_from_string(rvalue);
-                if (eo == _EXEC_OUTPUT_INVALID) {
+                if (eo < 0) {
                         log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse output specifier, ignoring: %s", rvalue);
                         return 0;
                 }
         }
 
         if (streq(lvalue, "StandardOutput")) {
+                if (eo == EXEC_OUTPUT_NAMED_FD)
+                        free_and_replace(c->stdio_fdname[STDOUT_FILENO], resolved);
+                else
+                        free_and_replace(c->stdio_file[STDOUT_FILENO], resolved);
+
                 c->std_output = eo;
-                r = free_and_strdup(&c->stdio_fdname[STDOUT_FILENO], name);
-                if (r < 0)
-                        log_oom();
-                return r;
-        } else if (streq(lvalue, "StandardError")) {
-                c->std_error = eo;
-                r = free_and_strdup(&c->stdio_fdname[STDERR_FILENO], name);
-                if (r < 0)
-                        log_oom();
-                return r;
+
         } else {
-                log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse output property, ignoring: %s", lvalue);
-                return 0;
+                assert(streq(lvalue, "StandardError"));
+
+                if (eo == EXEC_OUTPUT_NAMED_FD)
+                        free_and_replace(c->stdio_fdname[STDERR_FILENO], resolved);
+                else
+                        free_and_replace(c->stdio_file[STDERR_FILENO], resolved);
+
+                c->std_error = eo;
         }
+
+        return 0;
 }
 
 int config_parse_exec_io_class(const char *unit,
@@ -1086,17 +1268,30 @@ int config_parse_exec_cpu_affinity(const char *unit,
         if (ncpus < 0)
                 return ncpus;
 
-        if (c->cpuset)
-                CPU_FREE(c->cpuset);
-
-        if (ncpus == 0)
+        if (ncpus == 0) {
                 /* An empty assignment resets the CPU list */
-                c->cpuset = NULL;
-        else {
+                c->cpuset = cpu_set_mfree(c->cpuset);
+                c->cpuset_ncpus = 0;
+                return 0;
+        }
+
+        if (!c->cpuset) {
+                c->cpuset = cpuset;
+                cpuset = NULL;
+                c->cpuset_ncpus = (unsigned) ncpus;
+                return 0;
+        }
+
+        if (c->cpuset_ncpus < (unsigned) ncpus) {
+                CPU_OR_S(CPU_ALLOC_SIZE(c->cpuset_ncpus), cpuset, c->cpuset, cpuset);
+                CPU_FREE(c->cpuset);
                 c->cpuset = cpuset;
                 cpuset = NULL;
+                c->cpuset_ncpus = (unsigned) ncpus;
+                return 0;
         }
-        c->cpuset_ncpus = ncpus;
+
+        CPU_OR_S(CPU_ALLOC_SIZE((unsigned) ncpus), c->cpuset, c->cpuset, cpuset);
 
         return 0;
 }
@@ -1570,7 +1765,7 @@ int config_parse_trigger_unit(
         assert(rvalue);
         assert(data);
 
-        if (!set_isempty(u->dependencies[UNIT_TRIGGERS])) {
+        if (!hashmap_isempty(u->dependencies[UNIT_TRIGGERS])) {
                 log_syntax(unit, LOG_ERR, filename, line, 0, "Multiple units to trigger specified, ignoring: %s", rvalue);
                 return 0;
         }
@@ -1592,7 +1787,7 @@ int config_parse_trigger_unit(
                 return 0;
         }
 
-        r = unit_add_two_dependencies_by_name(u, UNIT_BEFORE, UNIT_TRIGGERS, p, NULL, true);
+        r = unit_add_two_dependencies_by_name(u, UNIT_BEFORE, UNIT_TRIGGERS, p, NULL, true, UNIT_DEPENDENCY_FILE);
         if (r < 0) {
                 log_syntax(unit, LOG_ERR, filename, line, r, "Failed to add trigger on %s, ignoring: %m", p);
                 return 0;
@@ -1792,11 +1987,11 @@ int config_parse_service_sockets(
                         continue;
                 }
 
-                r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_WANTS, UNIT_AFTER, k, NULL, true);
+                r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_WANTS, UNIT_AFTER, k, NULL, true, UNIT_DEPENDENCY_FILE);
                 if (r < 0)
                         log_syntax(unit, LOG_ERR, filename, line, r, "Failed to add dependency on %s, ignoring: %m", k);
 
-                r = unit_add_dependency_by_name(UNIT(s), UNIT_TRIGGERED_BY, k, NULL, true);
+                r = unit_add_dependency_by_name(UNIT(s), UNIT_TRIGGERED_BY, k, NULL, true, UNIT_DEPENDENCY_FILE);
                 if (r < 0)
                         log_syntax(unit, LOG_ERR, filename, line, r, "Failed to add dependency on %s, ignoring: %m", k);
         }
@@ -2317,7 +2512,7 @@ int config_parse_unset_environ(
         for (;;) {
                 _cleanup_free_ char *word = NULL, *k = NULL;
 
-                r = extract_first_word(&rvalue, &word, NULL, EXTRACT_QUOTES);
+                r = extract_first_word(&rvalue, &word, NULL, EXTRACT_CUNESCAPE|EXTRACT_QUOTES);
                 if (r == 0)
                         break;
                 if (r == -ENOMEM)
@@ -2363,6 +2558,78 @@ int config_parse_unset_environ(
         return 0;
 }
 
+int config_parse_log_extra_fields(
+                const char *unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        ExecContext *c = data;
+        Unit *u = userdata;
+        const char *p;
+        int r;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(c);
+
+        if (isempty(rvalue)) {
+                exec_context_free_log_extra_fields(c);
+                return 0;
+        }
+
+        for (p = rvalue;; ) {
+                _cleanup_free_ char *word = NULL, *k = NULL;
+                struct iovec *t;
+                const char *eq;
+
+                r = extract_first_word(&p, &word, NULL, EXTRACT_CUNESCAPE|EXTRACT_QUOTES);
+                if (r == 0)
+                        break;
+                if (r == -ENOMEM)
+                        return log_oom();
+                if (r < 0) {
+                        log_syntax(unit, LOG_WARNING, filename, line, r, "Invalid syntax, ignoring: %s", rvalue);
+                        return 0;
+                }
+
+                r = unit_full_printf(u, word, &k);
+                if (r < 0) {
+                        log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers on %s, ignoring field: %m", word);
+                        continue;
+                }
+
+                eq = strchr(k, '=');
+                if (!eq) {
+                        log_syntax(unit, LOG_ERR, filename, line, 0, "Log field lacks '=' character, ignoring field: %s", k);
+                        continue;
+                }
+
+                if (!journal_field_valid(k, eq-k, false)) {
+                        log_syntax(unit, LOG_ERR, filename, line, 0, "Log field name is invalid, ignoring field: %s", k);
+                        continue;
+                }
+
+                t = realloc_multiply(c->log_extra_fields, sizeof(struct iovec), c->n_log_extra_fields+1);
+                if (!t)
+                        return log_oom();
+
+                c->log_extra_fields = t;
+                c->log_extra_fields[c->n_log_extra_fields++] = IOVEC_MAKE_STRING(k);
+
+                k = NULL;
+        }
+
+        return 0;
+}
+
 int config_parse_ip_tos(const char *unit,
                         const char *filename,
                         unsigned line,
@@ -2601,7 +2868,7 @@ int config_parse_unit_requires_mounts_for(
                         continue;
                 }
 
-                r = unit_require_mounts_for(u, resolved);
+                r = unit_require_mounts_for(u, resolved, UNIT_DEPENDENCY_FILE);
                 if (r < 0) {
                         log_syntax(unit, LOG_ERR, filename, line, r, "Failed to add required mount \"%s\", ignoring: %m", resolved);
                         continue;
@@ -2664,7 +2931,8 @@ static int syscall_filter_parse_one(
                 ExecContext *c,
                 bool invert,
                 const char *t,
-                bool warn) {
+                bool warn,
+                int errno_num) {
         int r;
 
         if (t[0] == '@') {
@@ -2674,12 +2942,12 @@ static int syscall_filter_parse_one(
                 set = syscall_filter_set_find(t);
                 if (!set) {
                         if (warn)
-                                log_syntax(unit, LOG_WARNING, filename, line, 0, "Don't know system call group, ignoring: %s", t);
+                                log_syntax(unit, LOG_WARNING, filename, line, 0, "Unknown system call group, ignoring: %s", t);
                         return 0;
                 }
 
                 NULSTR_FOREACH(i, set->value) {
-                        r = syscall_filter_parse_one(unit, filename, line, c, invert, i, false);
+                        r = syscall_filter_parse_one(unit, filename, line, c, invert, i, false, errno_num);
                         if (r < 0)
                                 return r;
                 }
@@ -2694,16 +2962,16 @@ static int syscall_filter_parse_one(
                 }
 
                 /* If we previously wanted to forbid a syscall and now
-                 * we want to allow it, then remove it from the list
+                 * we want to allow it, then remove it from the list.
                  */
                 if (!invert == c->syscall_whitelist) {
-                        r = set_put(c->syscall_filter, INT_TO_PTR(id + 1));
+                        r = hashmap_put(c->syscall_filter, INT_TO_PTR(id + 1), INT_TO_PTR(errno_num));
                         if (r == 0)
                                 return 0;
                         if (r < 0)
                                 return log_oom();
                 } else
-                        (void) set_remove(c->syscall_filter, INT_TO_PTR(id + 1));
+                        (void) hashmap_remove(c->syscall_filter, INT_TO_PTR(id + 1));
         }
 
         return 0;
@@ -2734,7 +3002,7 @@ int config_parse_syscall_filter(
 
         if (isempty(rvalue)) {
                 /* Empty assignment resets the list */
-                c->syscall_filter = set_free(c->syscall_filter);
+                c->syscall_filter = hashmap_free(c->syscall_filter);
                 c->syscall_whitelist = false;
                 return 0;
         }
@@ -2745,7 +3013,7 @@ int config_parse_syscall_filter(
         }
 
         if (!c->syscall_filter) {
-                c->syscall_filter = set_new(NULL);
+                c->syscall_filter = hashmap_new(NULL);
                 if (!c->syscall_filter)
                         return log_oom();
 
@@ -2757,7 +3025,7 @@ int config_parse_syscall_filter(
                         c->syscall_whitelist = true;
 
                         /* Accept default syscalls if we are on a whitelist */
-                        r = syscall_filter_parse_one(unit, filename, line, c, false, "@default", false);
+                        r = syscall_filter_parse_one(unit, filename, line, c, false, "@default", false, -1);
                         if (r < 0)
                                 return r;
                 }
@@ -2765,7 +3033,8 @@ int config_parse_syscall_filter(
 
         p = rvalue;
         for (;;) {
-                _cleanup_free_ char *word = NULL;
+                _cleanup_free_ char *word = NULL, *name = NULL;
+                int num;
 
                 r = extract_first_word(&p, &word, NULL, 0);
                 if (r == 0)
@@ -2777,7 +3046,13 @@ int config_parse_syscall_filter(
                         break;
                 }
 
-                r = syscall_filter_parse_one(unit, filename, line, c, invert, word, true);
+                r = parse_syscall_and_errno(word, &name, &num);
+                if (r < 0) {
+                        log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to parse syscall:errno, ignoring: %s", word);
+                        continue;
+                }
+
+                r = syscall_filter_parse_one(unit, filename, line, c, invert, name, true, num);
                 if (r < 0)
                         return r;
         }
@@ -2863,8 +3138,8 @@ int config_parse_syscall_errno(
                 return 0;
         }
 
-        e = errno_from_name(rvalue);
-        if (e < 0) {
+        e = parse_errno(rvalue);
+        if (e <= 0) {
                 log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse error number, ignoring: %s", rvalue);
                 return 0;
         }
@@ -3226,6 +3501,73 @@ int config_parse_tasks_max(
         return 0;
 }
 
+int config_parse_delegate(
+                const char *unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        CGroupContext *c = data;
+        int r;
+
+        /* We either accept a boolean value, which may be used to turn on delegation for all controllers, or turn it
+         * off for all. Or it takes a list of controller names, in which case we add the specified controllers to the
+         * mask to delegate. */
+
+        if (isempty(rvalue)) {
+                c->delegate = true;
+                c->delegate_controllers = 0;
+                return 0;
+        }
+
+        r = parse_boolean(rvalue);
+        if (r < 0) {
+                const char *p = rvalue;
+                CGroupMask mask = 0;
+
+                for (;;) {
+                        _cleanup_free_ char *word = NULL;
+                        CGroupController cc;
+
+                        r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES);
+                        if (r == 0)
+                                break;
+                        if (r == -ENOMEM)
+                                return log_oom();
+                        if (r < 0) {
+                                log_syntax(unit, LOG_ERR, filename, line, r, "Invalid syntax, ignoring: %s", rvalue);
+                                return r;
+                        }
+
+                        cc = cgroup_controller_from_string(word);
+                        if (cc < 0) {
+                                log_syntax(unit, LOG_ERR, filename, line, r, "Invalid controller name '%s', ignoring", rvalue);
+                                continue;
+                        }
+
+                        mask |= CGROUP_CONTROLLER_TO_MASK(cc);
+                }
+
+                c->delegate = true;
+                c->delegate_controllers |= mask;
+
+        } else if (r > 0) {
+                c->delegate = true;
+                c->delegate_controllers = _CGROUP_MASK_ALL;
+        } else {
+                c->delegate = false;
+                c->delegate_controllers = 0;
+        }
+
+        return 0;
+}
+
 int config_parse_device_allow(
                 const char *unit,
                 const char *filename,
@@ -3253,7 +3595,7 @@ int config_parse_device_allow(
         }
 
         r = unit_full_printf(userdata, rvalue, &t);
-        if(r < 0) {
+        if (r < 0) {
                 log_syntax(unit, LOG_WARNING, filename, line, r,
                            "Failed to resolve specifiers in %s, ignoring: %m",
                            rvalue);
@@ -3747,7 +4089,7 @@ int config_parse_exec_directories(
                         continue;
                 }
 
-                if (!path_is_safe(k) || path_is_absolute(k)) {
+                if (!path_is_normalized(k) || path_is_absolute(k)) {
                         log_syntax(unit, LOG_ERR, filename, line, 0,
                                    "%s= path is not valid, ignoring assignment: %s", lvalue, rvalue);
                         continue;
@@ -4474,7 +4816,7 @@ static int load_from_path(Unit *u, const char *path) {
                 r = config_parse(u->id, filename, f,
                                  UNIT_VTABLE(u)->sections,
                                  config_item_perf_lookup, load_fragment_gperf_lookup,
-                                 false, true, false, u);
+                                 CONFIG_PARSE_ALLOW_INCLUDE, u);
                 if (r < 0)
                         return r;
         }
index 2473b6f..b9815aa 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -46,9 +47,9 @@ int config_parse_service_type(const char *unit, const char *filename, unsigned l
 int config_parse_service_restart(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_socket_bindtodevice(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_exec_output(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_output(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_exec_input(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_input(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_exec_input_text(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_exec_input_data(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_exec_io_class(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_exec_io_priority(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_exec_cpu_sched_policy(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
@@ -86,6 +87,7 @@ int config_parse_cpu_weight(const char *unit, const char *filename, unsigned lin
 int config_parse_cpu_shares(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_memory_limit(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_tasks_max(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_delegate(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_device_policy(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_device_allow(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_io_weight(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
@@ -121,6 +123,8 @@ int config_parse_bind_paths(const char *unit, const char *filename, unsigned lin
 int config_parse_exec_keyring_mode(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_job_timeout_sec(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_job_running_timeout_sec(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_log_extra_fields(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_collect_mode(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 
 /* gperf prototypes */
 const struct ConfigPerfItem* load_fragment_gperf_lookup(const char *key, GPERF_LEN_TYPE length);
index fdd847e..6240a83 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 3b97497..c1bee38 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index c167305..9a75525 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index e7547b8..9fac018 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index df3cc74..767e972 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 29f4620..cbd83ba 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index dd25fc6..5e9ac96 100644 (file)
@@ -1,4 +1,5 @@
 #  -*- Mode: rpm-spec; indent-tabs-mode: nil -*- */
+#  SPDX-License-Identifier: LGPL-2.1+
 #
 #  This file is part of systemd.
 #
index 8437fe0..42aa1cf 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -37,6 +38,7 @@
 
 #include "sd-bus.h"
 #include "sd-daemon.h"
+#include "sd-messages.h"
 
 #include "alloc-util.h"
 #include "architecture.h"
@@ -119,6 +121,7 @@ static usec_t arg_default_start_limit_interval = DEFAULT_START_LIMIT_INTERVAL;
 static unsigned arg_default_start_limit_burst = DEFAULT_START_LIMIT_BURST;
 static usec_t arg_runtime_watchdog = 0;
 static usec_t arg_shutdown_watchdog = 10 * USEC_PER_MINUTE;
+static char *arg_watchdog_device = NULL;
 static char **arg_default_environment = NULL;
 static struct rlimit *arg_default_rlimit[_RLIMIT_MAX] = {};
 static uint64_t arg_capability_bounding_set = CAP_ALL;
@@ -460,6 +463,13 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
                 if (arg_default_timeout_start_usec <= 0)
                         arg_default_timeout_start_usec = USEC_INFINITY;
 
+        } else if (proc_cmdline_key_streq(key, "systemd.watchdog_device")) {
+
+                if (proc_cmdline_value_missing(key, value))
+                        return 0;
+
+                parse_path_argument_and_warn(value, false, &arg_watchdog_device);
+
         } else if (streq(key, "quiet") && !value) {
 
                 if (arg_show_status == _SHOW_STATUS_UNSET)
@@ -571,6 +581,40 @@ static int config_parse_show_status(
         return 0;
 }
 
+static int config_parse_output_restricted(
+                const char* unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        ExecOutput t, *eo = data;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        t = exec_output_from_string(rvalue);
+        if (t < 0) {
+                log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse output type, ignoring: %s", rvalue);
+                return 0;
+        }
+
+        if (IN_SET(t, EXEC_OUTPUT_SOCKET, EXEC_OUTPUT_NAMED_FD, EXEC_OUTPUT_FILE)) {
+                log_syntax(unit, LOG_ERR, filename, line, 0, "Standard output types socket, fd:, file: are not supported as defaults, ignoring: %s", rvalue);
+                return 0;
+        }
+
+        *eo = t;
+        return 0;
+}
+
 static int config_parse_crash_chvt(
                 const char* unit,
                 const char *filename,
@@ -716,14 +760,15 @@ static int parse_config_file(void) {
                 { "Manager", "JoinControllers",           config_parse_join_controllers, 0, &arg_join_controllers                  },
                 { "Manager", "RuntimeWatchdogSec",        config_parse_sec,              0, &arg_runtime_watchdog                  },
                 { "Manager", "ShutdownWatchdogSec",       config_parse_sec,              0, &arg_shutdown_watchdog                 },
+                { "Manager", "WatchdogDevice",            config_parse_path,             0, &arg_watchdog_device                   },
                 { "Manager", "CapabilityBoundingSet",     config_parse_capability_set,   0, &arg_capability_bounding_set           },
 #if HAVE_SECCOMP
                 { "Manager", "SystemCallArchitectures",   config_parse_syscall_archs,    0, &arg_syscall_archs                     },
 #endif
                 { "Manager", "TimerSlackNSec",            config_parse_nsec,             0, &arg_timer_slack_nsec                  },
                 { "Manager", "DefaultTimerAccuracySec",   config_parse_sec,              0, &arg_default_timer_accuracy_usec       },
-                { "Manager", "DefaultStandardOutput",     config_parse_output,           0, &arg_default_std_output                },
-                { "Manager", "DefaultStandardError",      config_parse_output,           0, &arg_default_std_error                 },
+                { "Manager", "DefaultStandardOutput",     config_parse_output_restricted,0, &arg_default_std_output                },
+                { "Manager", "DefaultStandardError",      config_parse_output_restricted,0, &arg_default_std_error                 },
                 { "Manager", "DefaultTimeoutStartSec",    config_parse_sec,              0, &arg_default_timeout_start_usec        },
                 { "Manager", "DefaultTimeoutStopSec",     config_parse_sec,              0, &arg_default_timeout_stop_usec         },
                 { "Manager", "DefaultRestartSec",         config_parse_sec,              0, &arg_default_restart_usec              },
@@ -768,7 +813,7 @@ static int parse_config_file(void) {
                 CONF_PATHS_NULSTR("systemd/system.conf.d") :
                 CONF_PATHS_NULSTR("systemd/user.conf.d");
 
-        config_parse_many_nulstr(fn, conf_dirs_nulstr, "Manager\0", config_item_table_lookup, items, false, NULL);
+        (void) config_parse_many_nulstr(fn, conf_dirs_nulstr, "Manager\0", config_item_table_lookup, items, CONFIG_PARSE_WARN, NULL);
 
         /* Traditionally "0" was used to turn off the default unit timeouts. Fix this up so that we used USEC_INFINITY
          * like everywhere else. */
@@ -780,7 +825,7 @@ static int parse_config_file(void) {
         return 0;
 }
 
-static void manager_set_defaults(Manager *m) {
+static void set_manager_defaults(Manager *m) {
 
         assert(m);
 
@@ -804,6 +849,18 @@ static void manager_set_defaults(Manager *m) {
         manager_environment_add(m, NULL, arg_default_environment);
 }
 
+static void set_manager_settings(Manager *m) {
+
+        assert(m);
+
+        m->confirm_spawn = arg_confirm_spawn;
+        m->runtime_watchdog = arg_runtime_watchdog;
+        m->shutdown_watchdog = arg_shutdown_watchdog;
+        m->cad_burst_action = arg_cad_burst_action;
+
+        manager_set_show_status(m, arg_show_status);
+}
+
 static int parse_argv(int argc, char *argv[]) {
 
         enum {
@@ -1190,7 +1247,7 @@ static int bump_rlimit_nofile(struct rlimit *saved_rlimit) {
 
         /* Get current RLIMIT_NOFILE maximum compiled into the kernel. */
         r = read_one_line_file("/proc/sys/fs/nr_open", &nr_open);
-        if (r == 0)
+        if (r >= 0)
                 r = safe_atoi(nr_open, &min_max);
         /* If we fail, fallback to the hard-coded kernel limit of 1024 * 1024. */
         if (r < 0)
@@ -1387,291 +1444,841 @@ static int fixup_environment(void) {
         return 0;
 }
 
-int main(int argc, char *argv[]) {
-        Manager *m = NULL;
-        int r, retval = EXIT_FAILURE;
-        usec_t before_startup, after_startup;
-        char timespan[FORMAT_TIMESPAN_MAX];
-        FDSet *fds = NULL;
-        bool reexecute = false;
-        const char *shutdown_verb = NULL;
-        dual_timestamp initrd_timestamp = DUAL_TIMESTAMP_NULL;
-        dual_timestamp userspace_timestamp = DUAL_TIMESTAMP_NULL;
-        dual_timestamp kernel_timestamp = DUAL_TIMESTAMP_NULL;
-        dual_timestamp security_start_timestamp = DUAL_TIMESTAMP_NULL;
-        dual_timestamp security_finish_timestamp = DUAL_TIMESTAMP_NULL;
-        static char systemd[] = "systemd";
-        bool skip_setup = false;
-        unsigned j;
-        bool loaded_policy = false;
-        bool arm_reboot_watchdog = false;
-        bool queue_default_job = false;
-        bool empty_etc = false;
-        char *switch_root_dir = NULL, *switch_root_init = NULL;
-        struct rlimit saved_rlimit_nofile = RLIMIT_MAKE_CONST(0), saved_rlimit_memlock = RLIMIT_MAKE_CONST((rlim_t) -1);
-        const char *error_message = NULL;
+static void redirect_telinit(int argc, char *argv[]) {
+
+        /* This is compatibility support for SysV, where calling init as a user is identical to telinit. */
 
 #if HAVE_SYSV_COMPAT
-        if (getpid_cached() != 1 && strstr(program_invocation_short_name, "init")) {
-                /* This is compatibility support for SysV, where
-                 * calling init as a user is identical to telinit. */
+        if (getpid_cached() == 1)
+                return;
 
-                execv(SYSTEMCTL_BINARY_PATH, argv);
-                log_error_errno(errno, "Failed to exec " SYSTEMCTL_BINARY_PATH ": %m");
-                return 1;
-        }
-#endif
+        if (!strstr(program_invocation_short_name, "init"))
+                return;
 
-        dual_timestamp_from_monotonic(&kernel_timestamp, 0);
-        dual_timestamp_get(&userspace_timestamp);
+        execv(SYSTEMCTL_BINARY_PATH, argv);
+        log_error_errno(errno, "Failed to exec " SYSTEMCTL_BINARY_PATH ": %m");
+        exit(1);
+#endif
+}
 
-        /* Determine if this is a reexecution or normal bootup. We do
-         * the full command line parsing much later, so let's just
-         * have a quick peek here. */
-        if (strv_find(argv+1, "--deserialize"))
-                skip_setup = true;
+static int become_shutdown(
+                const char *shutdown_verb,
+                int retval) {
 
-        /* If we have switched root, do all the special setup
-         * things */
-        if (strv_find(argv+1, "--switched-root"))
-                skip_setup = false;
+        char log_level[DECIMAL_STR_MAX(int) + 1],
+                exit_code[DECIMAL_STR_MAX(uint8_t) + 1];
 
-        /* If we get started via the /sbin/init symlink then we are
-           called 'init'. After a subsequent reexecution we are then
-           called 'systemd'. That is confusing, hence let's call us
-           systemd right-away. */
-        program_invocation_short_name = systemd;
-        (void) prctl(PR_SET_NAME, systemd);
+        const char* command_line[11] = {
+                SYSTEMD_SHUTDOWN_BINARY_PATH,
+                shutdown_verb,
+                "--log-level", log_level,
+                "--log-target",
+        };
 
-        saved_argv = argv;
-        saved_argc = argc;
+        _cleanup_strv_free_ char **env_block = NULL;
+        size_t pos = 5;
+        int r;
 
-        log_set_upgrade_syslog_to_journal(true);
+        assert(shutdown_verb);
+        assert(!command_line[pos]);
+        env_block = strv_copy(environ);
 
-        if (getpid_cached() == 1) {
-                /* Disable the umask logic */
-                umask(0);
+        xsprintf(log_level, "%d", log_get_max_level());
 
-                /* Always reopen /dev/console when running as PID 1 or one of its pre-execve() children. This is
-                 * important so that we never end up logging to any foreign stderr, for example if we have to log in a
-                 * child process right before execve()'ing the actual binary, at a point in time where socket
-                 * activation stderr/stdout area already set up. */
-                log_set_always_reopen_console(true);
-        }
+        switch (log_get_target()) {
 
-        if (getpid_cached() == 1 && detect_container() <= 0) {
+        case LOG_TARGET_KMSG:
+        case LOG_TARGET_JOURNAL_OR_KMSG:
+        case LOG_TARGET_SYSLOG_OR_KMSG:
+                command_line[pos++] = "kmsg";
+                break;
 
-                /* Running outside of a container as PID 1 */
-                arg_system = true;
-                log_set_target(LOG_TARGET_KMSG);
-                log_open();
+        case LOG_TARGET_NULL:
+                command_line[pos++] = "null";
+                break;
 
-                if (in_initrd())
-                        initrd_timestamp = userspace_timestamp;
+        case LOG_TARGET_CONSOLE:
+        default:
+                command_line[pos++] = "console";
+                break;
+        };
 
-                if (!skip_setup) {
-                        r = mount_setup_early();
-                        if (r < 0) {
-                                error_message = "Failed to mount early API filesystems";
-                                goto finish;
-                        }
+        if (log_get_show_color())
+                command_line[pos++] = "--log-color";
 
-                        dual_timestamp_get(&security_start_timestamp);
-                        if (mac_selinux_setup(&loaded_policy) < 0) {
-                                error_message = "Failed to load SELinux policy";
-                                goto finish;
-                        } else if (mac_smack_setup(&loaded_policy) < 0) {
-                                error_message = "Failed to load SMACK policy";
-                                goto finish;
-                        } else if (ima_setup() < 0) {
-                                error_message = "Failed to load IMA policy";
-                                goto finish;
-                        }
-                        dual_timestamp_get(&security_finish_timestamp);
-                }
+        if (log_get_show_location())
+                command_line[pos++] = "--log-location";
 
-                if (mac_selinux_init() < 0) {
-                        error_message = "Failed to initialize SELinux policy";
-                        goto finish;
-                }
+        if (streq(shutdown_verb, "exit")) {
+                command_line[pos++] = "--exit-code";
+                command_line[pos++] = exit_code;
+                xsprintf(exit_code, "%d", retval);
+        }
 
-                if (!skip_setup) {
-                        if (clock_is_localtime(NULL) > 0) {
-                                int min;
-
-                                /*
-                                 * The very first call of settimeofday() also does a time warp in the kernel.
-                                 *
-                                 * In the rtc-in-local time mode, we set the kernel's timezone, and rely on
-                                 * external tools to take care of maintaining the RTC and do all adjustments.
-                                 * This matches the behavior of Windows, which leaves the RTC alone if the
-                                 * registry tells that the RTC runs in UTC.
-                                 */
-                                r = clock_set_timezone(&min);
-                                if (r < 0)
-                                        log_error_errno(r, "Failed to apply local time delta, ignoring: %m");
-                                else
-                                        log_info("RTC configured in localtime, applying delta of %i minutes to system time.", min);
-                        } else if (!in_initrd()) {
-                                /*
-                                 * Do a dummy very first call to seal the kernel's time warp magic.
-                                 *
-                                 * Do not call this from inside the initrd. The initrd might not
-                                 * carry /etc/adjtime with LOCAL, but the real system could be set up
-                                 * that way. In such case, we need to delay the time-warp or the sealing
-                                 * until we reach the real system.
-                                 *
-                                 * Do no set the kernel's timezone. The concept of local time cannot
-                                 * be supported reliably, the time will jump or be incorrect at every daylight
-                                 * saving time change. All kernel local time concepts will be treated
-                                 * as UTC that way.
-                                 */
-                                clock_reset_timewarp();
-                        }
-                }
+        assert(pos < ELEMENTSOF(command_line));
 
-                /* Set the default for later on, but don't actually
-                 * open the logs like this for now. Note that if we
-                 * are transitioning from the initrd there might still
-                 * be journal fd open, and we shouldn't attempt
-                 * opening that before we parsed /proc/cmdline which
-                 * might redirect output elsewhere. */
-                log_set_target(LOG_TARGET_JOURNAL_OR_KMSG);
+        if (streq(shutdown_verb, "reboot") &&
+            arg_shutdown_watchdog > 0 &&
+            arg_shutdown_watchdog != USEC_INFINITY) {
 
-        } else if (getpid_cached() == 1) {
-                /* Running inside a container, as PID 1 */
-                arg_system = true;
-                log_set_target(LOG_TARGET_CONSOLE);
-                log_close_console(); /* force reopen of /dev/console */
-                log_open();
+                char *e;
 
-                /* For later on, see above... */
-                log_set_target(LOG_TARGET_JOURNAL);
+                /* If we reboot let's set the shutdown
+                 * watchdog and tell the shutdown binary to
+                 * repeatedly ping it */
+                r = watchdog_set_timeout(&arg_shutdown_watchdog);
+                watchdog_close(r < 0);
 
-                /* clear the kernel timestamp,
-                 * because we are in a container */
-                kernel_timestamp = DUAL_TIMESTAMP_NULL;
-        } else {
-                /* Running as user instance */
-                arg_system = false;
-                log_set_target(LOG_TARGET_AUTO);
-                log_open();
+                /* Tell the binary how often to ping, ignore failure */
+                if (asprintf(&e, "WATCHDOG_USEC="USEC_FMT, arg_shutdown_watchdog) > 0)
+                        (void) strv_consume(&env_block, e);
 
-                /* clear the kernel timestamp,
-                 * because we are not PID 1 */
-                kernel_timestamp = DUAL_TIMESTAMP_NULL;
-        }
+                if (arg_watchdog_device &&
+                    asprintf(&e, "WATCHDOG_DEVICE=%s", arg_watchdog_device) > 0)
+                        (void) strv_consume(&env_block, e);
+        } else
+                watchdog_close(true);
 
-        if (getpid_cached() == 1) {
-                /* Don't limit the core dump size, so that coredump handlers such as systemd-coredump (which honour the limit)
-                 * will process core dumps for system services by default. */
-                if (setrlimit(RLIMIT_CORE, &RLIMIT_MAKE_CONST(RLIM_INFINITY)) < 0)
-                        log_warning_errno(errno, "Failed to set RLIMIT_CORE: %m");
+        /* Avoid the creation of new processes forked by the
+         * kernel; at this point, we will not listen to the
+         * signals anyway */
+        if (detect_container() <= 0)
+                (void) cg_uninstall_release_agent(SYSTEMD_CGROUP_CONTROLLER);
 
-                /* But at the same time, turn off the core_pattern logic by default, so that no coredumps are stored
-                 * until the systemd-coredump tool is enabled via sysctl. */
-                if (!skip_setup)
-                        (void) write_string_file("/proc/sys/kernel/core_pattern", "|/bin/false", 0);
-        }
+        execve(SYSTEMD_SHUTDOWN_BINARY_PATH, (char **) command_line, env_block);
+        return -errno;
+}
 
-        if (arg_system) {
-                if (fixup_environment() < 0) {
-                        error_message = "Failed to fix up PID1 environment";
-                        goto finish;
-                }
+static void initialize_clock(void) {
+        int r;
 
-                /* Try to figure out if we can use colors with the console. No
-                 * need to do that for user instances since they never log
-                 * into the console. */
-                log_show_color(colors_enabled());
-                r = make_null_stdio();
+        if (clock_is_localtime(NULL) > 0) {
+                int min;
+
+                /*
+                 * The very first call of settimeofday() also does a time warp in the kernel.
+                 *
+                 * In the rtc-in-local time mode, we set the kernel's timezone, and rely on external tools to take care
+                 * of maintaining the RTC and do all adjustments.  This matches the behavior of Windows, which leaves
+                 * the RTC alone if the registry tells that the RTC runs in UTC.
+                 */
+                r = clock_set_timezone(&min);
                 if (r < 0)
-                        log_warning_errno(r, "Failed to redirect standard streams to /dev/null: %m");
+                        log_error_errno(r, "Failed to apply local time delta, ignoring: %m");
+                else
+                        log_info("RTC configured in localtime, applying delta of %i minutes to system time.", min);
+
+        } else if (!in_initrd()) {
+                /*
+                 * Do a dummy very first call to seal the kernel's time warp magic.
+                 *
+                 * Do not call this from inside the initrd. The initrd might not carry /etc/adjtime with LOCAL, but the
+                 * real system could be set up that way. In such case, we need to delay the time-warp or the sealing
+                 * until we reach the real system.
+                 *
+                 * Do no set the kernel's timezone. The concept of local time cannot be supported reliably, the time
+                 * will jump or be incorrect at every daylight saving time change. All kernel local time concepts will
+                 * be treated as UTC that way.
+                 */
+                (void) clock_reset_timewarp();
         }
+}
 
-        r = initialize_join_controllers();
-        if (r < 0) {
-                error_message = "Failed to initialize cgroup controllers";
-                goto finish;
-        }
+static void initialize_coredump(bool skip_setup) {
 
-        /* Mount /proc, /sys and friends, so that /proc/cmdline and
-         * /proc/$PID/fd is available. */
-        if (getpid_cached() == 1) {
+        if (getpid_cached() != 1)
+                return;
 
-                /* Load the kernel modules early. */
-                if (!skip_setup)
-                        kmod_setup();
+        /* Don't limit the core dump size, so that coredump handlers such as systemd-coredump (which honour the limit)
+         * will process core dumps for system services by default. */
+        if (setrlimit(RLIMIT_CORE, &RLIMIT_MAKE_CONST(RLIM_INFINITY)) < 0)
+                log_warning_errno(errno, "Failed to set RLIMIT_CORE: %m");
 
-                r = mount_setup(loaded_policy);
-                if (r < 0) {
-                        error_message = "Failed to mount API filesystems";
-                        goto finish;
-                }
-        }
+        /* But at the same time, turn off the core_pattern logic by default, so that no coredumps are stored
+         * until the systemd-coredump tool is enabled via sysctl. */
+        if (!skip_setup)
+                (void) write_string_file("/proc/sys/kernel/core_pattern", "|/bin/false", 0);
+}
 
-        /* Reset all signal handlers. */
-        (void) reset_all_signal_handlers();
-        (void) ignore_signals(SIGNALS_IGNORE, -1);
+static void do_reexecute(
+                int argc,
+                char *argv[],
+                const struct rlimit *saved_rlimit_nofile,
+                const struct rlimit *saved_rlimit_memlock,
+                FDSet *fds,
+                const char *switch_root_dir,
+                const char *switch_root_init,
+                const char **ret_error_message) {
+
+        unsigned i, j, args_size;
+        const char **args;
+        int r;
 
-        arg_default_tasks_max = system_tasks_max_scale(DEFAULT_TASKS_MAX_PERCENTAGE, 100U);
+        assert(saved_rlimit_nofile);
+        assert(saved_rlimit_memlock);
+        assert(ret_error_message);
 
-        if (parse_config_file() < 0) {
-                error_message = "Failed to parse config file";
-                goto finish;
-        }
+        /* Close and disarm the watchdog, so that the new instance can reinitialize it, but doesn't get rebooted while
+         * we do that */
+        watchdog_close(true);
 
-        if (arg_system) {
-                r = proc_cmdline_parse(parse_proc_cmdline_item, NULL, 0);
-                if (r < 0)
-                        log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m");
-        }
+        /* Reset the RLIMIT_NOFILE to the kernel default, so that the new systemd can pass the kernel default to its
+         * child processes */
 
-        /* Note that this also parses bits from the kernel command
-         * line, including "debug". */
-        log_parse_environment();
+        if (saved_rlimit_nofile->rlim_cur > 0)
+                (void) setrlimit(RLIMIT_NOFILE, saved_rlimit_nofile);
+        if (saved_rlimit_memlock->rlim_cur != (rlim_t) -1)
+                (void) setrlimit(RLIMIT_MEMLOCK, saved_rlimit_memlock);
 
-        if (parse_argv(argc, argv) < 0) {
-                error_message = "Failed to parse commandline arguments";
-                goto finish;
-        }
+        if (switch_root_dir) {
+                /* Kill all remaining processes from the initrd, but don't wait for them, so that we can handle the
+                 * SIGCHLD for them after deserializing. */
+                broadcast_signal(SIGTERM, false, true);
 
-        /* Initialize default unit */
-        if (!arg_default_unit) {
-                arg_default_unit = strdup(SPECIAL_DEFAULT_TARGET);
-                if (!arg_default_unit) {
-                        r = log_oom();
-                        error_message = "Failed to set default unit";
-                        goto finish;
-                }
+                /* And switch root with MS_MOVE, because we remove the old directory afterwards and detach it. */
+                r = switch_root(switch_root_dir, "/mnt", true, MS_MOVE);
+                if (r < 0)
+                        log_error_errno(r, "Failed to switch root, trying to continue: %m");
         }
 
-        if (arg_action == ACTION_TEST &&
-            geteuid() == 0) {
-                log_error("Don't run test mode as root.");
-                goto finish;
-        }
+        args_size = MAX(6, argc+1);
+        args = newa(const char*, args_size);
 
-        if (!arg_system &&
-            arg_action == ACTION_RUN &&
-            sd_booted() <= 0) {
-                log_error("Trying to run as user instance, but the system has not been booted with systemd.");
-                goto finish;
-        }
+        if (!switch_root_init) {
+                char sfd[DECIMAL_STR_MAX(int) + 1];
 
-        if (arg_system &&
-            arg_action == ACTION_RUN &&
-            running_in_chroot() > 0) {
-                log_error("Cannot be run in a chroot() environment.");
-                goto finish;
-        }
+                /* First try to spawn ourselves with the right path, and with full serialization. We do this only if
+                 * the user didn't specify an explicit init to spawn. */
 
-        if (IN_SET(arg_action, ACTION_TEST, ACTION_HELP)) {
-                pager_open(arg_no_pager, false);
-                skip_setup = true;
-        }
+                assert(arg_serialization);
+                assert(fds);
 
-        if (arg_action == ACTION_HELP) {
+                xsprintf(sfd, "%i", fileno(arg_serialization));
+
+                i = 0;
+                args[i++] = SYSTEMD_BINARY_PATH;
+                if (switch_root_dir)
+                        args[i++] = "--switched-root";
+                args[i++] = arg_system ? "--system" : "--user";
+                args[i++] = "--deserialize";
+                args[i++] = sfd;
+                args[i++] = NULL;
+
+                assert(i <= args_size);
+
+                /*
+                 * We want valgrind to print its memory usage summary before reexecution.  Valgrind won't do this is on
+                 * its own on exec(), but it will do it on exit().  Hence, to ensure we get a summary here, fork() off
+                 * a child, let it exit() cleanly, so that it prints the summary, and wait() for it in the parent,
+                 * before proceeding into the exec().
+                 */
+                valgrind_summary_hack();
+
+                (void) execv(args[0], (char* const*) args);
+                log_debug_errno(errno, "Failed to execute our own binary, trying fallback: %m");
+        }
+
+        /* Try the fallback, if there is any, without any serialization. We pass the original argv[] and envp[]. (Well,
+         * modulo the ordering changes due to getopt() in argv[], and some cleanups in envp[], but let's hope that
+         * doesn't matter.) */
+
+        arg_serialization = safe_fclose(arg_serialization);
+        fds = fdset_free(fds);
+
+        /* Reopen the console */
+        (void) make_console_stdio();
+
+        for (j = 1, i = 1; j < (unsigned) argc; j++)
+                args[i++] = argv[j];
+        args[i++] = NULL;
+        assert(i <= args_size);
+
+        /* Reenable any blocked signals, especially important if we switch from initial ramdisk to init=... */
+        (void) reset_all_signal_handlers();
+        (void) reset_signal_mask();
+
+        if (switch_root_init) {
+                args[0] = switch_root_init;
+                (void) execv(args[0], (char* const*) args);
+                log_warning_errno(errno, "Failed to execute configured init, trying fallback: %m");
+        }
+
+        args[0] = "/sbin/init";
+        (void) execv(args[0], (char* const*) args);
+        r = -errno;
+
+        manager_status_printf(NULL, STATUS_TYPE_EMERGENCY,
+                              ANSI_HIGHLIGHT_RED "  !!  " ANSI_NORMAL,
+                              "Failed to execute /sbin/init");
+
+        if (r == -ENOENT) {
+                log_warning("No /sbin/init, trying fallback");
+
+                args[0] = "/bin/sh";
+                args[1] = NULL;
+                (void) execv(args[0], (char* const*) args);
+                log_error_errno(errno, "Failed to execute /bin/sh, giving up: %m");
+        } else
+                log_warning_errno(r, "Failed to execute /sbin/init, giving up: %m");
+
+        *ret_error_message = "Failed to execute fallback shell";
+}
+
+static int invoke_main_loop(
+                Manager *m,
+                bool *ret_reexecute,
+                int *ret_retval,                   /* Return parameters relevant for shutting down */
+                const char **ret_shutdown_verb,    /* … */
+                FDSet **ret_fds,                   /* Return parameters for reexecuting */
+                char **ret_switch_root_dir,        /* … */
+                char **ret_switch_root_init,       /* … */
+                const char **ret_error_message) {
+
+        int r;
+
+        assert(m);
+        assert(ret_reexecute);
+        assert(ret_retval);
+        assert(ret_shutdown_verb);
+        assert(ret_fds);
+        assert(ret_switch_root_dir);
+        assert(ret_switch_root_init);
+        assert(ret_error_message);
+
+        for (;;) {
+                r = manager_loop(m);
+                if (r < 0) {
+                        *ret_error_message = "Failed to run main loop";
+                        return log_emergency_errno(r, "Failed to run main loop: %m");
+                }
+
+                switch (m->exit_code) {
+
+                case MANAGER_RELOAD:
+                        log_info("Reloading.");
+
+                        r = parse_config_file();
+                        if (r < 0)
+                                log_warning_errno(r, "Failed to parse config file, ignoring: %m");
+
+                        set_manager_defaults(m);
+
+                        r = manager_reload(m);
+                        if (r < 0)
+                                log_warning_errno(r, "Failed to reload, ignoring: %m");
+
+                        break;
+
+                case MANAGER_REEXECUTE:
+
+                        r = prepare_reexecute(m, &arg_serialization, ret_fds, false);
+                        if (r < 0) {
+                                *ret_error_message = "Failed to prepare for reexecution";
+                                return r;
+                        }
+
+                        log_notice("Reexecuting.");
+
+                        *ret_reexecute = true;
+                        *ret_retval = EXIT_SUCCESS;
+                        *ret_shutdown_verb = NULL;
+                        *ret_switch_root_dir = *ret_switch_root_init = NULL;
+
+                        return 0;
+
+                case MANAGER_SWITCH_ROOT:
+                        if (!m->switch_root_init) {
+                                r = prepare_reexecute(m, &arg_serialization, ret_fds, true);
+                                if (r < 0) {
+                                        *ret_error_message = "Failed to prepare for reexecution";
+                                        return r;
+                                }
+                        } else
+                                *ret_fds = NULL;
+
+                        log_notice("Switching root.");
+
+                        *ret_reexecute = true;
+                        *ret_retval = EXIT_SUCCESS;
+                        *ret_shutdown_verb = NULL;
+
+                        /* Steal the switch root parameters */
+                        *ret_switch_root_dir = m->switch_root;
+                        *ret_switch_root_init = m->switch_root_init;
+                        m->switch_root = m->switch_root_init = NULL;
+
+                        return 0;
+
+                case MANAGER_EXIT:
+
+                        if (MANAGER_IS_USER(m)) {
+                                log_debug("Exit.");
+
+                                *ret_reexecute = false;
+                                *ret_retval = m->return_value;
+                                *ret_shutdown_verb = NULL;
+                                *ret_fds = NULL;
+                                *ret_switch_root_dir = *ret_switch_root_init = NULL;
+
+                                return 0;
+                        }
+
+                        _fallthrough_;
+                case MANAGER_REBOOT:
+                case MANAGER_POWEROFF:
+                case MANAGER_HALT:
+                case MANAGER_KEXEC: {
+                        static const char * const table[_MANAGER_EXIT_CODE_MAX] = {
+                                [MANAGER_EXIT] = "exit",
+                                [MANAGER_REBOOT] = "reboot",
+                                [MANAGER_POWEROFF] = "poweroff",
+                                [MANAGER_HALT] = "halt",
+                                [MANAGER_KEXEC] = "kexec"
+                        };
+
+                        log_notice("Shutting down.");
+
+                        *ret_reexecute = false;
+                        *ret_retval = m->return_value;
+                        assert_se(*ret_shutdown_verb = table[m->exit_code]);
+                        *ret_fds = NULL;
+                        *ret_switch_root_dir = *ret_switch_root_init = NULL;
+
+                        return 0;
+                }
+
+                default:
+                        assert_not_reached("Unknown exit code.");
+                }
+        }
+}
+
+static void log_execution_mode(bool *ret_first_boot) {
+        assert(ret_first_boot);
+
+        if (arg_system) {
+                int v;
+
+                log_info(PACKAGE_STRING " running in %ssystem mode. (" SYSTEMD_FEATURES ")",
+                         arg_action == ACTION_TEST ? "test " : "" );
+
+                v = detect_virtualization();
+                if (v > 0)
+                        log_info("Detected virtualization %s.", virtualization_to_string(v));
+
+                log_info("Detected architecture %s.", architecture_to_string(uname_architecture()));
+
+                if (in_initrd()) {
+                        *ret_first_boot = false;
+                        log_info("Running in initial RAM disk.");
+                } else {
+                        /* Let's check whether we are in first boot, i.e. whether /etc is still unpopulated. We use
+                         * /etc/machine-id as flag file, for this: if it exists we assume /etc is populated, if it
+                         * doesn't it's unpopulated. This allows container managers and installers to provision a
+                         * couple of files already. If the container manager wants to provision the machine ID itself
+                         * it should pass $container_uuid to PID 1. */
+
+                        *ret_first_boot = access("/etc/machine-id", F_OK) < 0;
+                        if (*ret_first_boot)
+                                log_info("Running with unpopulated /etc.");
+                }
+        } else {
+                _cleanup_free_ char *t;
+
+                t = uid_to_name(getuid());
+                log_debug(PACKAGE_STRING " running in %suser mode for user " UID_FMT "/%s. (" SYSTEMD_FEATURES ")",
+                          arg_action == ACTION_TEST ? " test" : "", getuid(), strna(t));
+
+                *ret_first_boot = false;
+        }
+}
+
+static int initialize_runtime(
+                bool skip_setup,
+                struct rlimit *saved_rlimit_nofile,
+                struct rlimit *saved_rlimit_memlock,
+                const char **ret_error_message) {
+
+        int r;
+
+        assert(ret_error_message);
+
+        /* Sets up various runtime parameters. Many of these initializations are conditionalized:
+         *
+         * - Some only apply to --system instances
+         * - Some only apply to --user instances
+         * - Some only apply when we first start up, but not when we reexecute
+         */
+
+        if (arg_system && !skip_setup) {
+                if (arg_show_status > 0)
+                        status_welcome();
+
+                hostname_setup();
+                machine_id_setup(NULL, arg_machine_id, NULL);
+                loopback_setup();
+                bump_unix_max_dgram_qlen();
+                test_usr();
+                write_container_id();
+        }
+
+        if (arg_system && arg_watchdog_device) {
+                r = watchdog_set_device(arg_watchdog_device);
+                if (r < 0)
+                        log_warning_errno(r, "Failed to set watchdog device to %s, ignoring: %m",
+                                          arg_watchdog_device);
+        }
+
+        if (arg_system && arg_runtime_watchdog > 0 && arg_runtime_watchdog != USEC_INFINITY)
+                watchdog_set_timeout(&arg_runtime_watchdog);
+
+        if (arg_timer_slack_nsec != NSEC_INFINITY)
+                if (prctl(PR_SET_TIMERSLACK, arg_timer_slack_nsec) < 0)
+                        log_error_errno(errno, "Failed to adjust timer slack: %m");
+
+        if (arg_system && !cap_test_all(arg_capability_bounding_set)) {
+                r = capability_bounding_set_drop_usermode(arg_capability_bounding_set);
+                if (r < 0) {
+                        *ret_error_message = "Failed to drop capability bounding set of usermode helpers";
+                        return log_emergency_errno(r, "Failed to drop capability bounding set of usermode helpers: %m");
+                }
+
+                r = capability_bounding_set_drop(arg_capability_bounding_set, true);
+                if (r < 0) {
+                        *ret_error_message = "Failed to drop capability bounding set";
+                        return log_emergency_errno(r, "Failed to drop capability bounding set: %m");
+                }
+        }
+
+        if (arg_syscall_archs) {
+                r = enforce_syscall_archs(arg_syscall_archs);
+                if (r < 0) {
+                        *ret_error_message = "Failed to set syscall architectures";
+                        return r;
+                }
+        }
+
+        if (!arg_system)
+                /* Become reaper of our children */
+                if (prctl(PR_SET_CHILD_SUBREAPER, 1) < 0)
+                        log_warning_errno(errno, "Failed to make us a subreaper: %m");
+
+        if (arg_system) {
+                /* Bump up RLIMIT_NOFILE for systemd itself */
+                (void) bump_rlimit_nofile(saved_rlimit_nofile);
+                (void) bump_rlimit_memlock(saved_rlimit_memlock);
+        }
+
+        return 0;
+}
+
+static int do_queue_default_job(
+                Manager *m,
+                const char **ret_error_message) {
+
+        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+        Job *default_unit_job;
+        Unit *target = NULL;
+        int r;
+
+        log_debug("Activating default unit: %s", arg_default_unit);
+
+        r = manager_load_unit(m, arg_default_unit, NULL, &error, &target);
+        if (r < 0)
+                log_error("Failed to load default target: %s", bus_error_message(&error, r));
+        else if (IN_SET(target->load_state, UNIT_ERROR, UNIT_NOT_FOUND))
+                log_error_errno(target->load_error, "Failed to load default target: %m");
+        else if (target->load_state == UNIT_MASKED)
+                log_error("Default target masked.");
+
+        if (!target || target->load_state != UNIT_LOADED) {
+                log_info("Trying to load rescue target...");
+
+                r = manager_load_unit(m, SPECIAL_RESCUE_TARGET, NULL, &error, &target);
+                if (r < 0) {
+                        *ret_error_message = "Failed to load rescue target";
+                        return log_emergency_errno(r, "Failed to load rescue target: %s", bus_error_message(&error, r));
+                } else if (IN_SET(target->load_state, UNIT_ERROR, UNIT_NOT_FOUND)) {
+                        *ret_error_message = "Failed to load rescue target";
+                        return log_emergency_errno(target->load_error, "Failed to load rescue target: %m");
+                } else if (target->load_state == UNIT_MASKED) {
+                        *ret_error_message = "Rescue target masked";
+                        log_emergency("Rescue target masked.");
+                        return -ERFKILL;
+                }
+        }
+
+        assert(target->load_state == UNIT_LOADED);
+
+        r = manager_add_job(m, JOB_START, target, JOB_ISOLATE, &error, &default_unit_job);
+        if (r == -EPERM) {
+                log_debug_errno(r, "Default target could not be isolated, starting instead: %s", bus_error_message(&error, r));
+
+                sd_bus_error_free(&error);
+
+                r = manager_add_job(m, JOB_START, target, JOB_REPLACE, &error, &default_unit_job);
+                if (r < 0) {
+                        *ret_error_message = "Failed to start default target";
+                        return log_emergency_errno(r, "Failed to start default target: %s", bus_error_message(&error, r));
+                }
+
+        } else if (r < 0) {
+                *ret_error_message = "Failed to isolate default target";
+                return log_emergency_errno(r, "Failed to isolate default target: %s", bus_error_message(&error, r));
+        }
+
+        m->default_unit_job_id = default_unit_job->id;
+
+        return 0;
+}
+
+static void free_arguments(void) {
+        size_t j;
+
+        /* Frees all arg_* variables, with the exception of arg_serialization */
+
+        for (j = 0; j < ELEMENTSOF(arg_default_rlimit); j++)
+                arg_default_rlimit[j] = mfree(arg_default_rlimit[j]);
+
+        arg_default_unit = mfree(arg_default_unit);
+        arg_confirm_spawn = mfree(arg_confirm_spawn);
+        arg_join_controllers = strv_free_free(arg_join_controllers);
+        arg_default_environment = strv_free(arg_default_environment);
+        arg_syscall_archs = set_free(arg_syscall_archs);
+}
+
+int main(int argc, char *argv[]) {
+        Manager *m = NULL;
+        int r, retval = EXIT_FAILURE;
+        usec_t before_startup, after_startup;
+        char timespan[FORMAT_TIMESPAN_MAX];
+        FDSet *fds = NULL;
+        bool reexecute = false;
+        const char *shutdown_verb = NULL;
+        dual_timestamp initrd_timestamp = DUAL_TIMESTAMP_NULL;
+        dual_timestamp userspace_timestamp = DUAL_TIMESTAMP_NULL;
+        dual_timestamp kernel_timestamp = DUAL_TIMESTAMP_NULL;
+        dual_timestamp security_start_timestamp = DUAL_TIMESTAMP_NULL;
+        dual_timestamp security_finish_timestamp = DUAL_TIMESTAMP_NULL;
+        static char systemd[] = "systemd";
+        bool skip_setup = false;
+        bool loaded_policy = false;
+        bool queue_default_job = false;
+        bool first_boot = false;
+        char *switch_root_dir = NULL, *switch_root_init = NULL;
+        struct rlimit saved_rlimit_nofile = RLIMIT_MAKE_CONST(0), saved_rlimit_memlock = RLIMIT_MAKE_CONST((rlim_t) -1);
+        const char *error_message = NULL;
+
+        redirect_telinit(argc, argv);
+
+        dual_timestamp_from_monotonic(&kernel_timestamp, 0);
+        dual_timestamp_get(&userspace_timestamp);
+
+        /* Determine if this is a reexecution or normal bootup. We do
+         * the full command line parsing much later, so let's just
+         * have a quick peek here. */
+        if (strv_find(argv+1, "--deserialize"))
+                skip_setup = true;
+
+        /* If we have switched root, do all the special setup
+         * things */
+        if (strv_find(argv+1, "--switched-root"))
+                skip_setup = false;
+
+        /* If we get started via the /sbin/init symlink then we are
+           called 'init'. After a subsequent reexecution we are then
+           called 'systemd'. That is confusing, hence let's call us
+           systemd right-away. */
+        program_invocation_short_name = systemd;
+        (void) prctl(PR_SET_NAME, systemd);
+
+        saved_argv = argv;
+        saved_argc = argc;
+
+        log_set_upgrade_syslog_to_journal(true);
+
+        if (getpid_cached() == 1) {
+                /* Disable the umask logic */
+                umask(0);
+
+                /* Always reopen /dev/console when running as PID 1 or one of its pre-execve() children. This is
+                 * important so that we never end up logging to any foreign stderr, for example if we have to log in a
+                 * child process right before execve()'ing the actual binary, at a point in time where socket
+                 * activation stderr/stdout area already set up. */
+                log_set_always_reopen_console(true);
+        }
+
+        if (getpid_cached() == 1 && detect_container() <= 0) {
+
+                /* Running outside of a container as PID 1 */
+                arg_system = true;
+                log_set_target(LOG_TARGET_KMSG);
+                log_open();
+
+                if (in_initrd())
+                        initrd_timestamp = userspace_timestamp;
+
+                if (!skip_setup) {
+                        r = mount_setup_early();
+                        if (r < 0) {
+                                error_message = "Failed to mount early API filesystems";
+                                goto finish;
+                        }
+
+                        dual_timestamp_get(&security_start_timestamp);
+                        if (mac_selinux_setup(&loaded_policy) < 0) {
+                                error_message = "Failed to load SELinux policy";
+                                goto finish;
+                        } else if (mac_smack_setup(&loaded_policy) < 0) {
+                                error_message = "Failed to load SMACK policy";
+                                goto finish;
+                        } else if (ima_setup() < 0) {
+                                error_message = "Failed to load IMA policy";
+                                goto finish;
+                        }
+                        dual_timestamp_get(&security_finish_timestamp);
+                }
+
+                if (mac_selinux_init() < 0) {
+                        error_message = "Failed to initialize SELinux policy";
+                        goto finish;
+                }
+
+                if (!skip_setup)
+                        initialize_clock();
+
+                /* Set the default for later on, but don't actually
+                 * open the logs like this for now. Note that if we
+                 * are transitioning from the initrd there might still
+                 * be journal fd open, and we shouldn't attempt
+                 * opening that before we parsed /proc/cmdline which
+                 * might redirect output elsewhere. */
+                log_set_target(LOG_TARGET_JOURNAL_OR_KMSG);
+
+        } else if (getpid_cached() == 1) {
+                /* Running inside a container, as PID 1 */
+                arg_system = true;
+                log_set_target(LOG_TARGET_CONSOLE);
+                log_close_console(); /* force reopen of /dev/console */
+                log_open();
+
+                /* For later on, see above... */
+                log_set_target(LOG_TARGET_JOURNAL);
+
+                /* clear the kernel timestamp,
+                 * because we are in a container */
+                kernel_timestamp = DUAL_TIMESTAMP_NULL;
+        } else {
+                /* Running as user instance */
+                arg_system = false;
+                log_set_target(LOG_TARGET_AUTO);
+                log_open();
+
+                /* clear the kernel timestamp,
+                 * because we are not PID 1 */
+                kernel_timestamp = DUAL_TIMESTAMP_NULL;
+        }
+
+        initialize_coredump(skip_setup);
+
+        if (arg_system) {
+                if (fixup_environment() < 0) {
+                        error_message = "Failed to fix up PID1 environment";
+                        goto finish;
+                }
+
+                /* Try to figure out if we can use colors with the console. No
+                 * need to do that for user instances since they never log
+                 * into the console. */
+                log_show_color(colors_enabled());
+                r = make_null_stdio();
+                if (r < 0)
+                        log_warning_errno(r, "Failed to redirect standard streams to /dev/null: %m");
+        }
+
+        r = initialize_join_controllers();
+        if (r < 0) {
+                error_message = "Failed to initialize cgroup controllers";
+                goto finish;
+        }
+
+        /* Mount /proc, /sys and friends, so that /proc/cmdline and
+         * /proc/$PID/fd is available. */
+        if (getpid_cached() == 1) {
+
+                /* Load the kernel modules early. */
+                if (!skip_setup)
+                        kmod_setup();
+
+                r = mount_setup(loaded_policy);
+                if (r < 0) {
+                        error_message = "Failed to mount API filesystems";
+                        goto finish;
+                }
+        }
+
+        /* Reset all signal handlers. */
+        (void) reset_all_signal_handlers();
+        (void) ignore_signals(SIGNALS_IGNORE, -1);
+
+        arg_default_tasks_max = system_tasks_max_scale(DEFAULT_TASKS_MAX_PERCENTAGE, 100U);
+
+        if (parse_config_file() < 0) {
+                error_message = "Failed to parse config file";
+                goto finish;
+        }
+
+        if (arg_system) {
+                r = proc_cmdline_parse(parse_proc_cmdline_item, NULL, 0);
+                if (r < 0)
+                        log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m");
+        }
+
+        /* Note that this also parses bits from the kernel command
+         * line, including "debug". */
+        log_parse_environment();
+
+        if (parse_argv(argc, argv) < 0) {
+                error_message = "Failed to parse commandline arguments";
+                goto finish;
+        }
+
+        /* Initialize default unit */
+        if (!arg_default_unit) {
+                arg_default_unit = strdup(SPECIAL_DEFAULT_TARGET);
+                if (!arg_default_unit) {
+                        r = log_oom();
+                        error_message = "Failed to set default unit";
+                        goto finish;
+                }
+        }
+
+        if (arg_action == ACTION_TEST &&
+            geteuid() == 0) {
+                log_error("Don't run test mode as root.");
+                goto finish;
+        }
+
+        if (!arg_system &&
+            arg_action == ACTION_RUN &&
+            sd_booted() <= 0) {
+                log_error("Trying to run as user instance, but the system has not been booted with systemd.");
+                goto finish;
+        }
+
+        if (arg_system &&
+            arg_action == ACTION_RUN &&
+            running_in_chroot() > 0) {
+                log_error("Cannot be run in a chroot() environment.");
+                goto finish;
+        }
+
+        if (IN_SET(arg_action, ACTION_TEST, ACTION_HELP)) {
+                pager_open(arg_no_pager, false);
+                skip_setup = true;
+        }
+
+        if (arg_action == ACTION_HELP) {
                 retval = help();
                 goto finish;
         } else if (arg_action == ACTION_VERSION) {
@@ -1745,95 +2352,15 @@ int main(int argc, char *argv[]) {
                         goto finish;
         }
 
-        if (arg_system) {
-                int v;
-
-                log_info(PACKAGE_STRING " running in %ssystem mode. (" SYSTEMD_FEATURES ")",
-                         arg_action == ACTION_TEST ? "test " : "" );
-
-                v = detect_virtualization();
-                if (v > 0)
-                        log_info("Detected virtualization %s.", virtualization_to_string(v));
-
-                write_container_id();
-
-                log_info("Detected architecture %s.", architecture_to_string(uname_architecture()));
-
-                if (in_initrd())
-                        log_info("Running in initial RAM disk.");
-
-                /* Let's check whether /etc is already populated. We
-                 * don't actually really check for that, but use
-                 * /etc/machine-id as flag file. This allows container
-                 * managers and installers to provision a couple of
-                 * files already. If the container manager wants to
-                 * provision the machine ID itself it should pass
-                 * $container_uuid to PID 1. */
-
-                empty_etc = access("/etc/machine-id", F_OK) < 0;
-                if (empty_etc)
-                        log_info("Running with unpopulated /etc.");
-        } else {
-                _cleanup_free_ char *t;
-
-                t = uid_to_name(getuid());
-                log_debug(PACKAGE_STRING " running in %suser mode for user "UID_FMT"/%s. (" SYSTEMD_FEATURES ")",
-                          arg_action == ACTION_TEST ? " test" : "", getuid(), t);
-        }
+        log_execution_mode(&first_boot);
 
         if (arg_action == ACTION_RUN) {
-                if (arg_system && !skip_setup) {
-                        if (arg_show_status > 0)
-                                status_welcome();
-
-                        hostname_setup();
-                        machine_id_setup(NULL, arg_machine_id, NULL);
-                        loopback_setup();
-                        bump_unix_max_dgram_qlen();
-
-                        test_usr();
-                }
-
-                if (arg_system && arg_runtime_watchdog > 0 && arg_runtime_watchdog != USEC_INFINITY)
-                        watchdog_set_timeout(&arg_runtime_watchdog);
-
-                if (arg_timer_slack_nsec != NSEC_INFINITY)
-                        if (prctl(PR_SET_TIMERSLACK, arg_timer_slack_nsec) < 0)
-                                log_error_errno(errno, "Failed to adjust timer slack: %m");
-
-                if (arg_system && !cap_test_all(arg_capability_bounding_set)) {
-                        r = capability_bounding_set_drop_usermode(arg_capability_bounding_set);
-                        if (r < 0) {
-                                log_emergency_errno(r, "Failed to drop capability bounding set of usermode helpers: %m");
-                                error_message = "Failed to drop capability bounding set of usermode helpers";
-                                goto finish;
-                        }
-                        r = capability_bounding_set_drop(arg_capability_bounding_set, true);
-                        if (r < 0) {
-                                log_emergency_errno(r, "Failed to drop capability bounding set: %m");
-                                error_message = "Failed to drop capability bounding set";
-                                goto finish;
-                        }
-                }
-
-                if (arg_syscall_archs) {
-                        r = enforce_syscall_archs(arg_syscall_archs);
-                        if (r < 0) {
-                                error_message = "Failed to set syscall architectures";
-                                goto finish;
-                        }
-                }
-
-                if (!arg_system)
-                        /* Become reaper of our children */
-                        if (prctl(PR_SET_CHILD_SUBREAPER, 1) < 0)
-                                log_warning_errno(errno, "Failed to make us a subreaper: %m");
-
-                if (arg_system) {
-                        /* Bump up RLIMIT_NOFILE for systemd itself */
-                        (void) bump_rlimit_nofile(&saved_rlimit_nofile);
-                        (void) bump_rlimit_memlock(&saved_rlimit_memlock);
-                }
+                r = initialize_runtime(skip_setup,
+                                       &saved_rlimit_nofile,
+                                       &saved_rlimit_memlock,
+                                       &error_message);
+                if (r < 0)
+                        goto finish;
         }
 
         r = manager_new(arg_system ? UNIT_FILE_SYSTEM : UNIT_FILE_USER,
@@ -1845,19 +2372,15 @@ int main(int argc, char *argv[]) {
                 goto finish;
         }
 
-        m->confirm_spawn = arg_confirm_spawn;
-        m->runtime_watchdog = arg_runtime_watchdog;
-        m->shutdown_watchdog = arg_shutdown_watchdog;
-        m->userspace_timestamp = userspace_timestamp;
-        m->kernel_timestamp = kernel_timestamp;
-        m->initrd_timestamp = initrd_timestamp;
-        m->security_start_timestamp = security_start_timestamp;
-        m->security_finish_timestamp = security_finish_timestamp;
-        m->cad_burst_action = arg_cad_burst_action;
+        m->timestamps[MANAGER_TIMESTAMP_KERNEL] = kernel_timestamp;
+        m->timestamps[MANAGER_TIMESTAMP_INITRD] = initrd_timestamp;
+        m->timestamps[MANAGER_TIMESTAMP_USERSPACE] = userspace_timestamp;
+        m->timestamps[MANAGER_TIMESTAMP_SECURITY_START] = security_start_timestamp;
+        m->timestamps[MANAGER_TIMESTAMP_SECURITY_FINISH] = security_finish_timestamp;
 
-        manager_set_defaults(m);
-        manager_set_show_status(m, arg_show_status);
-        manager_set_first_boot(m, empty_etc);
+        set_manager_defaults(m);
+        set_manager_settings(m);
+        manager_set_first_boot(m, first_boot);
 
         /* Remember whether we should queue the default job */
         queue_default_job = !arg_serialization || arg_switched_root;
@@ -1867,173 +2390,57 @@ int main(int argc, char *argv[]) {
         r = manager_startup(m, arg_serialization, fds);
         if (r < 0) {
                 log_error_errno(r, "Failed to fully start up daemon: %m");
+                error_message = "Failed to start up manager";
                 goto finish;
         }
 
-        /* This will close all file descriptors that were opened, but
-         * not claimed by any unit. */
+        /* This will close all file descriptors that were opened, but not claimed by any unit. */
         fds = fdset_free(fds);
-
         arg_serialization = safe_fclose(arg_serialization);
 
         if (queue_default_job) {
-                _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
-                Unit *target = NULL;
-                Job *default_unit_job;
-
-                log_debug("Activating default unit: %s", arg_default_unit);
-
-                r = manager_load_unit(m, arg_default_unit, NULL, &error, &target);
+                r = do_queue_default_job(m, &error_message);
                 if (r < 0)
-                        log_error("Failed to load default target: %s", bus_error_message(&error, r));
-                else if (IN_SET(target->load_state, UNIT_ERROR, UNIT_NOT_FOUND))
-                        log_error_errno(target->load_error, "Failed to load default target: %m");
-                else if (target->load_state == UNIT_MASKED)
-                        log_error("Default target masked.");
-
-                if (!target || target->load_state != UNIT_LOADED) {
-                        log_info("Trying to load rescue target...");
-
-                        r = manager_load_unit(m, SPECIAL_RESCUE_TARGET, NULL, &error, &target);
-                        if (r < 0) {
-                                log_emergency("Failed to load rescue target: %s", bus_error_message(&error, r));
-                                error_message = "Failed to load rescue target";
-                                goto finish;
-                        } else if (IN_SET(target->load_state, UNIT_ERROR, UNIT_NOT_FOUND)) {
-                                log_emergency_errno(target->load_error, "Failed to load rescue target: %m");
-                                error_message = "Failed to load rescue target";
-                                goto finish;
-                        } else if (target->load_state == UNIT_MASKED) {
-                                log_emergency("Rescue target masked.");
-                                error_message = "Rescue target masked";
-                                goto finish;
-                        }
-                }
-
-                assert(target->load_state == UNIT_LOADED);
-
-                if (arg_action == ACTION_TEST) {
-                        printf("-> By units:\n");
-                        manager_dump_units(m, stdout, "\t");
-                }
-
-                r = manager_add_job(m, JOB_START, target, JOB_ISOLATE, &error, &default_unit_job);
-                if (r == -EPERM) {
-                        log_debug("Default target could not be isolated, starting instead: %s", bus_error_message(&error, r));
-
-                        sd_bus_error_free(&error);
-
-                        r = manager_add_job(m, JOB_START, target, JOB_REPLACE, &error, &default_unit_job);
-                        if (r < 0) {
-                                log_emergency("Failed to start default target: %s", bus_error_message(&error, r));
-                                error_message = "Failed to start default target";
-                                goto finish;
-                        }
-                } else if (r < 0) {
-                        log_emergency("Failed to isolate default target: %s", bus_error_message(&error, r));
-                        error_message = "Failed to isolate default target";
-                        goto finish;
-                }
-
-                m->default_unit_job_id = default_unit_job->id;
-
-                after_startup = now(CLOCK_MONOTONIC);
-                log_full(arg_action == ACTION_TEST ? LOG_INFO : LOG_DEBUG,
-                         "Loaded units and determined initial transaction in %s.",
-                         format_timespan(timespan, sizeof(timespan), after_startup - before_startup, 100 * USEC_PER_MSEC));
-
-                if (arg_action == ACTION_TEST) {
-                        printf("-> By jobs:\n");
-                        manager_dump_jobs(m, stdout, "\t");
-                        retval = EXIT_SUCCESS;
                         goto finish;
-                }
         }
 
-        for (;;) {
-                r = manager_loop(m);
-                if (r < 0) {
-                        log_emergency_errno(r, "Failed to run main loop: %m");
-                        error_message = "Failed to run main loop";
-                        goto finish;
-                }
-
-                switch (m->exit_code) {
-
-                case MANAGER_RELOAD:
-                        log_info("Reloading.");
-
-                        r = parse_config_file();
-                        if (r < 0)
-                                log_error("Failed to parse config file.");
-
-                        manager_set_defaults(m);
-
-                        r = manager_reload(m);
-                        if (r < 0)
-                                log_error_errno(r, "Failed to reload: %m");
-                        break;
-
-                case MANAGER_REEXECUTE:
-
-                        if (prepare_reexecute(m, &arg_serialization, &fds, false) < 0) {
-                                error_message = "Failed to prepare for reexecution";
-                                goto finish;
-                        }
-
-                        reexecute = true;
-                        log_notice("Reexecuting.");
-                        goto finish;
-
-                case MANAGER_SWITCH_ROOT:
-                        /* Steal the switch root parameters */
-                        switch_root_dir = m->switch_root;
-                        switch_root_init = m->switch_root_init;
-                        m->switch_root = m->switch_root_init = NULL;
-
-                        if (!switch_root_init)
-                                if (prepare_reexecute(m, &arg_serialization, &fds, true) < 0) {
-                                        error_message = "Failed to prepare for reexecution";
-                                        goto finish;
-                                }
+        after_startup = now(CLOCK_MONOTONIC);
 
-                        reexecute = true;
-                        log_notice("Switching root.");
-                        goto finish;
-
-                case MANAGER_EXIT:
-                        retval = m->return_value;
-
-                        if (MANAGER_IS_USER(m)) {
-                                log_debug("Exit.");
-                                goto finish;
-                        }
-
-                        /* fallthrough */
-                case MANAGER_REBOOT:
-                case MANAGER_POWEROFF:
-                case MANAGER_HALT:
-                case MANAGER_KEXEC: {
-                        static const char * const table[_MANAGER_EXIT_CODE_MAX] = {
-                                [MANAGER_EXIT] = "exit",
-                                [MANAGER_REBOOT] = "reboot",
-                                [MANAGER_POWEROFF] = "poweroff",
-                                [MANAGER_HALT] = "halt",
-                                [MANAGER_KEXEC] = "kexec"
-                        };
+        log_full(arg_action == ACTION_TEST ? LOG_INFO : LOG_DEBUG,
+                 "Loaded units and determined initial transaction in %s.",
+                 format_timespan(timespan, sizeof(timespan), after_startup - before_startup, 100 * USEC_PER_MSEC));
 
-                        assert_se(shutdown_verb = table[m->exit_code]);
-                        arm_reboot_watchdog = m->exit_code == MANAGER_REBOOT;
+        if (arg_system) {
+                _cleanup_free_ char *taint;
+
+                taint = manager_taint_string(m);
+                if (!isempty(taint))
+                        log_struct(LOG_NOTICE,
+                                   LOG_MESSAGE("System is tainted: %s", taint),
+                                   "TAINT=%s", taint,
+                                   "MESSAGE_ID=" SD_MESSAGE_TAINTED_STR,
+                                   NULL);
+        }
 
-                        log_notice("Shutting down.");
-                        goto finish;
-                }
+        if (arg_action == ACTION_TEST) {
+                printf("-> By units:\n");
+                manager_dump_units(m, stdout, "\t");
 
-                default:
-                        assert_not_reached("Unknown exit code.");
-                }
+                printf("-> By jobs:\n");
+                manager_dump_jobs(m, stdout, "\t");
+                retval = EXIT_SUCCESS;
+                goto finish;
         }
 
+        r = invoke_main_loop(m,
+                             &reexecute,
+                             &retval,
+                             &shutdown_verb,
+                             &fds,
+                             &switch_root_dir,
+                             &switch_root_init,
+                             &error_message);
+
 finish:
         pager_close();
 
@@ -2042,126 +2449,17 @@ finish:
 
         m = manager_free(m);
 
-        for (j = 0; j < ELEMENTSOF(arg_default_rlimit); j++)
-                arg_default_rlimit[j] = mfree(arg_default_rlimit[j]);
-
-        arg_default_unit = mfree(arg_default_unit);
-        arg_confirm_spawn = mfree(arg_confirm_spawn);
-        arg_join_controllers = strv_free_free(arg_join_controllers);
-        arg_default_environment = strv_free(arg_default_environment);
-        arg_syscall_archs = set_free(arg_syscall_archs);
-
+        free_arguments();
         mac_selinux_finish();
 
-        if (reexecute) {
-                const char **args;
-                unsigned i, args_size;
-
-                /* Close and disarm the watchdog, so that the new
-                 * instance can reinitialize it, but doesn't get
-                 * rebooted while we do that */
-                watchdog_close(true);
-
-                /* Reset the RLIMIT_NOFILE to the kernel default, so
-                 * that the new systemd can pass the kernel default to
-                 * its child processes */
-                if (saved_rlimit_nofile.rlim_cur > 0)
-                        (void) setrlimit(RLIMIT_NOFILE, &saved_rlimit_nofile);
-                if (saved_rlimit_memlock.rlim_cur != (rlim_t) -1)
-                        (void) setrlimit(RLIMIT_MEMLOCK, &saved_rlimit_memlock);
-
-                if (switch_root_dir) {
-                        /* Kill all remaining processes from the
-                         * initrd, but don't wait for them, so that we
-                         * can handle the SIGCHLD for them after
-                         * deserializing. */
-                        broadcast_signal(SIGTERM, false, true);
-
-                        /* And switch root with MS_MOVE, because we remove the old directory afterwards and detach it. */
-                        r = switch_root(switch_root_dir, "/mnt", true, MS_MOVE);
-                        if (r < 0)
-                                log_error_errno(r, "Failed to switch root, trying to continue: %m");
-                }
-
-                args_size = MAX(6, argc+1);
-                args = newa(const char*, args_size);
-
-                if (!switch_root_init) {
-                        char sfd[DECIMAL_STR_MAX(int) + 1];
-
-                        /* First try to spawn ourselves with the right
-                         * path, and with full serialization. We do
-                         * this only if the user didn't specify an
-                         * explicit init to spawn. */
-
-                        assert(arg_serialization);
-                        assert(fds);
-
-                        xsprintf(sfd, "%i", fileno(arg_serialization));
-
-                        i = 0;
-                        args[i++] = SYSTEMD_BINARY_PATH;
-                        if (switch_root_dir)
-                                args[i++] = "--switched-root";
-                        args[i++] = arg_system ? "--system" : "--user";
-                        args[i++] = "--deserialize";
-                        args[i++] = sfd;
-                        args[i++] = NULL;
-
-                        assert(i <= args_size);
-
-                        /*
-                         * We want valgrind to print its memory usage summary before reexecution.
-                         * Valgrind won't do this is on its own on exec(), but it will do it on exit().
-                         * Hence, to ensure we get a summary here, fork() off a child, let it exit() cleanly,
-                         * so that it prints the summary, and wait() for it in the parent, before proceeding into the exec().
-                         */
-                        valgrind_summary_hack();
-
-                        (void) execv(args[0], (char* const*) args);
-                }
-
-                /* Try the fallback, if there is any, without any
-                 * serialization. We pass the original argv[] and
-                 * envp[]. (Well, modulo the ordering changes due to
-                 * getopt() in argv[], and some cleanups in envp[],
-                 * but let's hope that doesn't matter.) */
-
-                arg_serialization = safe_fclose(arg_serialization);
-                fds = fdset_free(fds);
-
-                /* Reopen the console */
-                (void) make_console_stdio();
-
-                for (j = 1, i = 1; j < (unsigned) argc; j++)
-                        args[i++] = argv[j];
-                args[i++] = NULL;
-                assert(i <= args_size);
-
-                /* Reenable any blocked signals, especially important
-                 * if we switch from initial ramdisk to init=... */
-                (void) reset_all_signal_handlers();
-                (void) reset_signal_mask();
-
-                if (switch_root_init) {
-                        args[0] = switch_root_init;
-                        (void) execv(args[0], (char* const*) args);
-                        log_warning_errno(errno, "Failed to execute configured init, trying fallback: %m");
-                }
-
-                args[0] = "/sbin/init";
-                (void) execv(args[0], (char* const*) args);
-
-                if (errno == ENOENT) {
-                        log_warning("No /sbin/init, trying fallback");
-
-                        args[0] = "/bin/sh";
-                        args[1] = NULL;
-                        (void) execv(args[0], (char* const*) args);
-                        log_error_errno(errno, "Failed to execute /bin/sh, giving up: %m");
-                } else
-                        log_warning_errno(errno, "Failed to execute /sbin/init, giving up: %m");
-        }
+        if (reexecute)
+                do_reexecute(argc, argv,
+                             &saved_rlimit_nofile,
+                             &saved_rlimit_memlock,
+                             fds,
+                             switch_root_dir,
+                             switch_root_init,
+                             &error_message); /* This only returns if reexecution failed */
 
         arg_serialization = safe_fclose(arg_serialization);
         fds = fdset_free(fds);
@@ -2171,85 +2469,25 @@ finish:
          * here explicitly. valgrind will only generate nice output on
          * exit(), not on exec(), hence let's do the former not the
          * latter here. */
-        if (getpid_cached() == 1 && RUNNING_ON_VALGRIND)
+        if (getpid_cached() == 1 && RUNNING_ON_VALGRIND) {
+                /* Cleanup watchdog_device strings for valgrind. We need them
+                 * in become_shutdown() so normally we cannot free them yet. */
+                watchdog_free_device();
+                arg_watchdog_device = mfree(arg_watchdog_device);
                 return 0;
+        }
 #endif
 
         if (shutdown_verb) {
-                char log_level[DECIMAL_STR_MAX(int) + 1];
-                char exit_code[DECIMAL_STR_MAX(uint8_t) + 1];
-                const char* command_line[11] = {
-                        SYSTEMD_SHUTDOWN_BINARY_PATH,
-                        shutdown_verb,
-                        "--log-level", log_level,
-                        "--log-target",
-                };
-                unsigned pos = 5;
-                _cleanup_strv_free_ char **env_block = NULL;
-
-                assert(command_line[pos] == NULL);
-                env_block = strv_copy(environ);
-
-                xsprintf(log_level, "%d", log_get_max_level());
-
-                switch (log_get_target()) {
-
-                case LOG_TARGET_KMSG:
-                case LOG_TARGET_JOURNAL_OR_KMSG:
-                case LOG_TARGET_SYSLOG_OR_KMSG:
-                        command_line[pos++] = "kmsg";
-                        break;
-
-                case LOG_TARGET_NULL:
-                        command_line[pos++] = "null";
-                        break;
-
-                case LOG_TARGET_CONSOLE:
-                default:
-                        command_line[pos++] = "console";
-                        break;
-                };
-
-                if (log_get_show_color())
-                        command_line[pos++] = "--log-color";
-
-                if (log_get_show_location())
-                        command_line[pos++] = "--log-location";
-
-                if (streq(shutdown_verb, "exit")) {
-                        command_line[pos++] = "--exit-code";
-                        command_line[pos++] = exit_code;
-                        xsprintf(exit_code, "%d", retval);
-                }
-
-                assert(pos < ELEMENTSOF(command_line));
-
-                if (arm_reboot_watchdog && arg_shutdown_watchdog > 0 && arg_shutdown_watchdog != USEC_INFINITY) {
-                        char *e;
-
-                        /* If we reboot let's set the shutdown
-                         * watchdog and tell the shutdown binary to
-                         * repeatedly ping it */
-                        r = watchdog_set_timeout(&arg_shutdown_watchdog);
-                        watchdog_close(r < 0);
+                r = become_shutdown(shutdown_verb, retval);
 
-                        /* Tell the binary how often to ping, ignore failure */
-                        if (asprintf(&e, "WATCHDOG_USEC="USEC_FMT, arg_shutdown_watchdog) > 0)
-                                (void) strv_push(&env_block, e);
-                } else
-                        watchdog_close(true);
-
-                /* Avoid the creation of new processes forked by the
-                 * kernel; at this point, we will not listen to the
-                 * signals anyway */
-                if (detect_container() <= 0)
-                        (void) cg_uninstall_release_agent(SYSTEMD_CGROUP_CONTROLLER);
-
-                execve(SYSTEMD_SHUTDOWN_BINARY_PATH, (char **) command_line, env_block);
-                log_error_errno(errno, "Failed to execute shutdown binary, %s: %m",
-                          getpid_cached() == 1 ? "freezing" : "quitting");
+                log_error_errno(r, "Failed to execute shutdown binary, %s: %m", getpid_cached() == 1 ? "freezing" : "quitting");
+                error_message = "Failed to execute shutdown binary";
         }
 
+        watchdog_free_device();
+        arg_watchdog_device = mfree(arg_watchdog_device);
+
         if (getpid_cached() == 1) {
                 if (error_message)
                         manager_status_printf(NULL, STATUS_TYPE_EMERGENCY,
index 2c84c36..705509d 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -21,6 +22,7 @@
 #include <fcntl.h>
 #include <linux/kd.h>
 #include <signal.h>
+#include <stdio_ext.h>
 #include <string.h>
 #include <sys/epoll.h>
 #include <sys/inotify.h>
@@ -46,6 +48,7 @@
 #include "bus-kernel.h"
 #include "bus-util.h"
 #include "clean-ipc.h"
+#include "clock-util.h"
 #include "dbus-job.h"
 #include "dbus-manager.h"
 #include "dbus-unit.h"
 #include "dirent-util.h"
 #include "env-util.h"
 #include "escape.h"
-#include "execute.h"
 #include "exec-util.h"
+#include "execute.h"
 #include "exit-status.h"
 #include "fd-util.h"
 #include "fileio.h"
 #include "fs-util.h"
 #include "hashmap.h"
 #include "io-util.h"
+#include "label.h"
 #include "locale-setup.h"
 #include "log.h"
 #include "macro.h"
@@ -136,7 +140,7 @@ static void manager_watch_jobs_in_progress(Manager *m) {
         (void) sd_event_source_set_description(m->jobs_in_progress_event_source, "manager-jobs-in-progress");
 }
 
-#define CYLON_BUFFER_EXTRA (2*(sizeof(ANSI_RED)-1) + sizeof(ANSI_HIGHLIGHT_RED)-1 + 2*(sizeof(ANSI_NORMAL)-1))
+#define CYLON_BUFFER_EXTRA (2*STRLEN(ANSI_RED) + STRLEN(ANSI_HIGHLIGHT_RED) + 2*STRLEN(ANSI_NORMAL))
 
 static void draw_cylon(char buffer[], size_t buflen, unsigned width, unsigned pos) {
         char *p = buffer;
@@ -600,6 +604,29 @@ static int manager_setup_prefix(Manager *m) {
         return 0;
 }
 
+static int manager_setup_run_queue(Manager *m) {
+        int r;
+
+        assert(m);
+        assert(!m->run_queue_event_source);
+
+        r = sd_event_add_defer(m->event, &m->run_queue_event_source, manager_dispatch_run_queue, m);
+        if (r < 0)
+                return r;
+
+        r = sd_event_source_set_priority(m->run_queue_event_source, SD_EVENT_PRIORITY_IDLE);
+        if (r < 0)
+                return r;
+
+        r = sd_event_source_set_enabled(m->run_queue_event_source, SD_EVENT_OFF);
+        if (r < 0)
+                return r;
+
+        (void) sd_event_source_set_description(m->run_queue_event_source, "manager-run-queue");
+
+        return 0;
+}
+
 int manager_new(UnitFileScope scope, unsigned test_run_flags, Manager **_m) {
         Manager *m;
         int r;
@@ -622,7 +649,9 @@ int manager_new(UnitFileScope scope, unsigned test_run_flags, Manager **_m) {
 
 #if ENABLE_EFI
         if (MANAGER_IS_SYSTEM(m) && detect_container() <= 0)
-                boot_timestamps(&m->userspace_timestamp, &m->firmware_timestamp, &m->loader_timestamp);
+                boot_timestamps(m->timestamps + MANAGER_TIMESTAMP_USERSPACE,
+                                m->timestamps + MANAGER_TIMESTAMP_FIRMWARE,
+                                m->timestamps + MANAGER_TIMESTAMP_LOADER);
 #endif
 
         /* Prepare log fields we can use for structured logging */
@@ -682,20 +711,10 @@ int manager_new(UnitFileScope scope, unsigned test_run_flags, Manager **_m) {
         if (r < 0)
                 goto fail;
 
-        r = sd_event_add_defer(m->event, &m->run_queue_event_source, manager_dispatch_run_queue, m);
-        if (r < 0)
-                goto fail;
-
-        r = sd_event_source_set_priority(m->run_queue_event_source, SD_EVENT_PRIORITY_IDLE);
-        if (r < 0)
-                goto fail;
-
-        r = sd_event_source_set_enabled(m->run_queue_event_source, SD_EVENT_OFF);
+        r = manager_setup_run_queue(m);
         if (r < 0)
                 goto fail;
 
-        (void) sd_event_source_set_description(m->run_queue_event_source, "manager-run-queue");
-
         r = manager_setup_signals(m);
         if (r < 0)
                 goto fail;
@@ -714,15 +733,23 @@ int manager_new(UnitFileScope scope, unsigned test_run_flags, Manager **_m) {
                 goto fail;
         }
 
-        /* Note that we do not set up the notify fd here. We do that after deserialization,
-         * since they might have gotten serialized across the reexec. */
-
-        m->taint_usr = dir_is_empty("/usr") > 0;
-
         r = manager_setup_prefix(m);
         if (r < 0)
                 goto fail;
 
+        if (MANAGER_IS_SYSTEM(m) && test_run_flags == 0) {
+                r = mkdir_label("/run/systemd/units", 0755);
+                if (r < 0 && r != -EEXIST)
+                        goto fail;
+        }
+
+        m->taint_usr =
+                !in_initrd() &&
+                dir_is_empty("/usr") > 0;
+
+        /* Note that we do not set up neither kdbus, nor the notify fd here. We do that after deserialization,
+         * since they might have gotten serialized across the reexec. */
+
         *_m = m;
         return 0;
 
@@ -934,9 +961,9 @@ static int manager_connect_bus(Manager *m, bool reexecuting) {
         u = manager_get_unit(m, SPECIAL_DBUS_SERVICE);
 
         try_bus_connect =
-                ((u && UNIT_IS_ACTIVE_OR_RELOADING(unit_active_state(u))) &&
-                 (reexecuting ||
-                  (MANAGER_IS_USER(m) && getenv("DBUS_SESSION_BUS_ADDRESS"))));
+                (u && SERVICE(u)->deserialized_state == SERVICE_RUNNING) &&
+                (reexecuting ||
+                 (MANAGER_IS_USER(m) && getenv("DBUS_SESSION_BUS_ADDRESS")));
 
         /* Try to connect to the buses, if possible. */
         return bus_init(m, try_bus_connect);
@@ -967,21 +994,23 @@ enum {
 };
 
 static void unit_gc_mark_good(Unit *u, unsigned gc_marker) {
-        Iterator i;
         Unit *other;
+        Iterator i;
+        void *v;
 
         u->gc_marker = gc_marker + GC_OFFSET_GOOD;
 
         /* Recursively mark referenced units as GOOD as well */
-        SET_FOREACH(other, u->dependencies[UNIT_REFERENCES], i)
+        HASHMAP_FOREACH_KEY(v, other, u->dependencies[UNIT_REFERENCES], i)
                 if (other->gc_marker == gc_marker + GC_OFFSET_UNSURE)
                         unit_gc_mark_good(other, gc_marker);
 }
 
 static void unit_gc_sweep(Unit *u, unsigned gc_marker) {
-        Iterator i;
         Unit *other;
         bool is_bad;
+        Iterator i;
+        void *v;
 
         assert(u);
 
@@ -999,7 +1028,7 @@ static void unit_gc_sweep(Unit *u, unsigned gc_marker) {
 
         is_bad = true;
 
-        SET_FOREACH(other, u->dependencies[UNIT_REFERENCED_BY], i) {
+        HASHMAP_FOREACH_KEY(v, other, u->dependencies[UNIT_REFERENCED_BY], i) {
                 unit_gc_sweep(other, gc_marker);
 
                 if (other->gc_marker == gc_marker + GC_OFFSET_GOOD)
@@ -1307,7 +1336,7 @@ static void manager_distribute_fds(Manager *m, FDSet *fds) {
 }
 
 int manager_startup(Manager *m, FILE *serialization, FDSet *fds) {
-        int r, q;
+        int r;
 
         assert(m);
 
@@ -1323,25 +1352,21 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds) {
         if (r < 0)
                 return r;
 
-        /* Make sure the transient directory always exists, so that it remains
-         * in the search path */
-        r = mkdir_p_label(m->lookup_paths.transient, 0755);
-        if (r < 0)
-                return r;
-
-        dual_timestamp_get(&m->generators_start_timestamp);
+        dual_timestamp_get(m->timestamps + MANAGER_TIMESTAMP_GENERATORS_START);
         r = manager_run_generators(m);
-        dual_timestamp_get(&m->generators_finish_timestamp);
+        dual_timestamp_get(m->timestamps + MANAGER_TIMESTAMP_GENERATORS_FINISH);
         if (r < 0)
                 return r;
 
+        /* If this is the first boot, and we are in the host system, then preset everything */
         if (m->first_boot > 0 &&
-            m->unit_file_scope == UNIT_FILE_SYSTEM &&
+            MANAGER_IS_SYSTEM(m) &&
             !m->test_run_flags) {
 
-                q = unit_file_preset_all(UNIT_FILE_SYSTEM, 0, NULL, UNIT_FILE_PRESET_ENABLE_ONLY, NULL, 0);
-                if (q < 0)
-                        log_full_errno(q == -EEXIST ? LOG_NOTICE : LOG_WARNING, q, "Failed to populate /etc with preset unit settings, ignoring: %m");
+                r = unit_file_preset_all(UNIT_FILE_SYSTEM, 0, NULL, UNIT_FILE_PRESET_ENABLE_ONLY, NULL, 0);
+                if (r < 0)
+                        log_full_errno(r == -EEXIST ? LOG_NOTICE : LOG_WARNING, r,
+                                       "Failed to populate /etc with preset unit settings, ignoring: %m");
                 else
                         log_info("Populated /etc with preset unit settings.");
         }
@@ -1356,15 +1381,15 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds) {
                 m->n_reloading++;
 
         /* First, enumerate what we can from all config files */
-        dual_timestamp_get(&m->units_load_start_timestamp);
+        dual_timestamp_get(m->timestamps + MANAGER_TIMESTAMP_UNITS_LOAD_START);
         manager_enumerate(m);
-        dual_timestamp_get(&m->units_load_finish_timestamp);
+        dual_timestamp_get(m->timestamps + MANAGER_TIMESTAMP_UNITS_LOAD_FINISH);
 
         /* Second, deserialize if there is something to deserialize */
         if (serialization) {
                 r = manager_deserialize(m, serialization, fds);
                 if (r < 0)
-                        log_error_errno(r, "Deserialization failed: %m");
+                        return log_error_errno(r, "Deserialization failed: %m");
         }
 
         /* Any fds left? Find some unit which wants them. This is
@@ -1375,17 +1400,20 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds) {
 
         /* We might have deserialized the notify fd, but if we didn't
          * then let's create the bus now */
-        q = manager_setup_notify(m);
-        if (q < 0 && r == 0)
-                r = q;
+        r = manager_setup_notify(m);
+        if (r < 0)
+                /* No sense to continue without notifications, our children would fail anyway. */
+                return r;
 
-        q = manager_setup_cgroups_agent(m);
-        if (q < 0 && r == 0)
-                r = q;
+        r = manager_setup_cgroups_agent(m);
+        if (r < 0)
+                /* Likewise, no sense to continue without empty cgroup notifications. */
+                return r;
 
-        q = manager_setup_user_lookup_fd(m);
-        if (q < 0 && r == 0)
-                r = q;
+        r = manager_setup_user_lookup_fd(m);
+        if (r < 0)
+                /* This shouldn't fail, except if things are really broken. */
+                return r;
 
         /* Let's connect to the bus now. */
         (void) manager_connect_bus(m, !!serialization);
@@ -1413,7 +1441,7 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds) {
                 m->send_reloading_done = true;
         }
 
-        return r;
+        return 0;
 }
 
 int manager_add_job(Manager *m, JobType type, Unit *unit, JobMode mode, sd_bus_error *e, Job **_ret) {
@@ -1693,6 +1721,55 @@ void manager_dump_units(Manager *s, FILE *f, const char *prefix) {
                         unit_dump(u, f, prefix);
 }
 
+void manager_dump(Manager *m, FILE *f, const char *prefix) {
+        ManagerTimestamp q;
+
+        assert(m);
+        assert(f);
+
+        for (q = 0; q < _MANAGER_TIMESTAMP_MAX; q++) {
+                char buf[FORMAT_TIMESTAMP_MAX];
+
+                if (dual_timestamp_is_set(m->timestamps + q))
+                        fprintf(f, "%sTimestamp %s: %s\n",
+                                strempty(prefix),
+                                manager_timestamp_to_string(q),
+                                format_timestamp(buf, sizeof(buf), m->timestamps[q].realtime));
+        }
+
+        manager_dump_units(m, f, prefix);
+        manager_dump_jobs(m, f, prefix);
+}
+
+int manager_get_dump_string(Manager *m, char **ret) {
+        _cleanup_free_ char *dump = NULL;
+        _cleanup_fclose_ FILE *f = NULL;
+        size_t size;
+        int r;
+
+        assert(m);
+        assert(ret);
+
+        f = open_memstream(&dump, &size);
+        if (!f)
+                return -errno;
+
+        (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
+
+        manager_dump(m, f, NULL);
+
+        r = fflush_and_check(f);
+        if (r < 0)
+                return r;
+
+        f = safe_fclose(f);
+
+        *ret = dump;
+        dump = NULL;
+
+        return 0;
+}
+
 void manager_clear_jobs(Manager *m) {
         Job *j;
 
@@ -2097,8 +2174,7 @@ static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t
                                 break;
                         }
 
-                        /* Fall through */
-
+                        _fallthrough_;
                 case SIGINT:
                         if (MANAGER_IS_SYSTEM(m))
                                 manager_handle_ctrl_alt_del(m);
@@ -2141,21 +2217,10 @@ static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t
 
                 case SIGUSR2: {
                         _cleanup_free_ char *dump = NULL;
-                        _cleanup_fclose_ FILE *f = NULL;
-                        size_t size;
 
-                        f = open_memstream(&dump, &size);
-                        if (!f) {
-                                log_warning_errno(errno, "Failed to allocate memory stream: %m");
-                                break;
-                        }
-
-                        manager_dump_units(m, f, "\t");
-                        manager_dump_jobs(m, f, "\t");
-
-                        r = fflush_and_check(f);
+                        r = manager_get_dump_string(m, &dump);
                         if (r < 0) {
-                                log_warning_errno(r, "Failed to write status stream: %m");
+                                log_warning_errno(errno, "Failed to acquire manager dump: %m");
                                 break;
                         }
 
@@ -2561,9 +2626,10 @@ int manager_open_serialization(Manager *m, FILE **_f) {
 }
 
 int manager_serialize(Manager *m, FILE *f, FDSet *fds, bool switching_root) {
+        ManagerTimestamp q;
+        const char *t;
         Iterator i;
         Unit *u;
-        const char *t;
         int r;
 
         assert(m);
@@ -2573,24 +2639,22 @@ int manager_serialize(Manager *m, FILE *f, FDSet *fds, bool switching_root) {
         m->n_reloading++;
 
         fprintf(f, "current-job-id=%"PRIu32"\n", m->current_job_id);
-        fprintf(f, "taint-usr=%s\n", yes_no(m->taint_usr));
         fprintf(f, "n-installed-jobs=%u\n", m->n_installed_jobs);
         fprintf(f, "n-failed-jobs=%u\n", m->n_failed_jobs);
+        fprintf(f, "taint-usr=%s\n", yes_no(m->taint_usr));
+        fprintf(f, "ready-sent=%s\n", yes_no(m->ready_sent));
 
-        dual_timestamp_serialize(f, "firmware-timestamp", &m->firmware_timestamp);
-        dual_timestamp_serialize(f, "loader-timestamp", &m->loader_timestamp);
-        dual_timestamp_serialize(f, "kernel-timestamp", &m->kernel_timestamp);
-        dual_timestamp_serialize(f, "initrd-timestamp", &m->initrd_timestamp);
+        for (q = 0; q < _MANAGER_TIMESTAMP_MAX; q++) {
+                /* The userspace and finish timestamps only apply to the host system, hence only serialize them there */
+                if (in_initrd() && IN_SET(q, MANAGER_TIMESTAMP_USERSPACE, MANAGER_TIMESTAMP_FINISH))
+                        continue;
 
-        if (!in_initrd()) {
-                dual_timestamp_serialize(f, "userspace-timestamp", &m->userspace_timestamp);
-                dual_timestamp_serialize(f, "finish-timestamp", &m->finish_timestamp);
-                dual_timestamp_serialize(f, "security-start-timestamp", &m->security_start_timestamp);
-                dual_timestamp_serialize(f, "security-finish-timestamp", &m->security_finish_timestamp);
-                dual_timestamp_serialize(f, "generators-start-timestamp", &m->generators_start_timestamp);
-                dual_timestamp_serialize(f, "generators-finish-timestamp", &m->generators_finish_timestamp);
-                dual_timestamp_serialize(f, "units-load-start-timestamp", &m->units_load_start_timestamp);
-                dual_timestamp_serialize(f, "units-load-finish-timestamp", &m->units_load_finish_timestamp);
+                t = manager_timestamp_to_string(q);
+                {
+                        char field[strlen(t) + STRLEN("-timestamp") + 1];
+                        strcpy(stpcpy(field, t), "-timestamp");
+                        dual_timestamp_serialize(f, field, m->timestamps + q);
+                }
         }
 
         if (!switching_root)
@@ -2640,15 +2704,15 @@ int manager_serialize(Manager *m, FILE *f, FDSet *fds, bool switching_root) {
         manager_serialize_uid_refs(m, f);
         manager_serialize_gid_refs(m, f);
 
-        fputc_unlocked('\n', f);
+        (void) fputc('\n', f);
 
         HASHMAP_FOREACH_KEY(u, t, m->units, i) {
                 if (u->id != t)
                         continue;
 
                 /* Start marker */
-                fputs_unlocked(u->id, f);
-                fputc_unlocked('\n', f);
+                fputs(u->id, f);
+                fputc('\n', f);
 
                 r = unit_serialize(u, f, fds, !switching_root);
                 if (r < 0) {
@@ -2732,31 +2796,16 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
                         else
                                 m->taint_usr = m->taint_usr || b;
 
-                } else if ((val = startswith(l, "firmware-timestamp=")))
-                        dual_timestamp_deserialize(val, &m->firmware_timestamp);
-                else if ((val = startswith(l, "loader-timestamp=")))
-                        dual_timestamp_deserialize(val, &m->loader_timestamp);
-                else if ((val = startswith(l, "kernel-timestamp=")))
-                        dual_timestamp_deserialize(val, &m->kernel_timestamp);
-                else if ((val = startswith(l, "initrd-timestamp=")))
-                        dual_timestamp_deserialize(val, &m->initrd_timestamp);
-                else if ((val = startswith(l, "userspace-timestamp=")))
-                        dual_timestamp_deserialize(val, &m->userspace_timestamp);
-                else if ((val = startswith(l, "finish-timestamp=")))
-                        dual_timestamp_deserialize(val, &m->finish_timestamp);
-                else if ((val = startswith(l, "security-start-timestamp=")))
-                        dual_timestamp_deserialize(val, &m->security_start_timestamp);
-                else if ((val = startswith(l, "security-finish-timestamp=")))
-                        dual_timestamp_deserialize(val, &m->security_finish_timestamp);
-                else if ((val = startswith(l, "generators-start-timestamp=")))
-                        dual_timestamp_deserialize(val, &m->generators_start_timestamp);
-                else if ((val = startswith(l, "generators-finish-timestamp=")))
-                        dual_timestamp_deserialize(val, &m->generators_finish_timestamp);
-                else if ((val = startswith(l, "units-load-start-timestamp=")))
-                        dual_timestamp_deserialize(val, &m->units_load_start_timestamp);
-                else if ((val = startswith(l, "units-load-finish-timestamp=")))
-                        dual_timestamp_deserialize(val, &m->units_load_finish_timestamp);
-                else if (startswith(l, "env=")) {
+                } else if ((val = startswith(l, "ready-sent="))) {
+                        int b;
+
+                        b = parse_boolean(val);
+                        if (b < 0)
+                                log_notice("Failed to parse ready-sent flag %s", val);
+                        else
+                                m->ready_sent = m->ready_sent || b;
+
+                } else if (startswith(l, "env=")) {
                         r = deserialize_environment(&m->environment, l);
                         if (r == -ENOMEM)
                                 goto finish;
@@ -2819,9 +2868,24 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
 
                         if (strv_extend(&m->deserialized_subscribed, val) < 0)
                                 log_oom();
+                } else {
+                        ManagerTimestamp q;
+
+                        for (q = 0; q < _MANAGER_TIMESTAMP_MAX; q++) {
+                                val = startswith(l, manager_timestamp_to_string(q));
+                                if (!val)
+                                        continue;
+
+                                val = startswith(val, "-timestamp=");
+                                if (val)
+                                        break;
+                        }
 
-                } else if (!startswith(l, "kdbus-fd=")) /* ignore this one */
-                        log_notice("Unknown serialization item '%s'", l);
+                        if (q < _MANAGER_TIMESTAMP_MAX) /* found it */
+                                dual_timestamp_deserialize(val, m->timestamps + q);
+                        else if (!startswith(l, "kdbus-fd=")) /* ignore kdbus */
+                                log_notice("Unknown serialization item '%s'", l);
+                }
         }
 
         for (;;) {
@@ -3007,20 +3071,20 @@ static void manager_notify_finished(Manager *m) {
 
         if (MANAGER_IS_SYSTEM(m) && detect_container() <= 0) {
 
-                /* Note that m->kernel_usec.monotonic is always at 0,
-                 * and m->firmware_usec.monotonic and
-                 * m->loader_usec.monotonic should be considered
+                /* Note that MANAGER_TIMESTAMP_KERNEL's monotonic value is always at 0, and
+                 * MANAGER_TIMESTAMP_FIRMWARE's and MANAGER_TIMESTAMP_LOADER's monotonic value should be considered
                  * negative values. */
 
-                firmware_usec = m->firmware_timestamp.monotonic - m->loader_timestamp.monotonic;
-                loader_usec = m->loader_timestamp.monotonic - m->kernel_timestamp.monotonic;
-                userspace_usec = m->finish_timestamp.monotonic - m->userspace_timestamp.monotonic;
-                total_usec = m->firmware_timestamp.monotonic + m->finish_timestamp.monotonic;
+                firmware_usec = m->timestamps[MANAGER_TIMESTAMP_FIRMWARE].monotonic - m->timestamps[MANAGER_TIMESTAMP_LOADER].monotonic;
+                loader_usec = m->timestamps[MANAGER_TIMESTAMP_LOADER].monotonic - m->timestamps[MANAGER_TIMESTAMP_KERNEL].monotonic;
+                userspace_usec = m->timestamps[MANAGER_TIMESTAMP_FINISH].monotonic - m->timestamps[MANAGER_TIMESTAMP_USERSPACE].monotonic;
+                total_usec = m->timestamps[MANAGER_TIMESTAMP_FIRMWARE].monotonic + m->timestamps[MANAGER_TIMESTAMP_FINISH].monotonic;
 
-                if (dual_timestamp_is_set(&m->initrd_timestamp)) {
+                if (dual_timestamp_is_set(&m->timestamps[MANAGER_TIMESTAMP_INITRD])) {
 
-                        kernel_usec = m->initrd_timestamp.monotonic - m->kernel_timestamp.monotonic;
-                        initrd_usec = m->userspace_timestamp.monotonic - m->initrd_timestamp.monotonic;
+                        /* The initrd case on bare-metal*/
+                        kernel_usec = m->timestamps[MANAGER_TIMESTAMP_INITRD].monotonic - m->timestamps[MANAGER_TIMESTAMP_KERNEL].monotonic;
+                        initrd_usec = m->timestamps[MANAGER_TIMESTAMP_USERSPACE].monotonic - m->timestamps[MANAGER_TIMESTAMP_INITRD].monotonic;
 
                         log_struct(LOG_INFO,
                                    "MESSAGE_ID=" SD_MESSAGE_STARTUP_FINISHED_STR,
@@ -3034,7 +3098,9 @@ static void manager_notify_finished(Manager *m) {
                                                format_timespan(sum, sizeof(sum), total_usec, USEC_PER_MSEC)),
                                    NULL);
                 } else {
-                        kernel_usec = m->userspace_timestamp.monotonic - m->kernel_timestamp.monotonic;
+                        /* The initrd-less case on bare-metal*/
+
+                        kernel_usec = m->timestamps[MANAGER_TIMESTAMP_USERSPACE].monotonic - m->timestamps[MANAGER_TIMESTAMP_KERNEL].monotonic;
                         initrd_usec = 0;
 
                         log_struct(LOG_INFO,
@@ -3048,8 +3114,9 @@ static void manager_notify_finished(Manager *m) {
                                    NULL);
                 }
         } else {
+                /* The container case */
                 firmware_usec = loader_usec = initrd_usec = kernel_usec = 0;
-                total_usec = userspace_usec = m->finish_timestamp.monotonic - m->userspace_timestamp.monotonic;
+                total_usec = userspace_usec = m->timestamps[MANAGER_TIMESTAMP_FINISH].monotonic - m->timestamps[MANAGER_TIMESTAMP_USERSPACE].monotonic;
 
                 log_struct(LOG_INFO,
                            "MESSAGE_ID=" SD_MESSAGE_USER_STARTUP_FINISHED_STR,
@@ -3063,9 +3130,11 @@ static void manager_notify_finished(Manager *m) {
         bus_manager_send_finished(m, firmware_usec, loader_usec, kernel_usec, initrd_usec, userspace_usec, total_usec);
 
         sd_notifyf(false,
-                   "READY=1\n"
-                   "STATUS=Startup finished in %s.",
+                   m->ready_sent ? "STATUS=Startup finished in %s."
+                                 : "READY=1\n"
+                                   "STATUS=Startup finished in %s.",
                    format_timespan(sum, sizeof(sum), total_usec, USEC_PER_MSEC));
+        m->ready_sent = true;
 }
 
 void manager_check_finished(Manager *m) {
@@ -3080,6 +3149,19 @@ void manager_check_finished(Manager *m) {
         if (m->exit_code != MANAGER_OK)
                 return;
 
+        /* For user managers, send out READY=1 as soon as we reach basic.target */
+        if (MANAGER_IS_USER(m) && !m->ready_sent) {
+                Unit *u;
+
+                u = manager_get_unit(m, SPECIAL_BASIC_TARGET);
+                if (u && !u->job) {
+                        sd_notifyf(false,
+                                   "READY=1\n"
+                                   "STATUS=Reached " SPECIAL_BASIC_TARGET ".");
+                        m->ready_sent = true;
+                }
+        }
+
         if (hashmap_size(m->jobs) > 0) {
                 if (m->jobs_in_progress_event_source)
                         /* Ignore any failure, this is only for feedback */
@@ -3102,10 +3184,10 @@ void manager_check_finished(Manager *m) {
         /* This is no longer the first boot */
         manager_set_first_boot(m, false);
 
-        if (dual_timestamp_is_set(&m->finish_timestamp))
+        if (MANAGER_IS_FINISHED(m))
                 return;
 
-        dual_timestamp_get(&m->finish_timestamp);
+        dual_timestamp_get(m->timestamps + MANAGER_TIMESTAMP_FINISH);
 
         manager_notify_finished(m);
 
@@ -3460,7 +3542,7 @@ ManagerState manager_state(Manager *m) {
         assert(m);
 
         /* Did we ever finish booting? If not then we are still starting up */
-        if (!dual_timestamp_is_set(&m->finish_timestamp)) {
+        if (!MANAGER_IS_FINISHED(m)) {
 
                 u = manager_get_unit(m, SPECIAL_BASIC_TARGET);
                 if (!u || !UNIT_IS_ACTIVE_OR_RELOADING(unit_active_state(u)))
@@ -3469,21 +3551,21 @@ ManagerState manager_state(Manager *m) {
                 return MANAGER_STARTING;
         }
 
-        /* Is the special shutdown target queued? If so, we are in shutdown state */
+        /* Is the special shutdown target active or queued? If so, we are in shutdown state */
         u = manager_get_unit(m, SPECIAL_SHUTDOWN_TARGET);
-        if (u && u->job && IN_SET(u->job->type, JOB_START, JOB_RESTART, JOB_RELOAD_OR_START))
+        if (u && unit_active_or_pending(u))
                 return MANAGER_STOPPING;
 
-        /* Are the rescue or emergency targets active or queued? If so we are in maintenance state */
-        u = manager_get_unit(m, SPECIAL_RESCUE_TARGET);
-        if (u && (UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)) ||
-                  (u->job && IN_SET(u->job->type, JOB_START, JOB_RESTART, JOB_RELOAD_OR_START))))
-                return MANAGER_MAINTENANCE;
+        if (MANAGER_IS_SYSTEM(m)) {
+                /* Are the rescue or emergency targets active or queued? If so we are in maintenance state */
+                u = manager_get_unit(m, SPECIAL_RESCUE_TARGET);
+                if (u && unit_active_or_pending(u))
+                        return MANAGER_MAINTENANCE;
 
-        u = manager_get_unit(m, SPECIAL_EMERGENCY_TARGET);
-        if (u && (UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)) ||
-                  (u->job && IN_SET(u->job->type, JOB_START, JOB_RESTART, JOB_RELOAD_OR_START))))
-                return MANAGER_MAINTENANCE;
+                u = manager_get_unit(m, SPECIAL_EMERGENCY_TARGET);
+                if (u && unit_active_or_pending(u))
+                        return MANAGER_MAINTENANCE;
+        }
 
         /* Are there any failed units? If so, we are in degraded mode */
         if (set_size(m->failed_units) > 0)
@@ -3786,6 +3868,58 @@ int manager_dispatch_user_lookup_fd(sd_event_source *source, int fd, uint32_t re
         return 0;
 }
 
+char *manager_taint_string(Manager *m) {
+        _cleanup_free_ char *destination = NULL, *overflowuid = NULL, *overflowgid = NULL;
+        char *buf, *e;
+        int r;
+
+        /* Returns a "taint string", e.g. "local-hwclock:var-run-bad".
+         * Only things that are detected at runtime should be tagged
+         * here. For stuff that is set during compilation, emit a warning
+         * in the configuration phase. */
+
+        assert(m);
+
+        buf = new(char, sizeof("split-usr:"
+                               "cgroups-missing:"
+                               "local-hwclock:"
+                               "var-run-bad:"
+                               "overflowuid-not-65534:"
+                               "overflowgid-not-65534:"));
+        if (!buf)
+                return NULL;
+
+        e = buf;
+        buf[0] = 0;
+
+        if (m->taint_usr)
+                e = stpcpy(e, "split-usr:");
+
+        if (access("/proc/cgroups", F_OK) < 0)
+                e = stpcpy(e, "cgroups-missing:");
+
+        if (clock_is_localtime(NULL) > 0)
+                e = stpcpy(e, "local-hwclock:");
+
+        r = readlink_malloc("/var/run", &destination);
+        if (r < 0 || !PATH_IN_SET(destination, "../run", "/run"))
+                e = stpcpy(e, "var-run-bad:");
+
+        r = read_one_line_file("/proc/sys/kernel/overflowuid", &overflowuid);
+        if (r >= 0 && !streq(overflowuid, "65534"))
+                e = stpcpy(e, "overflowuid-not-65534:");
+
+        r = read_one_line_file("/proc/sys/kernel/overflowgid", &overflowgid);
+        if (r >= 0 && !streq(overflowgid, "65534"))
+                e = stpcpy(e, "overflowgid-not-65534:");
+
+        /* remove the last ':' */
+        if (e != buf)
+                e[-1] = 0;
+
+        return buf;
+}
+
 static const char *const manager_state_table[_MANAGER_STATE_MAX] = {
         [MANAGER_INITIALIZING] = "initializing",
         [MANAGER_STARTING] = "starting",
@@ -3796,3 +3930,20 @@ static const char *const manager_state_table[_MANAGER_STATE_MAX] = {
 };
 
 DEFINE_STRING_TABLE_LOOKUP(manager_state, ManagerState);
+
+static const char *const manager_timestamp_table[_MANAGER_TIMESTAMP_MAX] = {
+        [MANAGER_TIMESTAMP_FIRMWARE] = "firmware",
+        [MANAGER_TIMESTAMP_LOADER] = "loader",
+        [MANAGER_TIMESTAMP_KERNEL] = "kernel",
+        [MANAGER_TIMESTAMP_INITRD] = "initrd",
+        [MANAGER_TIMESTAMP_USERSPACE] = "userspace",
+        [MANAGER_TIMESTAMP_FINISH] = "finish",
+        [MANAGER_TIMESTAMP_SECURITY_START] = "security-start",
+        [MANAGER_TIMESTAMP_SECURITY_FINISH] = "security-finish",
+        [MANAGER_TIMESTAMP_GENERATORS_START] = "generators-start",
+        [MANAGER_TIMESTAMP_GENERATORS_FINISH] = "generators-finish",
+        [MANAGER_TIMESTAMP_UNITS_LOAD_START] = "units-load-start",
+        [MANAGER_TIMESTAMP_UNITS_LOAD_FINISH] = "units-load-finish",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(manager_timestamp, ManagerTimestamp);
index 6fff7b2..902af26 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -69,6 +70,24 @@ typedef enum StatusType {
         STATUS_TYPE_EMERGENCY,
 } StatusType;
 
+typedef enum ManagerTimestamp {
+        MANAGER_TIMESTAMP_FIRMWARE,
+        MANAGER_TIMESTAMP_LOADER,
+        MANAGER_TIMESTAMP_KERNEL,
+        MANAGER_TIMESTAMP_INITRD,
+        MANAGER_TIMESTAMP_USERSPACE,
+        MANAGER_TIMESTAMP_FINISH,
+
+        MANAGER_TIMESTAMP_SECURITY_START,
+        MANAGER_TIMESTAMP_SECURITY_FINISH,
+        MANAGER_TIMESTAMP_GENERATORS_START,
+        MANAGER_TIMESTAMP_GENERATORS_FINISH,
+        MANAGER_TIMESTAMP_UNITS_LOAD_START,
+        MANAGER_TIMESTAMP_UNITS_LOAD_FINISH,
+        _MANAGER_TIMESTAMP_MAX,
+        _MANAGER_TIMESTAMP_INVALID = -1,
+} ManagerTimestamp;
+
 #include "execute.h"
 #include "job.h"
 #include "path-lookup.h"
@@ -170,19 +189,7 @@ struct Manager {
         usec_t runtime_watchdog;
         usec_t shutdown_watchdog;
 
-        dual_timestamp firmware_timestamp;
-        dual_timestamp loader_timestamp;
-        dual_timestamp kernel_timestamp;
-        dual_timestamp initrd_timestamp;
-        dual_timestamp userspace_timestamp;
-        dual_timestamp finish_timestamp;
-
-        dual_timestamp security_start_timestamp;
-        dual_timestamp security_finish_timestamp;
-        dual_timestamp generators_start_timestamp;
-        dual_timestamp generators_finish_timestamp;
-        dual_timestamp units_load_start_timestamp;
-        dual_timestamp units_load_finish_timestamp;
+        dual_timestamp timestamps[_MANAGER_TIMESTAMP_MAX];
 
         struct udev* udev;
 
@@ -254,6 +261,8 @@ struct Manager {
 
         bool taint_usr:1;
 
+        bool ready_sent:1;
+
         unsigned test_run_flags:8;
 
         /* If non-zero, exit with the following value when the systemd
@@ -343,6 +352,8 @@ struct Manager {
 
 #define MANAGER_IS_RELOADING(m) ((m)->n_reloading > 0)
 
+#define MANAGER_IS_FINISHED(m) (dual_timestamp_is_set((m)->timestamps + MANAGER_TIMESTAMP_FINISH))
+
 int manager_new(UnitFileScope scope, unsigned test_run_flags, Manager **m);
 Manager* manager_free(Manager *m);
 
@@ -365,6 +376,8 @@ int manager_propagate_reload(Manager *m, Unit *unit, JobMode mode, sd_bus_error
 
 void manager_dump_units(Manager *s, FILE *f, const char *prefix);
 void manager_dump_jobs(Manager *s, FILE *f, const char *prefix);
+void manager_dump(Manager *s, FILE *f, const char *prefix);
+int manager_get_dump_string(Manager *m, char **ret);
 
 void manager_clear_jobs(Manager *m);
 
@@ -422,9 +435,14 @@ void manager_deserialize_uid_refs_one(Manager *m, const char *value);
 void manager_serialize_gid_refs(Manager *m, FILE *f);
 void manager_deserialize_gid_refs_one(Manager *m, const char *value);
 
+char *manager_taint_string(Manager *m);
+
 const char *manager_state_to_string(ManagerState m) _const_;
 ManagerState manager_state_from_string(const char *s) _pure_;
 
 const char *manager_get_confirm_spawn(Manager *m);
 bool manager_is_confirm_spawn_disabled(Manager *m);
 void manager_disable_confirm_spawn(void);
+
+const char *manager_timestamp_to_string(ManagerTimestamp m) _const_;
+ManagerTimestamp manager_timestamp_from_string(const char *s) _pure_;
index 4355f9c..535ccde 100644 (file)
@@ -1,3 +1,20 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
+# Copyright 2017 Zbigniew Jędrzejewski-Szmek
+#
+# 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.
+#
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
 libcore_la_sources = '''
         audit-fd.c
         audit-fd.h
@@ -197,25 +214,15 @@ policy_in = configure_file(
         output : 'org.freedesktop.systemd1.policy.in',
         configuration : substs)
 
-custom_target(
+i18n.merge_file(
         'org.freedesktop.systemd1.policy',
         input : policy_in,
         output : 'org.freedesktop.systemd1.policy',
-        command : intltool_command,
+        po_dir : po_dir,
+        data_dirs : po_dir,
         install : install_polkit,
         install_dir : polkitpolicydir)
 
-# TODO: this might work with meson from git, see
-# https://github.com/mesonbuild/meson/issues/1441#issuecomment-283585493
-#
-# i18n.merge_file(
-#   'org.freedesktop.systemd1.policy',
-#   po_dir : po_dir,
-#   input : policy_in,
-#   output : 'org.freedesktop.systemd1.policy',
-#   install : install_polkit,
-#   install_dir : polkitpolicydir)
-
 install_data('system.conf',
              'user.conf',
              install_dir : pkgsysconfdir)
index a0b32ce..bc6bae9 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -28,6 +29,7 @@
 #include "cgroup-util.h"
 #include "dev-setup.h"
 #include "efivars.h"
+#include "fileio.h"
 #include "fs-util.h"
 #include "label.h"
 #include "log.h"
 #include "virt.h"
 
 typedef enum MountMode {
-        MNT_NONE  =        0,
-        MNT_FATAL =        1 <<  0,
-        MNT_IN_CONTAINER = 1 <<  1,
+        MNT_NONE  =           0,
+        MNT_FATAL =           1 <<  0,
+        MNT_IN_CONTAINER =    1 <<  1,
+        MNT_CHECK_WRITABLE  = 1 <<  2,
 } MountMode;
 
 typedef struct MountPoint {
@@ -102,13 +105,13 @@ static const MountPoint mount_table[] = {
           cg_is_legacy_wanted, MNT_FATAL|MNT_IN_CONTAINER },
 #endif
         { "cgroup",      "/sys/fs/cgroup",            "cgroup2",    "nsdelegate",              MS_NOSUID|MS_NOEXEC|MS_NODEV,
-          cg_is_unified_wanted, MNT_IN_CONTAINER },
+          cg_is_unified_wanted, MNT_IN_CONTAINER|MNT_CHECK_WRITABLE },
         { "cgroup",      "/sys/fs/cgroup",            "cgroup2",    NULL,                      MS_NOSUID|MS_NOEXEC|MS_NODEV,
-          cg_is_unified_wanted, MNT_IN_CONTAINER },
+          cg_is_unified_wanted, MNT_IN_CONTAINER|MNT_CHECK_WRITABLE },
         { "cgroup",      "/sys/fs/cgroup/unified",    "cgroup2",    "nsdelegate",              MS_NOSUID|MS_NOEXEC|MS_NODEV,
-          cg_is_hybrid_wanted, MNT_IN_CONTAINER },
+          cg_is_hybrid_wanted, MNT_IN_CONTAINER|MNT_CHECK_WRITABLE },
         { "cgroup",      "/sys/fs/cgroup/unified",    "cgroup2",    NULL,                      MS_NOSUID|MS_NOEXEC|MS_NODEV,
-          cg_is_hybrid_wanted, MNT_IN_CONTAINER },
+          cg_is_hybrid_wanted, MNT_IN_CONTAINER|MNT_CHECK_WRITABLE },
         { "cgroup",      "/sys/fs/cgroup/systemd",    "cgroup",     "none,name=systemd,xattr", MS_NOSUID|MS_NOEXEC|MS_NODEV,
           cg_is_legacy_wanted, MNT_IN_CONTAINER     },
         { "cgroup",      "/sys/fs/cgroup/systemd",    "cgroup",     "none,name=systemd",       MS_NOSUID|MS_NOEXEC|MS_NODEV,
@@ -205,6 +208,15 @@ static int mount_one(const MountPoint *p, bool relabel) {
         if (relabel)
                 (void) label_fix(p->where, false, false);
 
+        if (p->mode & MNT_CHECK_WRITABLE) {
+                r = access(p->where, W_OK);
+                if (r < 0) {
+                        (void) umount(p->where);
+                        (void) rmdir(p->where);
+                        return (p->mode & MNT_FATAL) ? r : 0;
+                }
+        }
+
         return 1;
 }
 
@@ -240,11 +252,7 @@ int mount_cgroup_controllers(char ***join_controllers) {
 
         /* Mount all available cgroup controllers that are built into the kernel. */
 
-        controllers = set_new(&string_hash_ops);
-        if (!controllers)
-                return log_oom();
-
-        r = cg_kernel_controllers(controllers);
+        r = cg_kernel_controllers(&controllers);
         if (r < 0)
                 return log_error_errno(r, "Failed to enumerate cgroup controllers: %m");
 
@@ -391,9 +399,19 @@ int mount_setup(bool loaded_policy) {
                 nftw("/dev/shm", nftw_cb, 64, FTW_MOUNT|FTW_PHYS|FTW_ACTIONRETVAL);
                 nftw("/run", nftw_cb, 64, FTW_MOUNT|FTW_PHYS|FTW_ACTIONRETVAL);
 
+                /* Temporarily remount the root cgroup filesystem to give it a proper label. */
+                r = cg_all_unified();
+                if (r == 0) {
+                        (void) mount(NULL, "/sys/fs/cgroup", NULL, MS_REMOUNT, NULL);
+                        label_fix("/sys/fs/cgroup", false, false);
+                        nftw("/sys/fs/cgroup", nftw_cb, 64, FTW_MOUNT|FTW_PHYS|FTW_ACTIONRETVAL);
+                        (void) mount(NULL, "/sys/fs/cgroup", NULL, MS_REMOUNT|MS_RDONLY, NULL);
+                } else if (r < 0)
+                        return log_error_errno(r, "Failed to determine whether we are in all unified mode: %m");
+
                 after_relabel = now(CLOCK_MONOTONIC);
 
-                log_info("Relabelled /dev and /run in %s.",
+                log_info("Relabelled /dev, /run and /sys/fs/cgroup in %s.",
                          format_timespan(timespan, sizeof(timespan), after_relabel - before_relabel, 0));
         }
 #endif
index 647bd77..2c96e64 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 903b3a9..b25bb9c 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -265,8 +266,7 @@ _pure_ static MountParameters* get_mount_parameters(Mount *m) {
         return get_mount_parameters_fragment(m);
 }
 
-static int mount_add_mount_links(Mount *m) {
-        _cleanup_free_ char *parent = NULL;
+static int mount_add_mount_dependencies(Mount *m) {
         MountParameters *pm;
         Unit *other;
         Iterator i;
@@ -276,33 +276,32 @@ static int mount_add_mount_links(Mount *m) {
         assert(m);
 
         if (!path_equal(m->where, "/")) {
-                /* Adds in links to other mount points that might lie further
-                 * up in the hierarchy */
+                _cleanup_free_ char *parent = NULL;
+
+                /* Adds in links to other mount points that might lie further up in the hierarchy */
 
                 parent = dirname_malloc(m->where);
                 if (!parent)
                         return -ENOMEM;
 
-                r = unit_require_mounts_for(UNIT(m), parent);
+                r = unit_require_mounts_for(UNIT(m), parent, UNIT_DEPENDENCY_IMPLICIT);
                 if (r < 0)
                         return r;
         }
 
-        /* Adds in links to other mount points that might be needed
-         * for the source path (if this is a bind mount or a loop mount) to be
-         * available. */
+        /* Adds in dependencies to other mount points that might be needed for the source path (if this is a bind mount
+         * or a loop mount) to be available. */
         pm = get_mount_parameters_fragment(m);
         if (pm && pm->what &&
             path_is_absolute(pm->what) &&
             (mount_is_bind(pm) || mount_is_loop(pm) || !mount_is_network(pm))) {
 
-                r = unit_require_mounts_for(UNIT(m), pm->what);
+                r = unit_require_mounts_for(UNIT(m), pm->what, UNIT_DEPENDENCY_FILE);
                 if (r < 0)
                         return r;
         }
 
-        /* Adds in links to other units that use this path or paths
-         * further down in the hierarchy */
+        /* Adds in dependencies to other units that use this path or paths further down in the hierarchy */
         s = manager_get_units_requiring_mounts_for(UNIT(m)->manager, m->where);
         SET_FOREACH(other, s, i) {
 
@@ -312,13 +311,13 @@ static int mount_add_mount_links(Mount *m) {
                 if (other == UNIT(m))
                         continue;
 
-                r = unit_add_dependency(other, UNIT_AFTER, UNIT(m), true);
+                r = unit_add_dependency(other, UNIT_AFTER, UNIT(m), true, UNIT_DEPENDENCY_PATH);
                 if (r < 0)
                         return r;
 
                 if (UNIT(m)->fragment_path) {
                         /* If we have fragment configuration, then make this dependency required */
-                        r = unit_add_dependency(other, UNIT_REQUIRES, UNIT(m), true);
+                        r = unit_add_dependency(other, UNIT_REQUIRES, UNIT(m), true, UNIT_DEPENDENCY_PATH);
                         if (r < 0)
                                 return r;
                 }
@@ -327,9 +326,10 @@ static int mount_add_mount_links(Mount *m) {
         return 0;
 }
 
-static int mount_add_device_links(Mount *m) {
-        MountParameters *p;
+static int mount_add_device_dependencies(Mount *m) {
         bool device_wants_mount = false;
+        UnitDependencyMask mask;
+        MountParameters *p;
         UnitDependency dep;
         int r;
 
@@ -367,16 +367,19 @@ static int mount_add_device_links(Mount *m) {
          * automatically stopped when the device disappears suddenly. */
         dep = mount_is_bound_to_device(m) ? UNIT_BINDS_TO : UNIT_REQUIRES;
 
-        r = unit_add_node_link(UNIT(m), p->what, device_wants_mount, dep);
+        mask = m->from_fragment ? UNIT_DEPENDENCY_FILE : UNIT_DEPENDENCY_MOUNTINFO_IMPLICIT;
+
+        r = unit_add_node_dependency(UNIT(m), p->what, device_wants_mount, dep, mask);
         if (r < 0)
                 return r;
 
         return 0;
 }
 
-static int mount_add_quota_links(Mount *m) {
-        int r;
+static int mount_add_quota_dependencies(Mount *m) {
+        UnitDependencyMask mask;
         MountParameters *p;
+        int r;
 
         assert(m);
 
@@ -390,11 +393,13 @@ static int mount_add_quota_links(Mount *m) {
         if (!needs_quota(p))
                 return 0;
 
-        r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_WANTS, SPECIAL_QUOTACHECK_SERVICE, NULL, true);
+        mask = m->from_fragment ? UNIT_DEPENDENCY_FILE : UNIT_DEPENDENCY_MOUNTINFO_IMPLICIT;
+
+        r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_WANTS, SPECIAL_QUOTACHECK_SERVICE, NULL, true, mask);
         if (r < 0)
                 return r;
 
-        r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_WANTS, SPECIAL_QUOTAON_SERVICE, NULL, true);
+        r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_WANTS, SPECIAL_QUOTAON_SERVICE, NULL, true, mask);
         if (r < 0)
                 return r;
 
@@ -433,9 +438,10 @@ static bool mount_is_extrinsic(Mount *m) {
 }
 
 static int mount_add_default_dependencies(Mount *m) {
+        UnitDependencyMask mask;
+        int r;
         MountParameters *p;
         const char *after;
-        int r;
 
         assert(m);
 
@@ -452,6 +458,8 @@ static int mount_add_default_dependencies(Mount *m) {
         if (!p)
                 return 0;
 
+        mask = m->from_fragment ? UNIT_DEPENDENCY_FILE : UNIT_DEPENDENCY_MOUNTINFO_DEFAULT;
+
         if (mount_is_network(p)) {
                 /* We order ourselves after network.target. This is
                  * primarily useful at shutdown: services that take
@@ -459,7 +467,7 @@ static int mount_add_default_dependencies(Mount *m) {
                  * network.target, so that they are shut down only
                  * after this mount unit is stopped. */
 
-                r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, SPECIAL_NETWORK_TARGET, NULL, true);
+                r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, SPECIAL_NETWORK_TARGET, NULL, true, mask);
                 if (r < 0)
                         return r;
 
@@ -470,7 +478,7 @@ static int mount_add_default_dependencies(Mount *m) {
                  * whose purpose it is to delay this until the network
                  * is "up". */
 
-                r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_WANTS, UNIT_AFTER, SPECIAL_NETWORK_ONLINE_TARGET, NULL, true);
+                r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_WANTS, UNIT_AFTER, SPECIAL_NETWORK_ONLINE_TARGET, NULL, true, mask);
                 if (r < 0)
                         return r;
 
@@ -478,14 +486,21 @@ static int mount_add_default_dependencies(Mount *m) {
         } else
                 after = SPECIAL_LOCAL_FS_PRE_TARGET;
 
-        r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, after, NULL, true);
+        r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, after, NULL, true, mask);
         if (r < 0)
                 return r;
 
-        r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
+        r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true, mask);
         if (r < 0)
                 return r;
 
+        /* If this is a tmpfs mount then we have to unmount it before we try to deactivate swaps */
+        if (streq_ptr(p->fstype, "tmpfs")) {
+                r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, SPECIAL_SWAP_TARGET, NULL, true, mask);
+                if (r < 0)
+                        return r;
+        }
+
         return 0;
 }
 
@@ -553,15 +568,15 @@ static int mount_add_extras(Mount *m) {
                         return r;
         }
 
-        r = mount_add_device_links(m);
+        r = mount_add_device_dependencies(m);
         if (r < 0)
                 return r;
 
-        r = mount_add_mount_links(m);
+        r = mount_add_mount_dependencies(m);
         if (r < 0)
                 return r;
 
-        r = mount_add_quota_links(m);
+        r = mount_add_quota_dependencies(m);
         if (r < 0)
                 return r;
 
@@ -735,31 +750,21 @@ static void mount_dump(Unit *u, FILE *f, const char *prefix) {
 }
 
 static int mount_spawn(Mount *m, ExecCommand *c, pid_t *_pid) {
-        pid_t pid;
-        int r;
+
         ExecParameters exec_params = {
                 .flags      = EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_APPLY_TTY_STDIN,
                 .stdin_fd   = -1,
                 .stdout_fd  = -1,
                 .stderr_fd  = -1,
         };
+        pid_t pid;
+        int r;
 
         assert(m);
         assert(c);
         assert(_pid);
 
-        (void) unit_realize_cgroup(UNIT(m));
-        if (m->reset_accounting) {
-                (void) unit_reset_cpu_accounting(UNIT(m));
-                (void) unit_reset_ip_accounting(UNIT(m));
-                m->reset_accounting = false;
-        }
-
-        r = unit_setup_exec_runtime(UNIT(m));
-        if (r < 0)
-                return r;
-
-        r = unit_setup_dynamic_creds(UNIT(m));
+        r = unit_prepare_exec(UNIT(m));
         if (r < 0)
                 return r;
 
@@ -933,9 +938,6 @@ static void mount_enter_mounting(Mount *m) {
 
         assert(m);
 
-        m->control_command_id = MOUNT_EXEC_MOUNT;
-        m->control_command = m->exec_command + MOUNT_EXEC_MOUNT;
-
         r = unit_fail_if_symlink(UNIT(m), m->where);
         if (r < 0)
                 goto fail;
@@ -944,6 +946,11 @@ static void mount_enter_mounting(Mount *m) {
 
         unit_warn_if_dir_nonempty(UNIT(m), m->where);
 
+        unit_warn_leftover_processes(UNIT(m));
+
+        m->control_command_id = MOUNT_EXEC_MOUNT;
+        m->control_command = m->exec_command + MOUNT_EXEC_MOUNT;
+
         /* Create the source directory for bind-mounts if needed */
         p = get_mount_parameters_fragment(m);
         if (p && mount_is_bind(p))
@@ -1074,7 +1081,8 @@ static int mount_start(Unit *u) {
 
         m->result = MOUNT_SUCCESS;
         m->reload_result = MOUNT_SUCCESS;
-        m->reset_accounting = true;
+
+        u->reset_accounting = true;
 
         mount_enter_mounting(m);
         return 1;
@@ -1339,7 +1347,7 @@ static int mount_dispatch_timer(sd_event_source *source, usec_t usec, void *user
                 break;
 
         case MOUNT_REMOUNTING:
-                log_unit_warning(UNIT(m), "Remounting timed out. Killing remount process.");
+                log_unit_warning(UNIT(m), "Remounting timed out. Terminating remount process.");
                 mount_set_reload_result(m, MOUNT_FAILURE_TIMEOUT);
                 mount_enter_signal(m, MOUNT_REMOUNTING_SIGTERM, MOUNT_SUCCESS);
                 break;
@@ -1364,7 +1372,7 @@ static int mount_dispatch_timer(sd_event_source *source, usec_t usec, void *user
                 break;
 
         case MOUNT_UNMOUNTING:
-                log_unit_warning(UNIT(m), "Unmounting timed out. Stopping.");
+                log_unit_warning(UNIT(m), "Unmounting timed out. Terminating.");
                 mount_enter_signal(m, MOUNT_UNMOUNTING_SIGTERM, MOUNT_FAILURE_TIMEOUT);
                 break;
 
@@ -1429,11 +1437,11 @@ static int mount_setup_new_unit(
                 int r;
 
                 target = mount_is_network(p) ? SPECIAL_REMOTE_FS_TARGET : SPECIAL_LOCAL_FS_TARGET;
-                r = unit_add_dependency_by_name(u, UNIT_BEFORE, target, NULL, true);
+                r = unit_add_dependency_by_name(u, UNIT_BEFORE, target, NULL, true, UNIT_DEPENDENCY_MOUNTINFO_IMPLICIT);
                 if (r < 0)
                         return r;
 
-                r = unit_add_dependency_by_name(u, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
+                r = unit_add_dependency_by_name(u, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true, UNIT_DEPENDENCY_MOUNTINFO_IMPLICIT);
                 if (r < 0)
                         return r;
         }
@@ -1491,7 +1499,7 @@ static int mount_setup_existing_unit(
                  * in the dependency "Set*" objects who created a
                  * dependency), we can only add deps, never lose them,
                  * until the next full daemon-reload. */
-                unit_add_dependency_by_name(u, UNIT_BEFORE, SPECIAL_REMOTE_FS_TARGET, NULL, true);
+                unit_add_dependency_by_name(u, UNIT_BEFORE, SPECIAL_REMOTE_FS_TARGET, NULL, true, UNIT_DEPENDENCY_MOUNTINFO_IMPLICIT);
                 load_extras = true;
         }
 
index f81e421..44fe3b8 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -67,8 +68,6 @@ struct Mount {
         bool just_mounted:1;
         bool just_changed:1;
 
-        bool reset_accounting:1;
-
         bool sloppy_options;
 
         bool lazy_unmount;
index 6d74b8d..a3262fc 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -191,7 +192,7 @@ static void mount_entry_done(MountEntry *p) {
         p->source_malloc = mfree(p->source_malloc);
 }
 
-static int append_access_mounts(MountEntry **p, char **strv, MountMode mode) {
+static int append_access_mounts(MountEntry **p, char **strv, MountMode mode, bool forcibly_require_prefix) {
         char **i;
 
         assert(p);
@@ -219,7 +220,7 @@ static int append_access_mounts(MountEntry **p, char **strv, MountMode mode) {
                         .path_const = e,
                         .mode = mode,
                         .ignore = ignore,
-                        .has_prefix = !needs_prefix,
+                        .has_prefix = !needs_prefix && !forcibly_require_prefix,
                 };
         }
 
@@ -795,8 +796,8 @@ static int apply_mount(
 
         case BIND_MOUNT:
                 rbind = false;
-                /* fallthrough */
 
+                _fallthrough_;
         case BIND_MOUNT_RECURSIVE:
                 /* Also chase the source mount */
 
@@ -898,7 +899,7 @@ static int make_read_only(MountEntry *m, char **blacklist, FILE *proc_self_mount
         return r;
 }
 
-static bool namespace_info_mount_apivfs(const char *root_directory, const NameSpaceInfo *ns_info) {
+static bool namespace_info_mount_apivfs(const char *root_directory, const NamespaceInfo *ns_info) {
         assert(ns_info);
 
         /*
@@ -916,7 +917,7 @@ static bool namespace_info_mount_apivfs(const char *root_directory, const NameSp
 
 static unsigned namespace_calculate_mounts(
                 const char* root_directory,
-                const NameSpaceInfo *ns_info,
+                const NamespaceInfo *ns_info,
                 char** read_write_paths,
                 char** read_only_paths,
                 char** inaccessible_paths,
@@ -960,7 +961,7 @@ static unsigned namespace_calculate_mounts(
 int setup_namespace(
                 const char* root_directory,
                 const char* root_image,
-                const NameSpaceInfo *ns_info,
+                const NamespaceInfo *ns_info,
                 char** read_write_paths,
                 char** read_only_paths,
                 char** inaccessible_paths,
@@ -983,6 +984,7 @@ int setup_namespace(
         bool make_slave = false;
         const char *root;
         unsigned n_mounts;
+        bool require_prefix = false;
         int r = 0;
 
         assert(ns_info);
@@ -1027,6 +1029,7 @@ int setup_namespace(
 
                 root = "/run/systemd/unit-root";
                 (void) mkdir_label(root, 0700);
+                require_prefix = true;
         } else
                 root = NULL;
 
@@ -1047,15 +1050,15 @@ int setup_namespace(
 
         if (n_mounts > 0) {
                 m = mounts = (MountEntry *) alloca0(n_mounts * sizeof(MountEntry));
-                r = append_access_mounts(&m, read_write_paths, READWRITE);
+                r = append_access_mounts(&m, read_write_paths, READWRITE, require_prefix);
                 if (r < 0)
                         goto finish;
 
-                r = append_access_mounts(&m, read_only_paths, READONLY);
+                r = append_access_mounts(&m, read_only_paths, READONLY, require_prefix);
                 if (r < 0)
                         goto finish;
 
-                r = append_access_mounts(&m, inaccessible_paths, INACCESSIBLE);
+                r = append_access_mounts(&m, inaccessible_paths, INACCESSIBLE, require_prefix);
                 if (r < 0)
                         goto finish;
 
@@ -1150,13 +1153,9 @@ int setup_namespace(
                 }
         }
 
-        /* Try to set up the new root directory before mounting anything there */
-        if (root)
-                (void) base_filesystem_create(root, UID_INVALID, GID_INVALID);
-
         if (root_image) {
                 /* A root image is specified, mount it to the right place */
-                r = dissected_image_mount(dissected_image, root, dissect_image_flags);
+                r = dissected_image_mount(dissected_image, root, UID_INVALID, dissect_image_flags);
                 if (r < 0)
                         goto finish;
 
@@ -1190,6 +1189,10 @@ int setup_namespace(
                 }
         }
 
+        /* Try to set up the new root directory before mounting anything else there. */
+        if (root_image || root_directory)
+                (void) base_filesystem_create(root, UID_INVALID, GID_INVALID);
+
         if (n_mounts > 0) {
                 _cleanup_fclose_ FILE *proc_self_mountinfo = NULL;
                 char **blacklist;
@@ -1428,6 +1431,17 @@ fail:
         return r;
 }
 
+bool ns_type_supported(NamespaceType type) {
+        const char *t, *ns_proc;
+
+        t = namespace_type_to_string(type);
+        if (!t) /* Don't know how to translate this? Then it's not supported */
+                return false;
+
+        ns_proc = strjoina("/proc/self/ns/", t);
+        return access(ns_proc, F_OK) == 0;
+}
+
 static const char *const protect_home_table[_PROTECT_HOME_MAX] = {
         [PROTECT_HOME_NO] = "no",
         [PROTECT_HOME_YES] = "yes",
@@ -1444,3 +1458,15 @@ static const char *const protect_system_table[_PROTECT_SYSTEM_MAX] = {
 };
 
 DEFINE_STRING_TABLE_LOOKUP(protect_system, ProtectSystem);
+
+static const char* const namespace_type_table[] = {
+        [NAMESPACE_MOUNT] = "mnt",
+        [NAMESPACE_CGROUP] = "cgroup",
+        [NAMESPACE_UTS] = "uts",
+        [NAMESPACE_IPC] = "ipc",
+        [NAMESPACE_USER] = "user",
+        [NAMESPACE_PID] = "pid",
+        [NAMESPACE_NET] = "net",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(namespace_type, NamespaceType);
index da8d85d..f0f1983 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -20,7 +21,7 @@
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
-typedef struct NameSpaceInfo NameSpaceInfo;
+typedef struct NamespaceInfo NamespaceInfo;
 typedef struct BindMount BindMount;
 
 #include <stdbool.h>
@@ -36,6 +37,18 @@ typedef enum ProtectHome {
         _PROTECT_HOME_INVALID = -1
 } ProtectHome;
 
+typedef enum NamespaceType {
+        NAMESPACE_MOUNT,
+        NAMESPACE_CGROUP,
+        NAMESPACE_UTS,
+        NAMESPACE_IPC,
+        NAMESPACE_USER,
+        NAMESPACE_PID,
+        NAMESPACE_NET,
+        _NAMESPACE_TYPE_MAX,
+        _NAMESPACE_TYPE_INVALID = -1,
+} NamespaceType;
+
 typedef enum ProtectSystem {
         PROTECT_SYSTEM_NO,
         PROTECT_SYSTEM_YES,
@@ -45,7 +58,7 @@ typedef enum ProtectSystem {
         _PROTECT_SYSTEM_INVALID = -1
 } ProtectSystem;
 
-struct NameSpaceInfo {
+struct NamespaceInfo {
         bool ignore_protect_paths:1;
         bool private_dev:1;
         bool protect_control_groups:1;
@@ -65,7 +78,7 @@ struct BindMount {
 int setup_namespace(
                 const char *root_directory,
                 const char *root_image,
-                const NameSpaceInfo *ns_info,
+                const NamespaceInfo *ns_info,
                 char **read_write_paths,
                 char **read_only_paths,
                 char **inaccessible_paths,
@@ -94,3 +107,8 @@ ProtectSystem protect_system_from_string(const char *s) _pure_;
 
 void bind_mount_free_many(BindMount *b, unsigned n);
 int bind_mount_add(BindMount **b, unsigned *n, const BindMount *item);
+
+const char* namespace_type_to_string(NamespaceType t) _const_;
+NamespaceType namespace_type_from_string(const char *s) _pure_;
+
+bool ns_type_supported(NamespaceType type);
index 43d85e0..e68bc99 100644 (file)
@@ -3,6 +3,8 @@
         "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   systemd is free software; you can redistribute it and/or modify it
index cc39a9e..2c6ed74 100644 (file)
@@ -3,6 +3,8 @@
         "http://www.freedesktop.org/standards/PolicyKit/1/policyconfig.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   systemd is free software; you can redistribute it and/or modify it
@@ -17,8 +19,8 @@
         <vendor_url>http://www.freedesktop.org/wiki/Software/systemd</vendor_url>
 
         <action id="org.freedesktop.systemd1.reply-password">
-                <_description>Send passphrase back to system</_description>
-                <_message>Authentication is required to send the entered passphrase back to the system.</_message>
+                <description>Send passphrase back to system</description>
+                <message>Authentication is required to send the entered passphrase back to the system.</message>
                 <defaults>
                         <allow_any>no</allow_any>
                         <allow_inactive>no</allow_inactive>
@@ -28,8 +30,8 @@
         </action>
 
         <action id="org.freedesktop.systemd1.manage-units">
-                <_description>Manage system services or other units</_description>
-                <_message>Authentication is required to manage system services or other units.</_message>
+                <description>Manage system services or other units</description>
+                <message>Authentication is required to manage system services or other units.</message>
                 <defaults>
                         <allow_any>auth_admin</allow_any>
                         <allow_inactive>auth_admin</allow_inactive>
@@ -38,8 +40,8 @@
         </action>
 
         <action id="org.freedesktop.systemd1.manage-unit-files">
-                <_description>Manage system service or unit files</_description>
-                <_message>Authentication is required to manage system service or unit files.</_message>
+                <description>Manage system service or unit files</description>
+                <message>Authentication is required to manage system service or unit files.</message>
                 <defaults>
                         <allow_any>auth_admin</allow_any>
                         <allow_inactive>auth_admin</allow_inactive>
@@ -48,8 +50,8 @@
         </action>
 
         <action id="org.freedesktop.systemd1.set-environment">
-                <_description>Set or unset system and service manager environment variables</_description>
-                <_message>Authentication is required to set or unset system and service manager environment variables.</_message>
+                <description>Set or unset system and service manager environment variables</description>
+                <message>Authentication is required to set or unset system and service manager environment variables.</message>
                 <defaults>
                         <allow_any>auth_admin</allow_any>
                         <allow_inactive>auth_admin</allow_inactive>
@@ -58,8 +60,8 @@
         </action>
 
         <action id="org.freedesktop.systemd1.reload-daemon">
-                <_description>Reload the systemd state</_description>
-                <_message>Authentication is required to reload the systemd state.</_message>
+                <description>Reload the systemd state</description>
+                <message>Authentication is required to reload the systemd state.</message>
                 <defaults>
                         <allow_any>auth_admin</allow_any>
                         <allow_inactive>auth_admin</allow_inactive>
index d4df3e9..8bd7302 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 44831f5..6b22451 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -277,14 +278,14 @@ static void path_done(Unit *u) {
         path_free_specs(p);
 }
 
-static int path_add_mount_links(Path *p) {
+static int path_add_mount_dependencies(Path *p) {
         PathSpec *s;
         int r;
 
         assert(p);
 
         LIST_FOREACH(spec, s, p->specs) {
-                r = unit_require_mounts_for(UNIT(p), s->path);
+                r = unit_require_mounts_for(UNIT(p), s->path, UNIT_DEPENDENCY_FILE);
                 if (r < 0)
                         return r;
         }
@@ -314,17 +315,33 @@ static int path_add_default_dependencies(Path *p) {
         if (!UNIT(p)->default_dependencies)
                 return 0;
 
-        r = unit_add_dependency_by_name(UNIT(p), UNIT_BEFORE, SPECIAL_PATHS_TARGET, NULL, true);
+        r = unit_add_dependency_by_name(UNIT(p), UNIT_BEFORE, SPECIAL_PATHS_TARGET, NULL, true, UNIT_DEPENDENCY_DEFAULT);
         if (r < 0)
                 return r;
 
         if (MANAGER_IS_SYSTEM(UNIT(p)->manager)) {
-                r = unit_add_two_dependencies_by_name(UNIT(p), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SYSINIT_TARGET, NULL, true);
+                r = unit_add_two_dependencies_by_name(UNIT(p), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SYSINIT_TARGET, NULL, true, UNIT_DEPENDENCY_DEFAULT);
                 if (r < 0)
                         return r;
         }
 
-        return unit_add_two_dependencies_by_name(UNIT(p), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true);
+        return unit_add_two_dependencies_by_name(UNIT(p), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true, UNIT_DEPENDENCY_DEFAULT);
+}
+
+static int path_add_trigger_dependencies(Path *p) {
+        Unit *x;
+        int r;
+
+        assert(p);
+
+        if (!hashmap_isempty(UNIT(p)->dependencies[UNIT_TRIGGERS]))
+                return 0;
+
+        r = unit_load_related_unit(UNIT(p), ".service", &x);
+        if (r < 0)
+                return r;
+
+        return unit_add_two_dependencies(UNIT(p), UNIT_BEFORE, UNIT_TRIGGERS, x, true, UNIT_DEPENDENCY_IMPLICIT);
 }
 
 static int path_load(Unit *u) {
@@ -340,19 +357,11 @@ static int path_load(Unit *u) {
 
         if (u->load_state == UNIT_LOADED) {
 
-                if (set_isempty(u->dependencies[UNIT_TRIGGERS])) {
-                        Unit *x;
-
-                        r = unit_load_related_unit(u, ".service", &x);
-                        if (r < 0)
-                                return r;
-
-                        r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, x, true);
-                        if (r < 0)
-                                return r;
-                }
+                r = path_add_trigger_dependencies(p);
+                if (r < 0)
+                        return r;
 
-                r = path_add_mount_links(p);
+                r = path_add_mount_dependencies(p);
                 if (r < 0)
                         return r;
 
index 4230c8f..41e3198 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 4cd5e3d..10454d5 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -58,7 +59,8 @@ static void scope_done(Unit *u) {
 
         assert(u);
 
-        free(s->controller);
+        s->controller = mfree(s->controller);
+        s->controller_track = sd_bus_track_unref(s->controller_track);
 
         s->timer_event_source = sd_event_source_unref(s->timer_event_source);
 }
@@ -124,7 +126,8 @@ static int scope_add_default_dependencies(Scope *s) {
         r = unit_add_two_dependencies_by_name(
                         UNIT(s),
                         UNIT_BEFORE, UNIT_CONFLICTS,
-                        SPECIAL_SHUTDOWN_TARGET, NULL, true);
+                        SPECIAL_SHUTDOWN_TARGET, NULL, true,
+                        UNIT_DEPENDENCY_DEFAULT);
         if (r < 0)
                 return r;
 
@@ -227,6 +230,8 @@ static int scope_coldplug(Unit *u) {
         if (!IN_SET(s->deserialized_state, SCOPE_DEAD, SCOPE_FAILED))
                 unit_watch_all_pids(UNIT(s));
 
+        bus_scope_track_controller(s);
+
         scope_set_state(s, s->deserialized_state);
         return 0;
 }
@@ -270,9 +275,8 @@ static void scope_enter_signal(Scope *s, ScopeState state, ScopeResult f) {
 
         unit_watch_all_pids(UNIT(s));
 
-        /* If we have a controller set let's ask the controller nicely
-         * to terminate the scope, instead of us going directly into
-         * SIGTERM berserk mode */
+        /* If we have a controller set let's ask the controller nicely to terminate the scope, instead of us going
+         * directly into SIGTERM berserk mode */
         if (state == SCOPE_STOP_SIGTERM)
                 skip_signal = bus_scope_send_request_stop(s) > 0;
 
@@ -330,6 +334,8 @@ static int scope_start(Unit *u) {
         if (!u->transient && !MANAGER_IS_RELOADING(u->manager))
                 return -ENOENT;
 
+        (void) bus_scope_track_controller(s);
+
         r = unit_acquire_invocation_id(u);
         if (r < 0)
                 return r;
@@ -338,6 +344,8 @@ static int scope_start(Unit *u) {
         (void) unit_reset_cpu_accounting(u);
         (void) unit_reset_ip_accounting(u);
 
+        unit_export_state_files(UNIT(s));
+
         r = unit_attach_pids_to_cgroup(u);
         if (r < 0) {
                 log_unit_warning_errno(UNIT(s), r, "Failed to add PIDs to scope's control group: %m");
@@ -407,11 +415,16 @@ static int scope_serialize(Unit *u, FILE *f, FDSet *fds) {
 
         unit_serialize_item(u, f, "state", scope_state_to_string(s->state));
         unit_serialize_item(u, f, "was-abandoned", yes_no(s->was_abandoned));
+
+        if (s->controller)
+                unit_serialize_item(u, f, "controller", s->controller);
+
         return 0;
 }
 
 static int scope_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
         Scope *s = SCOPE(u);
+        int r;
 
         assert(u);
         assert(key);
@@ -435,24 +448,18 @@ static int scope_deserialize_item(Unit *u, const char *key, const char *value, F
                         log_unit_debug(u, "Failed to parse boolean value: %s", value);
                 else
                         s->was_abandoned = k;
+        } else if (streq(key, "controller")) {
+
+                r = free_and_strdup(&s->controller, value);
+                if (r < 0)
+                        log_oom();
+
         } else
                 log_unit_debug(u, "Unknown serialization key: %s", key);
 
         return 0;
 }
 
-static bool scope_check_gc(Unit *u) {
-        assert(u);
-
-        /* Never clean up scopes that still have a process around,
-         * even if the scope is formally dead. */
-
-        if (!u->cgroup_path)
-                return false;
-
-        return cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path) <= 0;
-}
-
 static void scope_notify_cgroup_empty_event(Unit *u) {
         Scope *s = SCOPE(u);
         assert(u);
@@ -521,7 +528,11 @@ int scope_abandon(Scope *s) {
                 return -ESTALE;
 
         s->was_abandoned = true;
+
         s->controller = mfree(s->controller);
+        s->controller_track = sd_bus_track_unref(s->controller_track);
+
+        scope_set_state(s, SCOPE_ABANDONED);
 
         /* The client is no longer watching the remaining processes,
          * so let's step in here, under the assumption that the
@@ -531,12 +542,6 @@ int scope_abandon(Scope *s) {
         unit_tidy_watch_pids(UNIT(s), 0, 0);
         unit_watch_all_pids(UNIT(s));
 
-        /* If the PID set is empty now, then let's finish this off */
-        if (set_isempty(UNIT(s)->pids))
-                scope_notify_cgroup_empty_event(UNIT(s));
-        else
-                scope_set_state(s, SCOPE_ABANDONED);
-
         return 0;
 }
 
@@ -622,8 +627,6 @@ const UnitVTable scope_vtable = {
         .active_state = scope_active_state,
         .sub_state_to_string = scope_sub_state_to_string,
 
-        .check_gc = scope_check_gc,
-
         .sigchld_event = scope_sigchld_event,
 
         .reset_failed = scope_reset_failed,
index eaf8e8b..ca7c6c8 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -45,6 +46,8 @@ struct Scope {
         usec_t timeout_stop_usec;
 
         char *controller;
+        sd_bus_track *controller_track;
+
         bool was_abandoned;
 
         sd_event_source *timer_event_source;
index 2db4189..475c318 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 1f6a518..c5f5fb9 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 60361a5..7135542 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 7b61324..410991c 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index e4f061f..48522d5 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -253,6 +254,45 @@ static void service_start_watchdog(Service *s) {
                 log_unit_warning_errno(UNIT(s), r, "Failed to install watchdog timer: %m");
 }
 
+static void service_extend_timeout(Service *s, usec_t extend_timeout_usec) {
+        assert(s);
+
+        if (s->timer_event_source) {
+                uint64_t current = 0, extended = 0;
+                int r;
+
+                if (IN_SET(extend_timeout_usec, 0, USEC_INFINITY))
+                        return;
+
+                extended = usec_add(now(CLOCK_MONOTONIC), extend_timeout_usec);
+
+                r = sd_event_source_get_time(s->timer_event_source, &current);
+                if (r < 0)
+                        log_unit_error_errno(UNIT(s), r, "Failed to retrieve timeout timer: %m");
+                else if (extended > current) {
+                        r = sd_event_source_set_time(s->timer_event_source, extended);
+                        if (r < 0)
+                                log_unit_warning_errno(UNIT(s), r, "Failed to set timeout timer: %m");
+                }
+
+                if (s->watchdog_event_source) {
+                        /* extend watchdog if necessary. We've asked for an extended timeout so we
+                         * shouldn't expect a watchdog timeout in the interval in between */
+                        r = sd_event_source_get_time(s->watchdog_event_source, &current);
+                        if (r < 0) {
+                                log_unit_error_errno(UNIT(s), r, "Failed to retrieve watchdog timer: %m");
+                                return;
+                        }
+
+                        if (extended > current) {
+                                r = sd_event_source_set_time(s->watchdog_event_source, extended);
+                                if (r < 0)
+                                        log_unit_warning_errno(UNIT(s), r, "Failed to set watchdog timer: %m");
+                        }
+                }
+        }
+}
+
 static void service_reset_watchdog(Service *s) {
         assert(s);
 
@@ -297,6 +337,9 @@ static void service_fd_store_unlink(ServiceFDStore *fs) {
 static void service_release_fd_store(Service *s) {
         assert(s);
 
+        if (s->n_keep_fd_store > 0)
+                return;
+
         log_unit_debug(UNIT(s), "Releasing all stored fds");
         while (s->fd_store)
                 service_fd_store_unlink(s->fd_store);
@@ -304,7 +347,7 @@ static void service_release_fd_store(Service *s) {
         assert(s->n_fd_store == 0);
 }
 
-static void service_release_resources(Unit *u, bool inactive) {
+static void service_release_resources(Unit *u) {
         Service *s = SERVICE(u);
 
         assert(s);
@@ -318,8 +361,7 @@ static void service_release_resources(Unit *u, bool inactive) {
         s->stdout_fd = safe_close(s->stdout_fd);
         s->stderr_fd = safe_close(s->stderr_fd);
 
-        if (inactive)
-                service_release_fd_store(s);
+        service_release_fd_store(s);
 }
 
 static void service_done(Unit *u) {
@@ -363,7 +405,7 @@ static void service_done(Unit *u) {
 
         s->timer_event_source = sd_event_source_unref(s->timer_event_source);
 
-        service_release_resources(u, true);
+        service_release_resources(u);
 }
 
 static int on_fd_store_io(sd_event_source *e, int fd, uint32_t revents, void *userdata) {
@@ -458,6 +500,21 @@ static int service_add_fd_store_set(Service *s, FDSet *fds, const char *name) {
         return 0;
 }
 
+static void service_remove_fd_store(Service *s, const char *name) {
+        ServiceFDStore *fs, *n;
+
+        assert(s);
+        assert(name);
+
+        LIST_FOREACH_SAFE(fd_store, fs, n, s->fd_store) {
+                if (!streq(fs->fdname, name))
+                        continue;
+
+                log_unit_debug(UNIT(s), "Got explicit request to remove fd %i (%s), closing.", fs->fd, name);
+                service_fd_store_unlink(fs);
+        }
+}
+
 static int service_arm_timer(Service *s, usec_t usec) {
         int r;
 
@@ -565,7 +622,7 @@ static int service_add_default_dependencies(Service *s) {
                  * require it, so that we fail if we can't acquire
                  * it. */
 
-                r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SYSINIT_TARGET, NULL, true);
+                r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SYSINIT_TARGET, NULL, true, UNIT_DEPENDENCY_DEFAULT);
                 if (r < 0)
                         return r;
         } else {
@@ -573,7 +630,7 @@ static int service_add_default_dependencies(Service *s) {
                 /* In the --user instance there's no sysinit.target,
                  * in that case require basic.target instead. */
 
-                r = unit_add_dependency_by_name(UNIT(s), UNIT_REQUIRES, SPECIAL_BASIC_TARGET, NULL, true);
+                r = unit_add_dependency_by_name(UNIT(s), UNIT_REQUIRES, SPECIAL_BASIC_TARGET, NULL, true, UNIT_DEPENDENCY_DEFAULT);
                 if (r < 0)
                         return r;
         }
@@ -581,21 +638,19 @@ static int service_add_default_dependencies(Service *s) {
         /* Second, if the rest of the base system is in the same
          * transaction, order us after it, but do not pull it in or
          * even require it. */
-        r = unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, SPECIAL_BASIC_TARGET, NULL, true);
+        r = unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, SPECIAL_BASIC_TARGET, NULL, true, UNIT_DEPENDENCY_DEFAULT);
         if (r < 0)
                 return r;
 
         /* Third, add us in for normal shutdown. */
-        return unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true);
+        return unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true, UNIT_DEPENDENCY_DEFAULT);
 }
 
 static void service_fix_output(Service *s) {
         assert(s);
 
-        /* If nothing has been explicitly configured, patch default
-         * output in. If input is socket/tty we avoid this however,
-         * since in that case we want output to default to the same
-         * place as we read input from. */
+        /* If nothing has been explicitly configured, patch default output in. If input is socket/tty we avoid this
+         * however, since in that case we want output to default to the same place as we read input from. */
 
         if (s->exec_context.std_error == EXEC_OUTPUT_INHERIT &&
             s->exec_context.std_output == EXEC_OUTPUT_INHERIT &&
@@ -605,6 +660,10 @@ static void service_fix_output(Service *s) {
         if (s->exec_context.std_output == EXEC_OUTPUT_INHERIT &&
             s->exec_context.std_input == EXEC_INPUT_NULL)
                 s->exec_context.std_output = UNIT(s)->manager->default_std_output;
+
+        if (s->exec_context.std_input == EXEC_INPUT_NULL &&
+            s->exec_context.stdin_data_size > 0)
+                s->exec_context.std_input = EXEC_INPUT_DATA;
 }
 
 static int service_setup_bus_name(Service *s) {
@@ -615,12 +674,12 @@ static int service_setup_bus_name(Service *s) {
         if (!s->bus_name)
                 return 0;
 
-        r = unit_add_dependency_by_name(UNIT(s), UNIT_REQUIRES, SPECIAL_DBUS_SOCKET, NULL, true);
+        r = unit_add_dependency_by_name(UNIT(s), UNIT_REQUIRES, SPECIAL_DBUS_SOCKET, NULL, true, UNIT_DEPENDENCY_FILE);
         if (r < 0)
                 return log_unit_error_errno(UNIT(s), r, "Failed to add dependency on " SPECIAL_DBUS_SOCKET ": %m");
 
         /* We always want to be ordered against dbus.socket if both are in the transaction. */
-        r = unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, SPECIAL_DBUS_SOCKET, NULL, true);
+        r = unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, SPECIAL_DBUS_SOCKET, NULL, true, UNIT_DEPENDENCY_FILE);
         if (r < 0)
                 return log_unit_error_errno(UNIT(s), r, "Failed to add dependency on " SPECIAL_DBUS_SOCKET ": %m");
 
@@ -1160,11 +1219,12 @@ static int service_collect_fds(Service *s,
                 rn_socket_fds = 1;
         } else {
                 Iterator i;
+                void *v;
                 Unit *u;
 
                 /* Pass all our configured sockets for singleton services */
 
-                SET_FOREACH(u, UNIT(s)->dependencies[UNIT_TRIGGERED_BY], i) {
+                HASHMAP_FOREACH_KEY(v, u, UNIT(s)->dependencies[UNIT_TRIGGERED_BY], i) {
                         _cleanup_free_ int *cfds = NULL;
                         Socket *sock;
                         int cn_fds;
@@ -1274,24 +1334,26 @@ static int service_spawn(
                 ExecFlags flags,
                 pid_t *_pid) {
 
-        _cleanup_strv_free_ char **final_env = NULL, **our_env = NULL, **fd_names = NULL;
-        _cleanup_free_ int *fds = NULL;
-        unsigned n_storage_fds = 0, n_socket_fds = 0, n_env = 0;
-        pid_t pid;
-
         ExecParameters exec_params = {
                 .flags      = flags,
                 .stdin_fd   = -1,
                 .stdout_fd  = -1,
                 .stderr_fd  = -1,
         };
-
+        _cleanup_strv_free_ char **final_env = NULL, **our_env = NULL, **fd_names = NULL;
+        unsigned n_storage_fds = 0, n_socket_fds = 0, n_env = 0;
+        _cleanup_free_ int *fds = NULL;
+        pid_t pid;
         int r;
 
         assert(s);
         assert(c);
         assert(_pid);
 
+        r = unit_prepare_exec(UNIT(s));
+        if (r < 0)
+                return r;
+
         if (flags & EXEC_IS_CONTROL) {
                 /* If this is a control process, mask the permissions/chroot application if this is requested. */
                 if (s->permissions_start_only)
@@ -1300,21 +1362,6 @@ static int service_spawn(
                         exec_params.flags &= ~EXEC_APPLY_CHROOT;
         }
 
-        (void) unit_realize_cgroup(UNIT(s));
-        if (s->reset_accounting) {
-                (void) unit_reset_cpu_accounting(UNIT(s));
-                (void) unit_reset_ip_accounting(UNIT(s));
-                s->reset_accounting = false;
-        }
-
-        r = unit_setup_exec_runtime(UNIT(s));
-        if (r < 0)
-                return r;
-
-        r = unit_setup_dynamic_creds(UNIT(s));
-        if (r < 0)
-                return r;
-
         if ((flags & EXEC_PASS_FDS) ||
             s->exec_context.std_input == EXEC_INPUT_SOCKET ||
             s->exec_context.std_output == EXEC_OUTPUT_SOCKET ||
@@ -1351,17 +1398,14 @@ static int service_spawn(
                 union sockaddr_union sa;
                 socklen_t salen = sizeof(sa);
 
-                r = getpeername(s->socket_fd, &sa.sa, &salen);
-                if (r < 0) {
-                        r = -errno;
+                /* If this is a per-connection service instance, let's set $REMOTE_ADDR and $REMOTE_PORT to something
+                 * useful. Note that we do this only when we are still connected at this point in time, which we might
+                 * very well not be. Hence we ignore all errors when retrieving peer information (as that might result
+                 * in ENOTCONN), and just use whate we can use. */
 
-                        /* ENOTCONN is legitimate if the endpoint disappeared on shutdown.
-                         * This connection is over, but the socket unit lives on. */
-                        if (r != -ENOTCONN || !IN_SET(s->control_command_id, SERVICE_EXEC_STOP, SERVICE_EXEC_STOP_POST))
-                                return r;
-                }
+                if (getpeername(s->socket_fd, &sa.sa, &salen) >= 0 &&
+                    IN_SET(sa.sa.sa_family, AF_INET, AF_INET6, AF_VSOCK)) {
 
-                if (r == 0 && IN_SET(sa.sa.sa_family, AF_INET, AF_INET6, AF_VSOCK)) {
                         _cleanup_free_ char *addr = NULL;
                         char *t;
                         unsigned port;
@@ -1410,11 +1454,6 @@ static int service_spawn(
         if (!final_env)
                 return -ENOMEM;
 
-        if ((flags & EXEC_IS_CONTROL) && UNIT(s)->cgroup_path) {
-                exec_params.cgroup_path = strjoina(UNIT(s)->cgroup_path, "/control");
-                (void) cg_create(SYSTEMD_CGROUP_CONTROLLER, exec_params.cgroup_path);
-        }
-
         /* System services should get a new keyring by default. */
         SET_FLAG(exec_params.flags, EXEC_NEW_KEYRING, MANAGER_IS_SYSTEM(UNIT(s)->manager));
 
@@ -1550,9 +1589,13 @@ static bool service_shall_restart(Service *s) {
         }
 }
 
-static bool service_will_restart(Service *s) {
+static bool service_will_restart(Unit *u) {
+        Service *s = SERVICE(u);
+
         assert(s);
 
+        if (s->will_auto_restart)
+                return true;
         if (s->state == SERVICE_AUTO_RESTART)
                 return true;
         if (!UNIT(s)->job)
@@ -1578,16 +1621,23 @@ static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart)
         if (s->result != SERVICE_SUCCESS)
                 log_unit_warning(UNIT(s), "Failed with result '%s'.", service_result_to_string(s->result));
 
-        service_set_state(s, s->result != SERVICE_SUCCESS ? SERVICE_FAILED : SERVICE_DEAD);
+        if (allow_restart && service_shall_restart(s))
+                s->will_auto_restart = true;
 
-        if (s->result != SERVICE_SUCCESS)
-                emergency_action(UNIT(s)->manager, s->emergency_action, UNIT(s)->reboot_arg, "service failed");
+        /* Make sure service_release_resources() doesn't destroy our FD store, while we are changing through
+         * SERVICE_FAILED/SERVICE_DEAD before entering into SERVICE_AUTO_RESTART. */
+        s->n_keep_fd_store ++;
+
+        service_set_state(s, s->result != SERVICE_SUCCESS ? SERVICE_FAILED : SERVICE_DEAD);
 
-        if (allow_restart && service_shall_restart(s)) {
+        if (s->will_auto_restart) {
+                s->will_auto_restart = false;
 
                 r = service_arm_timer(s, usec_add(now(CLOCK_MONOTONIC), s->restart_usec));
-                if (r < 0)
+                if (r < 0) {
+                        s->n_keep_fd_store--;
                         goto fail;
+                }
 
                 service_set_state(s, SERVICE_AUTO_RESTART);
         } else
@@ -1595,6 +1645,11 @@ static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart)
                  * user can still introspect the counter. Do so on the next start. */
                 s->flush_n_restarts = true;
 
+        /* The new state is in effect, let's decrease the fd store ref counter again. Let's also readd us to the GC
+         * queue, so that the fd store is possibly gc'ed again */
+        s->n_keep_fd_store--;
+        unit_add_to_gc_queue(UNIT(s));
+
         /* The next restart might not be a manual stop, hence reset the flag indicating manual stops */
         s->forbid_restart = false;
 
@@ -1603,7 +1658,7 @@ static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart)
         s->exec_runtime = exec_runtime_unref(s->exec_runtime);
 
         if (s->exec_context.runtime_directory_preserve_mode == EXEC_PRESERVE_NO ||
-            (s->exec_context.runtime_directory_preserve_mode == EXEC_PRESERVE_RESTART && !service_will_restart(s)))
+            (s->exec_context.runtime_directory_preserve_mode == EXEC_PRESERVE_RESTART && !service_will_restart(UNIT(s))))
                 /* Also, remove the runtime directory */
                 exec_context_destroy_runtime_directory(&s->exec_context, UNIT(s)->manager->prefix[EXEC_DIRECTORY_RUNTIME]);
 
@@ -1848,39 +1903,22 @@ fail:
         service_enter_stop(s, SERVICE_FAILURE_RESOURCES);
 }
 
-static void service_kill_control_processes(Service *s) {
+static void service_kill_control_process(Service *s) {
         int r;
 
         assert(s);
 
-        if (s->control_pid > 0) {
-                r = kill_and_sigcont(s->control_pid, SIGKILL);
-                if (r < 0) {
-                        _cleanup_free_ char *comm = NULL;
-
-                        (void) get_process_comm(s->control_pid, &comm);
-
-                        log_unit_debug_errno(UNIT(s), r, "Failed to kill control process " PID_FMT " (%s), ignoring: %m",
-                                             s->control_pid, strna(comm));
-                }
-        }
+        if (s->control_pid <= 0)
+                return;
 
-        if (UNIT(s)->cgroup_path) {
-                _cleanup_set_free_ Set *pid_set = NULL;
-                char *p;
+        r = kill_and_sigcont(s->control_pid, SIGKILL);
+        if (r < 0) {
+                _cleanup_free_ char *comm = NULL;
 
-                if (s->control_pid > 0) {
-                        r = set_make(&pid_set, PID_TO_PTR(s->control_pid), NULL);
-                        if (r < 0) {
-                                log_oom();
-                                return;
-                        }
-                }
+                (void) get_process_comm(s->control_pid, &comm);
 
-                p = strjoina(UNIT(s)->cgroup_path, "/control");
-                r = cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, p, SIGKILL, CGROUP_SIGCONT|CGROUP_IGNORE_SELF|CGROUP_REMOVE, pid_set, NULL, NULL);
-                if (r < 0)
-                        log_unit_debug_errno(UNIT(s), r, "Failed to send SIGKILL to processes of control group %s: %m", p);
+                log_unit_debug_errno(UNIT(s), r, "Failed to kill control process " PID_FMT " (%s), ignoring: %m",
+                                     s->control_pid, strna(comm));
         }
 }
 
@@ -1895,10 +1933,7 @@ static void service_enter_start(Service *s) {
         service_unwatch_control_pid(s);
         service_unwatch_main_pid(s);
 
-        /* We want to ensure that nobody leaks processes from
-         * START_PRE here, so let's go on a killing spree, People
-         * should not spawn long running processes from START_PRE. */
-        service_kill_control_processes(s);
+        unit_warn_leftover_processes(UNIT(s));
 
         if (s->type == SERVICE_FORKING) {
                 s->control_command_id = SERVICE_EXEC_START;
@@ -1986,9 +2021,8 @@ static void service_enter_start_pre(Service *s) {
 
         s->control_command = s->exec_command[SERVICE_EXEC_START_PRE];
         if (s->control_command) {
-                /* Before we start anything, let's clear up what might
-                 * be left from previous runs. */
-                service_kill_control_processes(s);
+
+                unit_warn_leftover_processes(UNIT(s));
 
                 s->control_command_id = SERVICE_EXEC_START_PRE;
 
@@ -2144,7 +2178,7 @@ static void service_run_next_control(Service *s) {
 fail:
         log_unit_warning_errno(UNIT(s), r, "Failed to run next control task: %m");
 
-        if (IN_SET(s->state, SERVICE_START_PRE, SERVICE_STOP))
+        if (IN_SET(s->state, SERVICE_START_PRE, SERVICE_START_POST, SERVICE_STOP))
                 service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_FAILURE_RESOURCES);
         else if (s->state == SERVICE_STOP_POST)
                 service_enter_dead(s, SERVICE_FAILURE_RESOURCES, true);
@@ -2229,7 +2263,8 @@ static int service_start(Unit *u) {
         s->main_pid_known = false;
         s->main_pid_alien = false;
         s->forbid_restart = false;
-        s->reset_accounting = true;
+
+        u->reset_accounting = true;
 
         s->status_text = mfree(s->status_text);
         s->status_errno = 0;
@@ -2804,10 +2839,11 @@ static bool service_check_gc(Unit *u) {
 
         assert(s);
 
-        /* Never clean up services that still have a process around,
-         * even if the service is formally dead. */
-        if (cgroup_good(s) > 0 ||
-            main_pid_good(s) > 0 ||
+        /* Never clean up services that still have a process around, even if the service is formally dead. Note that
+         * unit_check_gc() already checked our cgroup for us, we just check our two additional PIDs, too, in case they
+         * have moved outside of the cgroup. */
+
+        if (main_pid_good(s) > 0 ||
             control_pid_good(s) > 0)
                 return true;
 
@@ -2936,8 +2972,7 @@ static void service_notify_cgroup_empty_event(Unit *u) {
                         break;
                 }
 
-                /* Fall through */
-
+                _fallthrough_;
         case SERVICE_START_POST:
                 if (s->pid_file_pathspec &&
                     main_pid_good(s) == 0 &&
@@ -3098,8 +3133,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
                                         break;
                                 }
 
-                                /* Fall through */
-
+                                _fallthrough_;
                         case SERVICE_RUNNING:
                                 service_enter_running(s, f);
                                 break;
@@ -3144,11 +3178,6 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
                 if (s->result == SERVICE_SUCCESS)
                         s->result = f;
 
-                /* Immediately get rid of the cgroup, so that the
-                 * kernel doesn't delay the cgroup empty messages for
-                 * the service cgroup any longer than necessary */
-                service_kill_control_processes(s);
-
                 if (s->control_command &&
                     s->control_command->command_next &&
                     f == SERVICE_SUCCESS) {
@@ -3311,7 +3340,7 @@ static int service_dispatch_timer(sd_event_source *source, usec_t usec, void *us
 
         case SERVICE_RELOAD:
                 log_unit_warning(UNIT(s), "Reload operation timed out. Killing reload process.");
-                service_kill_control_processes(s);
+                service_kill_control_process(s);
                 s->reload_result = SERVICE_FAILURE_TIMEOUT;
                 service_enter_running(s, SERVICE_SUCCESS);
                 break;
@@ -3429,6 +3458,7 @@ static void service_notify_message(
         Service *s = SERVICE(u);
         bool notify_dbus = false;
         const char *e;
+        char **i;
         int r;
 
         assert(u);
@@ -3471,44 +3501,43 @@ static void service_notify_message(
                 }
         }
 
-        /* Interpret RELOADING= */
-        if (strv_find(tags, "RELOADING=1")) {
+        /* Interpret READY=/STOPPING=/RELOADING=. Last one wins. */
+        STRV_FOREACH_BACKWARDS(i, tags) {
 
-                s->notify_state = NOTIFY_RELOADING;
+                if (streq(*i, "READY=1")) {
+                        s->notify_state = NOTIFY_READY;
 
-                if (s->state == SERVICE_RUNNING)
-                        service_enter_reload_by_notify(s);
-
-                notify_dbus = true;
-        }
-
-        /* Interpret READY= */
-        if (strv_find(tags, "READY=1")) {
+                        /* Type=notify services inform us about completed
+                         * initialization with READY=1 */
+                        if (s->type == SERVICE_NOTIFY && s->state == SERVICE_START)
+                                service_enter_start_post(s);
 
-                s->notify_state = NOTIFY_READY;
+                        /* Sending READY=1 while we are reloading informs us
+                         * that the reloading is complete */
+                        if (s->state == SERVICE_RELOAD && s->control_pid == 0)
+                                service_enter_running(s, SERVICE_SUCCESS);
 
-                /* Type=notify services inform us about completed
-                 * initialization with READY=1 */
-                if (s->type == SERVICE_NOTIFY && s->state == SERVICE_START)
-                        service_enter_start_post(s);
+                        notify_dbus = true;
+                        break;
 
-                /* Sending READY=1 while we are reloading informs us
-                 * that the reloading is complete */
-                if (s->state == SERVICE_RELOAD && s->control_pid == 0)
-                        service_enter_running(s, SERVICE_SUCCESS);
+                } else if (streq(*i, "RELOADING=1")) {
+                        s->notify_state = NOTIFY_RELOADING;
 
-                notify_dbus = true;
-        }
+                        if (s->state == SERVICE_RUNNING)
+                                service_enter_reload_by_notify(s);
 
-        /* Interpret STOPPING= */
-        if (strv_find(tags, "STOPPING=1")) {
+                        notify_dbus = true;
+                        break;
 
-                s->notify_state = NOTIFY_STOPPING;
+                } else if (streq(*i, "STOPPING=1")) {
+                        s->notify_state = NOTIFY_STOPPING;
 
-                if (s->state == SERVICE_RUNNING)
-                        service_enter_stop_by_notify(s);
+                        if (s->state == SERVICE_RUNNING)
+                                service_enter_stop_by_notify(s);
 
-                notify_dbus = true;
+                        notify_dbus = true;
+                        break;
+                }
         }
 
         /* Interpret STATUS= */
@@ -3537,21 +3566,52 @@ static void service_notify_message(
         if (e) {
                 int status_errno;
 
-                if (safe_atoi(e, &status_errno) < 0 || status_errno < 0)
-                        log_unit_warning(u, "Failed to parse ERRNO= field in notification message: %s", e);
-                else {
-                        if (s->status_errno != status_errno) {
-                                s->status_errno = status_errno;
-                                notify_dbus = true;
-                        }
+                status_errno = parse_errno(e);
+                if (status_errno < 0)
+                        log_unit_warning_errno(u, status_errno,
+                                               "Failed to parse ERRNO= field in notification message: %s", e);
+                else if (s->status_errno != status_errno) {
+                        s->status_errno = status_errno;
+                        notify_dbus = true;
                 }
         }
 
+        /* Interpret EXTEND_TIMEOUT= */
+        e = strv_find_startswith(tags, "EXTEND_TIMEOUT_USEC=");
+        if (e) {
+                usec_t extend_timeout_usec;
+                if (safe_atou64(e, &extend_timeout_usec) < 0)
+                        log_unit_warning(u, "Failed to parse EXTEND_TIMEOUT_USEC=%s", e);
+                else
+                        service_extend_timeout(s, extend_timeout_usec);
+        }
+
         /* Interpret WATCHDOG= */
         if (strv_find(tags, "WATCHDOG=1"))
                 service_reset_watchdog(s);
 
-        if (strv_find(tags, "FDSTORE=1")) {
+        e = strv_find_startswith(tags, "WATCHDOG_USEC=");
+        if (e) {
+                usec_t watchdog_override_usec;
+                if (safe_atou64(e, &watchdog_override_usec) < 0)
+                        log_unit_warning(u, "Failed to parse WATCHDOG_USEC=%s", e);
+                else
+                        service_reset_watchdog_timeout(s, watchdog_override_usec);
+        }
+
+        /* Process FD store messages. Either FDSTOREREMOVE=1 for removal, or FDSTORE=1 for addition. In both cases,
+         * process FDNAME= for picking the file descriptor name to use. Note that FDNAME= is required when removing
+         * fds, but optional when pushing in new fds, for compatibility reasons. */
+        if (strv_find(tags, "FDSTOREREMOVE=1")) {
+                const char *name;
+
+                name = strv_find_startswith(tags, "FDNAME=");
+                if (!name || !fdname_is_valid(name))
+                        log_unit_warning(u, "FDSTOREREMOVE=1 requested, but no valid file descriptor name passed, ignoring.");
+                else
+                        service_remove_fd_store(s, name);
+
+        } else if (strv_find(tags, "FDSTORE=1")) {
                 const char *name;
 
                 name = strv_find_startswith(tags, "FDNAME=");
@@ -3560,16 +3620,7 @@ static void service_notify_message(
                         name = NULL;
                 }
 
-                service_add_fd_store_set(s, fds, name);
-        }
-
-        e = strv_find_startswith(tags, "WATCHDOG_USEC=");
-        if (e) {
-                usec_t watchdog_override_usec;
-                if (safe_atou64(e, &watchdog_override_usec) < 0)
-                        log_unit_warning(u, "Failed to parse WATCHDOG_USEC=%s", e);
-                else
-                        service_reset_watchdog_timeout(s, watchdog_override_usec);
+                (void) service_add_fd_store_set(s, fds, name);
         }
 
         /* Notify clients about changed status or main pid */
@@ -3696,7 +3747,7 @@ int service_set_socket_fd(Service *s, int fd, Socket *sock, bool selinux_context
                         return r;
         }
 
-        r = unit_add_two_dependencies(UNIT(sock), UNIT_BEFORE, UNIT_TRIGGERS, UNIT(s), false);
+        r = unit_add_two_dependencies(UNIT(sock), UNIT_BEFORE, UNIT_TRIGGERS, UNIT(s), false, UNIT_DEPENDENCY_IMPLICIT);
         if (r < 0)
                 return r;
 
@@ -3839,6 +3890,8 @@ const UnitVTable service_vtable = {
         .active_state = service_active_state,
         .sub_state_to_string = service_sub_state_to_string,
 
+        .will_restart = service_will_restart,
+
         .check_gc = service_check_gc,
 
         .sigchld_event = service_sigchld_event,
index 16b7006..5c5b24e 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -163,18 +164,16 @@ struct Service {
         bool main_pid_alien:1;
         bool bus_name_good:1;
         bool forbid_restart:1;
+        /* Keep restart intention between UNIT_FAILED and UNIT_ACTIVATING */
+        bool will_auto_restart:1;
         bool start_timeout_defined:1;
 
-        bool reset_accounting:1;
-
         char *bus_name;
         char *bus_name_owner; /* unique name of the current owner */
 
         char *status_text;
         int status_errno;
 
-        EmergencyAction emergency_action;
-
         UnitRef accept_socket;
 
         sd_event_source *timer_event_source;
@@ -186,6 +185,7 @@ struct Service {
         ServiceFDStore *fd_store;
         unsigned n_fd_store;
         unsigned n_fd_store_max;
+        unsigned n_keep_fd_store;
 
         char *usb_function_descriptors;
         char *usb_function_strings;
index 8c94573..40658a2 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 9a29e72..a13d524 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 6d1cc31..aca89d1 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -31,6 +32,7 @@
 
 #include "alloc-util.h"
 #include "cgroup-util.h"
+#include "fd-util.h"
 #include "def.h"
 #include "exec-util.h"
 #include "fileio.h"
@@ -39,6 +41,7 @@
 #include "missing.h"
 #include "parse-util.h"
 #include "process-util.h"
+#include "signal-util.h"
 #include "string-util.h"
 #include "switch-root.h"
 #include "terminal-util.h"
@@ -49,6 +52,9 @@
 
 #define FINALIZE_ATTEMPTS 50
 
+#define SYNC_PROGRESS_ATTEMPTS 3
+#define SYNC_TIMEOUT_USEC (10*USEC_PER_SEC)
+
 static char* arg_verb;
 static uint8_t arg_exit_code;
 
@@ -158,6 +164,103 @@ static int switch_root_initramfs(void) {
         return switch_root("/run/initramfs", "/oldroot", false, MS_BIND);
 }
 
+/* Read the following fields from /proc/meminfo:
+ *
+ *  NFS_Unstable
+ *  Writeback
+ *  Dirty
+ *
+ * Return true if the sum of these fields is greater than the previous
+ * value input. For all other issues, report the failure and indicate that
+ * the sync is not making progress.
+ */
+static bool sync_making_progress(unsigned long long *prev_dirty) {
+        _cleanup_fclose_ FILE *f = NULL;
+        char line[LINE_MAX];
+        bool r = false;
+        unsigned long long val = 0;
+
+        f = fopen("/proc/meminfo", "re");
+        if (!f)
+                return log_warning_errno(errno, "Failed to open /proc/meminfo: %m");
+
+        FOREACH_LINE(line, f, log_warning_errno(errno, "Failed to parse /proc/meminfo: %m")) {
+                unsigned long long ull = 0;
+
+                if (!first_word(line, "NFS_Unstable:") && !first_word(line, "Writeback:") && !first_word(line, "Dirty:"))
+                        continue;
+
+                errno = 0;
+                if (sscanf(line, "%*s %llu %*s", &ull) != 1) {
+                        if (errno != 0)
+                                log_warning_errno(errno, "Failed to parse /proc/meminfo: %m");
+                        else
+                                log_warning("Failed to parse /proc/meminfo");
+
+                        return false;
+                }
+
+                val += ull;
+        }
+
+        r = *prev_dirty > val;
+
+        *prev_dirty = val;
+
+        return r;
+}
+
+static void sync_with_progress(void) {
+        unsigned checks;
+        pid_t pid;
+        int r;
+        unsigned long long dirty = ULONG_LONG_MAX;
+
+        BLOCK_SIGNALS(SIGCHLD);
+
+        /* Due to the possiblity of the sync operation hanging, we fork
+         * a child process and monitor the progress. If the timeout
+         * lapses, the assumption is that that particular sync stalled. */
+        pid = fork();
+        if (pid < 0) {
+                log_error_errno(errno, "Failed to fork: %m");
+                return;
+        }
+
+        if (pid == 0) {
+                /* Start the sync operation here in the child */
+                sync();
+                _exit(EXIT_SUCCESS);
+        }
+
+        log_info("Syncing filesystems and block devices.");
+
+        /* Start monitoring the sync operation. If more than
+         * SYNC_PROGRESS_ATTEMPTS lapse without progress being made,
+         * we assume that the sync is stalled */
+        for (checks = 0; checks < SYNC_PROGRESS_ATTEMPTS; checks++) {
+                r = wait_for_terminate_with_timeout(pid, SYNC_TIMEOUT_USEC);
+                if (r == 0)
+                        /* Sync finished without error.
+                         * (The sync itself does not return an error code) */
+                        return;
+                else if (r == -ETIMEDOUT) {
+                        /* Reset the check counter if the "Dirty" value is
+                         * decreasing */
+                        if (sync_making_progress(&dirty))
+                                checks = 0;
+                } else {
+                        log_error_errno(r, "Failed to sync filesystems and block devices: %m");
+                        return;
+                }
+        }
+
+        /* Only reached in the event of a timeout. We should issue a kill
+         * to the stray process. */
+        log_error("Syncing filesystems and block devices - timed out, issuing SIGKILL to PID "PID_FMT".", pid);
+        (void) kill(pid, SIGKILL);
+}
+
 int main(int argc, char *argv[]) {
         bool need_umount, need_swapoff, need_loop_detach, need_dm_detach;
         bool in_container, use_watchdog = false;
@@ -166,6 +269,7 @@ int main(int argc, char *argv[]) {
         unsigned retries;
         int cmd, r;
         static const char* const dirs[] = {SYSTEM_SHUTDOWN_PATH, NULL};
+        char *watchdog_device;
 
         log_parse_environment();
         r = parse_argv(argc, argv);
@@ -206,15 +310,23 @@ int main(int argc, char *argv[]) {
         in_container = detect_container() > 0;
 
         use_watchdog = !!getenv("WATCHDOG_USEC");
+        watchdog_device = getenv("WATCHDOG_DEVICE");
+        if (watchdog_device) {
+                r = watchdog_set_device(watchdog_device);
+                if (r < 0)
+                        log_warning_errno(r, "Failed to set watchdog device to %s, ignoring: %m",
+                                          watchdog_device);
+        }
 
         /* Lock us into memory */
         mlockall(MCL_CURRENT|MCL_FUTURE);
 
         /* Synchronize everything that is not written to disk yet at this point already. This is a good idea so that
          * slow IO is processed here already and the final process killing spree is not impacted by processes
-         * desperately trying to sync IO to disk within their timeout. */
+         * desperately trying to sync IO to disk within their timeout. Do not remove this sync, data corruption will
+         * result. */
         if (!in_container)
-                sync();
+                sync_with_progress();
 
         log_info("Sending SIGTERM to remaining processes...");
         broadcast_signal(SIGTERM, true, true);
@@ -319,6 +431,9 @@ int main(int argc, char *argv[]) {
 
  initrd_jump:
 
+        /* We're done with the watchdog. */
+        watchdog_free_device();
+
         arguments[0] = NULL;
         arguments[1] = arg_verb;
         arguments[2] = NULL;
@@ -353,9 +468,9 @@ int main(int argc, char *argv[]) {
         /* The kernel will automatically flush ATA disks and suchlike on reboot(), but the file systems need to be
          * sync'ed explicitly in advance. So let's do this here, but not needlessly slow down containers. Note that we
          * sync'ed things already once above, but we did some more work since then which might have caused IO, hence
-         * let's doit once more. */
+         * let's do it once more. Do not remove this sync, data corruption will result. */
         if (!in_container)
-                sync();
+                sync_with_progress();
 
         if (streq(arg_verb, "exit")) {
                 if (in_container)
@@ -395,8 +510,7 @@ int main(int argc, char *argv[]) {
                 }
 
                 cmd = RB_AUTOBOOT;
-                /* Fall through */
-
+                _fallthrough_;
         case RB_AUTOBOOT:
 
                 if (!in_container) {
index b15f751..5ab1e6f 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -97,7 +98,7 @@ static int slice_add_default_dependencies(Slice *s) {
         r = unit_add_two_dependencies_by_name(
                         UNIT(s),
                         UNIT_BEFORE, UNIT_CONFLICTS,
-                        SPECIAL_SHUTDOWN_TARGET, NULL, true);
+                        SPECIAL_SHUTDOWN_TARGET, NULL, true, UNIT_DEPENDENCY_DEFAULT);
         if (r < 0)
                 return r;
 
index c9f3f61..418327e 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 9cd539f..b0d3612 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -23,6 +24,7 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <stdio.h>
+#include <stdio_ext.h>
 #include <stdlib.h>
 #include <string.h>
 
@@ -102,7 +104,7 @@ static int write_access2_rules(const char* srcdir) {
 
                         _cleanup_free_ char *sbj = NULL, *obj = NULL, *acc1 = NULL, *acc2 = NULL;
 
-                        if (isempty(truncate_nl(buf)))
+                        if (isempty(truncate_nl(buf)) || strchr(COMMENTS, *buf))
                                 continue;
 
                         /* if 3 args -> load rule   : subject object access1 */
@@ -179,7 +181,7 @@ static int write_cipso2_rules(const char* srcdir) {
                              log_error_errno(errno, "Failed to read line from '%s': %m",
                                              entry->d_name)) {
 
-                        if (isempty(truncate_nl(buf)))
+                        if (isempty(truncate_nl(buf)) || strchr(COMMENTS, *buf))
                                 continue;
 
                         if (write(cipso2_fd, buf, strlen(buf)) < 0) {
@@ -242,20 +244,25 @@ static int write_netlabel_rules(const char* srcdir) {
                         continue;
                 }
 
+                (void) __fsetlocking(policy, FSETLOCKING_BYCALLER);
+
                 /* load2 write rules in the kernel require a line buffered stream */
                 FOREACH_LINE(buf, policy,
-                             log_error_errno(errno, "Failed to read line from %s: %m",
-                                       entry->d_name)) {
-                        if (!fputs_unlocked(buf, dst)) {
+                             log_error_errno(errno, "Failed to read line from %s: %m", entry->d_name)) {
+
+                        int q;
+
+                        if (!fputs(buf, dst)) {
                                 if (r == 0)
                                         r = -EINVAL;
                                 log_error_errno(errno, "Failed to write line to /sys/fs/smackfs/netlabel");
                                 break;
                         }
-                        if (fflush(dst)) {
+                        q = fflush_and_check(dst);
+                        if (q < 0) {
                                 if (r == 0)
-                                        r = -errno;
-                                log_error_errno(errno, "Failed to flush writes to /sys/fs/smackfs/netlabel: %m");
+                                        r = q;
+                                log_error_errno(q, "Failed to flush writes to /sys/fs/smackfs/netlabel: %m");
                                 break;
                         }
                 }
index 78164c8..8c2de5f 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 3fc478e..cdc2631 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -250,7 +251,7 @@ int socket_instantiate_service(Socket *s) {
 
         unit_ref_set(&s->service, u);
 
-        return unit_add_two_dependencies(UNIT(s), UNIT_BEFORE, UNIT_TRIGGERS, u, false);
+        return unit_add_two_dependencies(UNIT(s), UNIT_BEFORE, UNIT_TRIGGERS, u, false, UNIT_DEPENDENCY_IMPLICIT);
 }
 
 static bool have_non_accept_socket(Socket *s) {
@@ -273,7 +274,7 @@ static bool have_non_accept_socket(Socket *s) {
         return false;
 }
 
-static int socket_add_mount_links(Socket *s) {
+static int socket_add_mount_dependencies(Socket *s) {
         SocketPort *p;
         int r;
 
@@ -290,7 +291,7 @@ static int socket_add_mount_links(Socket *s) {
                 if (!path)
                         continue;
 
-                r = unit_require_mounts_for(UNIT(s), path);
+                r = unit_require_mounts_for(UNIT(s), path, UNIT_DEPENDENCY_FILE);
                 if (r < 0)
                         return r;
         }
@@ -298,7 +299,7 @@ static int socket_add_mount_links(Socket *s) {
         return 0;
 }
 
-static int socket_add_device_link(Socket *s) {
+static int socket_add_device_dependencies(Socket *s) {
         char *t;
 
         assert(s);
@@ -307,7 +308,7 @@ static int socket_add_device_link(Socket *s) {
                 return 0;
 
         t = strjoina("/sys/subsystem/net/devices/", s->bind_to_device);
-        return unit_add_node_link(UNIT(s), t, false, UNIT_BINDS_TO);
+        return unit_add_node_dependency(UNIT(s), t, false, UNIT_BINDS_TO, UNIT_DEPENDENCY_FILE);
 }
 
 static int socket_add_default_dependencies(Socket *s) {
@@ -317,17 +318,17 @@ static int socket_add_default_dependencies(Socket *s) {
         if (!UNIT(s)->default_dependencies)
                 return 0;
 
-        r = unit_add_dependency_by_name(UNIT(s), UNIT_BEFORE, SPECIAL_SOCKETS_TARGET, NULL, true);
+        r = unit_add_dependency_by_name(UNIT(s), UNIT_BEFORE, SPECIAL_SOCKETS_TARGET, NULL, true, UNIT_DEPENDENCY_DEFAULT);
         if (r < 0)
                 return r;
 
         if (MANAGER_IS_SYSTEM(UNIT(s)->manager)) {
-                r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SYSINIT_TARGET, NULL, true);
+                r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SYSINIT_TARGET, NULL, true, UNIT_DEPENDENCY_DEFAULT);
                 if (r < 0)
                         return r;
         }
 
-        return unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true);
+        return unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true, UNIT_DEPENDENCY_DEFAULT);
 }
 
 _pure_ static bool socket_has_exec(Socket *s) {
@@ -378,16 +379,16 @@ static int socket_add_extras(Socket *s) {
                         unit_ref_set(&s->service, x);
                 }
 
-                r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, UNIT_DEREF(s->service), true);
+                r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, UNIT_DEREF(s->service), true, UNIT_DEPENDENCY_IMPLICIT);
                 if (r < 0)
                         return r;
         }
 
-        r = socket_add_mount_links(s);
+        r = socket_add_mount_dependencies(s);
         if (r < 0)
                 return r;
 
-        r = socket_add_device_link(s);
+        r = socket_add_device_dependencies(s);
         if (r < 0)
                 return r;
 
@@ -1864,31 +1865,21 @@ static int socket_coldplug(Unit *u) {
 }
 
 static int socket_spawn(Socket *s, ExecCommand *c, pid_t *_pid) {
-        pid_t pid;
-        int r;
+
         ExecParameters exec_params = {
                 .flags      = EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_APPLY_TTY_STDIN,
                 .stdin_fd   = -1,
                 .stdout_fd  = -1,
                 .stderr_fd  = -1,
         };
+        pid_t pid;
+        int r;
 
         assert(s);
         assert(c);
         assert(_pid);
 
-        (void) unit_realize_cgroup(UNIT(s));
-        if (s->reset_accounting) {
-                (void) unit_reset_cpu_accounting(UNIT(s));
-                (void) unit_reset_ip_accounting(UNIT(s));
-                s->reset_accounting = false;
-        }
-
-        r = unit_setup_exec_runtime(UNIT(s));
-        if (r < 0)
-                return r;
-
-        r = unit_setup_dynamic_creds(UNIT(s));
+        r = unit_prepare_exec(UNIT(s));
         if (r < 0)
                 return r;
 
@@ -2196,6 +2187,9 @@ static void socket_enter_start_pre(Socket *s) {
         assert(s);
 
         socket_unwatch_control_pid(s);
+
+        unit_warn_leftover_processes(UNIT(s));
+
         s->control_command_id = SOCKET_EXEC_START_PRE;
         s->control_command = s->exec_command[SOCKET_EXEC_START_PRE];
 
@@ -2261,13 +2255,14 @@ static void socket_enter_running(Socket *s, int cfd) {
         }
 
         if (cfd < 0) {
-                Iterator i;
-                Unit *other;
                 bool pending = false;
+                Unit *other;
+                Iterator i;
+                void *v;
 
                 /* If there's already a start pending don't bother to
                  * do anything */
-                SET_FOREACH(other, UNIT(s)->dependencies[UNIT_TRIGGERS], i)
+                HASHMAP_FOREACH_KEY(v, other, UNIT(s)->dependencies[UNIT_TRIGGERS], i)
                         if (unit_active_or_pending(other)) {
                                 pending = true;
                                 break;
@@ -2467,7 +2462,8 @@ static int socket_start(Unit *u) {
                 return r;
 
         s->result = SOCKET_SUCCESS;
-        s->reset_accounting = true;
+
+        u->reset_accounting = true;
 
         socket_enter_start_pre(s);
         return 1;
@@ -2794,7 +2790,7 @@ const char* socket_port_type_to_string(SocketPort *p) {
                         if (socket_address_family(&p->address) == AF_NETLINK)
                                 return "Netlink";
 
-                        /* fall through */
+                        _fallthrough_;
                 default:
                         return NULL;
                 }
index 8c26396..e9e560e 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -161,8 +162,6 @@ struct Socket {
 
         char *user, *group;
 
-        bool reset_accounting:1;
-
         char *fdname;
 
         RateLimit trigger_limit;
index f475755..849ccbd 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -197,7 +198,7 @@ static int swap_arm_timer(Swap *s, usec_t usec) {
         return 0;
 }
 
-static int swap_add_device_links(Swap *s) {
+static int swap_add_device_dependencies(Swap *s) {
         assert(s);
 
         if (!s->what)
@@ -207,12 +208,12 @@ static int swap_add_device_links(Swap *s) {
                 return 0;
 
         if (is_device_path(s->what))
-                return unit_add_node_link(UNIT(s), s->what, MANAGER_IS_SYSTEM(UNIT(s)->manager), UNIT_BINDS_TO);
+                return unit_add_node_dependency(UNIT(s), s->what, MANAGER_IS_SYSTEM(UNIT(s)->manager), UNIT_BINDS_TO, UNIT_DEPENDENCY_FILE);
         else
                 /* File based swap devices need to be ordered after
                  * systemd-remount-fs.service, since they might need a
                  * writable file system. */
-                return unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, SPECIAL_REMOUNT_FS_SERVICE, NULL, true);
+                return unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, SPECIAL_REMOUNT_FS_SERVICE, NULL, true, UNIT_DEPENDENCY_FILE);
 }
 
 static int swap_add_default_dependencies(Swap *s) {
@@ -231,11 +232,11 @@ static int swap_add_default_dependencies(Swap *s) {
 
         /* swap units generated for the swap dev links are missing the
          * ordering dep against the swap target. */
-        r = unit_add_dependency_by_name(UNIT(s), UNIT_BEFORE, SPECIAL_SWAP_TARGET, NULL, true);
+        r = unit_add_dependency_by_name(UNIT(s), UNIT_BEFORE, SPECIAL_SWAP_TARGET, NULL, true, UNIT_DEPENDENCY_DEFAULT);
         if (r < 0)
                 return r;
 
-        return unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
+        return unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true, UNIT_DEPENDENCY_DEFAULT);
 }
 
 static int swap_verify(Swap *s) {
@@ -291,7 +292,10 @@ static int swap_load(Unit *u) {
         assert(u->load_state == UNIT_STUB);
 
         /* Load a .swap file */
-        r = unit_load_fragment_and_dropin_optional(u);
+        if (SWAP(u)->from_proc_swaps)
+                r = unit_load_fragment_and_dropin_optional(u);
+        else
+                r = unit_load_fragment_and_dropin(u);
         if (r < 0)
                 return r;
 
@@ -323,11 +327,11 @@ static int swap_load(Unit *u) {
                                 return r;
                 }
 
-                r = unit_require_mounts_for(UNIT(s), s->what);
+                r = unit_require_mounts_for(UNIT(s), s->what, UNIT_DEPENDENCY_IMPLICIT);
                 if (r < 0)
                         return r;
 
-                r = swap_add_device_links(s);
+                r = swap_add_device_dependencies(s);
                 if (r < 0)
                         return r;
 
@@ -599,33 +603,23 @@ static void swap_dump(Unit *u, FILE *f, const char *prefix) {
 }
 
 static int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) {
-        pid_t pid;
-        int r;
+
         ExecParameters exec_params = {
                 .flags     = EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_APPLY_TTY_STDIN,
                 .stdin_fd  = -1,
                 .stdout_fd = -1,
                 .stderr_fd = -1,
         };
+        pid_t pid;
+        int r;
 
         assert(s);
         assert(c);
         assert(_pid);
 
-        (void) unit_realize_cgroup(UNIT(s));
-        if (s->reset_accounting) {
-                (void) unit_reset_cpu_accounting(UNIT(s));
-                (void) unit_reset_ip_accounting(UNIT(s));
-                s->reset_accounting = false;
-        }
-
-        r = unit_setup_exec_runtime(UNIT(s));
+        r = unit_prepare_exec(UNIT(s));
         if (r < 0)
-                goto fail;
-
-        r = unit_setup_dynamic_creds(UNIT(s));
-        if (r < 0)
-                goto fail;
+                return r;
 
         r = swap_arm_timer(s, usec_add(now(CLOCK_MONOTONIC), s->timeout_usec));
         if (r < 0)
@@ -740,6 +734,8 @@ static void swap_enter_activating(Swap *s) {
 
         assert(s);
 
+        unit_warn_leftover_processes(UNIT(s));
+
         s->control_command_id = SWAP_EXEC_ACTIVATE;
         s->control_command = s->exec_command + SWAP_EXEC_ACTIVATE;
 
@@ -862,7 +858,8 @@ static int swap_start(Unit *u) {
                 return r;
 
         s->result = SWAP_SUCCESS;
-        s->reset_accounting = true;
+
+        u->reset_accounting = true;
 
         swap_enter_activating(s);
         return 1;
index 45da63c..fa9d45a 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -70,8 +71,6 @@ struct Swap {
         bool is_active:1;
         bool just_activated:1;
 
-        bool reset_accounting:1;
-
         SwapResult result;
 
         usec_t timeout_usec;
index ac52b30..655773e 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
@@ -27,6 +29,10 @@ modulesloaddir=@modulesloaddir@
 catalogdir=@catalogdir@
 systemuidmax=@systemuidmax@
 systemgidmax=@systemgidmax@
+dynamicuidmin=@dynamicuidmin@
+dynamicuidmax=@dynamicuidmax@
+containeruidbasemin=@containeruidbasemin@
+containeruidbasemax=@containeruidbasemax@
 
 Name: systemd
 Description: systemd System and Service Manager
index 2a58dd3..756cbbf 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -56,8 +57,6 @@ static int target_add_default_dependencies(Target *t) {
                 UNIT_PART_OF
         };
 
-        Iterator i;
-        Unit *other;
         int r;
         unsigned k;
 
@@ -66,23 +65,26 @@ static int target_add_default_dependencies(Target *t) {
         if (!UNIT(t)->default_dependencies)
                 return 0;
 
-        /* Imply ordering for requirement dependencies on target
-         * units. Note that when the user created a contradicting
-         * ordering manually we won't add anything in here to make
-         * sure we don't create a loop. */
+        /* Imply ordering for requirement dependencies on target units. Note that when the user created a contradicting
+         * ordering manually we won't add anything in here to make sure we don't create a loop. */
 
-        for (k = 0; k < ELEMENTSOF(deps); k++)
-                SET_FOREACH(other, UNIT(t)->dependencies[deps[k]], i) {
+        for (k = 0; k < ELEMENTSOF(deps); k++) {
+                Unit *other;
+                Iterator i;
+                void *v;
+
+                HASHMAP_FOREACH_KEY(v, other, UNIT(t)->dependencies[deps[k]], i) {
                         r = unit_add_default_target_dependency(other, UNIT(t));
                         if (r < 0)
                                 return r;
                 }
+        }
 
         if (unit_has_name(UNIT(t), SPECIAL_SHUTDOWN_TARGET))
                 return 0;
 
         /* Make sure targets are unloaded on shutdown */
-        return unit_add_two_dependencies_by_name(UNIT(t), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true);
+        return unit_add_two_dependencies_by_name(UNIT(t), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true, UNIT_DEPENDENCY_DEFAULT);
 }
 
 static int target_load(Unit *u) {
index 339aea1..8d44a11 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 8b3d54b..ca8fc6f 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -105,18 +106,18 @@ static int timer_add_default_dependencies(Timer *t) {
         if (!UNIT(t)->default_dependencies)
                 return 0;
 
-        r = unit_add_dependency_by_name(UNIT(t), UNIT_BEFORE, SPECIAL_TIMERS_TARGET, NULL, true);
+        r = unit_add_dependency_by_name(UNIT(t), UNIT_BEFORE, SPECIAL_TIMERS_TARGET, NULL, true, UNIT_DEPENDENCY_DEFAULT);
         if (r < 0)
                 return r;
 
         if (MANAGER_IS_SYSTEM(UNIT(t)->manager)) {
-                r = unit_add_two_dependencies_by_name(UNIT(t), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SYSINIT_TARGET, NULL, true);
+                r = unit_add_two_dependencies_by_name(UNIT(t), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SYSINIT_TARGET, NULL, true, UNIT_DEPENDENCY_DEFAULT);
                 if (r < 0)
                         return r;
 
                 LIST_FOREACH(value, v, t->values) {
                         if (v->base == TIMER_CALENDAR) {
-                                r = unit_add_dependency_by_name(UNIT(t), UNIT_AFTER, SPECIAL_TIME_SYNC_TARGET, NULL, true);
+                                r = unit_add_dependency_by_name(UNIT(t), UNIT_AFTER, SPECIAL_TIME_SYNC_TARGET, NULL, true, UNIT_DEPENDENCY_DEFAULT);
                                 if (r < 0)
                                         return r;
                                 break;
@@ -124,7 +125,23 @@ static int timer_add_default_dependencies(Timer *t) {
                 }
         }
 
-        return unit_add_two_dependencies_by_name(UNIT(t), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true);
+        return unit_add_two_dependencies_by_name(UNIT(t), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true, UNIT_DEPENDENCY_DEFAULT);
+}
+
+static int timer_add_trigger_dependencies(Timer *t) {
+        Unit *x;
+        int r;
+
+        assert(t);
+
+        if (!hashmap_isempty(UNIT(t)->dependencies[UNIT_TRIGGERS]))
+                return 0;
+
+        r = unit_load_related_unit(UNIT(t), ".service", &x);
+        if (r < 0)
+                return r;
+
+        return unit_add_two_dependencies(UNIT(t), UNIT_BEFORE, UNIT_TRIGGERS, x, true, UNIT_DEPENDENCY_IMPLICIT);
 }
 
 static int timer_setup_persistent(Timer *t) {
@@ -137,7 +154,7 @@ static int timer_setup_persistent(Timer *t) {
 
         if (MANAGER_IS_SYSTEM(UNIT(t)->manager)) {
 
-                r = unit_require_mounts_for(UNIT(t), "/var/lib/systemd/timers");
+                r = unit_require_mounts_for(UNIT(t), "/var/lib/systemd/timers", UNIT_DEPENDENCY_FILE);
                 if (r < 0)
                         return r;
 
@@ -179,17 +196,9 @@ static int timer_load(Unit *u) {
 
         if (u->load_state == UNIT_LOADED) {
 
-                if (set_isempty(u->dependencies[UNIT_TRIGGERS])) {
-                        Unit *x;
-
-                        r = unit_load_related_unit(u, ".service", &x);
-                        if (r < 0)
-                                return r;
-
-                        r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, x, true);
-                        if (r < 0)
-                                return r;
-                }
+                r = timer_add_trigger_dependencies(t);
+                if (r < 0)
+                        return r;
 
                 r = timer_setup_persistent(t);
                 if (r < 0)
@@ -408,9 +417,9 @@ static void timer_enter_waiting(Timer *t, bool initial, bool time_change) {
                                 /* In a container we don't want to include the time the host
                                  * was already up when the container started, so count from
                                  * our own startup. */
-                                /* fall through */
+                                _fallthrough_;
                         case TIMER_STARTUP:
-                                base = UNIT(t)->manager->userspace_timestamp.monotonic;
+                                base = UNIT(t)->manager->timestamps[MANAGER_TIMESTAMP_USERSPACE].monotonic;
                                 break;
 
                         case TIMER_UNIT_ACTIVE:
index 546c60d..096d48b 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 46c2fa4..32ad660 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -345,8 +346,7 @@ static char* merge_unit_ids(const char* unit_log_field, char **pairs) {
         STRV_FOREACH_PAIR(unit_id, job_type, pairs) {
                 next = strlen(unit_log_field) + strlen(*unit_id);
                 if (!GREEDY_REALLOC(ans, alloc, size + next + 1)) {
-                        free(ans);
-                        return NULL;
+                        return mfree(ans);
                 }
 
                 sprintf(ans + size, "%s%s", unit_log_field, *unit_id);
@@ -361,6 +361,7 @@ static char* merge_unit_ids(const char* unit_log_field, char **pairs) {
 static int transaction_verify_order_one(Transaction *tr, Job *j, Job *from, unsigned generation, sd_bus_error *e) {
         Iterator i;
         Unit *u;
+        void *v;
         int r;
 
         assert(tr);
@@ -452,7 +453,7 @@ static int transaction_verify_order_one(Transaction *tr, Job *j, Job *from, unsi
 
         /* We assume that the dependencies are bidirectional, and
          * hence can ignore UNIT_AFTER */
-        SET_FOREACH(u, j->unit->dependencies[UNIT_BEFORE], i) {
+        HASHMAP_FOREACH_KEY(v, u, j->unit->dependencies[UNIT_BEFORE], i) {
                 Job *o;
 
                 /* Is there a job for this unit? */
@@ -860,14 +861,15 @@ static void transaction_unlink_job(Transaction *tr, Job *j, bool delete_dependen
 
 void transaction_add_propagate_reload_jobs(Transaction *tr, Unit *unit, Job *by, bool ignore_order, sd_bus_error *e) {
         Iterator i;
-        Unit *dep;
         JobType nt;
+        Unit *dep;
+        void *v;
         int r;
 
         assert(tr);
         assert(unit);
 
-        SET_FOREACH(dep, unit->dependencies[UNIT_PROPAGATES_RELOAD_TO], i) {
+        HASHMAP_FOREACH_KEY(v, dep, unit->dependencies[UNIT_PROPAGATES_RELOAD_TO], i) {
                 nt = job_type_collapse(JOB_TRY_RELOAD, dep);
                 if (nt == JOB_NOP)
                         continue;
@@ -892,11 +894,13 @@ int transaction_add_job_and_dependencies(
                 bool ignore_requirements,
                 bool ignore_order,
                 sd_bus_error *e) {
-        Job *ret;
+
+        bool is_new;
         Iterator i;
         Unit *dep;
+        Job *ret;
+        void *v;
         int r;
-        bool is_new;
 
         assert(tr);
         assert(type < _JOB_TYPE_MAX);
@@ -969,7 +973,7 @@ int transaction_add_job_and_dependencies(
 
                 /* Finally, recursively add in all dependencies. */
                 if (IN_SET(type, JOB_START, JOB_RESTART)) {
-                        SET_FOREACH(dep, ret->unit->dependencies[UNIT_REQUIRES], i) {
+                        HASHMAP_FOREACH_KEY(v, dep, ret->unit->dependencies[UNIT_REQUIRES], i) {
                                 r = transaction_add_job_and_dependencies(tr, JOB_START, dep, ret, true, false, false, ignore_order, e);
                                 if (r < 0) {
                                         if (r != -EBADR) /* job type not applicable */
@@ -979,7 +983,7 @@ int transaction_add_job_and_dependencies(
                                 }
                         }
 
-                        SET_FOREACH(dep, ret->unit->dependencies[UNIT_BINDS_TO], i) {
+                        HASHMAP_FOREACH_KEY(v, dep, ret->unit->dependencies[UNIT_BINDS_TO], i) {
                                 r = transaction_add_job_and_dependencies(tr, JOB_START, dep, ret, true, false, false, ignore_order, e);
                                 if (r < 0) {
                                         if (r != -EBADR) /* job type not applicable */
@@ -989,7 +993,7 @@ int transaction_add_job_and_dependencies(
                                 }
                         }
 
-                        SET_FOREACH(dep, ret->unit->dependencies[UNIT_WANTS], i) {
+                        HASHMAP_FOREACH_KEY(v, dep, ret->unit->dependencies[UNIT_WANTS], i) {
                                 r = transaction_add_job_and_dependencies(tr, JOB_START, dep, ret, false, false, false, ignore_order, e);
                                 if (r < 0) {
                                         /* unit masked, job type not applicable and unit not found are not considered as errors. */
@@ -1001,7 +1005,7 @@ int transaction_add_job_and_dependencies(
                                 }
                         }
 
-                        SET_FOREACH(dep, ret->unit->dependencies[UNIT_REQUISITE], i) {
+                        HASHMAP_FOREACH_KEY(v, dep, ret->unit->dependencies[UNIT_REQUISITE], i) {
                                 r = transaction_add_job_and_dependencies(tr, JOB_VERIFY_ACTIVE, dep, ret, true, false, false, ignore_order, e);
                                 if (r < 0) {
                                         if (r != -EBADR) /* job type not applicable */
@@ -1011,7 +1015,7 @@ int transaction_add_job_and_dependencies(
                                 }
                         }
 
-                        SET_FOREACH(dep, ret->unit->dependencies[UNIT_CONFLICTS], i) {
+                        HASHMAP_FOREACH_KEY(v, dep, ret->unit->dependencies[UNIT_CONFLICTS], i) {
                                 r = transaction_add_job_and_dependencies(tr, JOB_STOP, dep, ret, true, true, false, ignore_order, e);
                                 if (r < 0) {
                                         if (r != -EBADR) /* job type not applicable */
@@ -1021,7 +1025,7 @@ int transaction_add_job_and_dependencies(
                                 }
                         }
 
-                        SET_FOREACH(dep, ret->unit->dependencies[UNIT_CONFLICTED_BY], i) {
+                        HASHMAP_FOREACH_KEY(v, dep, ret->unit->dependencies[UNIT_CONFLICTED_BY], i) {
                                 r = transaction_add_job_and_dependencies(tr, JOB_STOP, dep, ret, false, false, false, ignore_order, e);
                                 if (r < 0) {
                                         log_unit_warning(dep,
@@ -1050,7 +1054,7 @@ int transaction_add_job_and_dependencies(
                         ptype = type == JOB_RESTART ? JOB_TRY_RESTART : type;
 
                         for (j = 0; j < ELEMENTSOF(propagate_deps); j++)
-                                SET_FOREACH(dep, ret->unit->dependencies[propagate_deps[j]], i) {
+                                HASHMAP_FOREACH_KEY(v, dep, ret->unit->dependencies[propagate_deps[j]], i) {
                                         JobType nt;
 
                                         nt = job_type_collapse(ptype, dep);
index ddfdbf9..0d57b27 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index f8c8cbc..985c6d8 100644 (file)
@@ -1,4 +1,5 @@
 #  -*- Mode: rpm-spec; indent-tabs-mode: nil -*- */
+#  SPDX-License-Identifier: LGPL-2.1+
 #
 #  This file is part of systemd.
 #
index 813d257..7f8ddb9 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -27,6 +28,7 @@
 #include "libudev.h"
 
 #include "alloc-util.h"
+#include "def.h"
 #include "escape.h"
 #include "fd-util.h"
 #include "fstab-util.h"
@@ -34,6 +36,7 @@
 #include "list.h"
 #include "mount-setup.h"
 #include "path-util.h"
+#include "signal-util.h"
 #include "string-util.h"
 #include "udev-util.h"
 #include "umount.h"
@@ -158,7 +161,7 @@ static int swap_list_get(MountPoint **head) {
 
         for (i = 2;; i++) {
                 MountPoint *swap;
-                char *dev = NULL, *d;
+                _cleanup_free_ char *dev = NULL, *d = NULL;
                 int k;
 
                 k = fscanf(proc_swaps,
@@ -174,27 +177,21 @@ static int swap_list_get(MountPoint **head) {
                                 break;
 
                         log_warning("Failed to parse /proc/swaps:%u.", i);
-                        free(dev);
                         continue;
                 }
 
-                if (endswith(dev, " (deleted)")) {
-                        free(dev);
+                if (endswith(dev, " (deleted)"))
                         continue;
-                }
 
                 r = cunescape(dev, UNESCAPE_RELAX, &d);
-                free(dev);
                 if (r < 0)
                         return r;
 
                 swap = new0(MountPoint, 1);
-                if (!swap) {
-                        free(d);
+                if (!swap)
                         return -ENOMEM;
-                }
 
-                swap->path = d;
+                free_and_replace(swap->path, d);
                 LIST_PREPEND(mount_point, *head, swap);
         }
 
@@ -381,13 +378,95 @@ static bool nonunmountable_path(const char *path) {
                 || path_startswith(path, "/run/initramfs");
 }
 
-static int mount_points_list_umount(MountPoint **head, bool *changed, bool log_error) {
-        MountPoint *m, *n;
+static int remount_with_timeout(MountPoint *m, char *options, int *n_failed) {
+        pid_t pid;
+        int r;
+
+        BLOCK_SIGNALS(SIGCHLD);
+
+        /* Due to the possiblity of a remount operation hanging, we
+         * fork a child process and set a timeout. If the timeout
+         * lapses, the assumption is that that particular remount
+         * failed. */
+        pid = fork();
+        if (pid < 0)
+                return log_error_errno(errno, "Failed to fork: %m");
+
+        if (pid == 0) {
+                log_info("Remounting '%s' read-only in with options '%s'.", m->path, options);
+
+                /* Start the mount operation here in the child */
+                r = mount(NULL, m->path, NULL, MS_REMOUNT|MS_RDONLY, options);
+                if (r < 0)
+                        log_error_errno(errno, "Failed to remount '%s' read-only: %m", m->path);
+
+                _exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
+        }
+
+        r = wait_for_terminate_with_timeout(pid, DEFAULT_TIMEOUT_USEC);
+        if (r == -ETIMEDOUT) {
+                log_error_errno(errno, "Remounting '%s' - timed out, issuing SIGKILL to PID "PID_FMT".", m->path, pid);
+                (void) kill(pid, SIGKILL);
+        } else if (r < 0)
+                log_error_errno(r, "Failed to wait for process: %m");
+
+        return r;
+}
+
+static int umount_with_timeout(MountPoint *m, bool *changed) {
+        pid_t pid;
+        int r;
+
+        BLOCK_SIGNALS(SIGCHLD);
+
+        /* Due to the possiblity of a umount operation hanging, we
+         * fork a child process and set a timeout. If the timeout
+         * lapses, the assumption is that that particular umount
+         * failed. */
+        pid = fork();
+        if (pid < 0)
+                return log_error_errno(errno, "Failed to fork: %m");
+
+        if (pid == 0) {
+                log_info("Unmounting '%s'.", m->path);
+
+                /* Start the mount operation here in the child Using MNT_FORCE
+                 * causes some filesystems (e.g. FUSE and NFS and other network
+                 * filesystems) to abort any pending requests and return -EIO
+                 * rather than blocking indefinitely. If the filesysten is
+                 * "busy", this may allow processes to die, thus making the
+                 * filesystem less busy so the unmount might succeed (rather
+                 * then return EBUSY).*/
+                r = umount2(m->path, MNT_FORCE);
+                if (r < 0)
+                        log_error_errno(errno, "Failed to unmount %s: %m", m->path);
+
+                _exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
+        }
+
+        r = wait_for_terminate_with_timeout(pid, DEFAULT_TIMEOUT_USEC);
+        if (r == -ETIMEDOUT) {
+                log_error_errno(errno, "Unmounting '%s' - timed out, issuing SIGKILL to PID "PID_FMT".", m->path, pid);
+                (void) kill(pid, SIGKILL);
+        } else if (r < 0)
+                log_error_errno(r, "Failed to wait for process: %m");
+
+        return r;
+}
+
+/* This includes remounting readonly, which changes the kernel mount options.
+ * Therefore the list passed to this function is invalidated, and should not be reused. */
+
+static int mount_points_list_umount(MountPoint **head, bool *changed) {
+        MountPoint *m;
         int n_failed = 0;
 
         assert(head);
 
-        LIST_FOREACH_SAFE(mount_point, m, n, *head) {
+        LIST_FOREACH(mount_point, m, *head) {
+                bool mount_is_readonly;
+
+                mount_is_readonly = fstab_test_yes_no_option(m->options, "ro\0rw\0");
 
                 /* If we are in a container, don't attempt to
                    read-only mount anything as that brings no real
@@ -395,9 +474,12 @@ static int mount_points_list_umount(MountPoint **head, bool *changed, bool log_e
                    the superblock here, not the bind mount.
                    If the filesystem is a network fs, also skip the
                    remount.  It brings no value (we cannot leave
-                   a "dirty fs") and could hang if the network is down.  */
+                   a "dirty fs") and could hang if the network is down.
+                   Note that umount2() is more careful and will not
+                   hang because of the network being down. */
                 if (detect_container() <= 0 &&
-                    !fstype_is_network(m->type)) {
+                    !fstype_is_network(m->type) &&
+                    !mount_is_readonly) {
                         _cleanup_free_ char *options = NULL;
                         /* MS_REMOUNT requires that the data parameter
                          * should be the same from the original mount
@@ -421,13 +503,15 @@ static int mount_points_list_umount(MountPoint **head, bool *changed, bool log_e
                          * explicitly remount the super block of that
                          * alias read-only we hence should be
                          * relatively safe regarding keeping dirty an fs
-                         * we cannot otherwise see. */
-                        log_info("Remounting '%s' read-only with options '%s'.", m->path, options);
-                        if (mount(NULL, m->path, NULL, MS_REMOUNT|MS_RDONLY, options) < 0) {
-                                if (log_error)
-                                        log_notice_errno(errno, "Failed to remount '%s' read-only: %m", m->path);
+                         * we cannot otherwise see.
+                         *
+                         * Since the remount can hang in the instance of
+                         * remote filesystems, we remount asynchronously
+                         * and skip the subsequent umount if it fails */
+                        if (remount_with_timeout(m, options, &n_failed) < 0) {
                                 if (nonunmountable_path(m->path))
                                         n_failed++;
+                                continue;
                         }
                 }
 
@@ -437,19 +521,12 @@ static int mount_points_list_umount(MountPoint **head, bool *changed, bool log_e
                 if (nonunmountable_path(m->path))
                         continue;
 
-                /* Trying to umount. We don't force here since we rely
-                 * on busy NFS and FUSE file systems to return EBUSY
-                 * until we closed everything on top of them. */
-                log_info("Unmounting %s.", m->path);
-                if (umount2(m->path, 0) == 0) {
+                /* Trying to umount */
+                if (umount_with_timeout(m, changed) < 0)
+                        n_failed++;
+                else {
                         if (changed)
                                 *changed = true;
-
-                        mount_point_free(head, m);
-                } else {
-                        if (log_error)
-                                log_warning_errno(errno, "Could not unmount %s: %m", m->path);
-                        n_failed++;
                 }
         }
 
@@ -550,9 +627,8 @@ static int dm_points_list_detach(MountPoint **head, bool *changed) {
         return n_failed;
 }
 
-int umount_all(bool *changed) {
+static int umount_all_once(bool *changed) {
         int r;
-        bool umount_changed;
         LIST_HEAD(MountPoint, mp_list_head);
 
         LIST_HEAD_INIT(mp_list_head);
@@ -560,22 +636,29 @@ int umount_all(bool *changed) {
         if (r < 0)
                 goto end;
 
-        /* retry umount, until nothing can be umounted anymore */
+        r = mount_points_list_umount(&mp_list_head, changed);
+
+  end:
+        mount_points_list_free(&mp_list_head);
+
+        return r;
+}
+
+int umount_all(bool *changed) {
+        bool umount_changed;
+        int r;
+
+        /* Retry umount, until nothing can be umounted anymore. Mounts are
+         * processed in order, newest first. The retries are needed when
+         * an old mount has been moved, to a path inside a newer mount. */
         do {
                 umount_changed = false;
 
-                mount_points_list_umount(&mp_list_head, &umount_changed, false);
+                r = umount_all_once(&umount_changed);
                 if (umount_changed)
                         *changed = true;
-
         } while (umount_changed);
 
-        /* umount one more time with logging enabled */
-        r = mount_points_list_umount(&mp_list_head, &umount_changed, true);
-
-  end:
-        mount_points_list_free(&mp_list_head);
-
         return r;
 }
 
index 4e2215a..7c029c3 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 0480ec6..e61e0d1 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -143,13 +144,13 @@ static int specifier_cgroup_slice(char specifier, void *data, void *userdata, ch
         return 0;
 }
 
-static int specifier_runtime(char specifier, void *data, void *userdata, char **ret) {
+static int specifier_special_directory(char specifier, void *data, void *userdata, char **ret) {
         Unit *u = userdata;
         char *n = NULL;
 
         assert(u);
 
-        n = strdup(u->manager->prefix[EXEC_DIRECTORY_RUNTIME]);
+        n = strdup(u->manager->prefix[PTR_TO_UINT(data)]);
         if (!n)
                 return -ENOMEM;
 
@@ -157,46 +158,6 @@ static int specifier_runtime(char specifier, void *data, void *userdata, char **
         return 0;
 }
 
-static int specifier_user_name(char specifier, void *data, void *userdata, char **ret) {
-        char *t;
-
-        /* If we are UID 0 (root), this will not result in NSS,
-         * otherwise it might. This is good, as we want to be able to
-         * run this in PID 1, where our user ID is 0, but where NSS
-         * lookups are not allowed. */
-
-        t = getusername_malloc();
-        if (!t)
-                return -ENOMEM;
-
-        *ret = t;
-        return 0;
-}
-
-static int specifier_user_id(char specifier, void *data, void *userdata, char **ret) {
-
-        if (asprintf(ret, UID_FMT, getuid()) < 0)
-                return -ENOMEM;
-
-        return 0;
-}
-
-static int specifier_user_home(char specifier, void *data, void *userdata, char **ret) {
-
-        /* On PID 1 (which runs as root) this will not result in NSS,
-         * which is good. See above */
-
-        return get_home_dir(ret);
-}
-
-static int specifier_user_shell(char specifier, void *data, void *userdata, char **ret) {
-
-        /* On PID 1 (which runs as root) this will not result in NSS,
-         * which is good. See above */
-
-        return get_shell(ret);
-}
-
 int unit_name_printf(Unit *u, const char* format, char **ret) {
 
         /*
@@ -244,10 +205,15 @@ int unit_full_printf(Unit *u, const char *format, char **ret) {
          * (which are likely not suitable for unescaped inclusion in unit names):
          *
          * %f: the unescaped instance if set, otherwise the id unescaped as path
+         *
          * %c: cgroup path of unit (deprecated)
          * %r: where units in this slice are placed in the cgroup tree (deprecated)
          * %R: the root of this systemd's instance tree (deprecated)
-         * %t: the runtime directory to place sockets in (e.g. "/run" or $XDG_RUNTIME_DIR)
+         *
+         * %t: the runtime directory root (e.g. /run or $XDG_RUNTIME_DIR)
+         * %S: the state directory root (e.g. /var/lib or $XDG_CONFIG_HOME)
+         * %C: the cache directory root (e.g. /var/cache or $XDG_CACHE_HOME)
+         * %L: the log directory root (e.g. /var/log or $XDG_CONFIG_HOME/log)
          *
          * %h: the homedir of the running user
          * %s: the shell of the running user
@@ -271,7 +237,10 @@ int unit_full_printf(Unit *u, const char *format, char **ret) {
                 { 'c', specifier_cgroup,              NULL },
                 { 'r', specifier_cgroup_slice,        NULL },
                 { 'R', specifier_cgroup_root,         NULL },
-                { 't', specifier_runtime,             NULL },
+                { 't', specifier_special_directory,   UINT_TO_PTR(EXEC_DIRECTORY_RUNTIME) },
+                { 'S', specifier_special_directory,   UINT_TO_PTR(EXEC_DIRECTORY_STATE) },
+                { 'C', specifier_special_directory,   UINT_TO_PTR(EXEC_DIRECTORY_CACHE) },
+                { 'L', specifier_special_directory,   UINT_TO_PTR(EXEC_DIRECTORY_LOGS) },
 
                 { 'U', specifier_user_id,             NULL },
                 { 'u', specifier_user_name,           NULL },
index 4fc8531..f1b620e 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 357306d..7af8425 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -38,6 +39,7 @@
 #include "fd-util.h"
 #include "fileio-label.h"
 #include "format-util.h"
+#include "fs-util.h"
 #include "id128-util.h"
 #include "io-util.h"
 #include "load-dropin.h"
 #include "process-util.h"
 #include "set.h"
 #include "signal-util.h"
+#include "sparse-endian.h"
 #include "special.h"
+#include "specifier.h"
 #include "stat-util.h"
 #include "stdio-util.h"
+#include "string-table.h"
 #include "string-util.h"
 #include "strv.h"
 #include "umask-util.h"
@@ -73,7 +78,7 @@ const UnitVTable * const unit_vtable[_UNIT_TYPE_MAX] = {
         [UNIT_TIMER] = &timer_vtable,
         [UNIT_PATH] = &path_vtable,
         [UNIT_SLICE] = &slice_vtable,
-        [UNIT_SCOPE] = &scope_vtable
+        [UNIT_SCOPE] = &scope_vtable,
 };
 
 static void maybe_warn_about_dependency(Unit *u, const char *other, UnitDependency dependency);
@@ -104,6 +109,7 @@ Unit *unit_new(Manager *m, size_t size) {
         u->ref_uid = UID_INVALID;
         u->ref_gid = GID_INVALID;
         u->cpu_usage_last = NSEC_INFINITY;
+        u->cgroup_bpf_state = UNIT_CGROUP_BPF_INVALIDATED;
 
         u->ip_accounting_ingress_map_fd = -1;
         u->ip_accounting_egress_map_fd = -1;
@@ -112,6 +118,8 @@ Unit *unit_new(Manager *m, size_t size) {
         u->ipv4_deny_map_fd = -1;
         u->ipv6_deny_map_fd = -1;
 
+        u->last_section_private = -1;
+
         RATELIMIT_INIT(u->start_limit, m->default_start_limit_interval, m->default_start_limit_burst);
         RATELIMIT_INIT(u->auto_stop_ratelimit, 10 * USEC_PER_SEC, 16);
 
@@ -329,9 +337,13 @@ int unit_set_description(Unit *u, const char *description) {
 
 bool unit_check_gc(Unit *u) {
         UnitActiveState state;
-        bool inactive;
+        int r;
+
         assert(u);
 
+        /* Checks whether the unit is ready to be unloaded for garbage collection. Returns true, when the unit shall
+         * stay around, false if there's no reason to keep it loaded. */
+
         if (u->job)
                 return true;
 
@@ -339,18 +351,11 @@ bool unit_check_gc(Unit *u) {
                 return true;
 
         state = unit_active_state(u);
-        inactive = state == UNIT_INACTIVE;
 
-        /* If the unit is inactive and failed and no job is queued for
-         * it, then release its runtime resources */
+        /* If the unit is inactive and failed and no job is queued for it, then release its runtime resources */
         if (UNIT_IS_INACTIVE_OR_FAILED(state) &&
             UNIT_VTABLE(u)->release_resources)
-                UNIT_VTABLE(u)->release_resources(u, inactive);
-
-        /* But we keep the unit object around for longer when it is
-         * referenced or configured to not be gc'ed */
-        if (!inactive)
-                return true;
+                UNIT_VTABLE(u)->release_resources(u);
 
         if (u->perpetual)
                 return true;
@@ -361,6 +366,36 @@ bool unit_check_gc(Unit *u) {
         if (sd_bus_track_count(u->bus_track) > 0)
                 return true;
 
+        /* But we keep the unit object around for longer when it is referenced or configured to not be gc'ed */
+        switch (u->collect_mode) {
+
+        case COLLECT_INACTIVE:
+                if (state != UNIT_INACTIVE)
+                        return true;
+
+                break;
+
+        case COLLECT_INACTIVE_OR_FAILED:
+                if (!IN_SET(state, UNIT_INACTIVE, UNIT_FAILED))
+                        return true;
+
+                break;
+
+        default:
+                assert_not_reached("Unknown garbage collection mode");
+        }
+
+        if (u->cgroup_path) {
+                /* If the unit has a cgroup, then check whether there's anything in it. If so, we should stay
+                 * around. Units with active processes should never be collected. */
+
+                r = cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path);
+                if (r < 0)
+                        log_unit_debug_errno(u, r, "Failed to determine whether cgroup %s is empty: %m", u->cgroup_path);
+                if (r <= 0)
+                        return true;
+        }
+
         if (UNIT_VTABLE(u)->check_gc)
                 if (UNIT_VTABLE(u)->check_gc(u))
                         return true;
@@ -421,25 +456,25 @@ void unit_add_to_dbus_queue(Unit *u) {
         u->in_dbus_queue = true;
 }
 
-static void bidi_set_free(Unit *u, Set *s) {
-        Iterator i;
+static void bidi_set_free(Unit *u, Hashmap *h) {
         Unit *other;
+        Iterator i;
+        void *v;
 
         assert(u);
 
-        /* Frees the set and makes sure we are dropped from the
-         * inverse pointers */
+        /* Frees the hashmap and makes sure we are dropped from the inverse pointers */
 
-        SET_FOREACH(other, s, i) {
+        HASHMAP_FOREACH_KEY(v, other, h, i) {
                 UnitDependency d;
 
                 for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++)
-                        set_remove(other->dependencies[d], u);
+                        hashmap_remove(other->dependencies[d], u);
 
                 unit_add_to_gc_queue(other);
         }
 
-        set_free(s);
+        hashmap_free(h);
 }
 
 static void unit_remove_transient(Unit *u) {
@@ -474,30 +509,37 @@ static void unit_remove_transient(Unit *u) {
 }
 
 static void unit_free_requires_mounts_for(Unit *u) {
-        char **j;
+        assert(u);
+
+        for (;;) {
+                _cleanup_free_ char *path;
 
-        STRV_FOREACH(j, u->requires_mounts_for) {
-                char s[strlen(*j) + 1];
+                path = hashmap_steal_first_key(u->requires_mounts_for);
+                if (!path)
+                        break;
+                else {
+                        char s[strlen(path) + 1];
 
-                PATH_FOREACH_PREFIX_MORE(s, *j) {
-                        char *y;
-                        Set *x;
+                        PATH_FOREACH_PREFIX_MORE(s, path) {
+                                char *y;
+                                Set *x;
 
-                        x = hashmap_get2(u->manager->units_requiring_mounts_for, s, (void**) &y);
-                        if (!x)
-                                continue;
+                                x = hashmap_get2(u->manager->units_requiring_mounts_for, s, (void**) &y);
+                                if (!x)
+                                        continue;
 
-                        set_remove(x, u);
+                                (void) set_remove(x, u);
 
-                        if (set_isempty(x)) {
-                                hashmap_remove(u->manager->units_requiring_mounts_for, y);
-                                free(y);
-                                set_free(x);
+                                if (set_isempty(x)) {
+                                        (void) hashmap_remove(u->manager->units_requiring_mounts_for, y);
+                                        free(y);
+                                        set_free(x);
+                                }
                         }
                 }
         }
 
-        u->requires_mounts_for = strv_free(u->requires_mounts_for);
+        u->requires_mounts_for = hashmap_free(u->requires_mounts_for);
 }
 
 static void unit_done(Unit *u) {
@@ -529,8 +571,7 @@ void unit_free(Unit *u) {
         if (!u)
                 return;
 
-        if (u->transient_file)
-                fclose(u->transient_file);
+        u->transient_file = safe_fclose(u->transient_file);
 
         if (!MANAGER_IS_RELOADING(u->manager))
                 unit_remove_transient(u);
@@ -590,6 +631,9 @@ void unit_free(Unit *u) {
 
         unit_release_cgroup(u);
 
+        if (!MANAGER_IS_RELOADING(u->manager))
+                unit_unlink_state_files(u);
+
         unit_unref_uid_gid(u, false);
 
         (void) manager_update_failed_units(u->manager, u, false);
@@ -651,20 +695,33 @@ const char* unit_sub_state_to_string(Unit *u) {
         return UNIT_VTABLE(u)->sub_state_to_string(u);
 }
 
-static int complete_move(Set **s, Set **other) {
-        int r;
+static int set_complete_move(Set **s, Set **other) {
+        assert(s);
+        assert(other);
+
+        if (!other)
+                return 0;
+
+        if (*s)
+                return set_move(*s, *other);
+        else {
+                *s = *other;
+                *other = NULL;
+        }
 
+        return 0;
+}
+
+static int hashmap_complete_move(Hashmap **s, Hashmap **other) {
         assert(s);
         assert(other);
 
         if (!*other)
                 return 0;
 
-        if (*s) {
-                r = set_move(*s, *other);
-                if (r < 0)
-                        return r;
-        } else {
+        if (*s)
+                return hashmap_move(*s, *other);
+        else {
                 *s = *other;
                 *other = NULL;
         }
@@ -680,7 +737,7 @@ static int merge_names(Unit *u, Unit *other) {
         assert(u);
         assert(other);
 
-        r = complete_move(&u->names, &other->names);
+        r = set_complete_move(&u->names, &other->names);
         if (r < 0)
                 return r;
 
@@ -710,48 +767,73 @@ static int reserve_dependencies(Unit *u, Unit *other, UnitDependency d) {
                 return 0;
 
         /* merge_dependencies() will skip a u-on-u dependency */
-        n_reserve = set_size(other->dependencies[d]) - !!set_get(other->dependencies[d], u);
+        n_reserve = hashmap_size(other->dependencies[d]) - !!hashmap_get(other->dependencies[d], u);
 
-        return set_reserve(u->dependencies[d], n_reserve);
+        return hashmap_reserve(u->dependencies[d], n_reserve);
 }
 
 static void merge_dependencies(Unit *u, Unit *other, const char *other_id, UnitDependency d) {
         Iterator i;
         Unit *back;
+        void *v;
         int r;
 
+        /* Merges all dependencies of type 'd' of the unit 'other' into the deps of the unit 'u' */
+
         assert(u);
         assert(other);
         assert(d < _UNIT_DEPENDENCY_MAX);
 
-        /* Fix backwards pointers */
-        SET_FOREACH(back, other->dependencies[d], i) {
+        /* Fix backwards pointers. Let's iterate through all dependendent units of the other unit. */
+        HASHMAP_FOREACH_KEY(v, back, other->dependencies[d], i) {
                 UnitDependency k;
 
+                /* Let's now iterate through the dependencies of that dependencies of the other units, looking for
+                 * pointers back, and let's fix them up, to instead point to 'u'. */
+
                 for (k = 0; k < _UNIT_DEPENDENCY_MAX; k++) {
-                        /* Do not add dependencies between u and itself */
                         if (back == u) {
-                                if (set_remove(back->dependencies[k], other))
+                                /* Do not add dependencies between u and itself. */
+                                if (hashmap_remove(back->dependencies[k], other))
                                         maybe_warn_about_dependency(u, other_id, k);
                         } else {
-                                r = set_remove_and_put(back->dependencies[k], other, u);
-                                if (r == -EEXIST)
-                                        set_remove(back->dependencies[k], other);
-                                else
-                                        assert(r >= 0 || r == -ENOENT);
+                                UnitDependencyInfo di_u, di_other, di_merged;
+
+                                /* Let's drop this dependency between "back" and "other", and let's create it between
+                                 * "back" and "u" instead. Let's merge the bit masks of the dependency we are moving,
+                                 * and any such dependency which might already exist */
+
+                                di_other.data = hashmap_get(back->dependencies[k], other);
+                                if (!di_other.data)
+                                        continue; /* dependency isn't set, let's try the next one */
+
+                                di_u.data = hashmap_get(back->dependencies[k], u);
+
+                                di_merged = (UnitDependencyInfo) {
+                                        .origin_mask = di_u.origin_mask | di_other.origin_mask,
+                                        .destination_mask = di_u.destination_mask | di_other.destination_mask,
+                                };
+
+                                r = hashmap_remove_and_replace(back->dependencies[k], other, u, di_merged.data);
+                                if (r < 0)
+                                        log_warning_errno(r, "Failed to remove/replace: back=%s other=%s u=%s: %m", back->id, other_id, u->id);
+                                assert(r >= 0);
+
+                                /* assert_se(hashmap_remove_and_replace(back->dependencies[k], other, u, di_merged.data) >= 0); */
                         }
                 }
+
         }
 
         /* Also do not move dependencies on u to itself */
-        back = set_remove(other->dependencies[d], u);
+        back = hashmap_remove(other->dependencies[d], u);
         if (back)
                 maybe_warn_about_dependency(u, other_id, d);
 
         /* The move cannot fail. The caller must have performed a reservation. */
-        assert_se(complete_move(&u->dependencies[d], &other->dependencies[d]) == 0);
+        assert_se(hashmap_complete_move(&u->dependencies[d], &other->dependencies[d]) == 0);
 
-        other->dependencies[d] = set_free(other->dependencies[d]);
+        other->dependencies[d] = hashmap_free(other->dependencies[d]);
 }
 
 int unit_merge(Unit *u, Unit *other) {
@@ -876,19 +958,19 @@ int unit_add_exec_dependencies(Unit *u, ExecContext *c) {
         assert(c);
 
         if (c->working_directory) {
-                r = unit_require_mounts_for(u, c->working_directory);
+                r = unit_require_mounts_for(u, c->working_directory, UNIT_DEPENDENCY_FILE);
                 if (r < 0)
                         return r;
         }
 
         if (c->root_directory) {
-                r = unit_require_mounts_for(u, c->root_directory);
+                r = unit_require_mounts_for(u, c->root_directory, UNIT_DEPENDENCY_FILE);
                 if (r < 0)
                         return r;
         }
 
         if (c->root_image) {
-                r = unit_require_mounts_for(u, c->root_image);
+                r = unit_require_mounts_for(u, c->root_image, UNIT_DEPENDENCY_FILE);
                 if (r < 0)
                         return r;
         }
@@ -904,7 +986,7 @@ int unit_add_exec_dependencies(Unit *u, ExecContext *c) {
                         if (!p)
                                 return -ENOMEM;
 
-                        r = unit_require_mounts_for(u, p);
+                        r = unit_require_mounts_for(u, p, UNIT_DEPENDENCY_FILE);
                         if (r < 0)
                                 return r;
                 }
@@ -917,12 +999,12 @@ int unit_add_exec_dependencies(Unit *u, ExecContext *c) {
                 const char *p;
 
                 FOREACH_STRING(p, "/tmp", "/var/tmp") {
-                        r = unit_require_mounts_for(u, p);
+                        r = unit_require_mounts_for(u, p, UNIT_DEPENDENCY_FILE);
                         if (r < 0)
                                 return r;
                 }
 
-                r = unit_add_dependency_by_name(u, UNIT_AFTER, SPECIAL_TMPFILES_SETUP_SERVICE, NULL, true);
+                r = unit_add_dependency_by_name(u, UNIT_AFTER, SPECIAL_TMPFILES_SETUP_SERVICE, NULL, true, UNIT_DEPENDENCY_FILE);
                 if (r < 0)
                         return r;
         }
@@ -940,7 +1022,7 @@ int unit_add_exec_dependencies(Unit *u, ExecContext *c) {
         /* If syslog or kernel logging is requested, make sure our own
          * logging daemon is run first. */
 
-        r = unit_add_dependency_by_name(u, UNIT_AFTER, SPECIAL_JOURNALD_SOCKET, NULL, true);
+        r = unit_add_dependency_by_name(u, UNIT_AFTER, SPECIAL_JOURNALD_SOCKET, NULL, true, UNIT_DEPENDENCY_FILE);
         if (r < 0)
                 return r;
 
@@ -956,6 +1038,48 @@ const char *unit_description(Unit *u) {
         return strna(u->id);
 }
 
+static void print_unit_dependency_mask(FILE *f, const char *kind, UnitDependencyMask mask, bool *space) {
+        const struct {
+                UnitDependencyMask mask;
+                const char *name;
+        } table[] = {
+                { UNIT_DEPENDENCY_FILE,               "file"               },
+                { UNIT_DEPENDENCY_IMPLICIT,           "implicit"           },
+                { UNIT_DEPENDENCY_DEFAULT,            "default"            },
+                { UNIT_DEPENDENCY_UDEV,               "udev"               },
+                { UNIT_DEPENDENCY_PATH,               "path"               },
+                { UNIT_DEPENDENCY_MOUNTINFO_IMPLICIT, "mountinfo-implicit" },
+                { UNIT_DEPENDENCY_MOUNTINFO_DEFAULT,  "mountinfo-default"  },
+                { UNIT_DEPENDENCY_PROC_SWAP,          "proc-swap"          },
+        };
+        size_t i;
+
+        assert(f);
+        assert(kind);
+        assert(space);
+
+        for (i = 0; i < ELEMENTSOF(table); i++) {
+
+                if (mask == 0)
+                        break;
+
+                if ((mask & table[i].mask) == table[i].mask) {
+                        if (*space)
+                                fputc(' ', f);
+                        else
+                                *space = true;
+
+                        fputs(kind, f);
+                        fputs("-", f);
+                        fputs(table[i].name, f);
+
+                        mask &= ~table[i].mask;
+                }
+        }
+
+        assert(mask == 0);
+}
+
 void unit_dump(Unit *u, FILE *f, const char *prefix) {
         char *t, **j;
         UnitDependency d;
@@ -970,8 +1094,9 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) {
                 timespan[FORMAT_TIMESPAN_MAX];
         Unit *following;
         _cleanup_set_free_ Set *following_set = NULL;
-        int r;
         const char *n;
+        CGroupMask m;
+        int r;
 
         assert(u);
         assert(u->type >= 0);
@@ -994,6 +1119,7 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) {
                 "%s\tNeed Daemon Reload: %s\n"
                 "%s\tTransient: %s\n"
                 "%s\tPerpetual: %s\n"
+                "%s\tGarbage Collection Mode: %s\n"
                 "%s\tSlice: %s\n"
                 "%s\tCGroup: %s\n"
                 "%s\tCGroup realized: %s\n",
@@ -1011,6 +1137,7 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) {
                 prefix, yes_no(unit_need_daemon_reload(u)),
                 prefix, yes_no(u->transient),
                 prefix, yes_no(u->perpetual),
+                prefix, collect_mode_to_string(u->collect_mode),
                 prefix, strna(unit_slice_name(u)),
                 prefix, strna(u->cgroup_path),
                 prefix, yes_no(u->cgroup_realized));
@@ -1018,11 +1145,23 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) {
         if (u->cgroup_realized_mask != 0) {
                 _cleanup_free_ char *s = NULL;
                 (void) cg_mask_to_string(u->cgroup_realized_mask, &s);
-                fprintf(f, "%s\tCGroup mask: %s\n", prefix, strnull(s));
+                fprintf(f, "%s\tCGroup realized mask: %s\n", prefix, strnull(s));
+        }
+        if (u->cgroup_enabled_mask != 0) {
+                _cleanup_free_ char *s = NULL;
+                (void) cg_mask_to_string(u->cgroup_enabled_mask, &s);
+                fprintf(f, "%s\tCGroup enabled mask: %s\n", prefix, strnull(s));
+        }
+        m = unit_get_own_mask(u);
+        if (m != 0) {
+                _cleanup_free_ char *s = NULL;
+                (void) cg_mask_to_string(m, &s);
+                fprintf(f, "%s\tCGroup own mask: %s\n", prefix, strnull(s));
         }
-        if (u->cgroup_members_mask != 0) {
+        m = unit_get_members_mask(u);
+        if (m != 0) {
                 _cleanup_free_ char *s = NULL;
-                (void) cg_mask_to_string(u->cgroup_members_mask, &s);
+                (void) cg_mask_to_string(m, &s);
                 fprintf(f, "%s\tCGroup members mask: %s\n", prefix, strnull(s));
         }
 
@@ -1057,6 +1196,11 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) {
         STRV_FOREACH(j, u->dropin_paths)
                 fprintf(f, "%s\tDropIn Path: %s\n", prefix, *j);
 
+        if (u->failure_action != EMERGENCY_ACTION_NONE)
+                fprintf(f, "%s\tFailure Action: %s\n", prefix, emergency_action_to_string(u->failure_action));
+        if (u->success_action != EMERGENCY_ACTION_NONE)
+                fprintf(f, "%s\tSuccess Action: %s\n", prefix, emergency_action_to_string(u->success_action));
+
         if (u->job_timeout != USEC_INFINITY)
                 fprintf(f, "%s\tJob Timeout: %s\n", prefix, format_timespan(timespan, sizeof(timespan), u->job_timeout, 0));
 
@@ -1084,20 +1228,35 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) {
                         prefix, yes_no(u->assert_result));
 
         for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++) {
+                UnitDependencyInfo di;
                 Unit *other;
 
-                SET_FOREACH(other, u->dependencies[d], i)
-                        fprintf(f, "%s\t%s: %s\n", prefix, unit_dependency_to_string(d), other->id);
+                HASHMAP_FOREACH_KEY(di.data, other, u->dependencies[d], i) {
+                        bool space = false;
+
+                        fprintf(f, "%s\t%s: %s (", prefix, unit_dependency_to_string(d), other->id);
+
+                        print_unit_dependency_mask(f, "origin", di.origin_mask, &space);
+                        print_unit_dependency_mask(f, "destination", di.destination_mask, &space);
+
+                        fputs(")\n", f);
+                }
         }
 
-        if (!strv_isempty(u->requires_mounts_for)) {
-                fprintf(f,
-                        "%s\tRequiresMountsFor:", prefix);
+        if (!hashmap_isempty(u->requires_mounts_for)) {
+                UnitDependencyInfo di;
+                const char *path;
+
+                HASHMAP_FOREACH_KEY(di.data, path, u->requires_mounts_for, i) {
+                        bool space = false;
 
-                STRV_FOREACH(j, u->requires_mounts_for)
-                        fprintf(f, " %s", *j);
+                        fprintf(f, "%s\tRequiresMountsFor: %s (", prefix, path);
 
-                fputs("\n", f);
+                        print_unit_dependency_mask(f, "origin", di.origin_mask, &space);
+                        print_unit_dependency_mask(f, "destination", di.destination_mask, &space);
+
+                        fputs(")\n", f);
+                }
         }
 
         if (u->load_state == UNIT_LOADED) {
@@ -1198,10 +1357,10 @@ int unit_add_default_target_dependency(Unit *u, Unit *target) {
                 return 0;
 
         /* Don't create loops */
-        if (set_get(target->dependencies[UNIT_BEFORE], u))
+        if (hashmap_get(target->dependencies[UNIT_BEFORE], u))
                 return 0;
 
-        return unit_add_dependency(target, UNIT_AFTER, u, true);
+        return unit_add_dependency(target, UNIT_AFTER, u, true, UNIT_DEPENDENCY_DEFAULT);
 }
 
 static int unit_add_target_dependencies(Unit *u) {
@@ -1213,48 +1372,59 @@ static int unit_add_target_dependencies(Unit *u) {
                 UNIT_BOUND_BY
         };
 
-        Unit *target;
-        Iterator i;
         unsigned k;
         int r = 0;
 
         assert(u);
 
-        for (k = 0; k < ELEMENTSOF(deps); k++)
-                SET_FOREACH(target, u->dependencies[deps[k]], i) {
+        for (k = 0; k < ELEMENTSOF(deps); k++) {
+                Unit *target;
+                Iterator i;
+                void *v;
+
+                HASHMAP_FOREACH_KEY(v, target, u->dependencies[deps[k]], i) {
                         r = unit_add_default_target_dependency(u, target);
                         if (r < 0)
                                 return r;
                 }
+        }
 
         return r;
 }
 
 static int unit_add_slice_dependencies(Unit *u) {
+        UnitDependencyMask mask;
         assert(u);
 
         if (!UNIT_HAS_CGROUP_CONTEXT(u))
                 return 0;
 
+        /* Slice units are implicitly ordered against their parent slices (as this relationship is encoded in the
+           name), while all other units are ordered based on configuration (as in their case Slice= configures the
+           relationship). */
+        mask = u->type == UNIT_SLICE ? UNIT_DEPENDENCY_IMPLICIT : UNIT_DEPENDENCY_FILE;
+
         if (UNIT_ISSET(u->slice))
-                return unit_add_two_dependencies(u, UNIT_AFTER, UNIT_REQUIRES, UNIT_DEREF(u->slice), true);
+                return unit_add_two_dependencies(u, UNIT_AFTER, UNIT_REQUIRES, UNIT_DEREF(u->slice), true, mask);
 
         if (unit_has_name(u, SPECIAL_ROOT_SLICE))
                 return 0;
 
-        return unit_add_two_dependencies_by_name(u, UNIT_AFTER, UNIT_REQUIRES, SPECIAL_ROOT_SLICE, NULL, true);
+        return unit_add_two_dependencies_by_name(u, UNIT_AFTER, UNIT_REQUIRES, SPECIAL_ROOT_SLICE, NULL, true, mask);
 }
 
 static int unit_add_mount_dependencies(Unit *u) {
-        char **i;
+        UnitDependencyInfo di;
+        const char *path;
+        Iterator i;
         int r;
 
         assert(u);
 
-        STRV_FOREACH(i, u->requires_mounts_for) {
-                char prefix[strlen(*i) + 1];
+        HASHMAP_FOREACH_KEY(di.data, path, u->requires_mounts_for, i) {
+                char prefix[strlen(path) + 1];
 
-                PATH_FOREACH_PREFIX_MORE(prefix, *i) {
+                PATH_FOREACH_PREFIX_MORE(prefix, path) {
                         _cleanup_free_ char *p = NULL;
                         Unit *m;
 
@@ -1278,12 +1448,12 @@ static int unit_add_mount_dependencies(Unit *u) {
                         if (m->load_state != UNIT_LOADED)
                                 continue;
 
-                        r = unit_add_dependency(u, UNIT_AFTER, m, true);
+                        r = unit_add_dependency(u, UNIT_AFTER, m, true, di.origin_mask);
                         if (r < 0)
                                 return r;
 
                         if (m->fragment_path) {
-                                r = unit_add_dependency(u, UNIT_REQUIRES, m, true);
+                                r = unit_add_dependency(u, UNIT_REQUIRES, m, true, di.origin_mask);
                                 if (r < 0)
                                         return r;
                         }
@@ -1334,9 +1504,7 @@ int unit_load(Unit *u) {
                 if (r < 0)
                         goto fail;
 
-                fclose(u->transient_file);
-                u->transient_file = NULL;
-
+                u->transient_file = safe_fclose(u->transient_file);
                 u->fragment_mtime = now(CLOCK_REALTIME);
         }
 
@@ -1369,7 +1537,7 @@ int unit_load(Unit *u) {
                 if (r < 0)
                         goto fail;
 
-                if (u->on_failure_job_mode == JOB_ISOLATE && set_size(u->dependencies[UNIT_ON_FAILURE]) > 1) {
+                if (u->on_failure_job_mode == JOB_ISOLATE && hashmap_size(u->dependencies[UNIT_ON_FAILURE]) > 1) {
                         log_unit_error(u, "More than one OnFailure= dependencies specified but OnFailureJobMode=isolate set. Refusing.");
                         r = -EINVAL;
                         goto fail;
@@ -1525,7 +1693,7 @@ static void unit_status_log_starting_stopping_reloading(Unit *u, JobType t) {
         format = unit_get_status_message_format(u, t);
 
         DISABLE_WARNING_FORMAT_NONLITERAL;
-        snprintf(buf, sizeof buf, format, unit_description(u));
+        xsprintf(buf, format, unit_description(u));
         REENABLE_WARNING;
 
         mid = t == JOB_START ? "MESSAGE_ID=" SD_MESSAGE_UNIT_STARTING_STR :
@@ -1584,6 +1752,7 @@ bool unit_shall_confirm_spawn(Unit *u) {
 static bool unit_verify_deps(Unit *u) {
         Unit *other;
         Iterator j;
+        void *v;
 
         assert(u);
 
@@ -1592,9 +1761,9 @@ static bool unit_verify_deps(Unit *u) {
          * processing, but do not have any effect afterwards. We don't check BindsTo= dependencies that are not used in
          * conjunction with After= as for them any such check would make things entirely racy. */
 
-        SET_FOREACH(other, u->dependencies[UNIT_BINDS_TO], j) {
+        HASHMAP_FOREACH_KEY(v, other, u->dependencies[UNIT_BINDS_TO], j) {
 
-                if (!set_contains(u->dependencies[UNIT_AFTER], other))
+                if (!hashmap_contains(u->dependencies[UNIT_AFTER], other))
                         continue;
 
                 if (!UNIT_IS_ACTIVE_OR_RELOADING(unit_active_state(other))) {
@@ -1797,7 +1966,7 @@ bool unit_can_reload(Unit *u) {
         if (UNIT_VTABLE(u)->can_reload)
                 return UNIT_VTABLE(u)->can_reload(u);
 
-        if (!set_isempty(u->dependencies[UNIT_PROPAGATES_RELOAD_TO]))
+        if (!hashmap_isempty(u->dependencies[UNIT_PROPAGATES_RELOAD_TO]))
                 return true;
 
         return UNIT_VTABLE(u)->reload;
@@ -1814,8 +1983,6 @@ static void unit_check_unneeded(Unit *u) {
                 UNIT_BOUND_BY,
         };
 
-        Unit *other;
-        Iterator i;
         unsigned j;
         int r;
 
@@ -1830,10 +1997,15 @@ static void unit_check_unneeded(Unit *u) {
         if (!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)))
                 return;
 
-        for (j = 0; j < ELEMENTSOF(needed_dependencies); j++)
-                SET_FOREACH(other, u->dependencies[needed_dependencies[j]], i)
-                        if (unit_active_or_pending(other))
+        for (j = 0; j < ELEMENTSOF(needed_dependencies); j++) {
+                Unit *other;
+                Iterator i;
+                void *v;
+
+                HASHMAP_FOREACH_KEY(v, other, u->dependencies[needed_dependencies[j]], i)
+                        if (unit_active_or_pending(other) || unit_will_restart(other))
                                 return;
+        }
 
         /* If stopping a unit fails continuously we might enter a stop
          * loop here, hence stop acting on the service being
@@ -1856,6 +2028,7 @@ static void unit_check_binds_to(Unit *u) {
         bool stop = false;
         Unit *other;
         Iterator i;
+        void *v;
         int r;
 
         assert(u);
@@ -1866,7 +2039,7 @@ static void unit_check_binds_to(Unit *u) {
         if (unit_active_state(u) != UNIT_ACTIVE)
                 return;
 
-        SET_FOREACH(other, u->dependencies[UNIT_BINDS_TO], i) {
+        HASHMAP_FOREACH_KEY(v, other, u->dependencies[UNIT_BINDS_TO], i) {
                 if (other->job)
                         continue;
 
@@ -1904,65 +2077,68 @@ static void unit_check_binds_to(Unit *u) {
 static void retroactively_start_dependencies(Unit *u) {
         Iterator i;
         Unit *other;
+        void *v;
 
         assert(u);
         assert(UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)));
 
-        SET_FOREACH(other, u->dependencies[UNIT_REQUIRES], i)
-                if (!set_get(u->dependencies[UNIT_AFTER], other) &&
+        HASHMAP_FOREACH_KEY(v, other, u->dependencies[UNIT_REQUIRES], i)
+                if (!hashmap_get(u->dependencies[UNIT_AFTER], other) &&
                     !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
                         manager_add_job(u->manager, JOB_START, other, JOB_REPLACE, NULL, NULL);
 
-        SET_FOREACH(other, u->dependencies[UNIT_BINDS_TO], i)
-                if (!set_get(u->dependencies[UNIT_AFTER], other) &&
+        HASHMAP_FOREACH_KEY(v, other, u->dependencies[UNIT_BINDS_TO], i)
+                if (!hashmap_get(u->dependencies[UNIT_AFTER], other) &&
                     !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
                         manager_add_job(u->manager, JOB_START, other, JOB_REPLACE, NULL, NULL);
 
-        SET_FOREACH(other, u->dependencies[UNIT_WANTS], i)
-                if (!set_get(u->dependencies[UNIT_AFTER], other) &&
+        HASHMAP_FOREACH_KEY(v, other, u->dependencies[UNIT_WANTS], i)
+                if (!hashmap_get(u->dependencies[UNIT_AFTER], other) &&
                     !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
                         manager_add_job(u->manager, JOB_START, other, JOB_FAIL, NULL, NULL);
 
-        SET_FOREACH(other, u->dependencies[UNIT_CONFLICTS], i)
+        HASHMAP_FOREACH_KEY(v, other, u->dependencies[UNIT_CONFLICTS], i)
                 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
                         manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, NULL, NULL);
 
-        SET_FOREACH(other, u->dependencies[UNIT_CONFLICTED_BY], i)
+        HASHMAP_FOREACH_KEY(v, other, u->dependencies[UNIT_CONFLICTED_BY], i)
                 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
                         manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, NULL, NULL);
 }
 
 static void retroactively_stop_dependencies(Unit *u) {
-        Iterator i;
         Unit *other;
+        Iterator i;
+        void *v;
 
         assert(u);
         assert(UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u)));
 
         /* Pull down units which are bound to us recursively if enabled */
-        SET_FOREACH(other, u->dependencies[UNIT_BOUND_BY], i)
+        HASHMAP_FOREACH_KEY(v, other, u->dependencies[UNIT_BOUND_BY], i)
                 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
                         manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, NULL, NULL);
 }
 
 static void check_unneeded_dependencies(Unit *u) {
-        Iterator i;
         Unit *other;
+        Iterator i;
+        void *v;
 
         assert(u);
         assert(UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u)));
 
         /* Garbage collect services that might not be needed anymore, if enabled */
-        SET_FOREACH(other, u->dependencies[UNIT_REQUIRES], i)
+        HASHMAP_FOREACH_KEY(v, other, u->dependencies[UNIT_REQUIRES], i)
                 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
                         unit_check_unneeded(other);
-        SET_FOREACH(other, u->dependencies[UNIT_WANTS], i)
+        HASHMAP_FOREACH_KEY(v, other, u->dependencies[UNIT_WANTS], i)
                 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
                         unit_check_unneeded(other);
-        SET_FOREACH(other, u->dependencies[UNIT_REQUISITE], i)
+        HASHMAP_FOREACH_KEY(v, other, u->dependencies[UNIT_REQUISITE], i)
                 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
                         unit_check_unneeded(other);
-        SET_FOREACH(other, u->dependencies[UNIT_BINDS_TO], i)
+        HASHMAP_FOREACH_KEY(v, other, u->dependencies[UNIT_BINDS_TO], i)
                 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
                         unit_check_unneeded(other);
 }
@@ -1970,15 +2146,16 @@ static void check_unneeded_dependencies(Unit *u) {
 void unit_start_on_failure(Unit *u) {
         Unit *other;
         Iterator i;
+        void *v;
 
         assert(u);
 
-        if (set_size(u->dependencies[UNIT_ON_FAILURE]) <= 0)
+        if (hashmap_size(u->dependencies[UNIT_ON_FAILURE]) <= 0)
                 return;
 
         log_unit_info(u, "Triggering OnFailure= dependencies.");
 
-        SET_FOREACH(other, u->dependencies[UNIT_ON_FAILURE], i) {
+        HASHMAP_FOREACH_KEY(v, other, u->dependencies[UNIT_ON_FAILURE], i) {
                 int r;
 
                 r = manager_add_job(u->manager, JOB_START, other, u->on_failure_job_mode, NULL, NULL);
@@ -1990,10 +2167,11 @@ void unit_start_on_failure(Unit *u) {
 void unit_trigger_notify(Unit *u) {
         Unit *other;
         Iterator i;
+        void *v;
 
         assert(u);
 
-        SET_FOREACH(other, u->dependencies[UNIT_TRIGGERED_BY], i)
+        HASHMAP_FOREACH_KEY(v, other, u->dependencies[UNIT_TRIGGERED_BY], i)
                 if (UNIT_VTABLE(other)->trigger_notify)
                         UNIT_VTABLE(other)->trigger_notify(other, u);
 }
@@ -2160,9 +2338,11 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_su
         /* Keep track of failed units */
         (void) manager_update_failed_units(u->manager, u, ns == UNIT_FAILED);
 
-        /* Make sure the cgroup is always removed when we become inactive */
-        if (UNIT_IS_INACTIVE_OR_FAILED(ns))
+        /* Make sure the cgroup and state files are always removed when we become inactive */
+        if (UNIT_IS_INACTIVE_OR_FAILED(ns)) {
                 unit_prune_cgroup(u);
+                unit_unlink_state_files(u);
+        }
 
         /* Note that this doesn't apply to RemainAfterExit services exiting
          * successfully, since there's no change of state in that case. Which is
@@ -2341,6 +2521,11 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_su
                  * units go directly from starting to inactive,
                  * without ever entering started.) */
                 unit_check_binds_to(u);
+
+                if (os != UNIT_FAILED && ns == UNIT_FAILED)
+                        (void) emergency_action(u->manager, u->failure_action, u->reboot_arg, "unit failed");
+                else if (!UNIT_IS_INACTIVE_OR_FAILED(os) && ns == UNIT_INACTIVE)
+                        (void) emergency_action(u->manager, u->success_action, u->reboot_arg, "unit succeeded");
         }
 
         unit_add_to_dbus_queue(u);
@@ -2465,7 +2650,59 @@ static void maybe_warn_about_dependency(Unit *u, const char *other, UnitDependen
                 log_unit_warning(u, "Dependency %s=%s dropped, merged into %s", unit_dependency_to_string(dependency), strna(other), u->id);
 }
 
-int unit_add_dependency(Unit *u, UnitDependency d, Unit *other, bool add_reference) {
+static int unit_add_dependency_hashmap(
+                Hashmap **h,
+                Unit *other,
+                UnitDependencyMask origin_mask,
+                UnitDependencyMask destination_mask) {
+
+        UnitDependencyInfo info;
+        int r;
+
+        assert(h);
+        assert(other);
+        assert(origin_mask < _UNIT_DEPENDENCY_MASK_FULL);
+        assert(destination_mask < _UNIT_DEPENDENCY_MASK_FULL);
+        assert(origin_mask > 0 || destination_mask > 0);
+
+        r = hashmap_ensure_allocated(h, NULL);
+        if (r < 0)
+                return r;
+
+        assert_cc(sizeof(void*) == sizeof(info));
+
+        info.data = hashmap_get(*h, other);
+        if (info.data) {
+                /* Entry already exists. Add in our mask. */
+
+                if ((info.origin_mask & origin_mask) == info.origin_mask &&
+                    (info.destination_mask & destination_mask) == info.destination_mask)
+                        return 0; /* NOP */
+
+                info.origin_mask |= origin_mask;
+                info.destination_mask |= destination_mask;
+
+                r = hashmap_update(*h, other, info.data);
+        } else {
+                info = (UnitDependencyInfo) {
+                        .origin_mask = origin_mask,
+                        .destination_mask = destination_mask,
+                };
+
+                r = hashmap_put(*h, other, info.data);
+        }
+        if (r < 0)
+                return r;
+
+        return 1;
+}
+
+int unit_add_dependency(
+                Unit *u,
+                UnitDependency d,
+                Unit *other,
+                bool add_reference,
+                UnitDependencyMask mask) {
 
         static const UnitDependency inverse_table[_UNIT_DEPENDENCY_MAX] = {
                 [UNIT_REQUIRES] = UNIT_REQUIRED_BY,
@@ -2491,8 +2728,8 @@ int unit_add_dependency(Unit *u, UnitDependency d, Unit *other, bool add_referen
                 [UNIT_RELOAD_PROPAGATED_FROM] = UNIT_PROPAGATES_RELOAD_TO,
                 [UNIT_JOINS_NAMESPACE_OF] = UNIT_JOINS_NAMESPACE_OF,
         };
-        int r, q = 0, v = 0, w = 0;
-        Unit *orig_u = u, *orig_other = other;
+        Unit *original_u = u, *original_other = other;
+        int r;
 
         assert(u);
         assert(d >= 0 && d < _UNIT_DEPENDENCY_MAX);
@@ -2504,85 +2741,50 @@ int unit_add_dependency(Unit *u, UnitDependency d, Unit *other, bool add_referen
         /* We won't allow dependencies on ourselves. We will not
          * consider them an error however. */
         if (u == other) {
-                maybe_warn_about_dependency(orig_u, orig_other->id, d);
+                maybe_warn_about_dependency(original_u, original_other->id, d);
                 return 0;
         }
 
-        if (d == UNIT_BEFORE && other->type == UNIT_DEVICE) {
+        if ((d == UNIT_BEFORE && other->type == UNIT_DEVICE) ||
+            (d == UNIT_AFTER && u->type == UNIT_DEVICE)) {
                 log_unit_warning(u, "Dependency Before=%s ignored (.device units cannot be delayed)", other->id);
                 return 0;
         }
 
-        r = set_ensure_allocated(&u->dependencies[d], NULL);
+        r = unit_add_dependency_hashmap(u->dependencies + d, other, mask, 0);
         if (r < 0)
                 return r;
 
-        if (inverse_table[d] != _UNIT_DEPENDENCY_INVALID) {
-                r = set_ensure_allocated(&other->dependencies[inverse_table[d]], NULL);
+        if (inverse_table[d] != _UNIT_DEPENDENCY_INVALID && inverse_table[d] != d) {
+                r = unit_add_dependency_hashmap(other->dependencies + inverse_table[d], u, 0, mask);
                 if (r < 0)
                         return r;
         }
 
         if (add_reference) {
-                r = set_ensure_allocated(&u->dependencies[UNIT_REFERENCES], NULL);
+                r = unit_add_dependency_hashmap(u->dependencies + UNIT_REFERENCES, other, mask, 0);
                 if (r < 0)
                         return r;
 
-                r = set_ensure_allocated(&other->dependencies[UNIT_REFERENCED_BY], NULL);
+                r = unit_add_dependency_hashmap(other->dependencies + UNIT_REFERENCED_BY, u, 0, mask);
                 if (r < 0)
                         return r;
         }
 
-        q = set_put(u->dependencies[d], other);
-        if (q < 0)
-                return q;
-
-        if (inverse_table[d] != _UNIT_DEPENDENCY_INVALID && inverse_table[d] != d) {
-                v = set_put(other->dependencies[inverse_table[d]], u);
-                if (v < 0) {
-                        r = v;
-                        goto fail;
-                }
-        }
-
-        if (add_reference) {
-                w = set_put(u->dependencies[UNIT_REFERENCES], other);
-                if (w < 0) {
-                        r = w;
-                        goto fail;
-                }
-
-                r = set_put(other->dependencies[UNIT_REFERENCED_BY], u);
-                if (r < 0)
-                        goto fail;
-        }
-
         unit_add_to_dbus_queue(u);
         return 0;
-
-fail:
-        if (q > 0)
-                set_remove(u->dependencies[d], other);
-
-        if (v > 0)
-                set_remove(other->dependencies[inverse_table[d]], u);
-
-        if (w > 0)
-                set_remove(u->dependencies[UNIT_REFERENCES], other);
-
-        return r;
 }
 
-int unit_add_two_dependencies(Unit *u, UnitDependency d, UnitDependency e, Unit *other, bool add_reference) {
+int unit_add_two_dependencies(Unit *u, UnitDependency d, UnitDependency e, Unit *other, bool add_reference, UnitDependencyMask mask) {
         int r;
 
         assert(u);
 
-        r = unit_add_dependency(u, d, other, add_reference);
+        r = unit_add_dependency(u, d, other, add_reference, mask);
         if (r < 0)
                 return r;
 
-        return unit_add_dependency(u, e, other, add_reference);
+        return unit_add_dependency(u, e, other, add_reference, mask);
 }
 
 static int resolve_template(Unit *u, const char *name, const char*path, char **buf, const char **ret) {
@@ -2620,7 +2822,7 @@ static int resolve_template(Unit *u, const char *name, const char*path, char **b
         return 0;
 }
 
-int unit_add_dependency_by_name(Unit *u, UnitDependency d, const char *name, const char *path, bool add_reference) {
+int unit_add_dependency_by_name(Unit *u, UnitDependency d, const char *name, const char *path, bool add_reference, UnitDependencyMask mask) {
         _cleanup_free_ char *buf = NULL;
         Unit *other;
         int r;
@@ -2636,10 +2838,10 @@ int unit_add_dependency_by_name(Unit *u, UnitDependency d, const char *name, con
         if (r < 0)
                 return r;
 
-        return unit_add_dependency(u, d, other, add_reference);
+        return unit_add_dependency(u, d, other, add_reference, mask);
 }
 
-int unit_add_two_dependencies_by_name(Unit *u, UnitDependency d, UnitDependency e, const char *name, const char *path, bool add_reference) {
+int unit_add_two_dependencies_by_name(Unit *u, UnitDependency d, UnitDependency e, const char *name, const char *path, bool add_reference, UnitDependencyMask mask) {
         _cleanup_free_ char *buf = NULL;
         Unit *other;
         int r;
@@ -2655,7 +2857,7 @@ int unit_add_two_dependencies_by_name(Unit *u, UnitDependency d, UnitDependency
         if (r < 0)
                 return r;
 
-        return unit_add_two_dependencies(u, d, e, other, add_reference);
+        return unit_add_two_dependencies(u, d, e, other, add_reference, mask);
 }
 
 int set_unit_path(const char *p) {
@@ -2813,8 +3015,8 @@ static int signal_name_owner_changed(sd_bus_message *message, void *userdata, sd
                 return 0;
         }
 
-        old_owner = isempty(old_owner) ? NULL : old_owner;
-        new_owner = isempty(new_owner) ? NULL : new_owner;
+        old_owner = empty_to_null(old_owner);
+        new_owner = empty_to_null(new_owner);
 
         if (UNIT_VTABLE(u)->bus_name_owner_change)
                 UNIT_VTABLE(u)->bus_name_owner_change(u, name, old_owner, new_owner);
@@ -2949,6 +3151,10 @@ int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool serialize_jobs) {
 
         unit_serialize_item(u, f, "transient", yes_no(u->transient));
 
+        unit_serialize_item(u, f, "exported-invocation-id", yes_no(u->exported_invocation_id));
+        unit_serialize_item(u, f, "exported-log-level-max", yes_no(u->exported_log_level_max));
+        unit_serialize_item(u, f, "exported-log-extra-fields", yes_no(u->exported_log_extra_fields));
+
         unit_serialize_item_format(u, f, "cpu-usage-base", "%" PRIu64, u->cpu_usage_base);
         if (u->cpu_usage_last != NSEC_INFINITY)
                 unit_serialize_item_format(u, f, "cpu-usage-last", "%" PRIu64, u->cpu_usage_last);
@@ -3189,6 +3395,36 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds) {
 
                         continue;
 
+                } else if (streq(l, "exported-invocation-id")) {
+
+                        r = parse_boolean(v);
+                        if (r < 0)
+                                log_unit_debug(u, "Failed to parse exported invocation ID bool %s, ignoring.", v);
+                        else
+                                u->exported_invocation_id = r;
+
+                        continue;
+
+                } else if (streq(l, "exported-log-level-max")) {
+
+                        r = parse_boolean(v);
+                        if (r < 0)
+                                log_unit_debug(u, "Failed to parse exported log level max bool %s, ignoring.", v);
+                        else
+                                u->exported_log_level_max = r;
+
+                        continue;
+
+                } else if (streq(l, "exported-log-extra-fields")) {
+
+                        r = parse_boolean(v);
+                        if (r < 0)
+                                log_unit_debug(u, "Failed to parse exported log extra fields bool %s, ignoring.", v);
+                        else
+                                u->exported_log_extra_fields = r;
+
+                        continue;
+
                 } else if (STR_IN_SET(l, "cpu-usage-base", "cpuacct-usage-base")) {
 
                         r = safe_atou64(v, &u->cpu_usage_base);
@@ -3365,7 +3601,7 @@ void unit_deserialize_skip(FILE *f) {
 }
 
 
-int unit_add_node_link(Unit *u, const char *what, bool wants, UnitDependency dep) {
+int unit_add_node_dependency(Unit *u, const char *what, bool wants, UnitDependency dep, UnitDependencyMask mask) {
         Unit *device;
         _cleanup_free_ char *e = NULL;
         int r;
@@ -3397,12 +3633,12 @@ int unit_add_node_link(Unit *u, const char *what, bool wants, UnitDependency dep
 
         r = unit_add_two_dependencies(u, UNIT_AFTER,
                                       MANAGER_IS_SYSTEM(u->manager) ? dep : UNIT_WANTS,
-                                      device, true);
+                                      device, true, mask);
         if (r < 0)
                 return r;
 
         if (wants) {
-                r = unit_add_dependency(device, UNIT_WANTS, u, false);
+                r = unit_add_dependency(device, UNIT_WANTS, u, false, mask);
                 if (r < 0)
                         return r;
         }
@@ -3485,7 +3721,8 @@ bool unit_need_daemon_reload(Unit *u) {
         if (fragment_mtime_newer(u->source_path, u->source_mtime, false))
                 return true;
 
-        (void) unit_find_dropin_paths(u, &t);
+        if (u->load_state == UNIT_LOADED)
+                (void) unit_find_dropin_paths(u, &t);
         if (!strv_equal(u->dropin_paths, t))
                 return true;
 
@@ -3557,6 +3794,15 @@ bool unit_active_or_pending(Unit *u) {
         return false;
 }
 
+bool unit_will_restart(Unit *u) {
+        assert(u);
+
+        if (!UNIT_VTABLE(u)->will_restart)
+                return false;
+
+        return UNIT_VTABLE(u)->will_restart(u);
+}
+
 int unit_kill(Unit *u, KillWho w, int signo, sd_bus_error *error) {
         assert(u);
         assert(w >= 0 && w < _KILL_WHO_MAX);
@@ -3883,43 +4129,156 @@ ExecRuntime *unit_get_exec_runtime(Unit *u) {
         return *(ExecRuntime**) ((uint8_t*) u + offset);
 }
 
-static const char* unit_drop_in_dir(Unit *u, UnitSetPropertiesMode mode) {
+static const char* unit_drop_in_dir(Unit *u, UnitWriteFlags flags) {
         assert(u);
 
-        if (!IN_SET(mode, UNIT_RUNTIME, UNIT_PERSISTENT))
+        if (UNIT_WRITE_FLAGS_NOOP(flags))
                 return NULL;
 
         if (u->transient) /* Redirect drop-ins for transient units always into the transient directory. */
                 return u->manager->lookup_paths.transient;
 
-        if (mode == UNIT_RUNTIME)
-                return u->manager->lookup_paths.runtime_control;
-
-        if (mode == UNIT_PERSISTENT)
+        if (flags & UNIT_PERSISTENT)
                 return u->manager->lookup_paths.persistent_control;
 
+        if (flags & UNIT_RUNTIME)
+                return u->manager->lookup_paths.runtime_control;
+
         return NULL;
 }
 
-int unit_write_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data) {
-        _cleanup_free_ char *p = NULL, *q = NULL;
+char* unit_escape_setting(const char *s, UnitWriteFlags flags, char **buf) {
+        char *ret = NULL;
+
+        if (!s)
+                return NULL;
+
+        /* Escapes the input string as requested. Returns the escaped string. If 'buf' is specified then the allocated
+         * return buffer pointer is also written to *buf, except if no escaping was necessary, in which case *buf is
+         * set to NULL, and the input pointer is returned as-is. This means the return value always contains a properly
+         * escaped version, but *buf when passed only contains a pointer if an allocation was necessary. If *buf is
+         * not specified, then the return value always needs to be freed. Callers can use this to optimize memory
+         * allocations. */
+
+        if (flags & UNIT_ESCAPE_SPECIFIERS) {
+                ret = specifier_escape(s);
+                if (!ret)
+                        return NULL;
+
+                s = ret;
+        }
+
+        if (flags & UNIT_ESCAPE_C) {
+                char *a;
+
+                a = cescape(s);
+                free(ret);
+                if (!a)
+                        return NULL;
+
+                ret = a;
+        }
+
+        if (buf) {
+                *buf = ret;
+                return ret ?: (char*) s;
+        }
+
+        return ret ?: strdup(s);
+}
+
+char* unit_concat_strv(char **l, UnitWriteFlags flags) {
+        _cleanup_free_ char *result = NULL;
+        size_t n = 0, allocated = 0;
+        char **i, *ret;
+
+        /* Takes a list of strings, escapes them, and concatenates them. This may be used to format command lines in a
+         * way suitable for ExecStart= stanzas */
+
+        STRV_FOREACH(i, l) {
+                _cleanup_free_ char *buf = NULL;
+                const char *p;
+                size_t a;
+                char *q;
+
+                p = unit_escape_setting(*i, flags, &buf);
+                if (!p)
+                        return NULL;
+
+                a = (n > 0) + 1 + strlen(p) + 1; /* separating space + " + entry + " */
+                if (!GREEDY_REALLOC(result, allocated, n + a + 1))
+                        return NULL;
+
+                q = result + n;
+                if (n > 0)
+                        *(q++) = ' ';
+
+                *(q++) = '"';
+                q = stpcpy(q, p);
+                *(q++) = '"';
+
+                n += a;
+        }
+
+        if (!GREEDY_REALLOC(result, allocated, n + 1))
+                return NULL;
+
+        result[n] = 0;
+
+        ret = result;
+        result = NULL;
+
+        return ret;
+}
+
+int unit_write_setting(Unit *u, UnitWriteFlags flags, const char *name, const char *data) {
+        _cleanup_free_ char *p = NULL, *q = NULL, *escaped = NULL;
         const char *dir, *wrapped;
         int r;
 
         assert(u);
+        assert(name);
+        assert(data);
+
+        if (UNIT_WRITE_FLAGS_NOOP(flags))
+                return 0;
+
+        data = unit_escape_setting(data, flags, &escaped);
+        if (!data)
+                return -ENOMEM;
+
+        /* Prefix the section header. If we are writing this out as transient file, then let's suppress this if the
+         * previous section header is the same */
+
+        if (flags & UNIT_PRIVATE) {
+                if (!UNIT_VTABLE(u)->private_section)
+                        return -EINVAL;
+
+                if (!u->transient_file || u->last_section_private < 0)
+                        data = strjoina("[", UNIT_VTABLE(u)->private_section, "]\n", data);
+                else if (u->last_section_private == 0)
+                        data = strjoina("\n[", UNIT_VTABLE(u)->private_section, "]\n", data);
+        } else {
+                if (!u->transient_file || u->last_section_private < 0)
+                        data = strjoina("[Unit]\n", data);
+                else if (u->last_section_private > 0)
+                        data = strjoina("\n[Unit]\n", data);
+        }
 
         if (u->transient_file) {
                 /* When this is a transient unit file in creation, then let's not create a new drop-in but instead
                  * write to the transient unit file. */
                 fputs(data, u->transient_file);
-                fputc('\n', u->transient_file);
-                return 0;
-        }
 
-        if (!IN_SET(mode, UNIT_PERSISTENT, UNIT_RUNTIME))
+                if (!endswith(data, "\n"))
+                        fputc('\n', u->transient_file);
+
+                /* Remember which section we wrote this entry to */
+                u->last_section_private = !!(flags & UNIT_PRIVATE);
                 return 0;
+        }
 
-        dir = unit_drop_in_dir(u, mode);
+        dir = unit_drop_in_dir(u, flags);
         if (!dir)
                 return -EINVAL;
 
@@ -3932,7 +4291,7 @@ int unit_write_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name, co
         if (r < 0)
                 return r;
 
-        (void) mkdir_p(p, 0755);
+        (void) mkdir_p_label(p, 0755);
         r = write_string_file_atomic_label(q, wrapped);
         if (r < 0)
                 return r;
@@ -3949,47 +4308,7 @@ int unit_write_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name, co
         return 0;
 }
 
-int unit_write_drop_in_format(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *format, ...) {
-        _cleanup_free_ char *p = NULL;
-        va_list ap;
-        int r;
-
-        assert(u);
-        assert(name);
-        assert(format);
-
-        if (!IN_SET(mode, UNIT_PERSISTENT, UNIT_RUNTIME))
-                return 0;
-
-        va_start(ap, format);
-        r = vasprintf(&p, format, ap);
-        va_end(ap);
-
-        if (r < 0)
-                return -ENOMEM;
-
-        return unit_write_drop_in(u, mode, name, p);
-}
-
-int unit_write_drop_in_private(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data) {
-        const char *ndata;
-
-        assert(u);
-        assert(name);
-        assert(data);
-
-        if (!UNIT_VTABLE(u)->private_section)
-                return -EINVAL;
-
-        if (!IN_SET(mode, UNIT_PERSISTENT, UNIT_RUNTIME))
-                return 0;
-
-        ndata = strjoina("[", UNIT_VTABLE(u)->private_section, "]\n", data);
-
-        return unit_write_drop_in(u, mode, name, ndata);
-}
-
-int unit_write_drop_in_private_format(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *format, ...) {
+int unit_write_settingf(Unit *u, UnitWriteFlags flags, const char *name, const char *format, ...) {
         _cleanup_free_ char *p = NULL;
         va_list ap;
         int r;
@@ -3998,7 +4317,7 @@ int unit_write_drop_in_private_format(Unit *u, UnitSetPropertiesMode mode, const
         assert(name);
         assert(format);
 
-        if (!IN_SET(mode, UNIT_PERSISTENT, UNIT_RUNTIME))
+        if (UNIT_WRITE_FLAGS_NOOP(flags))
                 return 0;
 
         va_start(ap, format);
@@ -4008,18 +4327,20 @@ int unit_write_drop_in_private_format(Unit *u, UnitSetPropertiesMode mode, const
         if (r < 0)
                 return -ENOMEM;
 
-        return unit_write_drop_in_private(u, mode, name, p);
+        return unit_write_setting(u, flags, name, p);
 }
 
 int unit_make_transient(Unit *u) {
+        _cleanup_free_ char *path = NULL;
         FILE *f;
-        char *path;
 
         assert(u);
 
         if (!UNIT_VTABLE(u)->can_transient)
                 return -EOPNOTSUPP;
 
+        (void) mkdir_p_label(u->manager->lookup_paths.transient, 0755);
+
         path = strjoin(u->manager->lookup_paths.transient, "/", u->id);
         if (!path)
                 return -ENOMEM;
@@ -4029,18 +4350,14 @@ int unit_make_transient(Unit *u) {
 
         RUN_WITH_UMASK(0022) {
                 f = fopen(path, "we");
-                if (!f) {
-                        free(path);
+                if (!f)
                         return -errno;
-                }
         }
 
-        if (u->transient_file)
-                fclose(u->transient_file);
+        safe_fclose(u->transient_file);
         u->transient_file = f;
 
-        free(u->fragment_path);
-        u->fragment_path = path;
+        free_and_replace(u->fragment_path, path);
 
         u->source_path = mfree(u->source_path);
         u->dropin_paths = strv_free(u->dropin_paths);
@@ -4221,42 +4538,51 @@ int unit_kill_context(
         return wait_for_exit;
 }
 
-int unit_require_mounts_for(Unit *u, const char *path) {
+int unit_require_mounts_for(Unit *u, const char *path, UnitDependencyMask mask) {
         char prefix[strlen(path) + 1], *p;
+        UnitDependencyInfo di;
         int r;
 
         assert(u);
         assert(path);
 
-        /* Registers a unit for requiring a certain path and all its
-         * prefixes. We keep a simple array of these paths in the
-         * unit, since its usually short. However, we build a prefix
-         * table for all possible prefixes so that new appearing mount
-         * units can easily determine which units to make themselves a
-         * dependency of. */
+        /* Registers a unit for requiring a certain path and all its prefixes. We keep a hashtable of these paths in
+         * the unit (from the path to the UnitDependencyInfo structure indicating how to the dependency came to
+         * be). However, we build a prefix table for all possible prefixes so that new appearing mount units can easily
+         * determine which units to make themselves a dependency of. */
 
         if (!path_is_absolute(path))
                 return -EINVAL;
 
+        r = hashmap_ensure_allocated(&u->requires_mounts_for, &string_hash_ops);
+        if (r < 0)
+                return r;
+
         p = strdup(path);
         if (!p)
                 return -ENOMEM;
 
         path_kill_slashes(p);
 
-        if (!path_is_safe(p)) {
+        if (!path_is_normalized(p)) {
                 free(p);
                 return -EPERM;
         }
 
-        if (strv_contains(u->requires_mounts_for, p)) {
+        if (hashmap_contains(u->requires_mounts_for, p)) {
                 free(p);
                 return 0;
         }
 
-        r = strv_consume(&u->requires_mounts_for, p);
-        if (r < 0)
+        di = (UnitDependencyInfo) {
+                .origin_mask = mask
+        };
+
+        r = hashmap_put(u->requires_mounts_for, p, di.data);
+        if (r < 0) {
+                free(p);
                 return r;
+        }
 
         PATH_FOREACH_PREFIX_MORE(prefix, p) {
                 Set *x;
@@ -4298,8 +4624,9 @@ int unit_require_mounts_for(Unit *u, const char *path) {
 int unit_setup_exec_runtime(Unit *u) {
         ExecRuntime **rt;
         size_t offset;
-        Iterator i;
         Unit *other;
+        Iterator i;
+        void *v;
 
         offset = UNIT_VTABLE(u)->exec_runtime_offset;
         assert(offset > 0);
@@ -4310,7 +4637,7 @@ int unit_setup_exec_runtime(Unit *u) {
                 return 0;
 
         /* Try to get it from somebody else */
-        SET_FOREACH(other, u->dependencies[UNIT_JOINS_NAMESPACE_OF], i) {
+        HASHMAP_FOREACH_KEY(v, other, u->dependencies[UNIT_JOINS_NAMESPACE_OF], i) {
 
                 *rt = unit_get_exec_runtime(other);
                 if (*rt) {
@@ -4680,3 +5007,303 @@ int unit_fork_helper_process(Unit *u, pid_t *ret) {
         *ret = pid;
         return 1;
 }
+
+static void unit_update_dependency_mask(Unit *u, UnitDependency d, Unit *other, UnitDependencyInfo di) {
+        assert(u);
+        assert(d >= 0);
+        assert(d < _UNIT_DEPENDENCY_MAX);
+        assert(other);
+
+        if (di.origin_mask == 0 && di.destination_mask == 0) {
+                /* No bit set anymore, let's drop the whole entry */
+                assert_se(hashmap_remove(u->dependencies[d], other));
+                log_unit_debug(u, "%s lost dependency %s=%s", u->id, unit_dependency_to_string(d), other->id);
+        } else
+                /* Mask was reduced, let's update the entry */
+                assert_se(hashmap_update(u->dependencies[d], other, di.data) == 0);
+}
+
+void unit_remove_dependencies(Unit *u, UnitDependencyMask mask) {
+        UnitDependency d;
+
+        assert(u);
+
+        /* Removes all dependencies u has on other units marked for ownership by 'mask'. */
+
+        if (mask == 0)
+                return;
+
+        for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++) {
+                bool done;
+
+                do {
+                        UnitDependencyInfo di;
+                        Unit *other;
+                        Iterator i;
+
+                        done = true;
+
+                        HASHMAP_FOREACH_KEY(di.data, other, u->dependencies[d], i) {
+                                UnitDependency q;
+
+                                if ((di.origin_mask & ~mask) == di.origin_mask)
+                                        continue;
+                                di.origin_mask &= ~mask;
+                                unit_update_dependency_mask(u, d, other, di);
+
+                                /* We updated the dependency from our unit to the other unit now. But most dependencies
+                                 * imply a reverse dependency. Hence, let's delete that one too. For that we go through
+                                 * all dependency types on the other unit and delete all those which point to us and
+                                 * have the right mask set. */
+
+                                for (q = 0; q < _UNIT_DEPENDENCY_MAX; q++) {
+                                        UnitDependencyInfo dj;
+
+                                        dj.data = hashmap_get(other->dependencies[q], u);
+                                        if ((dj.destination_mask & ~mask) == dj.destination_mask)
+                                                continue;
+                                        dj.destination_mask &= ~mask;
+
+                                        unit_update_dependency_mask(other, q, u, dj);
+                                }
+
+                                unit_add_to_gc_queue(other);
+
+                                done = false;
+                                break;
+                        }
+
+                } while (!done);
+        }
+}
+
+static int unit_export_invocation_id(Unit *u) {
+        const char *p;
+        int r;
+
+        assert(u);
+
+        if (u->exported_invocation_id)
+                return 0;
+
+        if (sd_id128_is_null(u->invocation_id))
+                return 0;
+
+        p = strjoina("/run/systemd/units/invocation:", u->id);
+        r = symlink_atomic(u->invocation_id_string, p);
+        if (r < 0)
+                return log_unit_debug_errno(u, r, "Failed to create invocation ID symlink %s: %m", p);
+
+        u->exported_invocation_id = true;
+        return 0;
+}
+
+static int unit_export_log_level_max(Unit *u, const ExecContext *c) {
+        const char *p;
+        char buf[2];
+        int r;
+
+        assert(u);
+        assert(c);
+
+        if (u->exported_log_level_max)
+                return 0;
+
+        if (c->log_level_max < 0)
+                return 0;
+
+        assert(c->log_level_max <= 7);
+
+        buf[0] = '0' + c->log_level_max;
+        buf[1] = 0;
+
+        p = strjoina("/run/systemd/units/log-level-max:", u->id);
+        r = symlink_atomic(buf, p);
+        if (r < 0)
+                return log_unit_debug_errno(u, r, "Failed to create maximum log level symlink %s: %m", p);
+
+        u->exported_log_level_max = true;
+        return 0;
+}
+
+static int unit_export_log_extra_fields(Unit *u, const ExecContext *c) {
+        _cleanup_close_ int fd = -1;
+        struct iovec *iovec;
+        const char *p;
+        char *pattern;
+        le64_t *sizes;
+        ssize_t n;
+        size_t i;
+        int r;
+
+        if (u->exported_log_extra_fields)
+                return 0;
+
+        if (c->n_log_extra_fields <= 0)
+                return 0;
+
+        sizes = newa(le64_t, c->n_log_extra_fields);
+        iovec = newa(struct iovec, c->n_log_extra_fields * 2);
+
+        for (i = 0; i < c->n_log_extra_fields; i++) {
+                sizes[i] = htole64(c->log_extra_fields[i].iov_len);
+
+                iovec[i*2] = IOVEC_MAKE(sizes + i, sizeof(le64_t));
+                iovec[i*2+1] = c->log_extra_fields[i];
+        }
+
+        p = strjoina("/run/systemd/units/log-extra-fields:", u->id);
+        pattern = strjoina(p, ".XXXXXX");
+
+        fd = mkostemp_safe(pattern);
+        if (fd < 0)
+                return log_unit_debug_errno(u, fd, "Failed to create extra fields file %s: %m", p);
+
+        n = writev(fd, iovec, c->n_log_extra_fields*2);
+        if (n < 0) {
+                r = log_unit_debug_errno(u, errno, "Failed to write extra fields: %m");
+                goto fail;
+        }
+
+        (void) fchmod(fd, 0644);
+
+        if (rename(pattern, p) < 0) {
+                r = log_unit_debug_errno(u, errno, "Failed to rename extra fields file: %m");
+                goto fail;
+        }
+
+        u->exported_log_extra_fields = true;
+        return 0;
+
+fail:
+        (void) unlink(pattern);
+        return r;
+}
+
+void unit_export_state_files(Unit *u) {
+        const ExecContext *c;
+
+        assert(u);
+
+        if (!u->id)
+                return;
+
+        if (!MANAGER_IS_SYSTEM(u->manager))
+                return;
+
+        /* Exports a couple of unit properties to /run/systemd/units/, so that journald can quickly query this data
+         * from there. Ideally, journald would use IPC to query this, like everybody else, but that's hard, as long as
+         * the IPC system itself and PID 1 also log to the journal.
+         *
+         * Note that these files really shouldn't be considered API for anyone else, as use a runtime file system as
+         * IPC replacement is not compatible with today's world of file system namespaces. However, this doesn't really
+         * apply to communication between the journal and systemd, as we assume that these two daemons live in the same
+         * namespace at least.
+         *
+         * Note that some of the "files" exported here are actually symlinks and not regular files. Symlinks work
+         * better for storing small bits of data, in particular as we can write them with two system calls, and read
+         * them with one. */
+
+        (void) unit_export_invocation_id(u);
+
+        c = unit_get_exec_context(u);
+        if (c) {
+                (void) unit_export_log_level_max(u, c);
+                (void) unit_export_log_extra_fields(u, c);
+        }
+}
+
+void unit_unlink_state_files(Unit *u) {
+        const char *p;
+
+        assert(u);
+
+        if (!u->id)
+                return;
+
+        if (!MANAGER_IS_SYSTEM(u->manager))
+                return;
+
+        /* Undoes the effect of unit_export_state() */
+
+        if (u->exported_invocation_id) {
+                p = strjoina("/run/systemd/units/invocation:", u->id);
+                (void) unlink(p);
+
+                u->exported_invocation_id = false;
+        }
+
+        if (u->exported_log_level_max) {
+                p = strjoina("/run/systemd/units/log-level-max:", u->id);
+                (void) unlink(p);
+
+                u->exported_log_level_max = false;
+        }
+
+        if (u->exported_log_extra_fields) {
+                p = strjoina("/run/systemd/units/extra-fields:", u->id);
+                (void) unlink(p);
+
+                u->exported_log_extra_fields = false;
+        }
+}
+
+int unit_prepare_exec(Unit *u) {
+        int r;
+
+        assert(u);
+
+        /* Prepares everything so that we can fork of a process for this unit */
+
+        (void) unit_realize_cgroup(u);
+
+        if (u->reset_accounting) {
+                (void) unit_reset_cpu_accounting(u);
+                (void) unit_reset_ip_accounting(u);
+                u->reset_accounting = false;
+        }
+
+        unit_export_state_files(u);
+
+        r = unit_setup_exec_runtime(u);
+        if (r < 0)
+                return r;
+
+        r = unit_setup_dynamic_creds(u);
+        if (r < 0)
+                return r;
+
+        return 0;
+}
+
+static void log_leftover(pid_t pid, int sig, void *userdata) {
+        _cleanup_free_ char *comm = NULL;
+
+        (void) get_process_comm(pid, &comm);
+
+        if (comm && comm[0] == '(') /* Most likely our own helper process (PAM?), ignore */
+                return;
+
+        log_unit_warning(userdata,
+                         "Found left-over process " PID_FMT " (%s) in control group while starting unit. Ignoring.\n"
+                         "This usually indicates unclean termination of a previous run, or service implementation deficiencies.",
+                         pid, strna(comm));
+}
+
+void unit_warn_leftover_processes(Unit *u) {
+        assert(u);
+
+        (void) unit_pick_cgroup_path(u);
+
+        if (!u->cgroup_path)
+                return;
+
+        (void) cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, 0, 0, NULL, log_leftover, u);
+}
+
+static const char* const collect_mode_table[_COLLECT_MODE_MAX] = {
+        [COLLECT_INACTIVE] = "inactive",
+        [COLLECT_INACTIVE_OR_FAILED] = "inactive-or-failed",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(collect_mode, CollectMode);
index ded0edc..ccc0caa 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -45,6 +46,13 @@ typedef enum KillOperation {
         _KILL_OPERATION_INVALID = -1
 } KillOperation;
 
+typedef enum CollectMode {
+        COLLECT_INACTIVE,
+        COLLECT_INACTIVE_OR_FAILED,
+        _COLLECT_MODE_MAX,
+        _COLLECT_MODE_INVALID = -1,
+} CollectMode;
+
 static inline bool UNIT_IS_ACTIVE_OR_RELOADING(UnitActiveState t) {
         return IN_SET(t, UNIT_ACTIVE, UNIT_RELOADING);
 }
@@ -61,6 +69,53 @@ static inline bool UNIT_IS_INACTIVE_OR_FAILED(UnitActiveState t) {
         return IN_SET(t, UNIT_INACTIVE, UNIT_FAILED);
 }
 
+/* Stores the 'reason' a dependency was created as a bit mask, i.e. due to which configuration source it came to be. We
+ * use this so that we can selectively flush out parts of dependencies again. Note that the same dependency might be
+ * created as a result of multiple "reasons", hence the bitmask. */
+typedef enum UnitDependencyMask {
+        /* Configured directly by the unit file, .wants/.requries symlink or drop-in, or as an immediate result of a
+         * non-dependency option configured that way.  */
+        UNIT_DEPENDENCY_FILE               = 1 << 0,
+
+        /* As unconditional implicit dependency (not affected by unit configuration — except by the unit name and
+         * type) */
+        UNIT_DEPENDENCY_IMPLICIT           = 1 << 1,
+
+        /* A dependency effected by DefaultDependencies=yes. Note that dependencies marked this way are conceptually
+         * just a subset of UNIT_DEPENDENCY_FILE, as DefaultDependencies= is itself a unit file setting that can only
+         * be set in unit files. We make this two separate bits only to help debugging how dependencies came to be. */
+        UNIT_DEPENDENCY_DEFAULT            = 1 << 2,
+
+        /* A dependency created from udev rules */
+        UNIT_DEPENDENCY_UDEV               = 1 << 3,
+
+        /* A dependency created because of some unit's RequiresMountsFor= setting */
+        UNIT_DEPENDENCY_PATH               = 1 << 4,
+
+        /* A dependency created because of data read from /proc/self/mountinfo and no other configuration source */
+        UNIT_DEPENDENCY_MOUNTINFO_IMPLICIT = 1 << 5,
+
+        /* A dependency created because of data read from /proc/self/mountinfo, but conditionalized by
+         * DefaultDependencies= and thus also involving configuration from UNIT_DEPENDENCY_FILE sources */
+        UNIT_DEPENDENCY_MOUNTINFO_DEFAULT  = 1 << 6,
+
+        /* A dependency created because of data read from /proc/swaps and no other configuration source */
+        UNIT_DEPENDENCY_PROC_SWAP          = 1 << 7,
+
+        _UNIT_DEPENDENCY_MASK_FULL = (1 << 8) - 1,
+} UnitDependencyMask;
+
+/* The Unit's dependencies[] hashmaps use this structure as value. It has the same size as a void pointer, and thus can
+ * be stored directly as hashmap value, without any indirection. Note that this stores two masks, as both the origin
+ * and the destination of a dependency might have created it. */
+typedef union UnitDependencyInfo {
+        void *data;
+        struct {
+                UnitDependencyMask origin_mask:16;
+                UnitDependencyMask destination_mask:16;
+        } _packed_;
+} UnitDependencyInfo;
+
 #include "job.h"
 
 struct UnitRef {
@@ -89,9 +144,13 @@ struct Unit {
         char *instance;
 
         Set *names;
-        Set *dependencies[_UNIT_DEPENDENCY_MAX];
 
-        char **requires_mounts_for;
+        /* For each dependency type we maintain a Hashmap whose key is the Unit* object, and the value encodes why the
+         * dependency exists, using the UnitDependencyInfo type */
+        Hashmap *dependencies[_UNIT_DEPENDENCY_MAX];
+
+        /* Similar, for RequiresMountsFor= path dependencies. The key is the path, the value the UnitDependencyInfo type */
+        Hashmap *requires_mounts_for;
 
         char *description;
         char **documentation;
@@ -189,6 +248,9 @@ struct Unit {
         /* Put a ratelimit on unit starting */
         RateLimit start_limit;
         EmergencyAction start_limit_action;
+
+        EmergencyAction failure_action;
+        EmergencyAction success_action;
         char *reboot_arg;
 
         /* Make sure we never enter endless loops with the check unneeded logic, or the BindsTo= logic */
@@ -231,6 +293,9 @@ struct Unit {
         /* How to start OnFailure units */
         JobMode on_failure_job_mode;
 
+        /* Tweaking the GC logic */
+        CollectMode collect_mode;
+
         /* The current invocation ID */
         sd_id128_t invocation_id;
         char invocation_id_string[SD_ID128_STRING_MAX]; /* useful when logging */
@@ -280,6 +345,9 @@ struct Unit {
 
         UnitCGroupBPFState cgroup_bpf_state:2;
 
+        /* Reset cgroup accounting next time we fork something off */
+        bool reset_accounting:1;
+
         bool start_limit_hit:1;
 
         /* Did we already invoke unit_coldplug() for this unit? */
@@ -287,6 +355,15 @@ struct Unit {
 
         /* For transient units: whether to add a bus track reference after creating the unit */
         bool bus_track_add:1;
+
+        /* Remember which unit state files we created */
+        bool exported_invocation_id:1;
+        bool exported_log_level_max:1;
+        bool exported_log_extra_fields:1;
+
+        /* When writing transient unit files, stores which section we stored last. If < 0, we didn't write any yet. If
+         * == 0 we are in the [Unit] section, if > 0 we are in the unit type-specific section. */
+        int last_section_private:2;
 };
 
 struct UnitStatusMessageFormats {
@@ -295,11 +372,26 @@ struct UnitStatusMessageFormats {
         const char *finished_stop_job[_JOB_RESULT_MAX];
 };
 
-typedef enum UnitSetPropertiesMode {
-        UNIT_CHECK = 0,
-        UNIT_RUNTIME = 1,
-        UNIT_PERSISTENT = 2,
-} UnitSetPropertiesMode;
+/* Flags used when writing drop-in files or transient unit files */
+typedef enum UnitWriteFlags {
+        /* Write a runtime unit file or drop-in (i.e. one below /run) */
+        UNIT_RUNTIME           = 1 << 0,
+
+        /* Write a persistent drop-in (i.e. one below /etc) */
+        UNIT_PERSISTENT        = 1 << 1,
+
+        /* Place this item in the per-unit-type private section, instead of [Unit] */
+        UNIT_PRIVATE           = 1 << 2,
+
+        /* Apply specifier escaping before writing */
+        UNIT_ESCAPE_SPECIFIERS = 1 << 3,
+
+        /* Apply C escaping before writing */
+        UNIT_ESCAPE_C          = 1 << 4,
+} UnitWriteFlags;
+
+/* Returns true if neither persistent, nor runtime storage is requested, i.e. this is a check invocation only */
+#define UNIT_WRITE_FLAGS_NOOP(flags) (((flags) & (UNIT_RUNTIME|UNIT_PERSISTENT)) == 0)
 
 #include "automount.h"
 #include "device.h"
@@ -392,14 +484,16 @@ struct UnitVTable {
          * unit is in. */
         const char* (*sub_state_to_string)(Unit *u);
 
+        /* Additionally to UnitActiveState determine whether unit is to be restarted. */
+        bool (*will_restart)(Unit *u);
+
         /* Return true when there is reason to keep this entry around
          * even nothing references it and it isn't active in any
          * way */
         bool (*check_gc)(Unit *u);
 
-        /* When the unit is not running and no job for it queued we
-         * shall release its runtime resources */
-        void (*release_resources)(Unit *u, bool inactive);
+        /* When the unit is not running and no job for it queued we shall release its runtime resources */
+        void (*release_resources)(Unit *u);
 
         /* Invoked on every child that died */
         void (*sigchld_event)(Unit *u, pid_t pid, int code, int status);
@@ -418,7 +512,7 @@ struct UnitVTable {
         void (*bus_name_owner_change)(Unit *u, const char *name, const char *old_owner, const char *new_owner);
 
         /* Called for each property that is being set */
-        int (*bus_set_property)(Unit *u, const char *name, sd_bus_message *message, UnitSetPropertiesMode mode, sd_bus_error *error);
+        int (*bus_set_property)(Unit *u, const char *name, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
 
         /* Called after at least one property got changed to apply the necessary change */
         int (*bus_commit_properties)(Unit *u);
@@ -492,7 +586,7 @@ extern const UnitVTable * const unit_vtable[_UNIT_TYPE_MAX];
 #define UNIT_HAS_CGROUP_CONTEXT(u) (UNIT_VTABLE(u)->cgroup_context_offset > 0)
 #define UNIT_HAS_KILL_CONTEXT(u) (UNIT_VTABLE(u)->kill_context_offset > 0)
 
-#define UNIT_TRIGGER(u) ((Unit*) set_first((u)->dependencies[UNIT_TRIGGERS]))
+#define UNIT_TRIGGER(u) ((Unit*) hashmap_first_key((u)->dependencies[UNIT_TRIGGERS]))
 
 DEFINE_CAST(SERVICE, Service);
 DEFINE_CAST(SOCKET, Socket);
@@ -512,11 +606,11 @@ void unit_free(Unit *u);
 int unit_new_for_name(Manager *m, size_t size, const char *name, Unit **ret);
 int unit_add_name(Unit *u, const char *name);
 
-int unit_add_dependency(Unit *u, UnitDependency d, Unit *other, bool add_reference);
-int unit_add_two_dependencies(Unit *u, UnitDependency d, UnitDependency e, Unit *other, bool add_reference);
+int unit_add_dependency(Unit *u, UnitDependency d, Unit *other, bool add_reference, UnitDependencyMask mask);
+int unit_add_two_dependencies(Unit *u, UnitDependency d, UnitDependency e, Unit *other, bool add_reference, UnitDependencyMask mask);
 
-int unit_add_dependency_by_name(Unit *u, UnitDependency d, const char *name, const char *filename, bool add_reference);
-int unit_add_two_dependencies_by_name(Unit *u, UnitDependency d, UnitDependency e, const char *name, const char *path, bool add_reference);
+int unit_add_dependency_by_name(Unit *u, UnitDependency d, const char *name, const char *filename, bool add_reference, UnitDependencyMask mask);
+int unit_add_two_dependencies_by_name(Unit *u, UnitDependency d, UnitDependency e, const char *name, const char *path, bool add_reference, UnitDependencyMask mask);
 
 int unit_add_exec_dependencies(Unit *u, ExecContext *c);
 
@@ -596,7 +690,7 @@ int unit_serialize_item_escaped(Unit *u, FILE *f, const char *key, const char *v
 int unit_serialize_item_fd(Unit *u, FILE *f, FDSet *fds, const char *key, int fd);
 void unit_serialize_item_format(Unit *u, FILE *f, const char *key, const char *value, ...) _printf_(4,5);
 
-int unit_add_node_link(Unit *u, const char *what, bool wants, UnitDependency d);
+int unit_add_node_dependency(Unit *u, const char *what, bool wants, UnitDependency d, UnitDependencyMask mask);
 
 int unit_coldplug(Unit *u);
 
@@ -615,6 +709,7 @@ const char *unit_slice_name(Unit *u);
 bool unit_stop_pending(Unit *u) _pure_;
 bool unit_inactive_or_pending(Unit *u) _pure_;
 bool unit_active_or_pending(Unit *u);
+bool unit_will_restart(Unit *u);
 
 int unit_add_default_target_dependency(Unit *u, Unit *target);
 
@@ -641,17 +736,17 @@ ExecRuntime *unit_get_exec_runtime(Unit *u) _pure_;
 int unit_setup_exec_runtime(Unit *u);
 int unit_setup_dynamic_creds(Unit *u);
 
-int unit_write_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data);
-int unit_write_drop_in_format(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *format, ...) _printf_(4,5);
+char* unit_escape_setting(const char *s, UnitWriteFlags flags, char **buf);
+char* unit_concat_strv(char **l, UnitWriteFlags flags);
 
-int unit_write_drop_in_private(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data);
-int unit_write_drop_in_private_format(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *format, ...) _printf_(4,5);
+int unit_write_setting(Unit *u, UnitWriteFlags flags, const char *name, const char *data);
+int unit_write_settingf(Unit *u, UnitWriteFlags mode, const char *name, const char *format, ...) _printf_(4,5);
 
 int unit_kill_context(Unit *u, KillContext *c, KillOperation k, pid_t main_pid, pid_t control_pid, bool main_pid_alien);
 
 int unit_make_transient(Unit *u);
 
-int unit_require_mounts_for(Unit *u, const char *path);
+int unit_require_mounts_for(Unit *u, const char *path, UnitDependencyMask mask);
 
 bool unit_type_supported(UnitType t);
 
@@ -689,6 +784,15 @@ void unit_set_exec_params(Unit *s, ExecParameters *p);
 
 int unit_fork_helper_process(Unit *u, pid_t *ret);
 
+void unit_remove_dependencies(Unit *u, UnitDependencyMask mask);
+
+void unit_export_state_files(Unit *u);
+void unit_unlink_state_files(Unit *u);
+
+int unit_prepare_exec(Unit *u);
+
+void unit_warn_leftover_processes(Unit *u);
+
 /* Macros which append UNIT= or USER_UNIT= to the message */
 
 #define log_unit_full(unit, level, error, ...)                          \
@@ -713,3 +817,6 @@ int unit_fork_helper_process(Unit *u, pid_t *ret);
 #define LOG_UNIT_MESSAGE(unit, fmt, ...) "MESSAGE=%s: " fmt, (unit)->id, ##__VA_ARGS__
 #define LOG_UNIT_ID(unit) (unit)->manager->unit_log_format_string, (unit)->id
 #define LOG_UNIT_INVOCATION_ID(unit) (unit)->manager->invocation_log_format_string, (unit)->invocation_id_string
+
+const char* collect_mode_to_string(CollectMode m) _const_;
+CollectMode collect_mode_from_string(const char *s) _pure_;
index f02b6db..aede180 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -51,16 +52,11 @@ static void vacuum_candidate_free(struct vacuum_candidate *c) {
 
 DEFINE_TRIVIAL_CLEANUP_FUNC(struct vacuum_candidate*, vacuum_candidate_free);
 
-static void vacuum_candidate_hasmap_free(Hashmap *h) {
-        struct vacuum_candidate *c;
-
-        while ((c = hashmap_steal_first(h)))
-                vacuum_candidate_free(c);
-
-        hashmap_free(h);
+static void vacuum_candidate_hashmap_free(Hashmap *h) {
+        hashmap_free_with_destructor(h, vacuum_candidate_free);
 }
 
-DEFINE_TRIVIAL_CLEANUP_FUNC(Hashmap*, vacuum_candidate_hasmap_free);
+DEFINE_TRIVIAL_CLEANUP_FUNC(Hashmap*, vacuum_candidate_hashmap_free);
 
 static int uid_from_file_name(const char *filename, uid_t *uid) {
         const char *p, *e, *u;
@@ -159,7 +155,7 @@ int coredump_vacuum(int exclude_fd, uint64_t keep_free, uint64_t max_use) {
         }
 
         for (;;) {
-                _cleanup_(vacuum_candidate_hasmap_freep) Hashmap *h = NULL;
+                _cleanup_(vacuum_candidate_hashmap_freep) Hashmap *h = NULL;
                 struct vacuum_candidate *worst = NULL;
                 struct dirent *de;
                 uint64_t sum = 0;
index 4b7b9f2..c61d08f 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 300d647..e6063cc 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -19,6 +20,7 @@
 
 #include <errno.h>
 #include <stdio.h>
+#include <stdio_ext.h>
 #include <sys/prctl.h>
 #include <sys/xattr.h>
 #include <unistd.h>
@@ -147,7 +149,7 @@ static int parse_config(void) {
                                         CONF_PATHS_NULSTR("systemd/coredump.conf.d"),
                                         "Coredump\0",
                                         config_item_table_lookup, items,
-                                        false, NULL);
+                                        CONFIG_PARSE_WARN, NULL);
 }
 
 static inline uint64_t storage_size_max(void) {
@@ -164,7 +166,7 @@ static int fix_acl(int fd, uid_t uid) {
 
         assert(fd >= 0);
 
-        if (uid <= SYSTEM_UID_MAX)
+        if (uid_is_system(uid) || uid_is_dynamic(uid) || uid == UID_NOBODY)
                 return 0;
 
         /* Make sure normal users can read (but not write or delete)
@@ -539,6 +541,8 @@ static int compose_open_fds(pid_t pid, char **open_fds) {
         if (!stream)
                 return -ENOMEM;
 
+        (void) __fsetlocking(stream, FSETLOCKING_BYCALLER);
+
         FOREACH_DIRENT(dent, proc_fd_dir, return -errno) {
                 _cleanup_fclose_ FILE *fdinfo = NULL;
                 _cleanup_free_ char *fdname = NULL;
@@ -558,13 +562,13 @@ static int compose_open_fds(pid_t pid, char **open_fds) {
                         continue;
 
                 fdinfo = fdopen(fd, "re");
-                if (fdinfo == NULL) {
-                        close(fd);
+                if (!fdinfo) {
+                        safe_close(fd);
                         continue;
                 }
 
                 FOREACH_LINE(line, fdinfo, break) {
-                        fputs_unlocked(line, stream);
+                        fputs(line, stream);
                         if (!endswith(line, "\n"))
                                 fputc('\n', stream);
                 }
@@ -1214,7 +1218,7 @@ static int gather_pid_metadata(
         if (get_process_environ(pid, &t) >= 0)
                 set_iovec_field_free(iovec, n_iovec, "COREDUMP_ENVIRON=", t);
 
-        t = strjoin("COREDUMP_TIMESTAMP=", context[CONTEXT_TIMESTAMP], "000000", NULL);
+        t = strjoin("COREDUMP_TIMESTAMP=", context[CONTEXT_TIMESTAMP], "000000");
         if (t)
                 iovec[(*n_iovec)++] = IOVEC_MAKE_STRING(t);
 
index 0380df1..0d420b2 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -902,9 +903,9 @@ static int run_gdb(sd_journal *j) {
         if (r < 0)
                 return log_error_errno(r, "Failed to retrieve COREDUMP_EXE field: %m");
 
-        assert(len > strlen("COREDUMP_EXE="));
-        data += strlen("COREDUMP_EXE=");
-        len -= strlen("COREDUMP_EXE=");
+        assert(len > STRLEN("COREDUMP_EXE="));
+        data += STRLEN("COREDUMP_EXE=");
+        len -= STRLEN("COREDUMP_EXE=");
 
         exe = strndup(data, len);
         if (!exe)
index 25a0409..4e31e7c 100644 (file)
@@ -1,3 +1,20 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
+# Copyright 2017 Zbigniew Jędrzejewski-Szmek
+#
+# 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.
+#
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
 systemd_coredump_sources = files('''
         coredump.c
         coredump-vacuum.c
index 1726613..95fd27b 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -19,6 +20,7 @@
 
 #include <dwarf.h>
 #include <elfutils/libdwfl.h>
+#include <stdio_ext.h>
 
 #include "alloc-util.h"
 #include "fd-util.h"
@@ -107,7 +109,7 @@ static int thread_callback(Dwfl_Thread *thread, void *userdata) {
                 return DWARF_CB_ABORT;
 
         if (c->n_thread != 0)
-                fputc_unlocked('\n', c->f);
+                fputc('\n', c->f);
 
         c->n_frame = 0;
 
@@ -144,6 +146,8 @@ int coredump_make_stack_trace(int fd, const char *executable, char **ret) {
         if (!c.f)
                 return -ENOMEM;
 
+        (void) __fsetlocking(c.f, FSETLOCKING_BYCALLER);
+
         elf_version(EV_CURRENT);
 
         c.elf = elf_begin(fd, ELF_C_READ_MMAP, NULL);
index 15e9c04..d435878 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 70a57f1..0836825 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 3752ca2..7e61332 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -18,6 +19,7 @@
 ***/
 
 #include <errno.h>
+#include <stdio_ext.h>
 
 #include "alloc-util.h"
 #include "dropin.h"
@@ -31,6 +33,7 @@
 #include "parse-util.h"
 #include "path-util.h"
 #include "proc-cmdline.h"
+#include "specifier.h"
 #include "string-util.h"
 #include "strv.h"
 #include "unit-name.h"
@@ -59,7 +62,7 @@ static int create_disk(
                 const char *options) {
 
         _cleanup_free_ char *p = NULL, *n = NULL, *d = NULL, *u = NULL, *e = NULL,
-                *filtered = NULL;
+                *filtered = NULL, *u_escaped = NULL, *password_escaped = NULL, *filtered_escaped = NULL, *name_escaped = NULL;
         _cleanup_fclose_ FILE *f = NULL;
         const char *dmname;
         bool noauto, nofail, tmp, swap, netdev;
@@ -79,6 +82,10 @@ static int create_disk(
                 return -EINVAL;
         }
 
+        name_escaped = specifier_escape(name);
+        if (!name_escaped)
+                return log_oom();
+
         e = unit_name_escape(name);
         if (!e)
                 return log_oom();
@@ -95,14 +102,24 @@ static int create_disk(
         if (!u)
                 return log_oom();
 
+        u_escaped = specifier_escape(u);
+        if (!u_escaped)
+                return log_oom();
+
         r = unit_name_from_path(u, ".device", &d);
         if (r < 0)
                 return log_error_errno(r, "Failed to generate unit name: %m");
 
+        password_escaped = specifier_escape(password);
+        if (!password_escaped)
+                return log_oom();
+
         f = fopen(p, "wxe");
         if (!f)
                 return log_error_errno(errno, "Failed to create unit file %s: %m", p);
 
+        (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
+
         fprintf(f,
                 "# Automatically generated by systemd-cryptsetup-generator\n\n"
                 "[Unit]\n"
@@ -113,7 +130,7 @@ static int create_disk(
                 "Conflicts=umount.target\n"
                 "IgnoreOnIsolate=true\n"
                 "After=%s\n",
-                netdev ? "remote-cryptsetup-pre.target" : "cryptsetup-pre.target");
+                netdev ? "remote-fs-pre.target" : "cryptsetup-pre.target");
 
         if (!nofail)
                 fprintf(f,
@@ -122,7 +139,7 @@ static int create_disk(
 
         if (password) {
                 if (STR_IN_SET(password, "/dev/urandom", "/dev/random", "/dev/hw_random"))
-                        fputs_unlocked("After=systemd-random-seed.service\n", f);
+                        fputs("After=systemd-random-seed.service\n", f);
                 else if (!STR_IN_SET(password, "-", "none")) {
                         _cleanup_free_ char *uu;
 
@@ -141,7 +158,7 @@ static int create_disk(
 
                                         fprintf(f, "After=%1$s\nRequires=%1$s\n", dd);
                                 } else
-                                        fprintf(f, "RequiresMountsFor=%s\n", password);
+                                        fprintf(f, "RequiresMountsFor=%s\n", password_escaped);
                         }
                 }
         }
@@ -154,17 +171,22 @@ static int create_disk(
                         d, d);
 
                 if (swap)
-                        fputs_unlocked("Before=dev-mapper-%i.swap\n",
-                                       f);
+                        fputs("Before=dev-mapper-%i.swap\n",
+                              f);
         } else
                 fprintf(f,
                         "RequiresMountsFor=%s\n",
-                        u);
+                        u_escaped);
+
 
         r = generator_write_timeouts(arg_dest, device, name, options, &filtered);
         if (r < 0)
                 return r;
 
+        filtered_escaped = specifier_escape(filtered);
+        if (!filtered_escaped)
+                return log_oom();
+
         fprintf(f,
                 "\n[Service]\n"
                 "Type=oneshot\n"
@@ -173,18 +195,18 @@ static int create_disk(
                 "KeyringMode=shared\n" /* make sure we can share cached keys among instances */
                 "ExecStart=" SYSTEMD_CRYPTSETUP_PATH " attach '%s' '%s' '%s' '%s'\n"
                 "ExecStop=" SYSTEMD_CRYPTSETUP_PATH " detach '%s'\n",
-                name, u, strempty(password), strempty(filtered),
-                name);
+                name_escaped, u_escaped, strempty(password_escaped), strempty(filtered_escaped),
+                name_escaped);
 
         if (tmp)
                 fprintf(f,
                         "ExecStartPost=/sbin/mke2fs '/dev/mapper/%s'\n",
-                        name);
+                        name_escaped);
 
         if (swap)
                 fprintf(f,
                         "ExecStartPost=/sbin/mkswap '/dev/mapper/%s'\n",
-                        name);
+                        name_escaped);
 
         r = fflush_and_check(f);
         if (r < 0)
@@ -218,18 +240,12 @@ static int create_disk(
         return 0;
 }
 
-static void free_arg_disks(void) {
-        crypto_device *d;
-
-        while ((d = hashmap_steal_first(arg_disks))) {
-                free(d->uuid);
-                free(d->keyfile);
-                free(d->name);
-                free(d->options);
-                free(d);
-        }
-
-        hashmap_free(arg_disks);
+static void crypt_device_free(crypto_device *d) {
+        free(d->uuid);
+        free(d->keyfile);
+        free(d->name);
+        free(d->options);
+        free(d);
 }
 
 static crypto_device *get_crypto_device(const char *uuid) {
@@ -336,9 +352,7 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
 
                         d->create = arg_whitelist = true;
 
-                        free(d->name);
-                        d->name = uuid_value;
-                        uuid_value = NULL;
+                        free_and_replace(d->name, uuid_value);
                 } else
                         log_warning("Failed to parse luks name switch %s. Ignoring.", value);
         }
@@ -361,6 +375,8 @@ static int add_crypttab_devices(void) {
                 return 0;
         }
 
+        (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
+
         if (fstat(fileno(f), &st) < 0) {
                 log_error_errno(errno, "Failed to stat /etc/crypttab: %m");
                 return 0;
@@ -493,7 +509,7 @@ int main(int argc, char *argv[]) {
         r = 0;
 
 finish:
-        free_arg_disks();
+        hashmap_free_with_destructor(arg_disks, crypt_device_free);
         free(arg_default_options);
         free(arg_default_keyfile);
 
index 8fc35ad..21c5102 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -18,7 +19,6 @@
 ***/
 
 #include <errno.h>
-#include <libcryptsetup.h>
 #include <mntent.h>
 #include <string.h>
 #include <sys/mman.h>
@@ -27,6 +27,7 @@
 
 #include "alloc-util.h"
 #include "ask-password-api.h"
+#include "crypt-util.h"
 #include "device-util.h"
 #include "escape.h"
 #include "fileio.h"
 #include "strv.h"
 #include "util.h"
 
-static const char *arg_type = NULL; /* CRYPT_LUKS1, CRYPT_TCRYPT or CRYPT_PLAIN */
+/* internal helper */
+#define ANY_LUKS "LUKS"
+
+static const char *arg_type = NULL; /* ANY_LUKS, CRYPT_LUKS1, CRYPT_LUKS2, CRYPT_TCRYPT or CRYPT_PLAIN */
 static char *arg_cipher = NULL;
 static unsigned arg_key_size = 0;
 static int arg_key_slot = CRYPT_ANY_SLOT;
@@ -77,7 +81,7 @@ static int parse_one_option(const char *option) {
         assert(option);
 
         /* Handled outside of this tool */
-        if (STR_IN_SET(option, "noauto", "auto", "nofail", "fail"))
+        if (STR_IN_SET(option, "noauto", "auto", "nofail", "fail", "_netdev"))
                 return 0;
 
         if ((val = startswith(option, "cipher="))) {
@@ -102,7 +106,7 @@ static int parse_one_option(const char *option) {
 
         } else if ((val = startswith(option, "key-slot="))) {
 
-                arg_type = CRYPT_LUKS1;
+                arg_type = ANY_LUKS;
                 r = safe_atoi(val, &arg_key_slot);
                 if (r < 0) {
                         log_error_errno(r, "Failed to parse %s, ignoring: %m", option);
@@ -140,7 +144,7 @@ static int parse_one_option(const char *option) {
                         return log_oom();
 
         } else if ((val = startswith(option, "header="))) {
-                arg_type = CRYPT_LUKS1;
+                arg_type = ANY_LUKS;
 
                 if (!path_is_absolute(val)) {
                         log_error("Header path \"%s\" is not absolute, refusing.", val);
@@ -171,7 +175,7 @@ static int parse_one_option(const char *option) {
         else if (STR_IN_SET(option, "allow-discards", "discard"))
                 arg_discards = true;
         else if (streq(option, "luks"))
-                arg_type = CRYPT_LUKS1;
+                arg_type = ANY_LUKS;
         else if (streq(option, "tcrypt"))
                 arg_type = CRYPT_TCRYPT;
         else if (streq(option, "tcrypt-hidden")) {
@@ -245,27 +249,6 @@ static int parse_options(const char *options) {
         return 0;
 }
 
-static void log_glue(int level, const char *msg, void *usrptr) {
-        log_debug("%s", msg);
-}
-
-static int disk_major_minor(const char *path, char **ret) {
-        struct stat st;
-
-        assert(path);
-
-        if (stat(path, &st) < 0)
-                return -errno;
-
-        if (!S_ISBLK(st.st_mode))
-                return -EINVAL;
-
-        if (asprintf(ret, "/dev/block/%d:%d", major(st.st_rdev), minor(st.st_rdev)) < 0)
-                return -errno;
-
-        return 0;
-}
-
 static char* disk_description(const char *path) {
 
         static const char name_fields[] =
@@ -324,7 +307,7 @@ static char *disk_mount_point(const char *label) {
 }
 
 static int get_password(const char *vol, const char *src, usec_t until, bool accept_cached, char ***ret) {
-        _cleanup_free_ char *description = NULL, *name_buffer = NULL, *mount_point = NULL, *maj_min = NULL, *text = NULL, *escaped_name = NULL;
+        _cleanup_free_ char *description = NULL, *name_buffer = NULL, *mount_point = NULL, *text = NULL, *disk_path = NULL;
         _cleanup_strv_free_erase_ char **passwords = NULL;
         const char *name = NULL;
         char **p, *id;
@@ -337,6 +320,10 @@ static int get_password(const char *vol, const char *src, usec_t until, bool acc
         description = disk_description(src);
         mount_point = disk_mount_point(vol);
 
+        disk_path = cescape(src);
+        if (!disk_path)
+                return log_oom();
+
         if (description && streq(vol, description))
                 /* If the description string is simply the
                  * volume name, then let's not show this
@@ -358,19 +345,7 @@ static int get_password(const char *vol, const char *src, usec_t until, bool acc
         if (asprintf(&text, "Please enter passphrase for disk %s!", name) < 0)
                 return log_oom();
 
-        if (src)
-                (void) disk_major_minor(src, &maj_min);
-
-        if (maj_min) {
-                escaped_name = maj_min;
-                maj_min = NULL;
-        } else
-                escaped_name = cescape(name);
-
-        if (!escaped_name)
-                return log_oom();
-
-        id = strjoina("cryptsetup:", escaped_name);
+        id = strjoina("cryptsetup:", disk_path);
 
         r = ask_password_auto(text, "drive-harddisk", id, "cryptsetup", until,
                               ASK_PASSWORD_PUSH_CACHE | (accept_cached*ASK_PASSWORD_ACCEPT_CACHED),
@@ -386,7 +361,7 @@ static int get_password(const char *vol, const char *src, usec_t until, bool acc
                 if (asprintf(&text, "Please enter passphrase for disk %s! (verification)", name) < 0)
                         return log_oom();
 
-                id = strjoina("cryptsetup-verification:", escaped_name);
+                id = strjoina("cryptsetup-verification:", disk_path);
 
                 r = ask_password_auto(text, "drive-harddisk", id, "cryptsetup", until, ASK_PASSWORD_PUSH_CACHE, &passwords2);
                 if (r < 0)
@@ -491,8 +466,8 @@ static int attach_luks_or_plain(struct crypt_device *cd,
         assert(name);
         assert(key_file || passwords);
 
-        if (!arg_type || streq(arg_type, CRYPT_LUKS1)) {
-                r = crypt_load(cd, CRYPT_LUKS1, NULL);
+        if (!arg_type || STR_IN_SET(arg_type, ANY_LUKS, CRYPT_LUKS1)) {
+                r = crypt_load(cd, CRYPT_LUKS, NULL);
                 if (r < 0) {
                         log_error("crypt_load() failed on device %s.\n", crypt_get_device_name(cd));
                         return r;
@@ -595,7 +570,7 @@ static int help(void) {
 }
 
 int main(int argc, char *argv[]) {
-        struct crypt_device *cd = NULL;
+        _cleanup_(crypt_freep) struct crypt_device *cd = NULL;
         int r = -EINVAL;
 
         if (argc <= 1) {
@@ -657,7 +632,7 @@ int main(int argc, char *argv[]) {
                         goto finish;
                 }
 
-                crypt_set_log_callback(cd, log_glue, NULL);
+                crypt_set_log_callback(cd, cryptsetup_log_glue, NULL);
 
                 status = crypt_status(cd, argv[2]);
                 if (IN_SET(status, CRYPT_ACTIVE, CRYPT_BUSY)) {
@@ -741,7 +716,7 @@ int main(int argc, char *argv[]) {
                         goto finish;
                 }
 
-                crypt_set_log_callback(cd, log_glue, NULL);
+                crypt_set_log_callback(cd, cryptsetup_log_glue, NULL);
 
                 r = crypt_deactivate(cd, argv[2]);
                 if (r < 0) {
@@ -757,9 +732,6 @@ int main(int argc, char *argv[]) {
         r = 0;
 
 finish:
-        if (cd)
-                crypt_free(cd);
-
         free(arg_cipher);
         free(arg_hash);
         free(arg_header);
index 1d8bc71..604faa0 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 605bea5..d286881 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 4b8956f..0023574 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 06564e9..c8fb1c8 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -27,6 +28,8 @@
 #include "log.h"
 #include "loop-util.h"
 #include "string-util.h"
+#include "strv.h"
+#include "user-util.h"
 #include "util.h"
 
 static enum {
@@ -216,6 +219,10 @@ int main(int argc, char *argv[]) {
                 log_error_errno(r, "No suitable root partition found in image %s.", arg_image);
                 goto finish;
         }
+        if (r == -EPROTONOSUPPORT) {
+                log_error_errno(r, "Device %s is loopback block device with partition scanning turned off, please turn it on.", arg_image);
+                goto finish;
+        }
         if (r < 0) {
                 log_error_errno(r, "Failed to dissect image: %m");
                 goto finish;
@@ -259,6 +266,36 @@ int main(int argc, char *argv[]) {
                         putchar('\n');
                 }
 
+                r = dissected_image_acquire_metadata(m);
+                if (r < 0) {
+                        log_error_errno(r, "Failed to acquire image metadata: %m");
+                        goto finish;
+                }
+
+                if (m->hostname)
+                        printf("  Hostname: %s\n", m->hostname);
+
+                if (!sd_id128_is_null(m->machine_id))
+                        printf("Machine ID: " SD_ID128_FORMAT_STR "\n", SD_ID128_FORMAT_VAL(m->machine_id));
+
+                if (!strv_isempty(m->machine_info)) {
+                        char **p, **q;
+
+                        STRV_FOREACH_PAIR(p, q, m->machine_info)
+                                printf("%s %s=%s\n",
+                                       p == m->machine_info ? "Mach. Info:" : "           ",
+                                       *p, *q);
+                }
+
+                if (!strv_isempty(m->os_release)) {
+                        char **p, **q;
+
+                        STRV_FOREACH_PAIR(p, q, m->os_release)
+                                printf("%s %s=%s\n",
+                                       p == m->os_release ? "OS Release:" : "           ",
+                                       *p, *q);
+                }
+
                 break;
         }
 
@@ -267,7 +304,7 @@ int main(int argc, char *argv[]) {
                 if (r < 0)
                         goto finish;
 
-                r = dissected_image_mount(m, arg_path, arg_flags);
+                r = dissected_image_mount(m, arg_path, UID_INVALID, arg_flags);
                 if (r < 0) {
                         log_error_errno(r, "Failed to mount image: %m");
                         goto finish;
index 5518c2a..9c35b46 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 586674d..207ddeb 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
 
 static char *arg_root = NULL;
 static char *arg_locale = NULL;  /* $LANG */
+static char *arg_keymap = NULL;
 static char *arg_locale_messages = NULL; /* $LC_MESSAGES */
 static char *arg_timezone = NULL;
 static char *arg_hostname = NULL;
 static sd_id128_t arg_machine_id = {};
 static char *arg_root_password = NULL;
 static bool arg_prompt_locale = false;
+static bool arg_prompt_keymap = false;
 static bool arg_prompt_timezone = false;
 static bool arg_prompt_hostname = false;
 static bool arg_prompt_root_password = false;
 static bool arg_copy_locale = false;
+static bool arg_copy_keymap = false;
 static bool arg_copy_timezone = false;
 static bool arg_copy_root_password = false;
 
@@ -285,6 +289,80 @@ static int process_locale(void) {
         return 0;
 }
 
+static int prompt_keymap(void) {
+        _cleanup_strv_free_ char **kmaps = NULL;
+        int r;
+
+        if (arg_keymap)
+                return 0;
+
+        if (!arg_prompt_keymap)
+                return 0;
+
+        r = get_keymaps(&kmaps);
+        if (r == -ENOENT) /* no keymaps installed */
+                return r;
+        if (r < 0)
+                return log_error_errno(r, "Failed to read keymaps: %m");
+
+        print_welcome();
+
+        printf("\nAvailable keymaps:\n\n");
+        r = show_menu(kmaps, 3, 22, 60);
+        if (r < 0)
+                return r;
+
+        putchar('\n');
+
+        return prompt_loop("Please enter system keymap name or number",
+                           kmaps, keymap_is_valid, &arg_keymap);
+}
+
+static int process_keymap(void) {
+        const char *etc_vconsoleconf;
+        char **keymap;
+        int r;
+
+        etc_vconsoleconf = prefix_roota(arg_root, "/etc/vconsole.conf");
+        if (laccess(etc_vconsoleconf, F_OK) >= 0)
+                return 0;
+
+        if (arg_copy_keymap && arg_root) {
+
+                mkdir_parents(etc_vconsoleconf, 0755);
+                r = copy_file("/etc/vconsole.conf", etc_vconsoleconf, 0, 0644, 0, COPY_REFLINK);
+                if (r != -ENOENT) {
+                        if (r < 0)
+                                return log_error_errno(r, "Failed to copy %s: %m", etc_vconsoleconf);
+
+                        log_info("%s copied.", etc_vconsoleconf);
+                        return 0;
+                }
+        }
+
+        r = prompt_keymap();
+        if (r == -ENOENT)
+                return 0; /* don't fail if no keymaps are installed */
+        if (r < 0)
+                return r;
+
+        if (isempty(arg_keymap))
+                return 0;
+
+        keymap = STRV_MAKE(strjoina("KEYMAP=", arg_keymap));
+
+        r = mkdir_parents(etc_vconsoleconf, 0755);
+        if (r < 0)
+                return log_error_errno(r, "Failed to create the parent directory of %s: %m", etc_vconsoleconf);
+
+        r = write_env_file(etc_vconsoleconf, keymap);
+        if (r < 0)
+                return log_error_errno(r, "Failed to write %s: %m", etc_vconsoleconf);
+
+        log_info("%s written.", etc_vconsoleconf);
+        return 0;
+}
+
 static int prompt_timezone(void) {
         _cleanup_strv_free_ char **zones = NULL;
         int r;
@@ -613,20 +691,23 @@ static void help(void) {
                "     --root=PATH               Operate on an alternate filesystem root\n"
                "     --locale=LOCALE           Set primary locale (LANG=)\n"
                "     --locale-messages=LOCALE  Set message locale (LC_MESSAGES=)\n"
+               "     --keymap=KEYMAP           Set keymap\n"
                "     --timezone=TIMEZONE       Set timezone\n"
                "     --hostname=NAME           Set host name\n"
                "     --machine-ID=ID           Set machine ID\n"
                "     --root-password=PASSWORD  Set root password\n"
                "     --root-password-file=FILE Set root password from file\n"
                "     --prompt-locale           Prompt the user for locale settings\n"
+               "     --prompt-keymap           Prompt the user for keymap settings\n"
                "     --prompt-timezone         Prompt the user for timezone\n"
                "     --prompt-hostname         Prompt the user for hostname\n"
                "     --prompt-root-password    Prompt the user for root password\n"
                "     --prompt                  Prompt for all of the above\n"
                "     --copy-locale             Copy locale from host\n"
+               "     --copy-keymap             Copy keymap from host\n"
                "     --copy-timezone           Copy timezone from host\n"
                "     --copy-root-password      Copy root password from host\n"
-               "     --copy                    Copy locale, timezone, root password\n"
+               "     --copy                    Copy locale, keymap, timezone, root password\n"
                "     --setup-machine-id        Generate a new random machine ID\n"
                , program_invocation_short_name);
 }
@@ -638,6 +719,7 @@ static int parse_argv(int argc, char *argv[]) {
                 ARG_ROOT,
                 ARG_LOCALE,
                 ARG_LOCALE_MESSAGES,
+                ARG_KEYMAP,
                 ARG_TIMEZONE,
                 ARG_HOSTNAME,
                 ARG_MACHINE_ID,
@@ -645,11 +727,13 @@ static int parse_argv(int argc, char *argv[]) {
                 ARG_ROOT_PASSWORD_FILE,
                 ARG_PROMPT,
                 ARG_PROMPT_LOCALE,
+                ARG_PROMPT_KEYMAP,
                 ARG_PROMPT_TIMEZONE,
                 ARG_PROMPT_HOSTNAME,
                 ARG_PROMPT_ROOT_PASSWORD,
                 ARG_COPY,
                 ARG_COPY_LOCALE,
+                ARG_COPY_KEYMAP,
                 ARG_COPY_TIMEZONE,
                 ARG_COPY_ROOT_PASSWORD,
                 ARG_SETUP_MACHINE_ID,
@@ -661,6 +745,7 @@ static int parse_argv(int argc, char *argv[]) {
                 { "root",                 required_argument, NULL, ARG_ROOT                 },
                 { "locale",               required_argument, NULL, ARG_LOCALE               },
                 { "locale-messages",      required_argument, NULL, ARG_LOCALE_MESSAGES      },
+                { "keymap",               required_argument, NULL, ARG_KEYMAP               },
                 { "timezone",             required_argument, NULL, ARG_TIMEZONE             },
                 { "hostname",             required_argument, NULL, ARG_HOSTNAME             },
                 { "machine-id",           required_argument, NULL, ARG_MACHINE_ID           },
@@ -668,11 +753,13 @@ static int parse_argv(int argc, char *argv[]) {
                 { "root-password-file",   required_argument, NULL, ARG_ROOT_PASSWORD_FILE   },
                 { "prompt",               no_argument,       NULL, ARG_PROMPT               },
                 { "prompt-locale",        no_argument,       NULL, ARG_PROMPT_LOCALE        },
+                { "prompt-keymap",        no_argument,       NULL, ARG_PROMPT_KEYMAP        },
                 { "prompt-timezone",      no_argument,       NULL, ARG_PROMPT_TIMEZONE      },
                 { "prompt-hostname",      no_argument,       NULL, ARG_PROMPT_HOSTNAME      },
                 { "prompt-root-password", no_argument,       NULL, ARG_PROMPT_ROOT_PASSWORD },
                 { "copy",                 no_argument,       NULL, ARG_COPY                 },
                 { "copy-locale",          no_argument,       NULL, ARG_COPY_LOCALE          },
+                { "copy-keymap",          no_argument,       NULL, ARG_COPY_KEYMAP          },
                 { "copy-timezone",        no_argument,       NULL, ARG_COPY_TIMEZONE        },
                 { "copy-root-password",   no_argument,       NULL, ARG_COPY_ROOT_PASSWORD   },
                 { "setup-machine-id",     no_argument,       NULL, ARG_SETUP_MACHINE_ID     },
@@ -725,6 +812,18 @@ static int parse_argv(int argc, char *argv[]) {
 
                         break;
 
+                case ARG_KEYMAP:
+                        if (!keymap_is_valid(optarg)) {
+                                log_error("Keymap %s is not valid.", optarg);
+                                return -EINVAL;
+                        }
+
+                        r = free_and_strdup(&arg_keymap, optarg);
+                        if (r < 0)
+                                return log_oom();
+
+                        break;
+
                 case ARG_TIMEZONE:
                         if (!timezone_is_valid(optarg)) {
                                 log_error("Timezone %s is not valid.", optarg);
@@ -774,13 +873,17 @@ static int parse_argv(int argc, char *argv[]) {
                         break;
 
                 case ARG_PROMPT:
-                        arg_prompt_locale = arg_prompt_timezone = arg_prompt_hostname = arg_prompt_root_password = true;
+                        arg_prompt_locale = arg_prompt_keymap = arg_prompt_timezone = arg_prompt_hostname = arg_prompt_root_password = true;
                         break;
 
                 case ARG_PROMPT_LOCALE:
                         arg_prompt_locale = true;
                         break;
 
+                case ARG_PROMPT_KEYMAP:
+                        arg_prompt_keymap = true;
+                        break;
+
                 case ARG_PROMPT_TIMEZONE:
                         arg_prompt_timezone = true;
                         break;
@@ -794,13 +897,17 @@ static int parse_argv(int argc, char *argv[]) {
                         break;
 
                 case ARG_COPY:
-                        arg_copy_locale = arg_copy_timezone = arg_copy_root_password = true;
+                        arg_copy_locale = arg_copy_keymap = arg_copy_timezone = arg_copy_root_password = true;
                         break;
 
                 case ARG_COPY_LOCALE:
                         arg_copy_locale = true;
                         break;
 
+                case ARG_COPY_KEYMAP:
+                        arg_copy_keymap = true;
+                        break;
+
                 case ARG_COPY_TIMEZONE:
                         arg_copy_timezone = true;
                         break;
@@ -855,6 +962,10 @@ int main(int argc, char *argv[]) {
         if (r < 0)
                 goto finish;
 
+        r = process_keymap();
+        if (r < 0)
+                goto finish;
+
         r = process_timezone();
         if (r < 0)
                 goto finish;
@@ -875,6 +986,7 @@ finish:
         free(arg_root);
         free(arg_locale);
         free(arg_locale_messages);
+        free(arg_keymap);
         free(arg_timezone);
         free(arg_hostname);
         string_erase(arg_root_password);
index cf5a9c5..0091e38 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -397,7 +398,7 @@ int main(int argc, char *argv[]) {
                 goto finish;
         }
         if (pid == 0) {
-                char dash_c[sizeof("-C")-1 + DECIMAL_STR_MAX(int) + 1];
+                char dash_c[STRLEN("-C") + DECIMAL_STR_MAX(int) + 1];
                 int progress_socket = -1;
                 const char *cmdline[9];
                 int i = 0;
index ec70a34..22c4ae9 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
 #include <stdio.h>
 #include <string.h>
 #include <unistd.h>
+#include <stdio_ext.h>
 
 #include "alloc-util.h"
 #include "fd-util.h"
-#include "fs-util.h"
 #include "fileio.h"
+#include "fs-util.h"
 #include "fstab-util.h"
 #include "generator.h"
 #include "log.h"
@@ -37,6 +39,7 @@
 #include "path-util.h"
 #include "proc-cmdline.h"
 #include "special.h"
+#include "specifier.h"
 #include "stat-util.h"
 #include "string-util.h"
 #include "strv.h"
 #include "virt.h"
 #include "volatile-util.h"
 
+typedef enum MountpointFlags {
+        NOAUTO    = 1 << 0,
+        NOFAIL    = 1 << 1,
+        AUTOMOUNT = 1 << 2,
+        MAKEFS    = 1 << 3,
+        GROWFS    = 1 << 4,
+} MountpointFlags;
+
 static const char *arg_dest = "/tmp";
 static const char *arg_dest_late = "/tmp";
 static bool arg_fstab_enabled = true;
@@ -67,7 +78,7 @@ static int write_options(FILE *f, const char *options) {
         if (streq(options, "defaults"))
                 return 0;
 
-        o = strreplace(options, "%", "%%");
+        o = specifier_escape(options);
         if (!o)
                 return log_oom();
 
@@ -78,7 +89,7 @@ static int write_options(FILE *f, const char *options) {
 static int write_what(FILE *f, const char *what) {
         _cleanup_free_ char *w = NULL;
 
-        w = strreplace(what, "%", "%%");
+        w = specifier_escape(what);
         if (!w)
                 return log_oom();
 
@@ -89,8 +100,7 @@ static int write_what(FILE *f, const char *what) {
 static int add_swap(
                 const char *what,
                 struct mntent *me,
-                bool noauto,
-                bool nofail) {
+                MountpointFlags flags) {
 
         _cleanup_free_ char *name = NULL, *unit = NULL;
         _cleanup_fclose_ FILE *f = NULL;
@@ -125,11 +135,13 @@ static int add_swap(
                                        "Failed to create unit file %s: %m",
                                        unit);
 
-        fputs_unlocked("# Automatically generated by systemd-fstab-generator\n\n"
-                       "[Unit]\n"
-                       "SourcePath=/etc/fstab\n"
-                       "Documentation=man:fstab(5) man:systemd-fstab-generator(8)\n\n"
-                       "[Swap]\n", f);
+        (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
+
+        fputs("# Automatically generated by systemd-fstab-generator\n\n"
+              "[Unit]\n"
+              "SourcePath=/etc/fstab\n"
+              "Documentation=man:fstab(5) man:systemd-fstab-generator(8)\n\n"
+              "[Swap]\n", f);
 
         r = write_what(f, what);
         if (r < 0)
@@ -148,9 +160,19 @@ static int add_swap(
         if (r < 0)
                 return r;
 
-        if (!noauto) {
+        if (flags & MAKEFS) {
+                r = generator_hook_up_mkswap(arg_dest, what);
+                if (r < 0)
+                        return r;
+        }
+
+        if (flags & GROWFS)
+                /* TODO: swap devices must be wiped and recreated */
+                log_warning("%s: growing swap devices is currently unsupported.", what);
+
+        if (!(flags & NOAUTO)) {
                 r = generator_add_symlink(arg_dest, SPECIAL_SWAP_TARGET,
-                                          nofail ? "wants" : "requires", name);
+                                          (flags & NOFAIL) ? "wants" : "requires", name);
                 if (r < 0)
                         return r;
         }
@@ -261,7 +283,7 @@ static int write_before(FILE *f, const char *opts) {
 }
 
 static int write_requires_mounts_for(FILE *f, const char *opts) {
-        _cleanup_strv_free_ char **paths = NULL;
+        _cleanup_strv_free_ char **paths = NULL, **paths_escaped = NULL;
         _cleanup_free_ char *res = NULL;
         int r;
 
@@ -274,7 +296,11 @@ static int write_requires_mounts_for(FILE *f, const char *opts) {
         if (r == 0)
                 return 0;
 
-        res = strv_join(paths, " ");
+        r = specifier_escape_strv(paths, &paths_escaped);
+        if (r < 0)
+                return log_error_errno(r, "Failed to escape paths: %m");
+
+        res = strv_join(paths_escaped, " ");
         if (!res)
                 return log_oom();
 
@@ -291,16 +317,16 @@ static int add_mount(
                 const char *fstype,
                 const char *opts,
                 int passno,
-                bool noauto,
-                bool nofail,
-                bool automount,
+                MountpointFlags flags,
                 const char *post,
                 const char *source) {
 
         _cleanup_free_ char
-                *name = NULL, *unit = NULL,
+                *name = NULL,
                 *automount_name = NULL, *automount_unit = NULL,
-                *filtered = NULL;
+                *filtered = NULL,
+                *where_escaped = NULL;
+        const char *unit;
         _cleanup_fclose_ FILE *f = NULL;
         int r;
 
@@ -323,23 +349,21 @@ static int add_mount(
                 return 0;
 
         if (path_equal(where, "/")) {
-                if (noauto)
+                if (flags & NOAUTO)
                         log_warning("Ignoring \"noauto\" for root device");
-                if (nofail)
+                if (flags & NOFAIL)
                         log_warning("Ignoring \"nofail\" for root device");
-                if (automount)
+                if (flags & AUTOMOUNT)
                         log_warning("Ignoring automount option for root device");
 
-                noauto = nofail = automount = false;
+                SET_FLAG(flags, NOAUTO | NOFAIL | AUTOMOUNT, false);
         }
 
         r = unit_name_from_path(where, ".mount", &name);
         if (r < 0)
                 return log_error_errno(r, "Failed to generate unit name: %m");
 
-        unit = strjoin(dest, "/", name);
-        if (!unit)
-                return log_oom();
+        unit = strjoina(dest, "/", name);
 
         f = fopen(unit, "wxe");
         if (!f)
@@ -349,6 +373,8 @@ static int add_mount(
                                        "Failed to create unit file %s: %m",
                                        unit);
 
+        (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
+
         fprintf(f,
                 "# Automatically generated by systemd-fstab-generator\n\n"
                 "[Unit]\n"
@@ -356,7 +382,7 @@ static int add_mount(
                 "Documentation=man:fstab(5) man:systemd-fstab-generator(8)\n",
                 source);
 
-        if (STRPTR_IN_SET(fstype, "nfs", "nfs4") && !automount &&
+        if (STRPTR_IN_SET(fstype, "nfs", "nfs4") && !(flags & AUTOMOUNT) &&
             fstab_test_yes_no_option(opts, "bg\0" "fg\0")) {
                 /* The default retry timeout that mount.nfs uses for 'bg' mounts
                  * is 10000 minutes, where as it uses 2 minutes for 'fg' mounts.
@@ -367,13 +393,13 @@ static int add_mount(
                  * By placing these options first, they can be over-ridden by
                  * settings in /etc/fstab. */
                 opts = strjoina("x-systemd.mount-timeout=infinity,retry=10000,", opts, ",fg");
-                nofail = true;
+                SET_FLAG(flags, NOFAIL, true);
         }
 
-        if (!nofail && !automount)
+        if (!(flags & NOFAIL) && !(flags & AUTOMOUNT))
                 fprintf(f, "Before=%s\n", post);
 
-        if (!automount && opts) {
+        if (!(flags & AUTOMOUNT) && opts) {
                  r = write_after(f, opts);
                  if (r < 0)
                          return r;
@@ -397,14 +423,25 @@ static int add_mount(
         fprintf(f, "\n[Mount]\n");
         if (original_where)
                 fprintf(f, "# Canonicalized from %s\n", original_where);
-        fprintf(f, "Where=%s\n", where);
+
+        where_escaped = specifier_escape(where);
+        if (!where_escaped)
+                return log_oom();
+        fprintf(f, "Where=%s\n", where_escaped);
 
         r = write_what(f, what);
         if (r < 0)
                 return r;
 
-        if (!isempty(fstype) && !streq(fstype, "auto"))
-                fprintf(f, "Type=%s\n", fstype);
+        if (!isempty(fstype) && !streq(fstype, "auto")) {
+                _cleanup_free_ char *t;
+
+                t = specifier_escape(fstype);
+                if (!t)
+                        return -ENOMEM;
+
+                fprintf(f, "Type=%s\n", t);
+        }
 
         r = generator_write_timeouts(dest, what, where, opts, &filtered);
         if (r < 0)
@@ -426,14 +463,26 @@ static int add_mount(
         if (r < 0)
                 return log_error_errno(r, "Failed to write unit file %s: %m", unit);
 
-        if (!noauto && !automount) {
+        if (flags & MAKEFS) {
+                r = generator_hook_up_mkfs(dest, what, where, fstype);
+                if (r < 0)
+                        return r;
+        }
+
+        if (flags & GROWFS) {
+                r = generator_hook_up_growfs(dest, where, post);
+                if (r < 0)
+                        return r;
+        }
+
+        if (!(flags & NOAUTO) && !(flags & AUTOMOUNT)) {
                 r = generator_add_symlink(dest, post,
-                                          nofail ? "wants" : "requires", name);
+                                          (flags & NOFAIL) ? "wants" : "requires", name);
                 if (r < 0)
                         return r;
         }
 
-        if (automount) {
+        if (flags & AUTOMOUNT) {
                 r = unit_name_from_path(where, ".automount", &automount_name);
                 if (r < 0)
                         return log_error_errno(r, "Failed to generate unit name: %m");
@@ -447,6 +496,8 @@ static int add_mount(
                 if (!f)
                         return log_error_errno(errno, "Failed to create unit file %s: %m", automount_unit);
 
+                (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
+
                 fprintf(f,
                         "# Automatically generated by systemd-fstab-generator\n\n"
                         "[Unit]\n"
@@ -475,7 +526,7 @@ static int add_mount(
                         "\n"
                         "[Automount]\n"
                         "Where=%s\n",
-                        where);
+                        where_escaped);
 
                 r = write_idle_timeout(f, where, opts);
                 if (r < 0)
@@ -486,7 +537,7 @@ static int add_mount(
                         return log_error_errno(r, "Failed to write unit file %s: %m", automount_unit);
 
                 r = generator_add_symlink(dest, post,
-                                          nofail ? "wants" : "requires", automount_name);
+                                          (flags & NOFAIL) ? "wants" : "requires", automount_name);
                 if (r < 0)
                         return r;
         }
@@ -511,7 +562,7 @@ static int parse_fstab(bool initrd) {
 
         while ((me = getmntent(f))) {
                 _cleanup_free_ char *where = NULL, *what = NULL, *canonical_where = NULL;
-                bool noauto, nofail;
+                bool makefs, growfs, noauto, nofail;
                 int k;
 
                 if (initrd && !mount_in_initrd(me))
@@ -553,14 +604,18 @@ static int parse_fstab(bool initrd) {
                         }
                 }
 
+                makefs = fstab_test_option(me->mnt_opts, "x-systemd.makefs\0");
+                growfs = fstab_test_option(me->mnt_opts, "x-systemd.growfs\0");
                 noauto = fstab_test_yes_no_option(me->mnt_opts, "noauto\0" "auto\0");
                 nofail = fstab_test_yes_no_option(me->mnt_opts, "nofail\0" "fail\0");
-                log_debug("Found entry what=%s where=%s type=%s nofail=%s noauto=%s",
+                log_debug("Found entry what=%s where=%s type=%s makefs=%s nofail=%s noauto=%s",
                           what, where, me->mnt_type,
+                          yes_no(makefs),
                           yes_no(noauto), yes_no(nofail));
 
                 if (streq(me->mnt_type, "swap"))
-                        k = add_swap(what, me, noauto, nofail);
+                        k = add_swap(what, me,
+                                     makefs*MAKEFS | growfs*GROWFS | noauto*NOAUTO | nofail*NOFAIL);
                 else {
                         bool automount;
                         const char *post;
@@ -582,14 +637,12 @@ static int parse_fstab(bool initrd) {
                                       me->mnt_type,
                                       me->mnt_opts,
                                       me->mnt_passno,
-                                      noauto,
-                                      nofail,
-                                      automount,
+                                      makefs*MAKEFS | growfs*GROWFS | noauto*NOAUTO | nofail*NOFAIL | automount*AUTOMOUNT,
                                       post,
                                       fstab_path);
                 }
 
-                if (k < 0)
+                if (r >= 0 && k < 0)
                         r = k;
         }
 
@@ -645,9 +698,7 @@ static int add_sysroot_mount(void) {
                          arg_root_fstype,
                          opts,
                          is_device_path(what) ? 1 : 0, /* passno */
-                         false,                        /* noauto off */
-                         false,                        /* nofail off */
-                         false,                        /* automount off */
+                         0,                            /* makefs off, growfs off, noauto off, nofail off, automount off */
                          SPECIAL_INITRD_ROOT_FS_TARGET,
                          "/proc/cmdline");
 }
@@ -700,9 +751,7 @@ static int add_sysroot_usr_mount(void) {
                          arg_usr_fstype,
                          opts,
                          is_device_path(what) ? 1 : 0, /* passno */
-                         false,                        /* noauto off */
-                         false,                        /* nofail off */
-                         false,                        /* automount off */
+                         0,
                          SPECIAL_INITRD_FS_TARGET,
                          "/proc/cmdline");
 }
@@ -741,9 +790,7 @@ static int add_volatile_var(void) {
                          "tmpfs",
                          "mode=0755",
                          0,
-                         false,
-                         false,
-                         false,
+                         0,
                          SPECIAL_LOCAL_FS_TARGET,
                          "/proc/cmdline");
 }
@@ -780,19 +827,13 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
                         return log_oom();
 
         } else if (streq(key, "rootflags")) {
-                char *o;
 
                 if (proc_cmdline_value_missing(key, value))
                         return 0;
 
-                o = arg_root_options ?
-                        strjoin(arg_root_options, ",", value) :
-                        strdup(value);
-                if (!o)
+                if (!strextend_with_separator(&arg_root_options, ",", value, NULL))
                         return log_oom();
 
-                free(arg_root_options);
-                arg_root_options = o;
         } else if (streq(key, "roothash")) {
 
                 if (proc_cmdline_value_missing(key, value))
@@ -818,20 +859,13 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
                         return log_oom();
 
         } else if (streq(key, "mount.usrflags")) {
-                char *o;
 
                 if (proc_cmdline_value_missing(key, value))
                         return 0;
 
-                o = arg_usr_options ?
-                        strjoin(arg_usr_options, ",", value) :
-                        strdup(value);
-                if (!o)
+                if (!strextend_with_separator(&arg_usr_options, ",", value, NULL))
                         return log_oom();
 
-                free(arg_usr_options);
-                arg_usr_options = o;
-
         } else if (streq(key, "rw") && !value)
                 arg_root_rw = true;
         else if (streq(key, "ro") && !value)
index a143b54..3f62a81 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index ae0a8da..9e8b956 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -43,6 +44,7 @@
 #include "path-util.h"
 #include "proc-cmdline.h"
 #include "special.h"
+#include "specifier.h"
 #include "stat-util.h"
 #include "string-util.h"
 #include "udev-util.h"
@@ -56,7 +58,7 @@ static bool arg_root_enabled = true;
 static bool arg_root_rw = false;
 
 static int add_cryptsetup(const char *id, const char *what, bool rw, bool require, char **device) {
-        _cleanup_free_ char *e = NULL, *n = NULL, *p = NULL, *d = NULL, *to = NULL;
+        _cleanup_free_ char *e = NULL, *n = NULL, *p = NULL, *d = NULL, *id_escaped = NULL, *what_escaped = NULL;
         _cleanup_fclose_ FILE *f = NULL;
         char *ret;
         int r;
@@ -76,6 +78,14 @@ static int add_cryptsetup(const char *id, const char *what, bool rw, bool requir
         if (r < 0)
                 return log_error_errno(r, "Failed to generate unit name: %m");
 
+        id_escaped = specifier_escape(id);
+        if (!id_escaped)
+                return log_oom();
+
+        what_escaped = specifier_escape(what);
+        if (!what_escaped)
+                return log_oom();
+
         p = strjoin(arg_dest, "/", n);
         if (!p)
                 return log_oom();
@@ -103,8 +113,8 @@ static int add_cryptsetup(const char *id, const char *what, bool rw, bool requir
                 "ExecStart=" SYSTEMD_CRYPTSETUP_PATH " attach '%s' '%s' '' '%s'\n"
                 "ExecStop=" SYSTEMD_CRYPTSETUP_PATH " detach '%s'\n",
                 d, d,
-                id, what, rw ? "" : "read-only",
-                id);
+                id_escaped, what_escaped, rw ? "" : "read-only",
+                id_escaped);
 
         r = fflush_and_check(f);
         if (r < 0)
@@ -164,6 +174,10 @@ static int add_mount(
         _cleanup_fclose_ FILE *f = NULL;
         int r;
 
+        /* Note that we don't apply specifier escaping on the input strings here, since we know they are not configured
+         * externally, but all originate from our own sources here, and hence we know they contain no % characters that
+         * could potentially be understood as specifiers. */
+
         assert(id);
         assert(what);
         assert(where);
@@ -688,7 +702,7 @@ static int add_mounts(void) {
 }
 
 int main(int argc, char *argv[]) {
-        int r = 0, k;
+        int r, k;
 
         if (argc > 1 && argc != 4) {
                 log_error("This program takes three or no arguments.");
@@ -720,6 +734,8 @@ int main(int argc, char *argv[]) {
 
         if (arg_root_enabled)
                 r = add_root_mount();
+        else
+                r = 0;
 
         if (!in_initrd()) {
                 k = add_mounts();
index a97fe66..01222db 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 21df3c4..2a42721 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index f5a9de9..e06b111 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -41,18 +42,6 @@ static bool arg_transient = false;
 static bool arg_pretty = false;
 static bool arg_static = false;
 
-static void polkit_agent_open_if_enabled(void) {
-
-        /* Open the polkit agent as a child process if necessary */
-        if (!arg_ask_password)
-                return;
-
-        if (arg_transport != BUS_TRANSPORT_LOCAL)
-                return;
-
-        polkit_agent_open();
-}
-
 typedef struct StatusInfo {
         char *hostname;
         char *static_hostname;
@@ -243,7 +232,7 @@ static int set_simple_string(sd_bus *bus, const char *method, const char *value)
         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
         int r = 0;
 
-        polkit_agent_open_if_enabled();
+        polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
 
         r = sd_bus_call_method(
                         bus,
index fe0aa00..5feaa60 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -95,7 +96,7 @@ static int context_read_data(Context *c) {
         if (!c->data[PROP_HOSTNAME])
                 return -ENOMEM;
 
-        r = read_hostname_config("/etc/hostname", &c->data[PROP_STATIC_HOSTNAME]);
+        r = read_etc_hostname(NULL, &c->data[PROP_STATIC_HOSTNAME]);
         if (r < 0 && r != -ENOENT)
                 return r;
 
index 834300a..75cc948 100644 (file)
@@ -1,14 +1,32 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
+# Copyright 2017 Zbigniew Jędrzejewski-Szmek
+#
+# 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.
+#
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
 if conf.get('ENABLE_HOSTNAMED') == 1
         install_data('org.freedesktop.hostname1.conf',
                      install_dir : dbuspolicydir)
         install_data('org.freedesktop.hostname1.service',
                      install_dir : dbussystemservicedir)
 
-        custom_target(
+        i18n.merge_file(
                 'org.freedesktop.hostname1.policy',
                 input : 'org.freedesktop.hostname1.policy.in',
                 output : 'org.freedesktop.hostname1.policy',
-                command : intltool_command,
+                po_dir : po_dir,
+                data_dirs : po_dir,
                 install : install_polkit,
                 install_dir : polkitpolicydir)
 endif
index 46b4aad..e2658c6 100644 (file)
@@ -3,6 +3,8 @@
         "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   systemd is free software; you can redistribute it and/or modify it
index c32c1d4..b10ca31 100644 (file)
@@ -3,6 +3,8 @@
         "http://www.freedesktop.org/standards/PolicyKit/1/policyconfig.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   systemd is free software; you can redistribute it and/or modify it
@@ -17,8 +19,8 @@
         <vendor_url>http://www.freedesktop.org/wiki/Software/systemd</vendor_url>
 
         <action id="org.freedesktop.hostname1.set-hostname">
-                <_description>Set host name</_description>
-                <_message>Authentication is required to set the local host name.</_message>
+                <description>Set host name</description>
+                <message>Authentication is required to set the local host name.</message>
                 <defaults>
                         <allow_any>auth_admin_keep</allow_any>
                         <allow_inactive>auth_admin_keep</allow_inactive>
@@ -27,8 +29,8 @@
         </action>
 
         <action id="org.freedesktop.hostname1.set-static-hostname">
-                <_description>Set static host name</_description>
-                <_message>Authentication is required to set the statically configured local host name, as well as the pretty host name.</_message>
+                <description>Set static host name</description>
+                <message>Authentication is required to set the statically configured local host name, as well as the pretty host name.</message>
                 <defaults>
                         <allow_any>auth_admin_keep</allow_any>
                         <allow_inactive>auth_admin_keep</allow_inactive>
@@ -38,8 +40,8 @@
         </action>
 
         <action id="org.freedesktop.hostname1.set-machine-info">
-                <_description>Set machine information</_description>
-                <_message>Authentication is required to set local machine information.</_message>
+                <description>Set machine information</description>
+                <message>Authentication is required to set local machine information.</message>
                 <defaults>
                         <allow_any>auth_admin_keep</allow_any>
                         <allow_inactive>auth_admin_keep</allow_inactive>
index 6041ed6..421a8c6 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index c964a28..4540260 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 0e8f3fb..7069c95 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index a758cc5..c7c24c9 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index a3dbce1..8485027 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 8e723d4..f932a37 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 3bb6027..dafe3e1 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 1e3c8bb..5739ade 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index cc98c33..753d139 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index ae71682..2f989a1 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -103,28 +104,24 @@ int import_fork_tar_x(const char *path, pid_t *ret) {
 
                 pipefd[1] = safe_close(pipefd[1]);
 
-                if (dup2(pipefd[0], STDIN_FILENO) != STDIN_FILENO) {
-                        log_error_errno(errno, "Failed to dup2() fd: %m");
+                r = move_fd(pipefd[0], STDIN_FILENO, false);
+                if (r < 0) {
+                        log_error_errno(r, "Failed to move fd: %m");
                         _exit(EXIT_FAILURE);
                 }
 
-                if (pipefd[0] != STDIN_FILENO)
-                        pipefd[0] = safe_close(pipefd[0]);
-
                 null_fd = open("/dev/null", O_WRONLY|O_NOCTTY);
                 if (null_fd < 0) {
                         log_error_errno(errno, "Failed to open /dev/null: %m");
                         _exit(EXIT_FAILURE);
                 }
 
-                if (dup2(null_fd, STDOUT_FILENO) != STDOUT_FILENO) {
-                        log_error_errno(errno, "Failed to dup2() fd: %m");
+                r = move_fd(null_fd, STDOUT_FILENO, false);
+                if (r < 0) {
+                        log_error_errno(r, "Failed to move fd: %m");
                         _exit(EXIT_FAILURE);
                 }
 
-                if (null_fd != STDOUT_FILENO)
-                        null_fd = safe_close(null_fd);
-
                 stdio_unset_cloexec();
 
                 if (unshare(CLONE_NEWNET) < 0)
@@ -175,28 +172,24 @@ int import_fork_tar_c(const char *path, pid_t *ret) {
 
                 pipefd[0] = safe_close(pipefd[0]);
 
-                if (dup2(pipefd[1], STDOUT_FILENO) != STDOUT_FILENO) {
-                        log_error_errno(errno, "Failed to dup2() fd: %m");
+                r = move_fd(pipefd[1], STDOUT_FILENO, false);
+                if (r < 0) {
+                        log_error_errno(r, "Failed to move fd: %m");
                         _exit(EXIT_FAILURE);
                 }
 
-                if (pipefd[1] != STDOUT_FILENO)
-                        pipefd[1] = safe_close(pipefd[1]);
-
                 null_fd = open("/dev/null", O_RDONLY|O_NOCTTY);
                 if (null_fd < 0) {
                         log_error_errno(errno, "Failed to open /dev/null: %m");
                         _exit(EXIT_FAILURE);
                 }
 
-                if (dup2(null_fd, STDIN_FILENO) != STDIN_FILENO) {
-                        log_error_errno(errno, "Failed to dup2() fd: %m");
+                r = move_fd(null_fd, STDIN_FILENO, false);
+                if (r < 0) {
+                        log_error_errno(errno, "Failed to move fd: %m");
                         _exit(EXIT_FAILURE);
                 }
 
-                if (null_fd != STDIN_FILENO)
-                        null_fd = safe_close(null_fd);
-
                 stdio_unset_cloexec();
 
                 if (unshare(CLONE_NEWNET) < 0)
index 07d3250..55ec536 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 01b78fc..cb5b982 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 6b59d07..1eac4d4 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 55cf8e8..f117c94 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -206,9 +207,7 @@ static int raw_import_maybe_convert_qcow2(RawImport *i) {
         }
 
         (void) unlink(i->temp_path);
-        free(i->temp_path);
-        i->temp_path = t;
-        t = NULL;
+        free_and_replace(i->temp_path, t);
 
         safe_close(i->output_fd);
         i->output_fd = converted_fd;
index 4f543e0..1e0227a 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index ba140bc..c501449 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 24abe06..44743c9 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 2b6ca24..cc454ee 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 9b3fd06..9c7694c 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -18,6 +19,7 @@
 ***/
 
 #include <sys/prctl.h>
+#include <sys/wait.h>
 
 #include "sd-bus.h"
 
@@ -250,7 +252,7 @@ static void transfer_send_logs(Transfer *t, bool flush) {
                 n = strndup(t->log_message, e - t->log_message);
 
                 /* Skip over NUL and newlines */
-                while ((e < t->log_message + t->log_message_size) && IN_SET(*e, 0, '\n'))
+                while (e < t->log_message + t->log_message_size && (*e == 0 || *e == '\n'))
                         e++;
 
                 memmove(t->log_message, e, t->log_message + sizeof(t->log_message) - e);
index e3a0da6..2dcc0bc 100644 (file)
@@ -1,3 +1,20 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
+# Copyright 2017 Zbigniew Jędrzejewski-Szmek
+#
+# 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.
+#
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
 systemd_importd_sources = files('''
         importd.c
 '''.split())
@@ -54,11 +71,12 @@ if conf.get('ENABLE_IMPORTD') == 1
         install_data('org.freedesktop.import1.service',
                      install_dir : dbussystemservicedir)
 
-        custom_target(
+        i18n.merge_file(
                 'org.freedesktop.import1.policy',
                 input : 'org.freedesktop.import1.policy.in',
                 output : 'org.freedesktop.import1.policy',
-                command : intltool_command,
+                po_dir : po_dir,
+                data_dirs : po_dir,
                 install : install_polkit,
                 install_dir : polkitpolicydir)
 
index ed2539a..9889cd6 100644 (file)
@@ -3,6 +3,8 @@
         "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   systemd is free software; you can redistribute it and/or modify it
index 85924ed..d96ca2d 100644 (file)
@@ -3,6 +3,8 @@
         "http://www.freedesktop.org/standards/PolicyKit/1/policyconfig.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   systemd is free software; you can redistribute it and/or modify it
@@ -17,8 +19,8 @@
         <vendor_url>http://www.freedesktop.org/wiki/Software/systemd</vendor_url>
 
         <action id="org.freedesktop.import1.import">
-                <_description>Import a VM or container image</_description>
-                <_message>Authentication is required to import a VM or container image</_message>
+                <description>Import a VM or container image</description>
+                <message>Authentication is required to import a VM or container image</message>
                 <defaults>
                         <allow_any>auth_admin</allow_any>
                         <allow_inactive>auth_admin</allow_inactive>
@@ -27,8 +29,8 @@
         </action>
 
         <action id="org.freedesktop.import1.export">
-                <_description>Export a VM or container image</_description>
-                <_message>Authentication is required to export a VM or container image</_message>
+                <description>Export a VM or container image</description>
+                <message>Authentication is required to export a VM or container image</message>
                 <defaults>
                         <allow_any>auth_admin</allow_any>
                         <allow_inactive>auth_admin</allow_inactive>
@@ -37,8 +39,8 @@
         </action>
 
         <action id="org.freedesktop.import1.pull">
-                <_description>Download a VM or container image</_description>
-                <_message>Authentication is required to download a VM or container image</_message>
+                <description>Download a VM or container image</description>
+                <message>Authentication is required to download a VM or container image</message>
                 <defaults>
                         <allow_any>auth_admin</allow_any>
                         <allow_inactive>auth_admin</allow_inactive>
index 8fc4c47..34d26d0 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 78840dd..c2a3a6a 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -191,7 +192,7 @@ int pull_make_path(const char *url, const char *etag, const char *image_root, co
         }
 
         path = strjoin(image_root, "/", strempty(prefix), escaped_url, escaped_etag ? "." : "",
-                       strempty(escaped_etag), strempty(suffix), NULL);
+                       strempty(escaped_etag), strempty(suffix));
         if (!path)
                 return -ENOMEM;
 
@@ -209,7 +210,7 @@ int pull_make_path(const char *url, const char *etag, const char *image_root, co
                         return r;
 
                 path = strjoin(image_root, "/", strempty(prefix), hash, escaped_etag ? "." : "",
-                               strempty(escaped_etag), strempty(suffix), NULL);
+                               strempty(escaped_etag), strempty(suffix));
                 if (!path)
                         return -ENOMEM;
         }
@@ -492,28 +493,24 @@ int pull_verify(PullJob *main_job,
 
                 gpg_pipe[1] = safe_close(gpg_pipe[1]);
 
-                if (dup2(gpg_pipe[0], STDIN_FILENO) != STDIN_FILENO) {
-                        log_error_errno(errno, "Failed to dup2() fd: %m");
+                r = move_fd(gpg_pipe[0], STDIN_FILENO, false);
+                if (r < 0) {
+                        log_error_errno(errno, "Failed to move fd: %m");
                         _exit(EXIT_FAILURE);
                 }
 
-                if (gpg_pipe[0] != STDIN_FILENO)
-                        gpg_pipe[0] = safe_close(gpg_pipe[0]);
-
                 null_fd = open("/dev/null", O_WRONLY|O_NOCTTY);
                 if (null_fd < 0) {
                         log_error_errno(errno, "Failed to open /dev/null: %m");
                         _exit(EXIT_FAILURE);
                 }
 
-                if (dup2(null_fd, STDOUT_FILENO) != STDOUT_FILENO) {
-                        log_error_errno(errno, "Failed to dup2() fd: %m");
+                r = move_fd(null_fd, STDOUT_FILENO, false);
+                if (r < 0) {
+                        log_error_errno(errno, "Failed to move fd: %m");
                         _exit(EXIT_FAILURE);
                 }
 
-                if (null_fd != STDOUT_FILENO)
-                        null_fd = safe_close(null_fd);
-
                 cmd[k++] = strjoina("--homedir=", gpg_home);
 
                 /* We add the user keyring only to the command line
index f1f1a17..14c81fb 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 995a652..2b71766 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 412b66c..e8becdc 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index b45ac81..880cb84 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -268,9 +269,7 @@ static int raw_pull_maybe_convert_qcow2(RawPull *i) {
         }
 
         (void) unlink(i->temp_path);
-        free(i->temp_path);
-        i->temp_path = t;
-        t = NULL;
+        free_and_replace(i->temp_path, t);
 
         safe_close(i->raw_job->disk_fd);
         i->raw_job->disk_fd = converted_fd;
index 6954d98..c951fc2 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 12211a6..ed91511 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 7e63e49..9f004ac 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 4af5d9c..46e0fd5 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 0073486..7e37bf4 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 6dddac8..ae1fb8f 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index b820253..428191d 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index deb3f1b..5488999 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index a0f1f3e..82c70cf 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -225,7 +226,7 @@ static ssize_t request_reader_entries(
                         return MHD_CONTENT_READER_END_WITH_ERROR;
                 }
 
-                r = output_journal(m->tmp, m->journal, m->mode, 0, OUTPUT_FULL_WIDTH, NULL);
+                r = output_journal(m->tmp, m->journal, m->mode, 0, OUTPUT_FULL_WIDTH, NULL, NULL);
                 if (r < 0) {
                         log_error_errno(r, "Failed to serialize item: %m");
                         return MHD_CONTENT_READER_END_WITH_ERROR;
index d61d1c1..2c4e28a 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index e363252..7aa2f06 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 734cad3..c5c6abb 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index e04af54..7fffc29 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 9f51137..e44989e 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -26,6 +27,7 @@
 #include <sys/prctl.h>
 #include <sys/socket.h>
 #include <unistd.h>
+#include <stdint.h>
 
 #include "sd-daemon.h"
 
@@ -299,6 +301,9 @@ static int dispatch_raw_connection_event(sd_event_source *event,
                                          int fd,
                                          uint32_t revents,
                                          void *userdata);
+static int null_timer_event_handler(sd_event_source *s,
+                                uint64_t usec,
+                                void *userdata);
 static int dispatch_http_event(sd_event_source *event,
                                int fd,
                                uint32_t revents,
@@ -417,7 +422,7 @@ static int add_source(RemoteServer *s, int fd, char* name, bool own_name) {
 static int add_raw_socket(RemoteServer *s, int fd) {
         int r;
         _cleanup_close_ int fd_ = fd;
-        char name[sizeof("raw-socket-")-1 + DECIMAL_STR_MAX(int) + 1];
+        char name[STRLEN("raw-socket-") + DECIMAL_STR_MAX(int) + 1];
 
         assert(fd >= 0);
 
@@ -727,7 +732,7 @@ static int setup_microhttpd_server(RemoteServer *s,
                 goto error;
         }
 
-        r = sd_event_add_io(s->events, &d->event,
+        r = sd_event_add_io(s->events, &d->io_event,
                             epoll_fd, EPOLLIN,
                             dispatch_http_event, d);
         if (r < 0) {
@@ -735,7 +740,21 @@ static int setup_microhttpd_server(RemoteServer *s,
                 goto error;
         }
 
-        r = sd_event_source_set_description(d->event, "epoll-fd");
+        r = sd_event_source_set_description(d->io_event, "io_event");
+        if (r < 0) {
+                log_error_errno(r, "Failed to set source name: %m");
+                goto error;
+        }
+
+        r = sd_event_add_time(s->events, &d->timer_event,
+                              CLOCK_MONOTONIC, UINT64_MAX, 0,
+                              null_timer_event_handler, d);
+        if (r < 0) {
+                log_error_errno(r, "Failed to add timer_event: %m");
+                goto error;
+        }
+
+        r = sd_event_source_set_description(d->timer_event, "timer_event");
         if (r < 0) {
                 log_error_errno(r, "Failed to set source name: %m");
                 goto error;
@@ -777,12 +796,19 @@ static int setup_microhttpd_socket(RemoteServer *s,
         return setup_microhttpd_server(s, fd, key, cert, trust);
 }
 
+static int null_timer_event_handler(sd_event_source *timer_event,
+                                    uint64_t usec,
+                                    void *userdata) {
+        return dispatch_http_event(timer_event, 0, 0, userdata);
+}
+
 static int dispatch_http_event(sd_event_source *event,
                                int fd,
                                uint32_t revents,
                                void *userdata) {
         MHDDaemonWrapper *d = userdata;
         int r;
+        MHD_UNSIGNED_LONG_LONG timeout = ULONG_LONG_MAX;
 
         assert(d);
 
@@ -792,6 +818,18 @@ static int dispatch_http_event(sd_event_source *event,
                 // XXX: unregister daemon
                 return -EINVAL;
         }
+        if (MHD_get_timeout(d->daemon, &timeout) == MHD_NO)
+                timeout = ULONG_LONG_MAX;
+
+        r = sd_event_source_set_time(d->timer_event, timeout);
+        if (r < 0) {
+                log_warning_errno(r, "Unable to set event loop timeout: %m, this may result in indefinite blocking!");
+                return 1;
+        }
+
+        r = sd_event_source_set_enabled(d->timer_event, SD_EVENT_ON);
+        if (r < 0)
+                log_warning_errno(r, "Unable to enable timer_event: %m, this may result in indefinite blocking!");
 
         return 1; /* work to do */
 }
@@ -1005,17 +1043,17 @@ static int remoteserver_init(RemoteServer *s,
         return 0;
 }
 
+static void MHDDaemonWrapper_free(MHDDaemonWrapper *d) {
+        MHD_stop_daemon(d->daemon);
+        sd_event_source_unref(d->io_event);
+        sd_event_source_unref(d->timer_event);
+        free(d);
+}
+
 static void server_destroy(RemoteServer *s) {
         size_t i;
-        MHDDaemonWrapper *d;
-
-        while ((d = hashmap_steal_first(s->daemons))) {
-                MHD_stop_daemon(d->daemon);
-                sd_event_source_unref(d->event);
-                free(d);
-        }
 
-        hashmap_free(s->daemons);
+        hashmap_free_with_destructor(s->daemons, MHDDaemonWrapper_free);
 
         assert(s->sources_size == 0 || s->sources);
         for (i = 0; i < s->sources_size; i++)
@@ -1216,7 +1254,7 @@ static int parse_config(void) {
         return config_parse_many_nulstr(PKGSYSCONFDIR "/journal-remote.conf",
                                         CONF_PATHS_NULSTR("systemd/journal-remote.conf.d"),
                                         "Remote\0", config_item_table_lookup, items,
-                                        false, NULL);
+                                        CONFIG_PARSE_WARN, NULL);
 }
 
 static void help(void) {
index 30ad7df..30e5c4e 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -32,7 +33,8 @@ struct MHDDaemonWrapper {
         uint64_t fd;
         struct MHD_Daemon *daemon;
 
-        sd_event_source *event;
+        sd_event_source *io_event;
+        sd_event_source *timer_event;
 };
 
 struct RemoteServer {
index 3a36e46..6c214d2 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -62,8 +63,8 @@ static ssize_t write_entry(char *buf, size_t size, Uploader *u) {
                         }
 
                         pos += r;
-                }       /* fall through */
-
+                }
+                        _fallthrough_;
                 case ENTRY_REALTIME: {
                         usec_t realtime;
 
@@ -86,8 +87,8 @@ static ssize_t write_entry(char *buf, size_t size, Uploader *u) {
                         }
 
                         pos += r;
-                }       /* fall through */
-
+                }
+                        _fallthrough_;
                 case ENTRY_MONOTONIC: {
                         usec_t monotonic;
                         sd_id128_t boot_id;
@@ -111,8 +112,8 @@ static ssize_t write_entry(char *buf, size_t size, Uploader *u) {
                         }
 
                         pos += r;
-                }       /* fall through */
-
+                }
+                        _fallthrough_;
                 case ENTRY_BOOT_ID: {
                         sd_id128_t boot_id;
                         char sid[33];
@@ -136,8 +137,8 @@ static ssize_t write_entry(char *buf, size_t size, Uploader *u) {
                         }
 
                         pos += r;
-                }       /* fall through */
-
+                }
+                        _fallthrough_;
                 case ENTRY_NEW_FIELD: {
                         u->field_pos = 0;
 
@@ -158,8 +159,8 @@ static ssize_t write_entry(char *buf, size_t size, Uploader *u) {
                         }
 
                         u->entry_state++;
-                }       /* fall through */
-
+                }
+                        _fallthrough_;
                 case ENTRY_TEXT_FIELD:
                 case ENTRY_BINARY_FIELD: {
                         bool done;
@@ -208,8 +209,8 @@ static ssize_t write_entry(char *buf, size_t size, Uploader *u) {
 
                         u->field_pos = len + 1;
                         u->entry_state++;
-                }       /* fall through */
-
+                }
+                        _fallthrough_;
                 case ENTRY_BINARY_FIELD_SIZE: {
                         uint64_t le64;
 
index ea26498..69718aa 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -543,7 +544,7 @@ static int parse_config(void) {
         return config_parse_many_nulstr(PKGSYSCONFDIR "/journal-upload.conf",
                                         CONF_PATHS_NULSTR("systemd/journal-upload.conf.d"),
                                         "Upload\0", config_item_table_lookup, items,
-                                        false, NULL);
+                                        CONFIG_PARSE_WARN, NULL);
 }
 
 static void help(void) {
@@ -570,8 +571,6 @@ static void help(void) {
                "     --follow[=BOOL]        Do [not] wait for input\n"
                "     --save-state[=FILE]    Save uploaded cursors (default \n"
                "                            " STATE_FILE ")\n"
-               "  -h --help                 Show this help and exit\n"
-               "     --version              Print version string and exit\n"
                , program_invocation_short_name);
 }
 
index ed963d7..5fdc4cc 100644 (file)
@@ -1,3 +1,20 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
+# Copyright 2017 Zbigniew Jędrzejewski-Szmek
+#
+# 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.
+#
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
 systemd_journal_upload_sources = files('''
         journal-upload.h
         journal-upload.c
index 75c14ec..2466c4f 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 4b2e9da..76a7130 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 373d345..0af0364 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 1dd2163..603ad41 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -30,7 +31,7 @@ int audit_type_from_string(const char *s);
                 const char *_s_;                                        \
                 _s_ = audit_type_to_string(type);                       \
                 if (!_s_) {                                             \
-                        _s_ = alloca(strlen("AUDIT") + DECIMAL_STR_MAX(int)); \
+                        _s_ = alloca(STRLEN("AUDIT") + DECIMAL_STR_MAX(int)); \
                         sprintf((char*) _s_, "AUDIT%04i", type);        \
                 }                                                       \
                 _s_;                                                    \
index 08c844d..b2f9ed5 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index bf92da9..6775535 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 1b1014b..ce4fa07 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 834859b..92eb387 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -666,7 +667,7 @@ int decompress_stream_lz4(int in, int out, uint64_t max_bytes) {
 
         log_debug("LZ4 decompression finished (%zu -> %zu bytes, %.1f%%)",
                   total_in, total_out,
-                  (double) total_out / total_in * 100);
+                  total_in > 0 ? (double) total_out / total_in * 100 : 0.0);
  cleanup:
         munmap(src, st.st_size);
         return r;
index fb71662..917bef0 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index e7c2288..281b489 100644 (file)
@@ -1,4 +1,5 @@
-/*
+/* SPDX-License-Identifier: LGPL-2.1+
+ *
  * fsprg v0.1  -  (seekable) forward-secure pseudorandom generator
  * Copyright (C) 2012 B. Poettering
  * Contact: fsprg@point-at-infinity.org
index 829b56e..e0ec888 100644 (file)
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+
 #ifndef __fsprgh__
 #define __fsprgh__
 
index d8af113..cff6474 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 6c87319..e2866ea 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 1bd5de4..70ce1ab 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 3027801..7fef403 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
 /* The mmap context to use for the header we pick as one above the last defined typed */
 #define CONTEXT_HEADER _OBJECT_TYPE_MAX
 
+#ifdef __clang__
+#  pragma GCC diagnostic ignored "-Waddress-of-packed-member"
+#endif
+
 /* This may be called from a separate thread to prevent blocking the caller for the duration of fsync().
  * As a result we use atomic operations on f->offline_state for inter-thread communications with
  * journal_file_set_offline() and journal_file_set_online(). */
@@ -128,8 +133,7 @@ static void journal_file_set_offline_internal(JournalFile *f) {
                 case OFFLINE_OFFLINING:
                         if (!__sync_bool_compare_and_swap(&f->offline_state, OFFLINE_OFFLINING, OFFLINE_DONE))
                                 continue;
-                        /* fall through */
-
+                        _fallthrough_;
                 case OFFLINE_DONE:
                         return;
 
@@ -285,8 +289,7 @@ static int journal_file_set_online(JournalFile *f) {
                         if (!__sync_bool_compare_and_swap(&f->offline_state, OFFLINE_AGAIN_FROM_OFFLINING, OFFLINE_CANCEL))
                                 continue;
                         /* Canceled restart from offlining, must wait for offlining to complete however. */
-
-                        /* fall through */
+                        _fallthrough_;
                 default: {
                         int r;
 
@@ -397,15 +400,6 @@ JournalFile* journal_file_close(JournalFile *f) {
         return mfree(f);
 }
 
-void journal_file_close_set(Set *s) {
-        JournalFile *f;
-
-        assert(s);
-
-        while ((f = set_steal_first(s)))
-                (void) journal_file_close(f);
-}
-
 static int journal_file_init_header(JournalFile *f, JournalFile *template) {
         Header h = {};
         ssize_t k;
@@ -2578,7 +2572,7 @@ static int find_data_object_by_boot_id(
                 Object **o,
                 uint64_t *b) {
 
-        char t[sizeof("_BOOT_ID=")-1 + 32 + 1] = "_BOOT_ID=";
+        char t[STRLEN("_BOOT_ID=") + 32 + 1] = "_BOOT_ID=";
 
         sd_id128_to_string(boot_id, t + 9);
         return journal_file_find_data_object(f, t, sizeof(t) - 1, o, b);
@@ -3368,8 +3362,7 @@ int journal_file_open(
         f->header = h;
 
         if (!newly_created) {
-                if (deferred_closes)
-                        journal_file_close_set(deferred_closes);
+                set_clear_with_destructor(deferred_closes, journal_file_close);
 
                 r = journal_file_verify_header(f);
                 if (r < 0)
index 008dba6..c5cfa3d 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -160,7 +161,6 @@ int journal_file_open(
 int journal_file_set_offline(JournalFile *f, bool wait);
 bool journal_file_is_offlining(JournalFile *f);
 JournalFile* journal_file_close(JournalFile *j);
-void journal_file_close_set(Set *s);
 
 int journal_file_open_reliably(
                 const char *fname,
index 34a4814..5ec87e8 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 4e194bd..5a9dcaa 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -21,6 +22,7 @@
 #include <qrencode.h>
 #include <stdbool.h>
 #include <stdio.h>
+#include <stdio_ext.h>
 #include <stdlib.h>
 
 #include "journal-qrcode.h"
@@ -65,11 +67,13 @@ int print_qr_code(
         if (!f)
                 return -ENOMEM;
 
-        fputs_unlocked("fss://", f);
+        (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
+
+        fputs("fss://", f);
 
         for (i = 0; i < seed_size; i++) {
                 if (i > 0 && i % 3 == 0)
-                        fputc_unlocked('-', f);
+                        fputc('-', f);
                 fprintf(f, "%02x", ((uint8_t*) seed)[i]);
         }
 
index ef39085..cb26754 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 4acef26..a78aa07 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -95,7 +96,7 @@ _public_ int sd_journal_printv(int priority, const char *format, va_list ap) {
         /* FIXME: Instead of limiting things to LINE_MAX we could do a
            C99 variable-length array on the stack here in a loop. */
 
-        char buffer[8 + LINE_MAX], p[sizeof("PRIORITY=")-1 + DECIMAL_STR_MAX(int) + 1];
+        char buffer[8 + LINE_MAX], p[STRLEN("PRIORITY=") + DECIMAL_STR_MAX(int) + 1];
         struct iovec iov[2];
 
         assert_return(priority >= 0, -EINVAL);
@@ -356,7 +357,7 @@ static int fill_iovec_perror_and_send(const char *message, int skip, struct iove
                 errno = 0;
                 j = strerror_r(_saved_errno_, buffer + 8 + k, n - 8 - k);
                 if (errno == 0) {
-                        char error[sizeof("ERRNO=")-1 + DECIMAL_STR_MAX(int) + 1];
+                        char error[STRLEN("ERRNO=") + DECIMAL_STR_MAX(int) + 1];
 
                         if (j != buffer + 8 + k)
                                 memmove(buffer + 8 + k, j, strlen(j)+1);
@@ -458,7 +459,7 @@ _public_ int sd_journal_print_with_location(int priority, const char *file, cons
 }
 
 _public_ int sd_journal_printv_with_location(int priority, const char *file, const char *line, const char *func, const char *format, va_list ap) {
-        char buffer[8 + LINE_MAX], p[sizeof("PRIORITY=")-1 + DECIMAL_STR_MAX(int) + 1];
+        char buffer[8 + LINE_MAX], p[STRLEN("PRIORITY=") + DECIMAL_STR_MAX(int) + 1];
         struct iovec iov[5];
         char *f;
 
index 12ce2fd..c21e878 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 1e750a2..2aec412 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index e756f51..dc6b21b 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 8f0eaf6..4f99915 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index e826fa6..956d85a 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -123,6 +124,7 @@ static const char *arg_machine = NULL;
 static uint64_t arg_vacuum_size = 0;
 static uint64_t arg_vacuum_n_files = 0;
 static usec_t arg_vacuum_time = 0;
+static char **arg_output_fields = NULL;
 
 static enum {
         ACTION_SHOW,
@@ -302,6 +304,7 @@ static void help(void) {
                "                             short-iso, short-iso-precise, short-full,\n"
                "                             short-monotonic, short-unix, verbose, export,\n"
                "                             json, json-pretty, json-sse, cat)\n"
+               "     --output-fields=LIST  Select fields to print in verbose/export/json modes\n"
                "     --utc                 Express time in Coordinated Universal Time (UTC)\n"
                "  -x --catalog             Add message explanations where available\n"
                "     --no-full             Ellipsize fields\n"
@@ -377,6 +380,7 @@ static int parse_argv(int argc, char *argv[]) {
                 ARG_VACUUM_FILES,
                 ARG_VACUUM_TIME,
                 ARG_NO_HOSTNAME,
+                ARG_OUTPUT_FIELDS,
         };
 
         static const struct option options[] = {
@@ -435,6 +439,7 @@ static int parse_argv(int argc, char *argv[]) {
                 { "vacuum-files",   required_argument, NULL, ARG_VACUUM_FILES   },
                 { "vacuum-time",    required_argument, NULL, ARG_VACUUM_TIME    },
                 { "no-hostname",    no_argument,       NULL, ARG_NO_HOSTNAME    },
+                { "output-fields",  required_argument, NULL, ARG_OUTPUT_FIELDS  },
                 {}
         };
 
@@ -842,6 +847,24 @@ static int parse_argv(int argc, char *argv[]) {
                         arg_action = ACTION_SYNC;
                         break;
 
+                case ARG_OUTPUT_FIELDS: {
+                        _cleanup_strv_free_ char **v = NULL;
+
+                        v = strv_split(optarg, ",");
+                        if (!v)
+                                return log_oom();
+
+                        if (!arg_output_fields) {
+                                arg_output_fields = v;
+                                v = NULL;
+                        } else {
+                                r = strv_extend_strv(&arg_output_fields, v, true);
+                                if (r < 0)
+                                        return log_oom();
+                        }
+                        break;
+                }
+
                 case '?':
                         return -EINVAL;
 
@@ -1320,7 +1343,8 @@ static int add_dmesg(sd_journal *j) {
         if (!arg_dmesg)
                 return 0;
 
-        r = sd_journal_add_match(j, "_TRANSPORT=kernel", strlen("_TRANSPORT=kernel"));
+        r = sd_journal_add_match(j, "_TRANSPORT=kernel",
+                                 STRLEN("_TRANSPORT=kernel"));
         if (r < 0)
                 return log_error_errno(r, "Failed to add match: %m");
 
@@ -2452,7 +2476,7 @@ int main(int argc, char *argv[]) {
                                 arg_utc * OUTPUT_UTC |
                                 arg_no_hostname * OUTPUT_NO_HOSTNAME;
 
-                        r = output_journal(stdout, j, arg_output, 0, flags, &ellipsized);
+                        r = output_journal(stdout, j, arg_output, 0, flags, arg_output_fields, &ellipsized);
                         need_seek = true;
                         if (r == -EADDRNOTAVAIL)
                                 break;
@@ -2498,6 +2522,7 @@ finish:
         strv_free(arg_syslog_identifier);
         strv_free(arg_system_units);
         strv_free(arg_user_units);
+        strv_free(arg_output_fields);
 
         free(arg_root);
         free(arg_verify_key);
index 3334418..19f5375 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
 typedef struct MapField {
         const char *audit_field;
         const char *journal_field;
-        int (*map)(const char *field, const char **p, struct iovec **iov, size_t *n_iov_allocated, unsigned *n_iov);
+        int (*map)(const char *field, const char **p, struct iovec **iov, size_t *n_iov_allocated, size_t *n_iov);
 } MapField;
 
-static int map_simple_field(const char *field, const char **p, struct iovec **iov, size_t *n_iov_allocated, unsigned *n_iov) {
+static int map_simple_field(const char *field, const char **p, struct iovec **iov, size_t *n_iov_allocated, size_t *n_iov) {
         _cleanup_free_ char *c = NULL;
         size_t l = 0, allocated = 0;
         const char *e;
@@ -61,9 +62,7 @@ static int map_simple_field(const char *field, const char **p, struct iovec **io
         if (!GREEDY_REALLOC(*iov, *n_iov_allocated, *n_iov + 1))
                 return -ENOMEM;
 
-        (*iov)[*n_iov].iov_base = c;
-        (*iov)[*n_iov].iov_len = l;
-        (*n_iov)++;
+        (*iov)[(*n_iov)++] = IOVEC_MAKE(c, l);
 
         *p = e;
         c = NULL;
@@ -71,7 +70,7 @@ static int map_simple_field(const char *field, const char **p, struct iovec **io
         return 1;
 }
 
-static int map_string_field_internal(const char *field, const char **p, struct iovec **iov, size_t *n_iov_allocated, unsigned *n_iov, bool filter_printable) {
+static int map_string_field_internal(const char *field, const char **p, struct iovec **iov, size_t *n_iov_allocated, size_t *n_iov, bool filter_printable) {
         _cleanup_free_ char *c = NULL;
         const char *s, *e;
         size_t l;
@@ -140,9 +139,7 @@ static int map_string_field_internal(const char *field, const char **p, struct i
         if (!GREEDY_REALLOC(*iov, *n_iov_allocated, *n_iov + 1))
                 return -ENOMEM;
 
-        (*iov)[*n_iov].iov_base = c;
-        (*iov)[*n_iov].iov_len = l;
-        (*n_iov)++;
+        (*iov)[(*n_iov)++] = IOVEC_MAKE(c, l);
 
         *p = e;
         c = NULL;
@@ -150,15 +147,15 @@ static int map_string_field_internal(const char *field, const char **p, struct i
         return 1;
 }
 
-static int map_string_field(const char *field, const char **p, struct iovec **iov, size_t *n_iov_allocated, unsigned *n_iov) {
+static int map_string_field(const char *field, const char **p, struct iovec **iov, size_t *n_iov_allocated, size_t *n_iov) {
         return map_string_field_internal(field, p, iov, n_iov_allocated, n_iov, false);
 }
 
-static int map_string_field_printable(const char *field, const char **p, struct iovec **iov, size_t *n_iov_allocated, unsigned *n_iov) {
+static int map_string_field_printable(const char *field, const char **p, struct iovec **iov, size_t *n_iov_allocated, size_t *n_iov) {
         return map_string_field_internal(field, p, iov, n_iov_allocated, n_iov, true);
 }
 
-static int map_generic_field(const char *prefix, const char **p, struct iovec **iov, size_t *n_iov_allocated, unsigned *n_iov) {
+static int map_generic_field(const char *prefix, const char **p, struct iovec **iov, size_t *n_iov_allocated, size_t *n_iov) {
         const char *e, *f;
         char *c, *t;
         int r;
@@ -218,29 +215,29 @@ static const MapField map_fields_kernel[] = {
 
         /* First, we map certain well-known audit fields into native
          * well-known fields */
-        { "pid=",       "_PID=",                   map_simple_field },
-        { "ppid=",      "_PPID=",                  map_simple_field },
-        { "uid=",       "_UID=",                   map_simple_field },
-        { "euid=",      "_EUID=",                  map_simple_field },
-        { "fsuid=",     "_FSUID=",                 map_simple_field },
-        { "gid=",       "_GID=",                   map_simple_field },
-        { "egid=",      "_EGID=",                  map_simple_field },
-        { "fsgid=",     "_FSGID=",                 map_simple_field },
-        { "tty=",       "_TTY=",                   map_simple_field },
-        { "ses=",       "_AUDIT_SESSION=",         map_simple_field },
-        { "auid=",      "_AUDIT_LOGINUID=",        map_simple_field },
-        { "subj=",      "_SELINUX_CONTEXT=",       map_simple_field },
-        { "comm=",      "_COMM=",                  map_string_field },
-        { "exe=",       "_EXE=",                   map_string_field },
-        { "proctitle=", "_CMDLINE=",               map_string_field_printable },
+        { "pid=",       "_PID=",              map_simple_field },
+        { "ppid=",      "_PPID=",             map_simple_field },
+        { "uid=",       "_UID=",              map_simple_field },
+        { "euid=",      "_EUID=",             map_simple_field },
+        { "fsuid=",     "_FSUID=",            map_simple_field },
+        { "gid=",       "_GID=",              map_simple_field },
+        { "egid=",      "_EGID=",             map_simple_field },
+        { "fsgid=",     "_FSGID=",            map_simple_field },
+        { "tty=",       "_TTY=",              map_simple_field },
+        { "ses=",       "_AUDIT_SESSION=",    map_simple_field },
+        { "auid=",      "_AUDIT_LOGINUID=",   map_simple_field },
+        { "subj=",      "_SELINUX_CONTEXT=",  map_simple_field },
+        { "comm=",      "_COMM=",             map_string_field },
+        { "exe=",       "_EXE=",              map_string_field },
+        { "proctitle=", "_CMDLINE=",          map_string_field_printable },
 
         /* Some fields don't map to native well-known fields. However,
          * we know that they are string fields, hence let's undo
          * string field escaping for them, though we stick to the
          * generic field names. */
-        { "path=",      "_AUDIT_FIELD_PATH=",      map_string_field },
-        { "dev=",       "_AUDIT_FIELD_DEV=",       map_string_field },
-        { "name=",      "_AUDIT_FIELD_NAME=",      map_string_field },
+        { "path=",      "_AUDIT_FIELD_PATH=", map_string_field },
+        { "dev=",       "_AUDIT_FIELD_DEV=",  map_string_field },
+        { "name=",      "_AUDIT_FIELD_NAME=", map_string_field },
         {}
 };
 
@@ -248,11 +245,11 @@ static const MapField map_fields_kernel[] = {
  * msg='. All of these fields are untrusted, hence carry no "_"
  * prefix. We map the fields we don't know to AUDIT_FIELD_XYZ= */
 static const MapField map_fields_userspace[] = {
-        { "cwd=",       "AUDIT_FIELD_CWD=",  map_string_field },
-        { "cmd=",       "AUDIT_FIELD_CMD=",  map_string_field },
-        { "acct=",      "AUDIT_FIELD_ACCT=", map_string_field },
-        { "exe=",       "AUDIT_FIELD_EXE=",  map_string_field },
-        { "comm=",      "AUDIT_FIELD_COMM=", map_string_field },
+        { "cwd=",       "AUDIT_FIELD_CWD=",   map_string_field },
+        { "cmd=",       "AUDIT_FIELD_CMD=",   map_string_field },
+        { "acct=",      "AUDIT_FIELD_ACCT=",  map_string_field },
+        { "exe=",       "AUDIT_FIELD_EXE=",   map_string_field },
+        { "comm=",      "AUDIT_FIELD_COMM=",  map_string_field },
         {}
 };
 
@@ -263,7 +260,7 @@ static int map_all_fields(
                 bool handle_msg,
                 struct iovec **iov,
                 size_t *n_iov_allocated,
-                unsigned *n_iov) {
+                size_t *n_iov) {
 
         int r;
 
@@ -335,16 +332,15 @@ static int map_all_fields(
 }
 
 static void process_audit_string(Server *s, int type, const char *data, size_t size) {
+        size_t n_iov_allocated = 0, n_iov = 0, z;
         _cleanup_free_ struct iovec *iov = NULL;
-        size_t n_iov_allocated = 0;
-        unsigned n_iov = 0, k;
         uint64_t seconds, msec, id;
         const char *p, *type_name;
-        unsigned z;
         char id_field[sizeof("_AUDIT_ID=") + DECIMAL_STR_MAX(uint64_t)],
              type_field[sizeof("_AUDIT_TYPE=") + DECIMAL_STR_MAX(int)],
              source_time_field[sizeof("_SOURCE_REALTIME_TIMESTAMP=") + DECIMAL_STR_MAX(usec_t)];
         char *m;
+        int k;
 
         assert(s);
 
index 8c74577..83dd4bc 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 039f1a6..98fbb83 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -57,8 +58,8 @@ void server_forward_console(
 
         struct iovec iovec[5];
         struct timespec ts;
-        char tbuf[sizeof("[] ")-1 + DECIMAL_STR_MAX(ts.tv_sec) + DECIMAL_STR_MAX(ts.tv_nsec)-3 + 1];
-        char header_pid[sizeof("[]: ")-1 + DECIMAL_STR_MAX(pid_t)];
+        char tbuf[STRLEN("[] ") + DECIMAL_STR_MAX(ts.tv_sec) + DECIMAL_STR_MAX(ts.tv_nsec)-3 + 1];
+        char header_pid[STRLEN("[]: ") + DECIMAL_STR_MAX(pid_t)];
         _cleanup_free_ char *ident_buf = NULL;
         _cleanup_close_ int fd = -1;
         const char *tty;
index dda07e2..3b34550 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index eaa7f25..f5345e4 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
 #include "alloc-util.h"
 #include "audit-util.h"
 #include "cgroup-util.h"
+#include "fd-util.h"
+#include "fileio.h"
+#include "fs-util.h"
+#include "io-util.h"
+#include "journal-util.h"
 #include "journald-context.h"
 #include "process-util.h"
 #include "string-util.h"
+#include "syslog-util.h"
+#include "unaligned.h"
 #include "user-util.h"
 
 /* This implements a metadata cache for clients, which are identified by their PID. Requesting metadata through /proc
@@ -115,6 +123,8 @@ static int client_context_new(Server *s, pid_t pid, ClientContext **ret) {
         c->owner_uid = UID_INVALID;
         c->lru_index = PRIOQ_IDX_NULL;
         c->timestamp = USEC_INFINITY;
+        c->extra_fields_mtime = NSEC_INFINITY;
+        c->log_level_max = -1;
 
         r = hashmap_put(s->client_contexts, PID_TO_PTR(pid), c);
         if (r < 0) {
@@ -154,6 +164,13 @@ static void client_context_reset(ClientContext *c) {
 
         c->label = mfree(c->label);
         c->label_size = 0;
+
+        c->extra_fields_iovec = mfree(c->extra_fields_iovec);
+        c->extra_fields_n_iovec = 0;
+        c->extra_fields_data = mfree(c->extra_fields_data);
+        c->extra_fields_mtime = NSEC_INFINITY;
+
+        c->log_level_max = -1;
 }
 
 static ClientContext* client_context_free(Server *s, ClientContext *c) {
@@ -296,40 +313,141 @@ static int client_context_read_invocation_id(
                 Server *s,
                 ClientContext *c) {
 
-        _cleanup_free_ char *escaped = NULL, *slice_path = NULL;
-        char ids[SD_ID128_STRING_MAX];
+        _cleanup_free_ char *value = NULL;
         const char *p;
         int r;
 
         assert(s);
         assert(c);
 
-        /* Read the invocation ID of a unit off a unit. It's stored in the "trusted.invocation_id" extended attribute
-         * on the cgroup path. */
+        /* Read the invocation ID of a unit off a unit. PID 1 stores it in a per-unit symlink in /run/systemd/units/ */
 
-        if (!c->unit || !c->slice)
+        if (!c->unit)
                 return 0;
 
-        r = cg_slice_to_path(c->slice, &slice_path);
+        p = strjoina("/run/systemd/units/invocation:", c->unit);
+        r = readlink_malloc(p, &value);
         if (r < 0)
                 return r;
 
-        escaped = cg_escape(c->unit);
-        if (!escaped)
-                return -ENOMEM;
+        return sd_id128_from_string(value, &c->invocation_id);
+}
 
-        p = strjoina(s->cgroup_root, "/", slice_path, "/", escaped);
-        if (!p)
-                return -ENOMEM;
+static int client_context_read_log_level_max(
+                Server *s,
+                ClientContext *c) {
 
-        r = cg_get_xattr(SYSTEMD_CGROUP_CONTROLLER, p, "trusted.invocation_id", ids, 32);
+        _cleanup_free_ char *value = NULL;
+        const char *p;
+        int r, ll;
+
+        if (!c->unit)
+                return 0;
+
+        p = strjoina("/run/systemd/units/log-level-max:", c->unit);
+        r = readlink_malloc(p, &value);
         if (r < 0)
                 return r;
-        if (r != 32)
+
+        ll = log_level_from_string(value);
+        if (ll < 0)
                 return -EINVAL;
-        ids[32] = 0;
 
-        return sd_id128_from_string(ids, &c->invocation_id);
+        c->log_level_max = ll;
+        return 0;
+}
+
+static int client_context_read_extra_fields(
+                Server *s,
+                ClientContext *c) {
+
+        size_t size = 0, n_iovec = 0, n_allocated = 0, left;
+        _cleanup_free_ struct iovec *iovec = NULL;
+        _cleanup_free_ void *data = NULL;
+        _cleanup_fclose_ FILE *f = NULL;
+        struct stat st;
+        const char *p;
+        uint8_t *q;
+        int r;
+
+        if (!c->unit)
+                return 0;
+
+        p = strjoina("/run/systemd/units/log-extra-fields:", c->unit);
+
+        if (c->extra_fields_mtime != NSEC_INFINITY) {
+                if (stat(p, &st) < 0) {
+                        if (errno == ENOENT)
+                                return 0;
+
+                        return -errno;
+                }
+
+                if (timespec_load_nsec(&st.st_mtim) == c->extra_fields_mtime)
+                        return 0;
+        }
+
+        f = fopen(p, "re");
+        if (!f) {
+                if (errno == ENOENT)
+                        return 0;
+
+                return -errno;
+        }
+
+        if (fstat(fileno(f), &st) < 0) /* The file might have been replaced since the stat() above, let's get a new
+                                        * one, that matches the stuff we are reading */
+                return -errno;
+
+        r = read_full_stream(f, (char**) &data, &size);
+        if (r < 0)
+                return r;
+
+        q = data, left = size;
+        while (left > 0) {
+                uint8_t *field, *eq;
+                uint64_t v, n;
+
+                if (left < sizeof(uint64_t))
+                        return -EBADMSG;
+
+                v = unaligned_read_le64(q);
+                if (v < 2)
+                        return -EBADMSG;
+
+                n = sizeof(uint64_t) + v;
+                if (left < n)
+                        return -EBADMSG;
+
+                field = q + sizeof(uint64_t);
+
+                eq = memchr(field, '=', v);
+                if (!eq)
+                        return -EBADMSG;
+
+                if (!journal_field_valid((const char *) field, eq - field, false))
+                        return -EBADMSG;
+
+                if (!GREEDY_REALLOC(iovec, n_allocated, n_iovec+1))
+                        return -ENOMEM;
+
+                iovec[n_iovec++] = IOVEC_MAKE(field, v);
+
+                left -= n, q += n;
+        }
+
+        free(c->extra_fields_iovec);
+        free(c->extra_fields_data);
+
+        c->extra_fields_iovec = iovec;
+        c->extra_fields_n_iovec = n_iovec;
+        c->extra_fields_data = data;
+        c->extra_fields_mtime = timespec_load_nsec(&st.st_mtim);
+
+        iovec = NULL;
+        data = NULL;
+
+        return 0;
 }
 
 static void client_context_really_refresh(
@@ -356,6 +474,8 @@ static void client_context_really_refresh(
 
         (void) client_context_read_cgroup(s, c, unit_id);
         (void) client_context_read_invocation_id(s, c);
+        (void) client_context_read_log_level_max(s, c);
+        (void) client_context_read_extra_fields(s, c);
 
         c->timestamp = timestamp;
 
index eb1e219..e29f59c 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -60,6 +61,13 @@ struct ClientContext {
 
         char *label;
         size_t label_size;
+
+        int log_level_max;
+
+        struct iovec *extra_fields_iovec;
+        size_t extra_fields_n_iovec;
+        void *extra_fields_data;
+        nsec_t extra_fields_mtime;
 };
 
 int client_context_get(
@@ -90,3 +98,17 @@ void client_context_maybe_refresh(
 
 void client_context_acquire_default(Server *s);
 void client_context_flush_all(Server *s);
+
+static inline size_t client_context_extra_fields_n_iovec(const ClientContext *c) {
+        return c ? c->extra_fields_n_iovec : 0;
+}
+
+static inline bool client_context_test_priority(const ClientContext *c, int priority) {
+        if (!c)
+                return true;
+
+        if (c->log_level_max < 0)
+                return true;
+
+        return LOG_PRI(priority) <= c->log_level_max;
+}
index 6b05bda..e8c1f2e 100644 (file)
@@ -1,4 +1,7 @@
 %{
+#if __GNUC__ >= 7
+_Pragma("GCC diagnostic ignored \"-Wimplicit-fallthrough\"")
+#endif
 #include <stddef.h>
 #include <sys/socket.h>
 #include "conf-parser.h"
index f00313b..279e1c3 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -49,7 +50,7 @@ void server_forward_kmsg(
         _cleanup_free_ char *ident_buf = NULL;
         struct iovec iovec[5];
         char header_priority[DECIMAL_STR_MAX(priority) + 3],
-             header_pid[sizeof("[]: ")-1 + DECIMAL_STR_MAX(pid_t) + 1];
+             header_pid[STRLEN("[]: ") + DECIMAL_STR_MAX(pid_t) + 1];
         int n = 0;
 
         assert(s);
@@ -109,15 +110,16 @@ static bool is_us(const char *pid) {
 }
 
 static void dev_kmsg_record(Server *s, const char *p, size_t l) {
-        struct iovec iovec[N_IOVEC_META_FIELDS + 7 + N_IOVEC_KERNEL_FIELDS + 2 + N_IOVEC_UDEV_FIELDS];
+
         _cleanup_free_ char *message = NULL, *syslog_priority = NULL, *syslog_pid = NULL, *syslog_facility = NULL, *syslog_identifier = NULL, *source_time = NULL, *identifier = NULL, *pid = NULL;
-        int priority, r;
-        unsigned n = 0, z = 0, j;
+        struct iovec iovec[N_IOVEC_META_FIELDS + 7 + N_IOVEC_KERNEL_FIELDS + 2 + N_IOVEC_UDEV_FIELDS];
+        char *kernel_device = NULL;
         unsigned long long usec;
+        size_t n = 0, z = 0, j;
+        int priority, r;
         char *e, *f, *k;
         uint64_t serial;
         size_t pl;
-        char *kernel_device = NULL;
 
         assert(s);
         assert(p);
@@ -155,7 +157,7 @@ static void dev_kmsg_record(Server *s, const char *p, size_t l) {
 
                 /* Did we lose any? */
                 if (serial > *s->kernel_seqnum)
-                        server_driver_message(s,
+                        server_driver_message(s, 0,
                                               "MESSAGE_ID=" SD_MESSAGE_JOURNAL_MISSED_STR,
                                               LOG_MESSAGE("Missed %"PRIu64" kernel messages",
                                                           serial - *s->kernel_seqnum),
index dab49f1..af795ea 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index d45c9c2..65fb6ab 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -28,6 +29,7 @@
 #include "fs-util.h"
 #include "io-util.h"
 #include "journal-importer.h"
+#include "journal-util.h"
 #include "journald-console.h"
 #include "journald-kmsg.h"
 #include "journald-native.h"
 #include "string-util.h"
 #include "unaligned.h"
 
-bool valid_user_field(const char *p, size_t l, bool allow_protected) {
-        const char *a;
-
-        /* We kinda enforce POSIX syntax recommendations for
-           environment variables here, but make a couple of additional
-           requirements.
-
-           http://pubs.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap08.html */
-
-        /* No empty field names */
-        if (l <= 0)
-                return false;
-
-        /* Don't allow names longer than 64 chars */
-        if (l > 64)
-                return false;
-
-        /* Variables starting with an underscore are protected */
-        if (!allow_protected && p[0] == '_')
-                return false;
-
-        /* Don't allow digits as first character */
-        if (p[0] >= '0' && p[0] <= '9')
-                return false;
-
-        /* Only allow A-Z0-9 and '_' */
-        for (a = p; a < p + l; a++)
-                if ((*a < 'A' || *a > 'Z') &&
-                    (*a < '0' || *a > '9') &&
-                    *a != '_')
-                        return false;
-
-        return true;
-}
-
 static bool allow_object_pid(const struct ucred *ucred) {
         return ucred && ucred->uid == 0;
 }
@@ -128,13 +95,14 @@ static void server_process_entry_meta(
                         *message = t;
                 }
 
-        } else if (l > strlen("OBJECT_PID=") &&
-                   l < strlen("OBJECT_PID=")  + DECIMAL_STR_MAX(pid_t) &&
+        } else if (l > STRLEN("OBJECT_PID=") &&
+                   l < STRLEN("OBJECT_PID=")  + DECIMAL_STR_MAX(pid_t) &&
                    startswith(p, "OBJECT_PID=") &&
                    allow_object_pid(ucred)) {
                 char buf[DECIMAL_STR_MAX(pid_t)];
-                memcpy(buf, p + strlen("OBJECT_PID="), l - strlen("OBJECT_PID="));
-                buf[l-strlen("OBJECT_PID=")] = '\0';
+                memcpy(buf, p + STRLEN("OBJECT_PID="),
+                       l - STRLEN("OBJECT_PID="));
+                buf[l-STRLEN("OBJECT_PID=")] = '\0';
 
                 (void) parse_pid(buf, object_pid);
         }
@@ -148,19 +116,17 @@ static int server_process_entry(
                 const struct timeval *tv,
                 const char *label, size_t label_len) {
 
-        /* Process a single entry from a native message.
-         * Returns 0 if nothing special happened and the message processing should continue,
-         * and a negative or positive value otherwise.
+        /* Process a single entry from a native message. Returns 0 if nothing special happened and the message
+         * processing should continue, and a negative or positive value otherwise.
          *
          * Note that *remaining is altered on both success and failure. */
 
+        size_t n = 0, j, tn = (size_t) -1, m = 0, entry_size = 0;
+        char *identifier = NULL, *message = NULL;
         struct iovec *iovec = NULL;
-        unsigned n = 0, j, tn = (unsigned) -1;
-        const char *p;
-        size_t m = 0, entry_size = 0;
         int priority = LOG_INFO;
-        char *identifier = NULL, *message = NULL;
         pid_t object_pid = 0;
+        const char *p;
         int r = 0;
 
         p = buffer;
@@ -194,26 +160,25 @@ static int server_process_entry(
                 /* A property follows */
 
                 /* n existing properties, 1 new, +1 for _TRANSPORT */
-                if (!GREEDY_REALLOC(iovec, m, n + 2 + N_IOVEC_META_FIELDS + N_IOVEC_OBJECT_FIELDS)) {
+                if (!GREEDY_REALLOC(iovec, m,
+                                    n + 2 +
+                                    N_IOVEC_META_FIELDS + N_IOVEC_OBJECT_FIELDS +
+                                    client_context_extra_fields_n_iovec(context))) {
                         r = log_oom();
                         break;
                 }
 
                 q = memchr(p, '=', e - p);
                 if (q) {
-                        if (valid_user_field(p, q - p, false)) {
+                        if (journal_field_valid(p, q - p, false)) {
                                 size_t l;
 
                                 l = e - p;
 
-                                /* If the field name starts with an
-                                 * underscore, skip the variable,
-                                 * since that indicates a trusted
-                                 * field */
-                                iovec[n].iov_base = (char*) p;
-                                iovec[n].iov_len = l;
+                                /* If the field name starts with an underscore, skip the variable, since that indicates
+                                 * a trusted field */
+                                iovec[n++] = IOVEC_MAKE((char*) p, l);
                                 entry_size += l;
-                                n++;
 
                                 server_process_entry_meta(p, l, ucred,
                                                           &priority,
@@ -257,7 +222,7 @@ static int server_process_entry(
                         k[e - p] = '=';
                         memcpy(k + (e - p) + 1, e + 1 + sizeof(uint64_t), l);
 
-                        if (valid_user_field(p, e - p, false)) {
+                        if (journal_field_valid(p, e - p, false)) {
                                 iovec[n].iov_base = k;
                                 iovec[n].iov_len = (e - p) + 1 + l;
                                 entry_size += iovec[n].iov_len;
@@ -281,13 +246,17 @@ static int server_process_entry(
                 goto finish;
         }
 
+        if (!client_context_test_priority(context, priority)) {
+                r = 0;
+                goto finish;
+        }
+
         tn = n++;
         iovec[tn] = IOVEC_MAKE_STRING("_TRANSPORT=journal");
-        entry_size += strlen("_TRANSPORT=journal");
+        entry_size += STRLEN("_TRANSPORT=journal");
 
         if (entry_size + n + 1 > ENTRY_SIZE_MAX) { /* data + separators + trailer */
-                log_debug("Entry is too big with %u properties and %zu bytes, ignoring.",
-                          n, entry_size);
+                log_debug("Entry is too big with %zu properties and %zu bytes, ignoring.", n, entry_size);
                 goto finish;
         }
 
@@ -332,7 +301,7 @@ void server_process_native_message(
                 const char *label, size_t label_len) {
 
         size_t remaining = buffer_size;
-        ClientContext *context;
+        ClientContext *context = NULL;
         int r;
 
         assert(s);
index 1ab415a..7ca17ec 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index a340422..3517ce2 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index bb0abb7..af7bb49 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 00ad168..48375f9 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -219,7 +220,8 @@ void server_space_usage_message(Server *s, JournalStorage *storage) {
         format_bytes(fb5, sizeof(fb5), storage->space.limit);
         format_bytes(fb6, sizeof(fb6), storage->space.available);
 
-        server_driver_message(s, "MESSAGE_ID=" SD_MESSAGE_JOURNAL_USAGE_STR,
+        server_driver_message(s, 0,
+                              "MESSAGE_ID=" SD_MESSAGE_JOURNAL_USAGE_STR,
                               LOG_MESSAGE("%s (%s) is %s, max %s, %s free.",
                                           storage->name, storage->path, fb1, fb5, fb6),
                               "JOURNAL_NAME=%s", storage->name,
@@ -246,7 +248,7 @@ static void server_add_acls(JournalFile *f, uid_t uid) {
         assert(f);
 
 #if HAVE_ACL
-        if (uid <= SYSTEM_UID_MAX)
+        if (uid_is_system(uid) || uid_is_dynamic(uid) || uid == UID_NOBODY)
                 return;
 
         r = add_acls_for_user(f->fd, uid);
@@ -404,7 +406,7 @@ static JournalFile* find_journal(Server *s, uid_t uid) {
         if (s->runtime_journal)
                 return s->runtime_journal;
 
-        if (uid <= SYSTEM_UID_MAX || uid_is_dynamic(uid))
+        if (uid_is_system(uid) || uid_is_dynamic(uid) || uid == UID_NOBODY)
                 return s->system_journal;
 
         r = sd_id128_get_machine(&machine);
@@ -722,7 +724,7 @@ static void write_to_journal(Server *s, uid_t uid, struct iovec *iovec, unsigned
 #define IOVEC_ADD_NUMERIC_FIELD(iovec, n, value, type, isset, format, field)  \
         if (isset(value)) {                                             \
                 char *k;                                                \
-                k = newa(char, strlen(field "=") + DECIMAL_STR_MAX(type) + 1); \
+                k = newa(char, STRLEN(field "=") + DECIMAL_STR_MAX(type) + 1); \
                 sprintf(k, field "=" format, value);                    \
                 iovec[n++] = IOVEC_MAKE_STRING(k);                      \
         }
@@ -737,7 +739,7 @@ static void write_to_journal(Server *s, uid_t uid, struct iovec *iovec, unsigned
 #define IOVEC_ADD_ID128_FIELD(iovec, n, value, field)                   \
         if (!sd_id128_is_null(value)) {                                 \
                 char *k;                                                \
-                k = newa(char, strlen(field "=") + SD_ID128_STRING_MAX); \
+                k = newa(char, STRLEN(field "=") + SD_ID128_STRING_MAX); \
                 sd_id128_to_string(value, stpcpy(k, field "="));        \
                 iovec[n++] = IOVEC_MAKE_STRING(k);                      \
         }
@@ -745,14 +747,14 @@ static void write_to_journal(Server *s, uid_t uid, struct iovec *iovec, unsigned
 #define IOVEC_ADD_SIZED_FIELD(iovec, n, value, value_size, field)       \
         if (value_size > 0) {                                           \
                 char *k;                                                \
-                k = newa(char, strlen(field "=") + value_size + 1);     \
+                k = newa(char, STRLEN(field "=") + value_size + 1);     \
                 *((char*) mempcpy(stpcpy(k, field "="), value, value_size)) = 0; \
                 iovec[n++] = IOVEC_MAKE_STRING(k);                      \
         }                                                               \
 
 static void dispatch_message_real(
                 Server *s,
-                struct iovec *iovec, unsigned n, unsigned m,
+                struct iovec *iovec, size_t n, size_t m,
                 const ClientContext *c,
                 const struct timeval *tv,
                 int priority,
@@ -765,7 +767,10 @@ static void dispatch_message_real(
         assert(s);
         assert(iovec);
         assert(n > 0);
-        assert(n + N_IOVEC_META_FIELDS + (pid_is_valid(object_pid) ? N_IOVEC_OBJECT_FIELDS : 0) <= m);
+        assert(n +
+               N_IOVEC_META_FIELDS +
+               (pid_is_valid(object_pid) ? N_IOVEC_OBJECT_FIELDS : 0) +
+               client_context_extra_fields_n_iovec(c) <= m);
 
         if (c) {
                 IOVEC_ADD_NUMERIC_FIELD(iovec, n, c->pid, pid_t, pid_is_valid, PID_FMT, "_PID");
@@ -791,6 +796,11 @@ static void dispatch_message_real(
                 IOVEC_ADD_STRING_FIELD(iovec, n, c->user_slice, "_SYSTEMD_USER_SLICE");
 
                 IOVEC_ADD_ID128_FIELD(iovec, n, c->invocation_id, "_SYSTEMD_INVOCATION_ID");
+
+                if (c->extra_fields_n_iovec > 0) {
+                        memcpy(iovec + n, c->extra_fields_iovec, c->extra_fields_n_iovec * sizeof(struct iovec));
+                        n += c->extra_fields_n_iovec;
+                }
         }
 
         assert(n <= m);
@@ -859,16 +869,19 @@ static void dispatch_message_real(
         write_to_journal(s, journal_uid, iovec, n, priority);
 }
 
-void server_driver_message(Server *s, const char *message_id, const char *format, ...) {
+void server_driver_message(Server *s, pid_t object_pid, const char *message_id, const char *format, ...) {
 
-        struct iovec iovec[N_IOVEC_META_FIELDS + 5 + N_IOVEC_PAYLOAD_FIELDS];
-        unsigned n = 0, m;
+        struct iovec *iovec;
+        size_t n = 0, k, m;
         va_list ap;
         int r;
 
         assert(s);
         assert(format);
 
+        m = N_IOVEC_META_FIELDS + 5 + N_IOVEC_PAYLOAD_FIELDS + client_context_extra_fields_n_iovec(s->my_context) + N_IOVEC_OBJECT_FIELDS;
+        iovec = newa(struct iovec, m);
+
         assert_cc(3 == LOG_FAC(LOG_DAEMON));
         iovec[n++] = IOVEC_MAKE_STRING("SYSLOG_FACILITY=3");
         iovec[n++] = IOVEC_MAKE_STRING("SYSLOG_IDENTIFIER=systemd-journald");
@@ -879,18 +892,18 @@ void server_driver_message(Server *s, const char *message_id, const char *format
 
         if (message_id)
                 iovec[n++] = IOVEC_MAKE_STRING(message_id);
-        m = n;
+        k = n;
 
         va_start(ap, format);
-        r = log_format_iovec(iovec, ELEMENTSOF(iovec), &n, false, 0, format, ap);
+        r = log_format_iovec(iovec, m, &n, false, 0, format, ap);
         /* Error handling below */
         va_end(ap);
 
         if (r >= 0)
-                dispatch_message_real(s, iovec, n, ELEMENTSOF(iovec), s->my_context, NULL, LOG_INFO, 0);
+                dispatch_message_real(s, iovec, n, m, s->my_context, NULL, LOG_INFO, object_pid);
 
-        while (m < n)
-                free(iovec[m++].iov_base);
+        while (k < n)
+                free(iovec[k++].iov_base);
 
         if (r < 0) {
                 /* We failed to format the message. Emit a warning instead. */
@@ -901,13 +914,13 @@ void server_driver_message(Server *s, const char *message_id, const char *format
                 n = 3;
                 iovec[n++] = IOVEC_MAKE_STRING("PRIORITY=4");
                 iovec[n++] = IOVEC_MAKE_STRING(buf);
-                dispatch_message_real(s, iovec, n, ELEMENTSOF(iovec), s->my_context, NULL, LOG_INFO, 0);
+                dispatch_message_real(s, iovec, n, m, s->my_context, NULL, LOG_INFO, object_pid);
         }
 }
 
 void server_dispatch_message(
                 Server *s,
-                struct iovec *iovec, unsigned n, unsigned m,
+                struct iovec *iovec, size_t n, size_t m,
                 ClientContext *c,
                 const struct timeval *tv,
                 int priority,
@@ -939,8 +952,10 @@ void server_dispatch_message(
 
                 /* Write a suppression message if we suppressed something */
                 if (rl > 1)
-                        server_driver_message(s, "MESSAGE_ID=" SD_MESSAGE_JOURNAL_DROPPED_STR,
-                                              LOG_MESSAGE("Suppressed %u messages from %s", rl - 1, c->unit),
+                        server_driver_message(s, c->pid,
+                                              "MESSAGE_ID=" SD_MESSAGE_JOURNAL_DROPPED_STR,
+                                              LOG_MESSAGE("Suppressed %i messages from %s", rl - 1, c->unit),
+                                              "N_DROPPED=%i", rl - 1,
                                               NULL);
         }
 
@@ -1038,7 +1053,7 @@ finish:
 
         sd_journal_close(j);
 
-        server_driver_message(s, NULL,
+        server_driver_message(s, 0, NULL,
                               LOG_MESSAGE("Time spent on flushing to /var is %s for %u entries.",
                                           format_timespan(ts, sizeof(ts), now(CLOCK_MONOTONIC) - start, 0),
                                           n),
@@ -1398,7 +1413,7 @@ static int server_parse_config_file(Server *s) {
                                         CONF_PATHS_NULSTR("systemd/journald.conf.d"),
                                         "Journal\0",
                                         config_item_perf_lookup, journald_gperf_lookup,
-                                        false, s);
+                                        CONFIG_PARSE_WARN, s);
 }
 
 static int server_dispatch_sync(sd_event_source *es, usec_t t, void *userdata) {
@@ -1884,13 +1899,9 @@ void server_maybe_append_tags(Server *s) {
 }
 
 void server_done(Server *s) {
-        JournalFile *f;
         assert(s);
 
-        if (s->deferred_closes) {
-                journal_file_close_set(s->deferred_closes);
-                set_free(s->deferred_closes);
-        }
+        set_free_with_destructor(s->deferred_closes, journal_file_close);
 
         while (s->stdout_streams)
                 stdout_stream_free(s->stdout_streams);
@@ -1903,10 +1914,7 @@ void server_done(Server *s) {
         if (s->runtime_journal)
                 (void) journal_file_close(s->runtime_journal);
 
-        while ((f = ordered_hashmap_steal_first(s->user_journals)))
-                (void) journal_file_close(f);
-
-        ordered_hashmap_free(s->user_journals);
+        ordered_hashmap_free_with_destructor(s->user_journals, journal_file_close);
 
         sd_event_source_unref(s->syslog_event_source);
         sd_event_source_unref(s->native_event_source);
index f4bdd58..bf4ba68 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -179,16 +180,25 @@ struct Server {
         ClientContext *pid1_context; /* the context of PID 1 */
 };
 
-#define SERVER_MACHINE_ID(s) ((s)->machine_id_field + strlen("_MACHINE_ID="))
+#define SERVER_MACHINE_ID(s) ((s)->machine_id_field + STRLEN("_MACHINE_ID="))
 
+/* Extra fields for any log messages */
 #define N_IOVEC_META_FIELDS 22
+
+/* Extra fields for log messages that contain OBJECT_PID= (i.e. log about another process) */
+#define N_IOVEC_OBJECT_FIELDS 18
+
+/* Maximum number of fields we'll add in for driver (i.e. internal) messages */
+#define N_IOVEC_PAYLOAD_FIELDS 16
+
+/* kmsg: Maximum number of extra fields we'll import from the kernel's /dev/kmsg */
 #define N_IOVEC_KERNEL_FIELDS 64
+
+/* kmsg: Maximum number of extra fields we'll import from udev's devices */
 #define N_IOVEC_UDEV_FIELDS 32
-#define N_IOVEC_OBJECT_FIELDS 14
-#define N_IOVEC_PAYLOAD_FIELDS 15
 
-void server_dispatch_message(Server *s, struct iovec *iovec, unsigned n, unsigned m, ClientContext *c, const struct timeval *tv, int priority, pid_t object_pid);
-void server_driver_message(Server *s, const char *message_id, const char *format, ...) _printf_(3,0) _sentinel_;
+void server_dispatch_message(Server *s, struct iovec *iovec, size_t n, size_t m, ClientContext *c, const struct timeval *tv, int priority, pid_t object_pid);
+void server_driver_message(Server *s, pid_t object_pid, const char *message_id, const char *format, ...) _sentinel_ _printf_(4,0);
 
 /* gperf lookup function */
 const struct ConfigPerfItem* journald_gperf_lookup(const char *key, GPERF_LEN_TYPE length);
index 54dd096..671ada7 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -105,7 +106,7 @@ struct StdoutStream {
         LIST_FIELDS(StdoutStream, stdout_stream);
         LIST_FIELDS(StdoutStream, stdout_stream_notify_queue);
 
-        char id_field[sizeof("_STREAM_ID=")-1 + SD_ID128_STRING_MAX];
+        char id_field[STRLEN("_STREAM_ID=") + SD_ID128_STRING_MAX];
 };
 
 void stdout_stream_free(StdoutStream *s) {
@@ -193,7 +194,7 @@ static int stdout_stream_save(StdoutStream *s) {
                 s->forward_to_syslog,
                 s->forward_to_kmsg,
                 s->forward_to_console,
-                s->id_field + strlen("_STREAM_ID="));
+                s->id_field + STRLEN("_STREAM_ID="));
 
         if (!isempty(s->identifier)) {
                 _cleanup_free_ char *escaped;
@@ -251,22 +252,33 @@ fail:
 }
 
 static int stdout_stream_log(StdoutStream *s, const char *p, LineBreak line_break) {
-        struct iovec iovec[N_IOVEC_META_FIELDS + 7];
+        struct iovec *iovec;
         int priority;
         char syslog_priority[] = "PRIORITY=\0";
-        char syslog_facility[sizeof("SYSLOG_FACILITY=")-1 + DECIMAL_STR_MAX(int) + 1];
+        char syslog_facility[STRLEN("SYSLOG_FACILITY=") + DECIMAL_STR_MAX(int) + 1];
         _cleanup_free_ char *message = NULL, *syslog_identifier = NULL;
-        unsigned n = 0;
+        size_t n = 0, m;
         int r;
 
         assert(s);
         assert(p);
 
+        if (s->context)
+                (void) client_context_maybe_refresh(s->server, s->context, NULL, NULL, 0, NULL, USEC_INFINITY);
+        else if (pid_is_valid(s->ucred.pid)) {
+                r = client_context_acquire(s->server, s->ucred.pid, &s->ucred, s->label, strlen_ptr(s->label), s->unit_id, &s->context);
+                if (r < 0)
+                        log_warning_errno(r, "Failed to acquire client context, ignoring: %m");
+        }
+
         priority = s->priority;
 
         if (s->level_prefix)
                 syslog_parse_priority(&p, &priority, false);
 
+        if (!client_context_test_priority(s->context, priority))
+                return 0;
+
         if (isempty(p))
                 return 0;
 
@@ -282,10 +294,13 @@ static int stdout_stream_log(StdoutStream *s, const char *p, LineBreak line_brea
         if (s->server->forward_to_wall)
                 server_forward_wall(s->server, priority, s->identifier, p, &s->ucred);
 
+        m = N_IOVEC_META_FIELDS + 7 + client_context_extra_fields_n_iovec(s->context);
+        iovec = newa(struct iovec, m);
+
         iovec[n++] = IOVEC_MAKE_STRING("_TRANSPORT=stdout");
         iovec[n++] = IOVEC_MAKE_STRING(s->id_field);
 
-        syslog_priority[strlen("PRIORITY=")] = '0' + LOG_PRI(priority);
+        syslog_priority[STRLEN("PRIORITY=")] = '0' + LOG_PRI(priority);
         iovec[n++] = IOVEC_MAKE_STRING(syslog_priority);
 
         if (priority & LOG_FACMASK) {
@@ -315,15 +330,7 @@ static int stdout_stream_log(StdoutStream *s, const char *p, LineBreak line_brea
         if (message)
                 iovec[n++] = IOVEC_MAKE_STRING(message);
 
-        if (s->context)
-                (void) client_context_maybe_refresh(s->server, s->context, NULL, NULL, 0, NULL, USEC_INFINITY);
-        else if (pid_is_valid(s->ucred.pid)) {
-                r = client_context_acquire(s->server, s->ucred.pid, &s->ucred, s->label, strlen_ptr(s->label), s->unit_id, &s->context);
-                if (r < 0)
-                        log_warning_errno(r, "Failed to acquire client context, ignoring: %m");
-        }
-
-        server_dispatch_message(s->server, iovec, n, ELEMENTSOF(iovec), s->context, NULL, priority, 0);
+        server_dispatch_message(s->server, iovec, n, m, s->context, NULL, priority, 0);
         return 0;
 }
 
@@ -829,7 +836,7 @@ int server_open_stdout_socket(Server *s) {
 void stdout_stream_send_notify(StdoutStream *s) {
         struct iovec iovec = {
                 .iov_base = (char*) "FDSTORE=1",
-                .iov_len = strlen("FDSTORE=1"),
+                .iov_len = STRLEN("FDSTORE=1"),
         };
         struct msghdr msghdr = {
                 .msg_iov = &iovec,
index db4c67f..fd220b5 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index e17561d..d1cf385 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -131,7 +132,7 @@ static void forward_syslog_raw(Server *s, int priority, const char *buffer, cons
 void server_forward_syslog(Server *s, int priority, const char *identifier, const char *message, const struct ucred *ucred, const struct timeval *tv) {
         struct iovec iovec[5];
         char header_priority[DECIMAL_STR_MAX(priority) + 3], header_time[64],
-             header_pid[sizeof("[]: ")-1 + DECIMAL_STR_MAX(pid_t) + 1];
+             header_pid[STRLEN("[]: ") + DECIMAL_STR_MAX(pid_t) + 1];
         int n = 0;
         time_t t;
         struct tm *tm;
@@ -288,8 +289,7 @@ static void syslog_skip_date(char **buf) {
                         if (*p == ' ')
                                 break;
 
-                        /* fall through */
-
+                        _fallthrough_;
                 case NUMBER:
                         if (*p < '0' || *p > '9')
                                 return;
@@ -326,18 +326,27 @@ void server_process_syslog_message(
              syslog_facility[sizeof("SYSLOG_FACILITY=") + DECIMAL_STR_MAX(int)];
         const char *message = NULL, *syslog_identifier = NULL, *syslog_pid = NULL;
         _cleanup_free_ char *identifier = NULL, *pid = NULL;
-        struct iovec iovec[N_IOVEC_META_FIELDS + 6];
         int priority = LOG_USER | LOG_INFO, r;
         ClientContext *context = NULL;
+        struct iovec *iovec;
         const char *orig;
-        unsigned n = 0;
+        size_t n = 0, m;
 
         assert(s);
         assert(buf);
 
+        if (ucred && pid_is_valid(ucred->pid)) {
+                r = client_context_get(s, ucred->pid, ucred, label, label_len, NULL, &context);
+                if (r < 0)
+                        log_warning_errno(r, "Failed to retrieve credentials for PID " PID_FMT ", ignoring: %m", ucred->pid);
+        }
+
         orig = buf;
         syslog_parse_priority(&buf, &priority, true);
 
+        if (!client_context_test_priority(context, priority))
+                return;
+
         if (s->forward_to_syslog)
                 forward_syslog_raw(s, priority, orig, ucred, tv);
 
@@ -353,6 +362,9 @@ void server_process_syslog_message(
         if (s->forward_to_wall)
                 server_forward_wall(s, priority, identifier, buf, ucred);
 
+        m = N_IOVEC_META_FIELDS + 6 + client_context_extra_fields_n_iovec(context);
+        iovec = newa(struct iovec, m);
+
         iovec[n++] = IOVEC_MAKE_STRING("_TRANSPORT=syslog");
 
         xsprintf(syslog_priority, "PRIORITY=%i", priority & LOG_PRIMASK);
@@ -377,13 +389,7 @@ void server_process_syslog_message(
         if (message)
                 iovec[n++] = IOVEC_MAKE_STRING(message);
 
-        if (ucred && pid_is_valid(ucred->pid)) {
-                r = client_context_get(s, ucred->pid, ucred, label, label_len, NULL, &context);
-                if (r < 0)
-                        log_warning_errno(r, "Failed to retrieve credentials for PID " PID_FMT ", ignoring: %m", ucred->pid);
-        }
-
-        server_dispatch_message(s, iovec, n, ELEMENTSOF(iovec), context, tv, priority, 0);
+        server_dispatch_message(s, iovec, n, m, context, tv, priority, 0);
 }
 
 int server_open_syslog_socket(Server *s) {
@@ -451,7 +457,7 @@ void server_maybe_warn_forward_syslog_missed(Server *s) {
         if (s->last_warn_forward_syslog_missed + WARN_FORWARD_SYSLOG_MISSED_USEC > n)
                 return;
 
-        server_driver_message(s,
+        server_driver_message(s, 0,
                               "MESSAGE_ID=" SD_MESSAGE_FORWARD_SYSLOG_MISSED_STR,
                               LOG_MESSAGE("Forwarding to syslog missed %u messages.",
                                           s->n_forward_syslog_missed),
index 46ad715..3438107 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index bfe53ce..431abfe 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index ebc2b89..46ceac2 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 318e067..6d670e2 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -56,7 +57,7 @@ int main(int argc, char *argv[]) {
         server_flush_dev_kmsg(&server);
 
         log_debug("systemd-journald running as pid "PID_FMT, getpid_cached());
-        server_driver_message(&server,
+        server_driver_message(&server, 0,
                               "MESSAGE_ID=" SD_MESSAGE_JOURNAL_START_STR,
                               LOG_MESSAGE("Journal started"),
                               NULL);
@@ -115,7 +116,7 @@ int main(int argc, char *argv[]) {
         }
 
         log_debug("systemd-journald stopped as pid "PID_FMT, getpid_cached());
-        server_driver_message(&server,
+        server_driver_message(&server, 0,
                               "MESSAGE_ID=" SD_MESSAGE_JOURNAL_STOP_STR,
                               LOG_MESSAGE("Journal stopped"),
                               NULL);
index da42fd8..edb2a1a 100644 (file)
@@ -1,3 +1,20 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
+# Copyright 2017 Zbigniew Jędrzejewski-Szmek
+#
+# 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.
+#
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
 journal_internal_sources = files('''
         audit-type.c
         audit-type.h
index ac72520..630ae6f 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index cf6af19..00bcafd 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index fc86b99..8a1b161 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -1976,18 +1977,13 @@ fail:
 
 _public_ void sd_journal_close(sd_journal *j) {
         Directory *d;
-        JournalFile *f;
-        char *p;
 
         if (!j)
                 return;
 
         sd_journal_flush_matches(j);
 
-        while ((f = ordered_hashmap_steal_first(j->files)))
-                (void) journal_file_close(f);
-
-        ordered_hashmap_free(j->files);
+        ordered_hashmap_free_with_destructor(j->files, journal_file_close);
 
         while ((d = hashmap_first(j->directories_by_path)))
                 remove_directory(j, d);
@@ -2005,9 +2001,7 @@ _public_ void sd_journal_close(sd_journal *j) {
                 mmap_cache_unref(j->mmap);
         }
 
-        while ((p = hashmap_steal_first(j->errors)))
-                free(p);
-        hashmap_free(j->errors);
+        hashmap_free_free(j->errors);
 
         free(j->path);
         free(j->prefix);
index 88a2e6d..0f97803 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index b7d9e7b..2ad9909 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index be5a665..409a876 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd
 
index 893f2ab..ea1ffcc 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd
 
@@ -26,6 +27,7 @@
 #include "fd-util.h"
 #include "fileio.h"
 #include "macro.h"
+#include "path-util.h"
 #include "random-util.h"
 #include "util.h"
 
@@ -156,9 +158,15 @@ static void test_compress_stream(int compression,
         char pattern[] = "/tmp/systemd-test.compressed.XXXXXX",
              pattern2[] = "/tmp/systemd-test.compressed.XXXXXX";
         int r;
-        _cleanup_free_ char *cmd = NULL, *cmd2;
+        _cleanup_free_ char *cmd = NULL, *cmd2 = NULL;
         struct stat st = {};
 
+        r = find_binary(cat, NULL);
+        if (r < 0) {
+                log_error_errno(r, "Skipping %s, could not find %s binary: %m", __func__, cat);
+                return;
+        }
+
         log_debug("/* testing %s compression */",
                   object_compressed_to_string(compression));
 
index 354c2c3..9733eec 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index ba8b20b..f9b7b75 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index ef21e2d..0743291 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 35cae23..5a88b27 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 3ab554b..018e965 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index d70f0b0..8e69a52 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -30,16 +31,16 @@ int main(int argc, char *argv[]) {
 
         /* utf-8 and non-utf-8, message-less and message-ful iovecs */
         struct iovec graph1[] = {
-                {(char*) "GRAPH=graph", strlen("GRAPH=graph")}
+                {(char*) "GRAPH=graph", STRLEN("GRAPH=graph")}
         };
         struct iovec graph2[] = {
-                {(char*) "GRAPH=graph\n", strlen("GRAPH=graph\n")}
+                {(char*) "GRAPH=graph\n", STRLEN("GRAPH=graph\n")}
         };
         struct iovec message1[] = {
-                {(char*) "MESSAGE=graph", strlen("MESSAGE=graph")}
+                {(char*) "MESSAGE=graph", STRLEN("MESSAGE=graph")}
         };
         struct iovec message2[] = {
-                {(char*) "MESSAGE=graph\n", strlen("MESSAGE=graph\n")}
+                {(char*) "MESSAGE=graph\n", STRLEN("MESSAGE=graph\n")}
         };
 
         assert_se(sd_journal_print(LOG_INFO, "piepapo") == 0);
index 7e5a980..73ed6e5 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 0828b88..ab57d2b 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 3d2312f..fbb75e4 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index df685e9..517c910 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 702434e..39e7510 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index d6b062b..e6361dc 100644 (file)
@@ -1,6 +1,7 @@
 #!/bin/bash
 # -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
 # ex: ts=8 sw=4 sts=4 et filetype=sh
+# SPDX-License-Identifier: LGPL-2.1+
 #
 # This file is part of systemd.
 #
index ede3323..65f483f 100644 (file)
@@ -1,3 +1,20 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
+# Copyright 2017 Zbigniew Jędrzejewski-Szmek
+#
+# 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.
+#
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
 install_data('kernel-install',
              install_mode : 'rwxr-xr-x',
              install_dir : bindir)
index 2e02b3f..67409cc 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 3ef56b0..decfce3 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index a21efc4..f33817c 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 1cc0f9f..0ccee7a 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 3fdf02d..a535269 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index a440a20..010090a 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index c105196..0489579 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -190,9 +191,7 @@ static int parse_options(const uint8_t options[], size_t buflen, uint8_t *overlo
                                 if (!ascii_is_valid(string))
                                         return -EINVAL;
 
-                                free(*error_message);
-                                *error_message = string;
-                                string = NULL;
+                                free_and_replace(*error_message, string);
                         }
 
                         break;
index 475c572..1c4ab5d 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 5cf7abb..73a9f75 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 945c3b9..cb5b359 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -61,6 +62,7 @@ typedef struct DHCP6IA DHCP6IA;
 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, DHCP6IA *ia);
+int dhcp6_option_append_fqdn(uint8_t **buf, size_t *buflen, const char *fqdn);
 int dhcp6_option_parse(uint8_t **buf, size_t *buflen, uint16_t *optcode,
                        size_t *optlen, uint8_t **optvalue);
 int dhcp6_option_parse_ia(uint8_t **buf, size_t *buflen, uint16_t iatype,
index fd2d60c..b3b8fdd 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index f8056db..f346bda 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -136,6 +137,33 @@ int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, DHCP6IA *ia) {
         return 0;
 }
 
+int dhcp6_option_append_fqdn(uint8_t **buf, size_t *buflen, const char *fqdn) {
+        uint8_t buffer[1 + DNS_WIRE_FOMAT_HOSTNAME_MAX];
+        int r;
+
+        assert_return(buf && *buf && buflen && fqdn, -EINVAL);
+
+        buffer[0] = DHCP6_FQDN_FLAG_S; /* Request server to perform AAAA RR DNS updates */
+
+        /* Store domain name after flags field */
+        r = dns_name_to_wire_format(fqdn, buffer + 1, sizeof(buffer) - 1,  false);
+        if (r <= 0)
+                return r;
+
+        /*
+         * According to RFC 4704, chapter 4.2 only add terminating zero-length
+         * label in case a FQDN is provided. Since dns_name_to_wire_format
+         * always adds terminating zero-length label remove if only a hostname
+         * is provided.
+         */
+        if (dns_name_is_single_label(fqdn))
+                r--;
+
+        r = dhcp6_option_append(buf, buflen, SD_DHCP6_OPTION_FQDN, 1 + r, buffer);
+
+        return r;
+}
+
 
 static int option_parse_hdr(uint8_t **buf, size_t *buflen, uint16_t *optcode, size_t *optlen) {
         DHCP6Option *option = (DHCP6Option*) *buf;
index 2487c47..7bbf183 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -104,3 +105,9 @@ enum {
         DHCP6_STATUS_USE_MULTICAST              = 5,
         _DHCP6_STATUS_MAX                       = 6,
 };
+
+enum {
+        DHCP6_FQDN_FLAG_S = (1 << 0),
+        DHCP6_FQDN_FLAG_O = (1 << 1),
+        DHCP6_FQDN_FLAG_N = (1 << 2),
+};
index cf69044..dd4e28b 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 16b8be8..ce14f41 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index becc162..2673aa1 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index f1fecba..1a6ea28 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index c1a7606..76d4c0c 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index ae2f674..cb3841e 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index c4cf8c7..c0f8cbe 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 78c7456..c710ab4 100644 (file)
@@ -1,3 +1,20 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
+# Copyright 2017 Zbigniew Jędrzejewski-Szmek
+#
+# 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.
+#
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
 sources = files('''
         sd-dhcp-client.c
         sd-dhcp-server.c
index 82b896d..2743d85 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 845a6b7..2954928 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 1fe703d..f3757f6 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 337241a..e48b7d2 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
  This file is part of systemd.
 
index 4666f17..a54adac 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 5601be8..441939b 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -25,8 +26,6 @@
 #include "list.h"
 #include "sparse-endian.h"
 
-#define SD_RADV_DEFAULT_MIN_TIMEOUT_USEC        (200*USEC_PER_SEC)
-#define SD_RADV_DEFAULT_MAX_TIMEOUT_USEC        (600*USEC_PER_SEC)
 assert_cc(SD_RADV_DEFAULT_MIN_TIMEOUT_USEC <= SD_RADV_DEFAULT_MAX_TIMEOUT_USEC)
 
 #define SD_RADV_MAX_INITIAL_RTR_ADVERT_INTERVAL_USEC (16*USEC_PER_SEC)
index 29b22ee..228af69 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -415,9 +416,9 @@ int sd_dhcp_client_set_hostname(
 
         assert_return(client, -EINVAL);
 
-        /* Refuse hostnames that neither qualify as DNS nor as Linux hosntames */
+        /* Make sure hostnames qualify as DNS and as Linux hostnames */
         if (hostname &&
-            !(hostname_is_valid(hostname, false) || dns_name_is_valid(hostname) > 0))
+            !(hostname_is_valid(hostname, false) && dns_name_is_valid(hostname) > 0))
                 return -EINVAL;
 
         return free_and_strdup(&client->hostname, hostname);
@@ -828,7 +829,6 @@ static int client_send_request(sd_dhcp_client *client) {
                    client’s IP address.
                 */
 
-                /* fall through */
         case DHCP_STATE_REBINDING:
                 /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
                    option MUST NOT be filled in, ’ciaddr’ MUST be filled in with
index 1ab5697..78b8e05 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -21,6 +22,7 @@
 #include <arpa/inet.h>
 #include <errno.h>
 #include <stdio.h>
+#include <stdio_ext.h>
 #include <stdlib.h>
 #include <string.h>
 
@@ -392,9 +394,7 @@ static int lease_parse_domain(const uint8_t *option, size_t len, char **ret) {
         if (dns_name_is_root(normalized))
                 return -EINVAL;
 
-        free(*ret);
-        *ret = normalized;
-        normalized = NULL;
+        free_and_replace(*ret, normalized);
 
         return 0;
 }
@@ -683,9 +683,7 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void
                         return 0;
                 }
 
-                free(lease->timezone);
-                lease->timezone = tz;
-                tz = NULL;
+                free_and_replace(lease->timezone, tz);
 
                 break;
         }
@@ -879,7 +877,8 @@ int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file) {
         if (r < 0)
                 goto fail;
 
-        fchmod(fileno(f), 0644);
+        (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
+        (void) fchmod(fileno(f), 0644);
 
         fprintf(f,
                 "# This is private data. Do not parse.\n");
@@ -926,16 +925,16 @@ int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file) {
 
         r = sd_dhcp_lease_get_dns(lease, &addresses);
         if (r > 0) {
-                fputs_unlocked("DNS=", f);
+                fputs("DNS=", f);
                 serialize_in_addrs(f, addresses, r);
-                fputs_unlocked("\n", f);
+                fputs("\n", f);
         }
 
         r = sd_dhcp_lease_get_ntp(lease, &addresses);
         if (r > 0) {
-                fputs_unlocked("NTP=", f);
+                fputs("NTP=", f);
                 serialize_in_addrs(f, addresses, r);
-                fputs_unlocked("\n", f);
+                fputs("\n", f);
         }
 
         r = sd_dhcp_lease_get_domainname(lease, &string);
@@ -944,9 +943,9 @@ int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file) {
 
         r = sd_dhcp_lease_get_search_domains(lease, &search_domains);
         if (r > 0) {
-                fputs_unlocked("DOMAIN_SEARCH_LIST=", f);
+                fputs("DOMAIN_SEARCH_LIST=", f);
                 fputstrv(f, search_domains, NULL, NULL);
-                fputs_unlocked("\n", f);
+                fputs("\n", f);
         }
 
         r = sd_dhcp_lease_get_hostname(lease, &string);
@@ -990,7 +989,7 @@ int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file) {
         }
 
         LIST_FOREACH(options, option, lease->private_options) {
-                char key[strlen("OPTION_000")+1];
+                char key[STRLEN("OPTION_000")+1];
 
                 xsprintf(key, "OPTION_%" PRIu8, option->tag);
                 r = serialize_dhcp_option(f, key, option->data, option->length);
index 663fd0e..63fb355 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -86,7 +87,6 @@ int sd_dhcp_server_configure_pool(sd_dhcp_server *server, struct in_addr *addres
                 size = size_max;
 
         if (server->address != address->s_addr || server->netmask != netmask || server->pool_size != size || server->pool_offset != offset) {
-                DHCPLease *lease;
 
                 free(server->bound_leases);
                 server->bound_leases = new0(DHCPLease*, size);
@@ -104,8 +104,7 @@ int sd_dhcp_server_configure_pool(sd_dhcp_server *server, struct in_addr *addres
                         server->bound_leases[server_off - offset] = &server->invalid_lease;
 
                 /* Drop any leases associated with the old address range */
-                while ((lease = hashmap_steal_first(server->leases_by_client_id)))
-                        dhcp_lease_free(lease);
+                hashmap_clear_with_destructor(server->leases_by_client_id, dhcp_lease_free);
         }
 
         return 0;
index eba0c8b..1c12e54 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -29,7 +30,9 @@
 #include "dhcp6-internal.h"
 #include "dhcp6-lease-internal.h"
 #include "dhcp6-protocol.h"
+#include "dns-domain.h"
 #include "fd-util.h"
+#include "hostname-util.h"
 #include "in-addr-util.h"
 #include "network-internal.h"
 #include "random-util.h"
@@ -59,6 +62,7 @@ struct sd_dhcp6_client {
         be16_t *req_opts;
         size_t req_opts_allocated;
         size_t req_opts_len;
+        char *fqdn;
         sd_event_source *receive_message;
         usec_t retransmit_time;
         uint8_t retransmit_count;
@@ -231,6 +235,20 @@ int sd_dhcp6_client_set_iaid(sd_dhcp6_client *client, uint32_t iaid) {
         return 0;
 }
 
+int sd_dhcp6_client_set_fqdn(
+                sd_dhcp6_client *client,
+                const char *fqdn) {
+
+        assert_return(client, -EINVAL);
+
+        /* Make sure FQDN qualifies as DNS and as Linux hostname */
+        if (fqdn &&
+            !(hostname_is_valid(fqdn, false) && dns_name_is_valid(fqdn) > 0))
+                return -EINVAL;
+
+        return free_and_strdup(&client->fqdn, fqdn);
+}
+
 int sd_dhcp6_client_set_information_request(sd_dhcp6_client *client, int enabled) {
         assert_return(client, -EINVAL);
         assert_return(IN_SET(client->state, DHCP6_STATE_STOPPED), -EBUSY);
@@ -389,6 +407,12 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
                 if (r < 0)
                         return r;
 
+                if (client->fqdn) {
+                        r = dhcp6_option_append_fqdn(&opt, &optlen, client->fqdn);
+                        if (r < 0)
+                                return r;
+                }
+
                 break;
 
         case DHCP6_STATE_REQUEST:
@@ -409,6 +433,12 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
                 if (r < 0)
                         return r;
 
+                if (client->fqdn) {
+                        r = dhcp6_option_append_fqdn(&opt, &optlen, client->fqdn);
+                        if (r < 0)
+                                return r;
+                }
+
                 break;
 
         case DHCP6_STATE_REBIND:
@@ -418,6 +448,12 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
                 if (r < 0)
                         return r;
 
+                if (client->fqdn) {
+                        r = dhcp6_option_append_fqdn(&opt, &optlen, client->fqdn);
+                        if (r < 0)
+                                return r;
+                }
+
                 break;
 
         case DHCP6_STATE_STOPPED:
@@ -431,7 +467,7 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
         if (r < 0)
                 return r;
 
-        assert (client->duid_len);
+        assert(client->duid_len);
         r = dhcp6_option_append(&opt, &optlen, SD_DHCP6_OPTION_CLIENTID,
                                 client->duid_len, &client->duid);
         if (r < 0)
@@ -999,7 +1035,7 @@ static int client_receive_message(
                         break;
                 }
 
-                /* fall through */ /* for Soliciation Rapid Commit option check */
+                _fallthrough_; /* for Soliciation Rapid Commit option check */
         case DHCP6_STATE_REQUEST:
         case DHCP6_STATE_RENEW:
         case DHCP6_STATE_REBIND:
@@ -1064,7 +1100,7 @@ static int client_start(sd_dhcp6_client *client, enum DHCP6State state) {
                         return 0;
                 }
 
-                /* fall through */
+                _fallthrough_;
         case DHCP6_STATE_SOLICITATION:
                 client->state = DHCP6_STATE_SOLICITATION;
 
@@ -1300,6 +1336,7 @@ sd_dhcp6_client *sd_dhcp6_client_unref(sd_dhcp6_client *client) {
         sd_dhcp6_client_detach_event(client);
 
         free(client->req_opts);
+        free(client->fqdn);
         return mfree(client);
 }
 
index 8396407..6f604e0 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 909b470..7cf4f03 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -287,8 +288,7 @@ static int ipv4acd_on_timeout(sd_event_source *s, uint64_t usec, void *userdata)
                         break;
                 }
 
-                /* fall through */
-
+                _fallthrough_;
         case IPV4ACD_STATE_WAITING_ANNOUNCE:
                 /* Send announcement packet */
                 r = arp_send_announcement(acd->fd, acd->ifindex, acd->address, &acd->mac_addr);
index 88a90e5..23e2f52 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 0f591a8..2c05416 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 4bf558b..b5c6d6e 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index c42fdce..f6c984f 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -159,8 +160,9 @@ static int radv_send(sd_radv *ra, const struct in6_addr *dst,
                 .nd_opt_mtu_type = ND_OPT_MTU,
                 .nd_opt_mtu_len = 1,
         };
-        /* Reserve iov space for RA header, linkaddr, MTU, N prefixes, RDNSS */
-        struct iovec iov[4 + ra->n_prefixes];
+        /* Reserve iov space for RA header, linkaddr, MTU, N prefixes, RDNSS
+           and DNSSL */
+        struct iovec iov[5 + ra->n_prefixes];
         struct msghdr msg = {
                 .msg_name = &dst_addr,
                 .msg_namelen = sizeof(dst_addr),
index 27fcc33..7968c90 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 1942199..0e25310 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -75,6 +76,12 @@ static void test_request_basic(sd_event *e) {
         assert_se(sd_dhcp_client_set_ifindex(client, 0) == -EINVAL);
         assert_se(sd_dhcp_client_set_ifindex(client, 1) == 0);
 
+        assert_se(sd_dhcp_client_set_hostname(client, "host") == 1);
+        assert_se(sd_dhcp_client_set_hostname(client, "host.domain") == 1);
+        assert_se(sd_dhcp_client_set_hostname(client, NULL) == 1);
+        assert_se(sd_dhcp_client_set_hostname(client, "~host") == -EINVAL);
+        assert_se(sd_dhcp_client_set_hostname(client, "~host.domain") == -EINVAL);
+
         assert_se(sd_dhcp_client_set_request_option(client,
                                         SD_DHCP_OPTION_SUBNET_MASK) == -EEXIST);
         assert_se(sd_dhcp_client_set_request_option(client,
@@ -102,8 +109,8 @@ static void test_request_basic(sd_event *e) {
 
         /* RFC7844: option 33 (SD_DHCP_OPTION_STATIC_ROUTE) is set in the
          * default PRL when using Anonymize, so it is changed to other option
-         * that is not set by default, to check that it succed setting it.
-         * Ooptions not set by default (using or not anonymize) are option 17
+         * that is not set by default, to check that it was set successfully.
+         * Options not set by default (using or not anonymize) are option 17
          * (SD_DHCP_OPTION_ROOT_PATH) and 42 (SD_DHCP_OPTION_NTP_SERVER) */
         assert_se(sd_dhcp_client_set_request_option(client, 17) == 0);
         assert_se(sd_dhcp_client_set_request_option(client, 17) == -EEXIST);
index 26f2178..6632316 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index bd289fa..a0418ec 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -68,6 +69,12 @@ static int test_client_basic(sd_event *e) {
                                           sizeof (mac_addr),
                                           ARPHRD_ETHER) >= 0);
 
+        assert_se(sd_dhcp6_client_set_fqdn(client, "host") == 1);
+        assert_se(sd_dhcp6_client_set_fqdn(client, "host.domain") == 1);
+        assert_se(sd_dhcp6_client_set_fqdn(client, NULL) == 1);
+        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) == -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);
@@ -202,6 +209,11 @@ static uint8_t msg_reply[173] = {
         0x00, 0x00, 0x00, 0x00, 0x01
 };
 
+static uint8_t fqdn_wire[16] = {
+        0x04, 'h', 'o', 's', 't', 0x03, 'l', 'a', 'b',
+        0x05, 'i', 'n', 't', 'r', 'a', 0x00
+};
+
 static int test_advertise_option(sd_event *e) {
         _cleanup_(sd_dhcp6_lease_unrefp) sd_dhcp6_lease *lease = NULL;
         DHCP6Message *advertise = (DHCP6Message *)msg_advertise;
@@ -410,7 +422,7 @@ static int test_client_verify_request(DHCP6Message *request, uint8_t *option,
         uint16_t optcode;
         size_t optlen;
         bool found_clientid = false, found_iana = false, found_serverid = false,
-                found_elapsed_time = false;
+                found_elapsed_time = false, found_fqdn = false;
         int r;
         struct in6_addr addr;
         be32_t val;
@@ -467,6 +479,15 @@ static int test_client_verify_request(DHCP6Message *request, uint8_t *option,
                         assert_se(optlen == 2);
 
                         break;
+                case SD_DHCP6_OPTION_FQDN:
+                        assert_se(!found_fqdn);
+                        found_fqdn = true;
+
+                        assert_se(optlen == 17);
+
+                        assert_se(optval[0] == 0x01);
+                        assert_se(!memcmp(optval + 1, fqdn_wire, sizeof(fqdn_wire)));
+                        break;
                 }
         }
 
@@ -511,7 +532,7 @@ static int test_client_verify_solicit(DHCP6Message *solicit, uint8_t *option,
         uint16_t optcode;
         size_t optlen;
         bool found_clientid = false, found_iana = false,
-                found_elapsed_time = false;
+                found_elapsed_time = false, found_fqdn = false;
         int r;
 
         assert_se(solicit->type == DHCP6_SOLICIT);
@@ -545,6 +566,17 @@ static int test_client_verify_solicit(DHCP6Message *solicit, uint8_t *option,
                         assert_se(optlen == 2);
 
                         break;
+
+                case SD_DHCP6_OPTION_FQDN:
+                        assert_se(!found_fqdn);
+                        found_fqdn = true;
+
+                        assert_se(optlen == 17);
+
+                        assert_se(optval[0] == 0x01);
+                        assert_se(!memcmp(optval + 1, fqdn_wire, sizeof(fqdn_wire)));
+
+                        break;
                 }
         }
 
@@ -716,6 +748,7 @@ static int test_client_solicit(sd_event *e) {
         assert_se(sd_dhcp6_client_set_mac(client, (const uint8_t *) &mac_addr,
                                           sizeof (mac_addr),
                                           ARPHRD_ETHER) >= 0);
+        assert_se(sd_dhcp6_client_set_fqdn(client, "host.lab.intra") == 1);
 
         assert_se(sd_dhcp6_client_get_information_request(client, &val) >= 0);
         assert_se(val == false);
index 2b1387f..37092ea 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 89864fd..d062059 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 430c58a..c626893 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 18205ef..c1a8d5a 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -261,7 +262,7 @@ static int radv_recv(sd_event_source *s, int fd, uint32_t revents, void *userdat
         unsigned char buf[168];
         size_t i;
 
-        read(test_fd[0], &buf, sizeof(buf));
+        assert_se(read(test_fd[0], &buf, sizeof(buf)) == sizeof(buf));
 
         /* router lifetime must be zero when test is stopped */
         if (test_stopped) {
index c3e1a8e..e1a2b9f 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -202,7 +203,7 @@ int icmp6_bind_router_advertisement(int index) {
 
 int icmp6_receive(int fd, void *iov_base, size_t iov_len,
                   struct in6_addr *dst, triple_timestamp *timestamp) {
-        assert (read (fd, iov_base, iov_len) == (ssize_t)iov_len);
+        assert_se(read (fd, iov_base, iov_len) == (ssize_t)iov_len);
 
         if (timestamp)
                 triple_timestamp_get(timestamp);
index 7e6d499..c861905 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 92cb790..1a29b03 100644 (file)
@@ -1,4 +1,6 @@
 /***
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   systemd is free software; you can redistribute it and/or modify it
@@ -522,3 +524,9 @@ LIBSYSTEMD_234 {
 global:
         sd_bus_message_appendv;
 } LIBSYSTEMD_233;
+
+LIBSYSTEMD_236 {
+global:
+        sd_bus_message_new;
+        sd_bus_message_seal;
+} LIBSYSTEMD_234;
index bf73bd5..ecd9bd3 100644 (file)
@@ -1,3 +1,20 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
+# Copyright 2017 Zbigniew Jędrzejewski-Szmek
+#
+# 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.
+#
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
 sd_login_c = files('sd-login/sd-login.c')
 
 libsystemd_internal_sources = files('''
index 112769f..ebda651 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index c824622..2650762 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index b40ba25..07a1f50 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 4523be0..42c0f52 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -82,6 +83,8 @@
 #define BUS_ERROR_NO_SUCH_LINK "org.freedesktop.resolve1.NoSuchLink"
 #define BUS_ERROR_LINK_BUSY "org.freedesktop.resolve1.LinkBusy"
 #define BUS_ERROR_NETWORK_DOWN "org.freedesktop.resolve1.NetworkDown"
+#define BUS_ERROR_NO_SUCH_DNSSD_SERVICE "org.freedesktop.resolve1.NoSuchDnssdService"
+#define BUS_ERROR_DNSSD_SERVICE_EXISTS "org.freedesktop.resolve1.DnssdServiceExists"
 #define _BUS_ERROR_DNS "org.freedesktop.resolve1.DnsError."
 
 #define BUS_ERROR_NO_SUCH_TRANSFER "org.freedesktop.import1.NoSuchTransfer"
index 9827a42..8f6d348 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 35952d9..6921ffd 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index fcd4d27..12478e7 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 01c7187..c9d434c 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index e171c53..9d3b596 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 21a15c8..b6ef4a0 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index df8a1f1..c4c60fa 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index c316e4d..93dc473 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 1a5e9bc..ffd2b16 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 378f7a3..c951749 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index e2c4cf4..6181e37 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 5878276..6a990a0 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 6da637f..474e131 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index dacd243..3c381b0 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 90dee1b..e3b09da 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 9fcb596..9bd2dad 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -17,6 +18,8 @@
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
+#include <stdio_ext.h>
+
 #include "bus-internal.h"
 #include "bus-introspect.h"
 #include "bus-protocol.h"
@@ -36,8 +39,10 @@ int introspect_begin(struct introspect *i, bool trusted) {
         if (!i->f)
                 return -ENOMEM;
 
-        fputs_unlocked(BUS_INTROSPECT_DOCTYPE
-                       "<node>\n", i->f);
+        (void) __fsetlocking(i->f, FSETLOCKING_BYCALLER);
+
+        fputs(BUS_INTROSPECT_DOCTYPE
+              "<node>\n", i->f);
 
         return 0;
 }
@@ -45,12 +50,12 @@ int introspect_begin(struct introspect *i, bool trusted) {
 int introspect_write_default_interfaces(struct introspect *i, bool object_manager) {
         assert(i);
 
-        fputs_unlocked(BUS_INTROSPECT_INTERFACE_PEER
-                       BUS_INTROSPECT_INTERFACE_INTROSPECTABLE
-                       BUS_INTROSPECT_INTERFACE_PROPERTIES, i->f);
+        fputs(BUS_INTROSPECT_INTERFACE_PEER
+              BUS_INTROSPECT_INTERFACE_INTROSPECTABLE
+              BUS_INTROSPECT_INTERFACE_PROPERTIES, i->f);
 
         if (object_manager)
-                fputs_unlocked(BUS_INTROSPECT_INTERFACE_OBJECT_MANAGER, i->f);
+                fputs(BUS_INTROSPECT_INTERFACE_OBJECT_MANAGER, i->f);
 
         return 0;
 }
@@ -76,27 +81,27 @@ int introspect_write_child_nodes(struct introspect *i, Set *s, const char *prefi
 
 static void introspect_write_flags(struct introspect *i, int type, int flags) {
         if (flags & SD_BUS_VTABLE_DEPRECATED)
-                fputs_unlocked("   <annotation name=\"org.freedesktop.DBus.Deprecated\" value=\"true\"/>\n", i->f);
+                fputs("   <annotation name=\"org.freedesktop.DBus.Deprecated\" value=\"true\"/>\n", i->f);
 
         if (type == _SD_BUS_VTABLE_METHOD && (flags & SD_BUS_VTABLE_METHOD_NO_REPLY))
-                fputs_unlocked("   <annotation name=\"org.freedesktop.DBus.Method.NoReply\" value=\"true\"/>\n", i->f);
+                fputs("   <annotation name=\"org.freedesktop.DBus.Method.NoReply\" value=\"true\"/>\n", i->f);
 
         if (IN_SET(type, _SD_BUS_VTABLE_PROPERTY, _SD_BUS_VTABLE_WRITABLE_PROPERTY)) {
                 if (flags & SD_BUS_VTABLE_PROPERTY_EXPLICIT)
-                        fputs_unlocked("   <annotation name=\"org.freedesktop.systemd1.Explicit\" value=\"true\"/>\n", i->f);
+                        fputs("   <annotation name=\"org.freedesktop.systemd1.Explicit\" value=\"true\"/>\n", i->f);
 
                 if (flags & SD_BUS_VTABLE_PROPERTY_CONST)
-                        fputs_unlocked("   <annotation name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" value=\"const\"/>\n", i->f);
+                        fputs("   <annotation name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" value=\"const\"/>\n", i->f);
                 else if (flags & SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION)
-                        fputs_unlocked("   <annotation name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" value=\"invalidates\"/>\n", i->f);
+                        fputs("   <annotation name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" value=\"invalidates\"/>\n", i->f);
                 else if (!(flags & SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE))
-                        fputs_unlocked("   <annotation name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" value=\"false\"/>\n", i->f);
+                        fputs("   <annotation name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" value=\"false\"/>\n", i->f);
         }
 
         if (!i->trusted &&
             IN_SET(type, _SD_BUS_VTABLE_METHOD, _SD_BUS_VTABLE_WRITABLE_PROPERTY) &&
             !(flags & SD_BUS_VTABLE_UNPRIVILEGED))
-                fputs_unlocked("   <annotation name=\"org.freedesktop.systemd1.Privileged\" value=\"true\"/>\n", i->f);
+                fputs("   <annotation name=\"org.freedesktop.systemd1.Privileged\" value=\"true\"/>\n", i->f);
 }
 
 static int introspect_write_arguments(struct introspect *i, const char *signature, const char *direction) {
@@ -117,7 +122,7 @@ static int introspect_write_arguments(struct introspect *i, const char *signatur
                 if (direction)
                         fprintf(i->f, " direction=\"%s\"/>\n", direction);
                 else
-                        fputs_unlocked("/>\n", i->f);
+                        fputs("/>\n", i->f);
 
                 signature += l;
         }
@@ -140,7 +145,7 @@ int introspect_write_interface(struct introspect *i, const sd_bus_vtable *v) {
 
                 case _SD_BUS_VTABLE_START:
                         if (v->flags & SD_BUS_VTABLE_DEPRECATED)
-                                fputs_unlocked("  <annotation name=\"org.freedesktop.DBus.Deprecated\" value=\"true\"/>\n", i->f);
+                                fputs("  <annotation name=\"org.freedesktop.DBus.Deprecated\" value=\"true\"/>\n", i->f);
                         break;
 
                 case _SD_BUS_VTABLE_METHOD:
@@ -148,7 +153,7 @@ int introspect_write_interface(struct introspect *i, const sd_bus_vtable *v) {
                         introspect_write_arguments(i, strempty(v->x.method.signature), "in");
                         introspect_write_arguments(i, strempty(v->x.method.result), "out");
                         introspect_write_flags(i, v->type, v->flags);
-                        fputs_unlocked("  </method>\n", i->f);
+                        fputs("  </method>\n", i->f);
                         break;
 
                 case _SD_BUS_VTABLE_PROPERTY:
@@ -158,14 +163,14 @@ int introspect_write_interface(struct introspect *i, const sd_bus_vtable *v) {
                                 v->x.property.signature,
                                 v->type == _SD_BUS_VTABLE_WRITABLE_PROPERTY ? "readwrite" : "read");
                         introspect_write_flags(i, v->type, v->flags);
-                        fputs_unlocked("  </property>\n", i->f);
+                        fputs("  </property>\n", i->f);
                         break;
 
                 case _SD_BUS_VTABLE_SIGNAL:
                         fprintf(i->f, "  <signal name=\"%s\">\n", v->x.signal.member);
                         introspect_write_arguments(i, strempty(v->x.signal.signature), NULL);
                         introspect_write_flags(i, v->type, v->flags);
-                        fputs_unlocked("  </signal>\n", i->f);
+                        fputs("  </signal>\n", i->f);
                         break;
                 }
 
@@ -182,7 +187,7 @@ int introspect_finish(struct introspect *i, sd_bus *bus, sd_bus_message *m, sd_b
         assert(m);
         assert(reply);
 
-        fputs_unlocked("</node>\n", i->f);
+        fputs("</node>\n", i->f);
 
         r = fflush_and_check(i->f);
         if (r < 0)
index 8e2f380..5d2d5a1 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 5a3c4d6..c6179b4 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 49c0ab3..d9f8093 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index a972c13..8d798c0 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -17,6 +18,8 @@
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
+#include <stdio_ext.h>
+
 #include "alloc-util.h"
 #include "bus-internal.h"
 #include "bus-match.h"
@@ -953,22 +956,24 @@ char *bus_match_to_string(struct bus_match_component *components, unsigned n_com
         if (!f)
                 return NULL;
 
+        __fsetlocking(f, FSETLOCKING_BYCALLER);
+
         for (i = 0; i < n_components; i++) {
                 char buf[32];
 
                 if (i != 0)
-                        fputc_unlocked(',', f);
+                        fputc(',', f);
 
-                fputs_unlocked(bus_match_node_type_to_string(components[i].type, buf, sizeof(buf)), f);
-                fputc_unlocked('=', f);
-                fputc_unlocked('\'', f);
+                fputs(bus_match_node_type_to_string(components[i].type, buf, sizeof(buf)), f);
+                fputc('=', f);
+                fputc('\'', f);
 
                 if (components[i].type == BUS_MATCH_MESSAGE_TYPE)
-                        fputs_unlocked(bus_message_type_to_string(components[i].value_u8), f);
+                        fputs(bus_message_type_to_string(components[i].value_u8), f);
                 else
-                        fputs_unlocked(components[i].value_str, f);
+                        fputs(components[i].value_str, f);
 
-                fputc_unlocked('\'', f);
+                fputc('\'', f);
         }
 
         r = fflush_and_check(f);
index 8cbbb63..ac2e51a 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 3fc447d..219cff1 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -573,28 +574,36 @@ fail:
         return r;
 }
 
-static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
-        sd_bus_message *m;
+_public_ int sd_bus_message_new(
+                sd_bus *bus,
+                sd_bus_message **m,
+                uint8_t type) {
 
-        assert(bus);
+        sd_bus_message *t;
 
-        m = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
-        if (!m)
-                return NULL;
+        assert_return(bus, -ENOTCONN);
+        assert_return(bus->state != BUS_UNSET, -ENOTCONN);
+        assert_return(m, -EINVAL);
+        assert_return(type < _SD_BUS_MESSAGE_TYPE_MAX, -EINVAL);
 
-        m->n_ref = 1;
-        m->header = (struct bus_header*) ((uint8_t*) m + ALIGN(sizeof(struct sd_bus_message)));
-        m->header->endian = BUS_NATIVE_ENDIAN;
-        m->header->type = type;
-        m->header->version = bus->message_version;
-        m->allow_fds = bus->can_fds || !IN_SET(bus->state, BUS_HELLO, BUS_RUNNING);
-        m->root_container.need_offsets = BUS_MESSAGE_IS_GVARIANT(m);
-        m->bus = sd_bus_ref(bus);
+        t = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
+        if (!t)
+                return -ENOMEM;
+
+        t->n_ref = 1;
+        t->header = (struct bus_header*) ((uint8_t*) t + ALIGN(sizeof(struct sd_bus_message)));
+        t->header->endian = BUS_NATIVE_ENDIAN;
+        t->header->type = type;
+        t->header->version = bus->message_version;
+        t->allow_fds = bus->can_fds || !IN_SET(bus->state, BUS_HELLO, BUS_RUNNING);
+        t->root_container.need_offsets = BUS_MESSAGE_IS_GVARIANT(t);
+        t->bus = sd_bus_ref(bus);
 
         if (bus->allow_interactive_authorization)
-                m->header->flags |= BUS_MESSAGE_ALLOW_INTERACTIVE_AUTHORIZATION;
+                t->header->flags |= BUS_MESSAGE_ALLOW_INTERACTIVE_AUTHORIZATION;
 
-        return m;
+        *m = t;
+        return 0;
 }
 
 _public_ int sd_bus_message_new_signal(
@@ -614,10 +623,12 @@ _public_ int sd_bus_message_new_signal(
         assert_return(member_name_is_valid(member), -EINVAL);
         assert_return(m, -EINVAL);
 
-        t = message_new(bus, SD_BUS_MESSAGE_SIGNAL);
-        if (!t)
+        r = sd_bus_message_new(bus, &t, SD_BUS_MESSAGE_SIGNAL);
+        if (r < 0)
                 return -ENOMEM;
 
+        assert(t);
+
         t->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
 
         r = message_append_field_string(t, BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
@@ -657,10 +668,12 @@ _public_ int sd_bus_message_new_method_call(
         assert_return(member_name_is_valid(member), -EINVAL);
         assert_return(m, -EINVAL);
 
-        t = message_new(bus, SD_BUS_MESSAGE_METHOD_CALL);
-        if (!t)
+        r = sd_bus_message_new(bus, &t, SD_BUS_MESSAGE_METHOD_CALL);
+        if (r < 0)
                 return -ENOMEM;
 
+        assert(t);
+
         r = message_append_field_string(t, BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
         if (r < 0)
                 goto fail;
@@ -694,6 +707,7 @@ static int message_new_reply(
                 sd_bus_message **m) {
 
         sd_bus_message *t;
+        uint64_t cookie;
         int r;
 
         assert_return(call, -EINVAL);
@@ -702,15 +716,18 @@ static int message_new_reply(
         assert_return(call->bus->state != BUS_UNSET, -ENOTCONN);
         assert_return(m, -EINVAL);
 
-        t = message_new(call->bus, type);
-        if (!t)
+        cookie = BUS_MESSAGE_COOKIE(call);
+        if (cookie == 0)
+                return -EOPNOTSUPP;
+
+        r = sd_bus_message_new(call->bus, &t, type);
+        if (r < 0)
                 return -ENOMEM;
 
-        t->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
-        t->reply_cookie = BUS_MESSAGE_COOKIE(call);
-        if (t->reply_cookie == 0)
-                return -EOPNOTSUPP;
+        assert(t);
 
+        t->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
+        t->reply_cookie = cookie;
         r = message_append_reply_cookie(t, t->reply_cookie);
         if (r < 0)
                 goto fail;
@@ -858,10 +875,12 @@ int bus_message_new_synthetic_error(
         assert(sd_bus_error_is_set(e));
         assert(m);
 
-        t = message_new(bus, SD_BUS_MESSAGE_METHOD_ERROR);
-        if (!t)
+        r = sd_bus_message_new(bus, &t, SD_BUS_MESSAGE_METHOD_ERROR);
+        if (r < 0)
                 return -ENOMEM;
 
+        assert(t);
+
         t->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
         t->reply_cookie = cookie;
 
@@ -1436,7 +1455,7 @@ int message_append_basic(sd_bus_message *m, char type, const void *p, const void
                 case SD_BUS_TYPE_STRING:
                         p = strempty(p);
 
-                        /* Fall through... */
+                        _fallthrough_;
                 case SD_BUS_TYPE_OBJECT_PATH:
                         if (!p)
                                 return -EINVAL;
@@ -1496,7 +1515,7 @@ int message_append_basic(sd_bus_message *m, char type, const void *p, const void
                          * into the empty string */
                         p = strempty(p);
 
-                        /* Fall through... */
+                        _fallthrough_;
                 case SD_BUS_TYPE_OBJECT_PATH:
 
                         if (!p)
@@ -2857,13 +2876,13 @@ static int bus_message_close_header(sd_bus_message *m) {
         return 0;
 }
 
-int bus_message_seal(sd_bus_message *m, uint64_t cookie, usec_t timeout) {
+_public_ int sd_bus_message_seal(sd_bus_message *m, uint64_t cookie, uint64_t timeout_usec) {
         struct bus_body_part *part;
         size_t a;
         unsigned i;
         int r;
 
-        assert(m);
+        assert_return(m, -EINVAL);
 
         if (m->sealed)
                 return -EPERM;
@@ -2913,7 +2932,7 @@ int bus_message_seal(sd_bus_message *m, uint64_t cookie, usec_t timeout) {
         else
                 m->header->dbus1.serial = (uint32_t) cookie;
 
-        m->timeout = m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED ? 0 : timeout;
+        m->timeout = m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED ? 0 : timeout_usec;
 
         /* Add padding at the end of the fields part, since we know
          * the body needs to start at an 8 byte alignment. We made
@@ -5787,10 +5806,12 @@ int bus_message_remarshal(sd_bus *bus, sd_bus_message **m) {
         case SD_BUS_MESSAGE_METHOD_RETURN:
         case SD_BUS_MESSAGE_METHOD_ERROR:
 
-                n = message_new(bus, (*m)->header->type);
-                if (!n)
+                r = sd_bus_message_new(bus, &n, (*m)->header->type);
+                if (r < 0)
                         return -ENOMEM;
 
+                assert(n);
+
                 n->reply_cookie = (*m)->reply_cookie;
 
                 r = message_append_reply_cookie(n, n->reply_cookie);
@@ -5833,7 +5854,7 @@ int bus_message_remarshal(sd_bus *bus, sd_bus_message **m) {
         if (timeout == 0 && !((*m)->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED))
                 timeout = BUS_DEFAULT_TIMEOUT;
 
-        r = bus_message_seal(n, BUS_MESSAGE_COOKIE(*m), timeout);
+        r = sd_bus_message_seal(n, BUS_MESSAGE_COOKIE(*m), timeout);
         if (r < 0)
                 return r;
 
index a84f908..1e4b209 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -187,7 +188,6 @@ static inline bool BUS_MESSAGE_IS_GVARIANT(sd_bus_message *m) {
         return m->header->version == 2;
 }
 
-int bus_message_seal(sd_bus_message *m, uint64_t serial, usec_t timeout);
 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz);
 int bus_message_read_strv_extend(sd_bus_message *m, char ***l);
 
index df2bdc8..121197b 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -959,7 +960,7 @@ static int process_introspect(
                 if (!streq_ptr(previous_interface, c->interface)) {
 
                         if (previous_interface)
-                                fputs_unlocked(" </interface>\n", intro.f);
+                                fputs(" </interface>\n", intro.f);
 
                         fprintf(intro.f, " <interface name=\"%s\">\n", c->interface);
                 }
@@ -972,7 +973,7 @@ static int process_introspect(
         }
 
         if (previous_interface)
-                fputs_unlocked(" </interface>\n", intro.f);
+                fputs(" </interface>\n", intro.f);
 
         if (empty) {
                 /* Nothing?, let's see if we exist at all, and if not
@@ -1475,8 +1476,7 @@ static struct node *bus_node_allocate(sd_bus *bus, const char *path) {
         r = hashmap_put(bus->nodes, n->path, n);
         if (r < 0) {
                 free(n->path);
-                free(n);
-                return NULL;
+                return mfree(n);
         }
 
         if (parent)
@@ -1498,7 +1498,7 @@ void bus_node_gc(sd_bus *b, struct node *n) {
             n->object_managers)
                 return;
 
-        assert(hashmap_remove(b->nodes, n->path) == n);
+        assert_se(hashmap_remove(b->nodes, n->path) == n);
 
         if (n->parent)
                 LIST_REMOVE(siblings, n->parent->child, n);
@@ -1755,8 +1755,7 @@ static int add_object_vtable_internal(
                                 goto fail;
                         }
 
-                        /* Fall through */
-
+                        _fallthrough_;
                 case _SD_BUS_VTABLE_PROPERTY: {
                         struct vtable_member *m;
 
index e0b8c53..6bffeda 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 9d180cb..0d5dfd9 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 7bc2434..d16461f 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 1e0cd7f..a6be184 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 725265b..756761c 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 3b8b94d..beebaa1 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 235fe26..07a9c8a 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -231,8 +232,9 @@ static int bus_socket_auth_verify_client(sd_bus *b) {
 
         if (f)
                 b->can_fds =
-                        (f - e == strlen("\r\nAGREE_UNIX_FD")) &&
-                        memcmp(e + 2, "AGREE_UNIX_FD", strlen("AGREE_UNIX_FD")) == 0;
+                        (f - e == STRLEN("\r\nAGREE_UNIX_FD")) &&
+                        memcmp(e + 2, "AGREE_UNIX_FD",
+                               STRLEN("AGREE_UNIX_FD")) == 0;
 
         b->rbuffer_size -= (start - (char*) b->rbuffer);
         memmove(b->rbuffer, start, b->rbuffer_size);
index 684feea..915a283 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 4acaf24..ab22d6e 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -62,7 +63,7 @@ struct sd_bus_track {
         ({                                                              \
                 char *_x;                                               \
                 size_t _l = strlen(name);                               \
-                _x = alloca(strlen(MATCH_PREFIX)+_l+strlen(MATCH_SUFFIX)+1); \
+                _x = alloca(STRLEN(MATCH_PREFIX)+_l+STRLEN(MATCH_SUFFIX)+1); \
                 strcpy(stpcpy(stpcpy(_x, MATCH_PREFIX), name), MATCH_SUFFIX); \
                 _x;                                                     \
         })
@@ -183,8 +184,6 @@ _public_ sd_bus_track* sd_bus_track_ref(sd_bus_track *track) {
 }
 
 _public_ sd_bus_track* sd_bus_track_unref(sd_bus_track *track) {
-        struct track_item *i;
-
         if (!track)
                 return NULL;
 
@@ -195,14 +194,11 @@ _public_ sd_bus_track* sd_bus_track_unref(sd_bus_track *track) {
                 return NULL;
         }
 
-        while ((i = hashmap_steal_first(track->names)))
-                track_item_free(i);
-
         if (track->in_list)
                 LIST_REMOVE(tracks, track->bus->tracks, track);
 
         bus_track_remove_from_queue(track);
-        hashmap_free(track->names);
+        hashmap_free_with_destructor(track->names, track_item_free);
         sd_bus_unref(track->bus);
         return mfree(track);
 }
@@ -428,8 +424,6 @@ void bus_track_dispatch(sd_bus_track *track) {
 }
 
 void bus_track_close(sd_bus_track *track) {
-        struct track_item *i;
-
         assert(track);
 
         /* Called whenever our bus connected is closed. If so, and our track object is non-empty, dispatch it
@@ -447,8 +441,7 @@ void bus_track_close(sd_bus_track *track) {
                 return;
 
         /* Let's flush out all names */
-        while ((i = hashmap_steal_first(track->names)))
-                track_item_free(i);
+        hashmap_clear_with_destructor(track->names, track_item_free);
 
         /* Invoke handler */
         if (track->handler)
index 26bd05f..0c5636b 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index c692afc..fe486f4 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 5c87eb5..ae272b1 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 621fabb..5fb15a7 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -785,9 +786,7 @@ static int parse_container_unix_address(sd_bus *b, const char **p, char **guid)
                 if (!machine_name_is_valid(machine))
                         return -EINVAL;
 
-                free(b->machine);
-                b->machine = machine;
-                machine = NULL;
+                free_and_replace(b->machine, machine);
         } else {
                 b->machine = mfree(b->machine);
         }
@@ -1412,7 +1411,7 @@ static int bus_seal_message(sd_bus *b, sd_bus_message *m, usec_t timeout) {
         if (timeout == 0)
                 timeout = BUS_DEFAULT_TIMEOUT;
 
-        return bus_message_seal(m, ++b->cookie, timeout);
+        return sd_bus_message_seal(m, ++b->cookie, timeout);
 }
 
 static int bus_remarshal_message(sd_bus *b, sd_bus_message **m) {
@@ -1452,7 +1451,7 @@ int bus_seal_synthetic_message(sd_bus *b, sd_bus_message *m) {
          * pick a fixed, artificial one. We use (uint32_t) -1 rather
          * than (uint64_t) -1 since dbus1 only had 32bit identifiers,
          * even though kdbus can do 64bit. */
-        return bus_message_seal(m, 0xFFFFFFFFULL, 0);
+        return sd_bus_message_seal(m, 0xFFFFFFFFULL, 0);
 }
 
 static int bus_write_message(sd_bus *bus, sd_bus_message *m, bool hint_sync_call, size_t *idx) {
index 6f0ca47..6587b13 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 0fc6fc9..1b2efb9 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 4d81e67..d5601fc 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 64bd76a..f654692 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 66a3874..4e3f404 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 94fa964..4c372fd 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -153,7 +154,7 @@ static void test_marshal(void) {
                                         4712, "second-string-parameter", "(a(si))", 2, "Y", 5, "Z", 6,
                                         4713, "third-string-parameter", "(uu)", 1, 2) >= 0);
 
-        assert_se(bus_message_seal(m, 4711, 0) >= 0);
+        assert_se(sd_bus_message_seal(m, 4711, 0) >= 0);
 
 #if HAVE_GLIB
         {
@@ -209,7 +210,7 @@ static void test_marshal(void) {
 
         assert_se(sd_bus_message_append(m, "as", 0) >= 0);
 
-        assert_se(bus_message_seal(m, 4712, 0) >= 0);
+        assert_se(sd_bus_message_seal(m, 4712, 0) >= 0);
         assert_se(bus_message_dump(m, NULL, BUS_MESSAGE_DUMP_WITH_HEADER) >= 0);
 }
 
index 4425cfa..8dee936 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 221dbd3..ebf55e8 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -196,7 +197,7 @@ int main(int argc, char *argv[]) {
         r = sd_bus_message_append(m, "a(stdo)", 1, "foo", 815ULL, 47.0, "/");
         assert_se(r >= 0);
 
-        r = bus_message_seal(m, 4711, 0);
+        r = sd_bus_message_seal(m, 4711, 0);
         assert_se(r >= 0);
 
         bus_message_dump(m, stdout, BUS_MESSAGE_DUMP_WITH_HEADER);
@@ -359,7 +360,7 @@ int main(int argc, char *argv[]) {
         r = sd_bus_message_copy(copy, m, true);
         assert_se(r >= 0);
 
-        r = bus_message_seal(copy, 4712, 0);
+        r = sd_bus_message_seal(copy, 4712, 0);
         assert_se(r >= 0);
 
         fclose(ms);
index 8fd9d03..47b4564 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -121,7 +122,7 @@ int main(int argc, char *argv[]) {
 
         assert_se(sd_bus_message_new_signal(bus, &m, "/foo/bar", "bar.x", "waldo") >= 0);
         assert_se(sd_bus_message_append(m, "ssssas", "one", "two", "/prefix/three", "prefix.four", 3, "pi", "pa", "po") >= 0);
-        assert_se(bus_message_seal(m, 1, 0) >= 0);
+        assert_se(sd_bus_message_seal(m, 1, 0) >= 0);
 
         zero(mask);
         assert_se(bus_match_run(NULL, &root, m) == 0);
index 0b33ab7..58ef8b6 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index b6272ef..245f570 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 4f4fd09..aa6160d 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 5f5661c..320e834 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index cb416fd..00cee89 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index ebb8b2d..cd9ec04 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -292,7 +293,7 @@ static int device_compare(const void *_a, const void *_b) {
                  * entire sound card completed. The kernel makes this guarantee
                  * when creating those devices, and hence we should too when
                  * enumerating them. */
-                sound_a += strlen("/sound/card");
+                sound_a += STRLEN("/sound/card");
                 sound_a = strchr(sound_a, '/');
 
                 if (sound_a) {
index 0505a27..6be84f9 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 8839c32..77f0f4b 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -677,13 +678,9 @@ static int device_update_properties_bufs(sd_device *device) {
                 i++;
         }
 
-        free(device->properties_nulstr);
-        device->properties_nulstr = buf_nulstr;
-        buf_nulstr = NULL;
+        free_and_replace(device->properties_nulstr, buf_nulstr);
         device->properties_nulstr_len = nulstr_len;
-        free(device->properties_strv);
-        device->properties_strv = buf_strv;
-        buf_strv = NULL;
+        free_and_replace(device->properties_strv, buf_strv);
 
         device->properties_buf_outdated = false;
 
@@ -1053,7 +1050,7 @@ int device_update_db(sd_device *device) {
                         const char *devlink;
 
                         FOREACH_DEVICE_DEVLINK(device, devlink)
-                                fprintf(f, "S:%s\n", devlink + strlen("/dev/"));
+                                fprintf(f, "S:%s\n", devlink + STRLEN("/dev/"));
 
                         if (device->devlink_priority != 0)
                                 fprintf(f, "L:%i\n", device->devlink_priority);
index 29b3e15..02d93c9 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 5b42e11..d55b810 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 3b5a04d..a96d744 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -208,15 +209,13 @@ int device_set_syspath(sd_device *device, const char *_syspath, bool verify) {
                         return -ENOMEM;
         }
 
-        devpath = syspath + strlen("/sys");
+        devpath = syspath + STRLEN("/sys");
 
         r = device_add_property_internal(device, "DEVPATH", devpath);
         if (r < 0)
                 return r;
 
-        free(device->syspath);
-        device->syspath = syspath;
-        syspath = NULL;
+        free_and_replace(device->syspath, syspath);
 
         device->devpath = devpath;
 
@@ -346,9 +345,7 @@ int device_set_devtype(sd_device *device, const char *_devtype) {
         if (r < 0)
                 return r;
 
-        free(device->devtype);
-        device->devtype = devtype;
-        devtype = NULL;
+        free_and_replace(device->devtype, devtype);
 
         return 0;
 }
@@ -393,9 +390,7 @@ int device_set_devname(sd_device *device, const char *_devname) {
         if (r < 0)
                 return r;
 
-        free(device->devname);
-        device->devname = devname;
-        devname = NULL;
+        free_and_replace(device->devname, devname);
 
         return 0;
 }
@@ -563,7 +558,7 @@ int device_read_uevent_file(sd_device *device) {
                         value = &uevent[i];
                         state = VALUE;
 
-                        /* fall through */ /* to handle empty property */
+                        _fallthrough_; /* to handle empty property */
                 case VALUE:
                         if (strchr(NEWLINE, uevent[i])) {
                                 uevent[i] = '\0';
@@ -705,7 +700,7 @@ static int device_new_from_child(sd_device **ret, sd_device *child) {
         path = strdup(syspath);
         if (!path)
                 return -ENOMEM;
-        subdir = path + strlen("/sys");
+        subdir = path + STRLEN("/sys");
 
         for (;;) {
                 char *pos;
@@ -760,9 +755,7 @@ int device_set_subsystem(sd_device *device, const char *_subsystem) {
         if (r < 0)
                 return r;
 
-        free(device->subsystem);
-        device->subsystem = subsystem;
-        subsystem = NULL;
+        free_and_replace(device->subsystem, subsystem);
 
         device->subsystem_set = true;
 
@@ -785,9 +778,7 @@ static int device_set_drivers_subsystem(sd_device *device, const char *_subsyste
         if (r < 0)
                 return r;
 
-        free(device->driver_subsystem);
-        device->driver_subsystem = subsystem;
-        subsystem = NULL;
+        free_and_replace(device->driver_subsystem, subsystem);
 
         return 0;
 }
@@ -935,9 +926,7 @@ int device_set_driver(sd_device *device, const char *_driver) {
         if (r < 0)
                 return r;
 
-        free(device->driver);
-        device->driver = driver;
-        driver = NULL;
+        free_and_replace(device->driver, driver);
 
         device->driver_set = true;
 
@@ -1044,9 +1033,7 @@ static int device_set_sysname(sd_device *device) {
         if (len == 0)
                 sysnum = NULL;
 
-        free(device->sysname);
-        device->sysname = sysname;
-        sysname = NULL;
+        free_and_replace(device->sysname, sysname);
 
         device->sysnum = sysnum;
 
index 2c5c2eb..a5f3e85 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 1a581ae..7f32838 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -317,11 +318,11 @@ static void test_rtqueue(void) {
 
         assert_se(sd_event_source_set_priority(v, -10) >= 0);
 
-        assert(sigqueue(getpid_cached(), SIGRTMIN+2, (union sigval) { .sival_int = 1 }) >= 0);
-        assert(sigqueue(getpid_cached(), SIGRTMIN+3, (union sigval) { .sival_int = 2 }) >= 0);
-        assert(sigqueue(getpid_cached(), SIGUSR2, (union sigval) { .sival_int = 3 }) >= 0);
-        assert(sigqueue(getpid_cached(), SIGRTMIN+3, (union sigval) { .sival_int = 4 }) >= 0);
-        assert(sigqueue(getpid_cached(), SIGUSR2, (union sigval) { .sival_int = 5 }) >= 0);
+        assert_se(sigqueue(getpid_cached(), SIGRTMIN+2, (union sigval) { .sival_int = 1 }) >= 0);
+        assert_se(sigqueue(getpid_cached(), SIGRTMIN+3, (union sigval) { .sival_int = 2 }) >= 0);
+        assert_se(sigqueue(getpid_cached(), SIGUSR2, (union sigval) { .sival_int = 3 }) >= 0);
+        assert_se(sigqueue(getpid_cached(), SIGRTMIN+3, (union sigval) { .sival_int = 4 }) >= 0);
+        assert_se(sigqueue(getpid_cached(), SIGUSR2, (union sigval) { .sival_int = 5 }) >= 0);
 
         assert_se(n_rtqueue == 0);
         assert_se(last_rtqueue_sigval == 0);
index 2f4934a..36dae8c 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 5e21e50..b305352 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index f8246ea..9418e8c 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index f5c017f..5541e8d 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -116,7 +117,7 @@ int id128_read_fd(int fd, Id128Format f, sd_id128_t *ret) {
                 if (buffer[32] != '\n')
                         return -EINVAL;
 
-                /* fall through */
+                _fallthrough_;
         case 32: /* plain UUID without trailing newline */
                 if (f == ID128_UUID)
                         return -EINVAL;
@@ -128,7 +129,7 @@ int id128_read_fd(int fd, Id128Format f, sd_id128_t *ret) {
                 if (buffer[36] != '\n')
                         return -EINVAL;
 
-                /* fall through */
+                _fallthrough_;
         case 36: /* RFC UUID without trailing newline */
                 if (f == ID128_PLAIN)
                         return -EINVAL;
index 6b3855a..9f3340e 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index d44d75e..561bcdf 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 5fb7fd9..e8adaa6 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 02a73f9..559529e 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index d82ca80..23acec4 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index ac0427f..c887545 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 129bfd2..22be943 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 979dc68..f8be296 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
 #include <linux/if_tunnel.h>
 #include <linux/fib_rules.h>
 
+#if HAVE_VXCAN_INFO_PEER
+#include <linux/can/vxcan.h>
+#endif
+
 #include "macro.h"
 #include "missing.h"
 #include "netlink-types.h"
@@ -91,6 +96,10 @@ static const NLType rtnl_link_info_data_veth_types[] = {
         [VETH_INFO_PEER]  = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
 };
 
+static const NLType rtnl_link_info_data_vxcan_types[] = {
+        [VXCAN_INFO_PEER]  = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
+};
+
 static const NLType rtnl_link_info_data_ipvlan_types[] = {
         [IFLA_IPVLAN_MODE]  = { .type = NETLINK_TYPE_U16 },
 };
@@ -327,6 +336,8 @@ static const char* const nl_union_link_info_data_table[] = {
         [NL_UNION_LINK_INFO_DATA_VRF] = "vrf",
         [NL_UNION_LINK_INFO_DATA_VCAN] = "vcan",
         [NL_UNION_LINK_INFO_DATA_GENEVE] = "geneve",
+        [NL_UNION_LINK_INFO_DATA_VXCAN] = "vxcan",
+
 };
 
 DEFINE_STRING_TABLE_LOOKUP(nl_union_link_info_data, NLUnionLinkInfoData);
@@ -370,6 +381,8 @@ static const NLTypeSystem rtnl_link_info_data_type_systems[] = {
                                                        .types = rtnl_link_info_data_vrf_types },
         [NL_UNION_LINK_INFO_DATA_GENEVE] =           { .count = ELEMENTSOF(rtnl_link_info_data_geneve_types),
                                                        .types = rtnl_link_info_data_geneve_types },
+        [NL_UNION_LINK_INFO_DATA_VXCAN] =            { .count = ELEMENTSOF(rtnl_link_info_data_vxcan_types),
+                                                       .types = rtnl_link_info_data_vxcan_types },
 };
 
 static const NLTypeSystemUnion rtnl_link_info_data_type_system_union = {
index ae65c1d..57b4633 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -89,6 +90,7 @@ typedef enum NLUnionLinkInfoData {
         NL_UNION_LINK_INFO_DATA_VRF,
         NL_UNION_LINK_INFO_DATA_VCAN,
         NL_UNION_LINK_INFO_DATA_GENEVE,
+        NL_UNION_LINK_INFO_DATA_VXCAN,
         _NL_UNION_LINK_INFO_DATA_MAX,
         _NL_UNION_LINK_INFO_DATA_INVALID = -1
 } NLUnionLinkInfoData;
index 6b660b7..b32fad2 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
  This file is part of systemd.
 
index d2fb651..c804f55 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index d851ac2..24345c4 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 77f4d5b..924b0c9 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index e0e28cc..bb195b9 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 83f0395..73e5af0 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index a0d9b5f..0957d59 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 26780dc..9c6b3fc 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 41b97ca..8f48140 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -103,7 +104,7 @@ _public_ int sd_network_get_route_domains(char ***ret) {
 }
 
 static int network_link_get_string(int ifindex, const char *field, char **ret) {
-        char path[strlen("/run/systemd/netif/links/") + DECIMAL_STR_MAX(ifindex) + 1];
+        char path[STRLEN("/run/systemd/netif/links/") + DECIMAL_STR_MAX(ifindex) + 1];
         _cleanup_free_ char *s = NULL;
         int r;
 
@@ -127,7 +128,7 @@ static int network_link_get_string(int ifindex, const char *field, char **ret) {
 }
 
 static int network_link_get_strv(int ifindex, const char *key, char ***ret) {
-        char path[strlen("/run/systemd/netif/links/") + DECIMAL_STR_MAX(ifindex) + 1];
+        char path[STRLEN("/run/systemd/netif/links/") + DECIMAL_STR_MAX(ifindex) + 1];
         _cleanup_strv_free_ char **a = NULL;
         _cleanup_free_ char *s = NULL;
         int r;
@@ -171,6 +172,21 @@ _public_ int sd_network_link_get_operational_state(int ifindex, char **state) {
         return network_link_get_string(ifindex, "OPER_STATE", state);
 }
 
+_public_ int sd_network_link_get_required_for_online(int ifindex) {
+        _cleanup_free_ char *s = NULL;
+        int r;
+
+        r = network_link_get_string(ifindex, "REQUIRED_FOR_ONLINE", &s);
+        if (r < 0) {
+                /* Handle -ENODATA as RequiredForOnline=yes, for compatibility */
+                if (r == -ENODATA)
+                        return true;
+                return r;
+        }
+
+        return parse_boolean(s);
+}
+
 _public_ int sd_network_link_get_llmnr(int ifindex, char **llmnr) {
         return network_link_get_string(ifindex, "LLMNR", llmnr);
 }
@@ -208,7 +224,7 @@ _public_ int sd_network_link_get_route_domains(int ifindex, char ***ret) {
 }
 
 static int network_link_get_ifindexes(int ifindex, const char *key, int **ret) {
-        char path[strlen("/run/systemd/netif/links/") + DECIMAL_STR_MAX(ifindex) + 1];
+        char path[STRLEN("/run/systemd/netif/links/") + DECIMAL_STR_MAX(ifindex) + 1];
         _cleanup_free_ int *ifis = NULL;
         _cleanup_free_ char *s = NULL;
         size_t allocated = 0, c = 0;
index 6570d01..cd76e35 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 12fae65..be3748e 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -32,6 +33,7 @@
 #include "sd-resolve.h"
 
 #include "alloc-util.h"
+#include "dns-domain.h"
 #include "fd-util.h"
 #include "io-util.h"
 #include "list.h"
@@ -811,25 +813,36 @@ static int handle_response(sd_resolve *resolve, const Packet *packet, size_t len
                 assert(length >= sizeof(NameInfoResponse));
                 assert(q->type == REQUEST_NAMEINFO);
 
-                q->ret = ni_resp->ret;
-                q->_errno = ni_resp->_errno;
-                q->_h_errno = ni_resp->_h_errno;
-
-                if (ni_resp->hostlen > 0) {
-                        q->host = strndup((const char*) ni_resp + sizeof(NameInfoResponse), ni_resp->hostlen-1);
-                        if (!q->host) {
-                                q->ret = EAI_MEMORY;
-                                q->_errno = ENOMEM;
-                                q->_h_errno = 0;
+                if (ni_resp->hostlen > DNS_HOSTNAME_MAX ||
+                    ni_resp->servlen > DNS_HOSTNAME_MAX ||
+                    sizeof(NameInfoResponse) + ni_resp->hostlen + ni_resp->servlen > length + 2) {
+                        q->ret = EAI_SYSTEM;
+                        q->_errno = -EIO;
+                        q->_h_errno = 0;
+
+                } else {
+                        q->ret = ni_resp->ret;
+                        q->_errno = ni_resp->_errno;
+                        q->_h_errno = ni_resp->_h_errno;
+
+                        if (ni_resp->hostlen > 0) {
+                                q->host = strndup((const char*) ni_resp + sizeof(NameInfoResponse),
+                                                  ni_resp->hostlen-1);
+                                if (!q->host) {
+                                        q->ret = EAI_MEMORY;
+                                        q->_errno = ENOMEM;
+                                        q->_h_errno = 0;
+                                }
                         }
-                }
 
-                if (ni_resp->servlen > 0) {
-                        q->serv = strndup((const char*) ni_resp + sizeof(NameInfoResponse) + ni_resp->hostlen, ni_resp->servlen-1);
-                        if (!q->serv) {
-                                q->ret = EAI_MEMORY;
-                                q->_errno = ENOMEM;
-                                q->_h_errno = 0;
+                        if (ni_resp->servlen > 0) {
+                                q->serv = strndup((const char*) ni_resp + sizeof(NameInfoResponse) + ni_resp->hostlen,
+                                                  ni_resp->servlen-1);
+                                if (!q->serv) {
+                                        q->ret = EAI_MEMORY;
+                                        q->_errno = ENOMEM;
+                                        q->_h_errno = 0;
+                                }
                         }
                 }
 
@@ -889,6 +902,8 @@ _public_ int sd_resolve_wait(sd_resolve *resolve, uint64_t timeout_usec) {
 
         if (r < 0)
                 return r;
+        if (r == 0)
+                return -ETIMEDOUT;
 
         return sd_resolve_process(resolve);
 }
index 1be1a7f..752eb15 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -33,6 +34,8 @@
 #include "socket-util.h"
 #include "string-util.h"
 
+#define TEST_TIMEOUT_USEC (20*USEC_PER_SEC)
+
 static int getaddrinfo_handler(sd_resolve_query *q, int ret, const struct addrinfo *ai, void *userdata) {
         const struct addrinfo *i;
 
@@ -101,9 +104,18 @@ int main(int argc, char *argv[]) {
 
         /* Wait until all queries are completed */
         for (;;) {
-                r = sd_resolve_wait(resolve, (uint64_t) -1);
+                r = sd_resolve_wait(resolve, TEST_TIMEOUT_USEC);
                 if (r == 0)
                         break;
+                if (r == -ETIMEDOUT) {
+                        /* Let's catch time-outs here, so that we can run safely in a CI that has no reliable DNS. Note
+                         * that we invoke exit() directly here, as the stuck NSS call will not allow us to exit
+                         * cleanly. */
+
+                        log_notice_errno(r, "sd_resolve_wait() timed out, but that's OK");
+                        exit(EXIT_SUCCESS);
+                        break;
+                }
                 if (r < 0) {
                         log_error_errno(r, "sd_resolve_wait(): %m");
                         assert_not_reached("sd_resolve_wait() failed");
index 33a5a04..b8db7eb 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 0e9af8e..445acd9 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 2aae072..868926e 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index c5f3672..82df426 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index ea80c75..2718800 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 4bdc37d..d266527 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -112,8 +113,7 @@ _public_ struct udev_hwdb *udev_hwdb_unref(struct udev_hwdb *hwdb) {
                 return NULL;
         sd_hwdb_unref(hwdb->hwdb);
         udev_list_cleanup(&hwdb->properties_list);
-        free(hwdb);
-        return NULL;
+        return mfree(hwdb);
 }
 
 /**
index 0d51322..29fbdbd 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 32f2154..ca14373 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -95,8 +96,7 @@ struct udev_monitor_netlink_header {
         unsigned int filter_tag_bloom_lo;
 };
 
-static struct udev_monitor *udev_monitor_new(struct udev *udev)
-{
+static struct udev_monitor *udev_monitor_new(struct udev *udev) {
         struct udev_monitor *udev_monitor;
 
         udev_monitor = new0(struct udev_monitor, 1);
@@ -114,16 +114,15 @@ static struct udev_monitor *udev_monitor_new(struct udev *udev)
 /* we consider udev running when /dev is on devtmpfs */
 static bool udev_has_devtmpfs(struct udev *udev) {
 
-        union file_handle_union h = FILE_HANDLE_INIT;
         _cleanup_fclose_ FILE *f = NULL;
         char line[LINE_MAX], *e;
-        int mount_id;
-        int r;
+        int mount_id, r;
 
-        r = name_to_handle_at(AT_FDCWD, "/dev", &h.handle, &mount_id, 0);
+        r = path_get_mnt_id("/dev", &mount_id);
         if (r < 0) {
-                if (errno != EOPNOTSUPP)
-                        log_debug_errno(errno, "name_to_handle_at on /dev: %m");
+                if (r != -EOPNOTSUPP)
+                        log_debug_errno(r, "name_to_handle_at on /dev: %m");
+
                 return false;
         }
 
@@ -168,8 +167,7 @@ static void monitor_set_nl_address(struct udev_monitor *udev_monitor) {
                 udev_monitor->snl.nl.nl_pid = snl.nl.nl_pid;
 }
 
-struct udev_monitor *udev_monitor_new_from_netlink_fd(struct udev *udev, const char *name, int fd)
-{
+struct udev_monitor *udev_monitor_new_from_netlink_fd(struct udev *udev, const char *name, int fd) {
         struct udev_monitor *udev_monitor;
         unsigned int group;
 
@@ -253,8 +251,7 @@ struct udev_monitor *udev_monitor_new_from_netlink_fd(struct udev *udev, const c
  *
  * Returns: a new udev monitor, or #NULL, in case of an error
  **/
-_public_ struct udev_monitor *udev_monitor_new_from_netlink(struct udev *udev, const char *name)
-{
+_public_ struct udev_monitor *udev_monitor_new_from_netlink(struct udev *udev, const char *name) {
         return udev_monitor_new_from_netlink_fd(udev, name, -1);
 }
 
@@ -496,8 +493,7 @@ _public_ struct udev_monitor *udev_monitor_unref(struct udev_monitor *udev_monit
                 close(udev_monitor->sock);
         udev_list_cleanup(&udev_monitor->filter_subsystem_list);
         udev_list_cleanup(&udev_monitor->filter_tag_list);
-        free(udev_monitor);
-        return NULL;
+        return mfree(udev_monitor);
 }
 
 /**
index 52c5075..76730cc 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -138,7 +139,6 @@ int udev_queue_export_device_finished(struct udev_queue_export *udev_queue_expor
 #define UDEV_ALLOWED_CHARS_INPUT        "/ $%?,"
 int util_log_priority(const char *priority);
 size_t util_path_encode(const char *src, char *dest, size_t size);
-void util_remove_trailing_chars(char *path, char c);
 int util_replace_whitespace(const char *str, char *to, size_t len);
 int util_replace_chars(char *str, const char *white);
 unsigned int util_string_hash32(const char *key);
index f3143d4..b941afb 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -114,8 +115,7 @@ _public_ struct udev_queue *udev_queue_unref(struct udev_queue *udev_queue)
 
         safe_close(udev_queue->fd);
 
-        free(udev_queue);
-        return NULL;
+        return mfree(udev_queue);
 }
 
 /**
index 1d73d8f..977caad 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -150,17 +151,6 @@ size_t util_path_encode(const char *src, char *dest, size_t size)
         return j;
 }
 
-void util_remove_trailing_chars(char *path, char c)
-{
-        size_t len;
-
-        if (path == NULL)
-                return;
-        len = strlen(path);
-        while (len > 0 && path[len-1] == c)
-                path[--len] = '\0';
-}
-
 /*
  * Copy from 'str' to 'to', while removing all leading and trailing whitespace,
  * and replacing each run of consecutive whitespace with a single underscore.
index ce8d5b5..64904c5 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -135,8 +136,7 @@ _public_ struct udev *udev_unref(struct udev *udev) {
         udev->refcount--;
         if (udev->refcount > 0)
                 return udev;
-        free(udev);
-        return NULL;
+        return mfree(udev);
 }
 
 /**
index 3f6d0ed..be465a0 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 1becae4..69f5c64 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 76726fc..1e8dbfa 100644 (file)
@@ -1,4 +1,6 @@
 /***
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   systemd is free software; you can redistribute it and/or modify it
index 57d678f..30d6721 100644 (file)
@@ -1,3 +1,20 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
+# Copyright 2017 Zbigniew Jędrzejewski-Szmek
+#
+# 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.
+#
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
 libudev_sources = files('''
         libudev-private.h
         libudev-device-internal.h
index b71091f..2d78810 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -19,6 +20,7 @@
 ***/
 
 #include <errno.h>
+#include <stdio_ext.h>
 #include <string.h>
 #include <unistd.h>
 
@@ -200,9 +202,7 @@ static int x11_read_data(Context *c) {
                                         p = &c->x11_options;
 
                                 if (p) {
-                                        free(*p);
-                                        *p = a[2];
-                                        a[2] = NULL;
+                                        free_and_replace(*p, a[2]);
                                 }
                         }
 
@@ -359,14 +359,15 @@ int x11_write_data(Context *c) {
         if (r < 0)
                 return r;
 
-        fchmod(fileno(f), 0644);
+        (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
+        (void) fchmod(fileno(f), 0644);
 
-        fputs_unlocked("# Written by systemd-localed(8), read by systemd-localed and Xorg. It's\n"
-                       "# probably wise not to edit this file manually. Use localectl(1) to\n"
-                       "# instruct systemd-localed to update it.\n"
-                       "Section \"InputClass\"\n"
-                       "        Identifier \"system-keyboard\"\n"
-                       "        MatchIsKeyboard \"on\"\n", f);
+        fputs("# Written by systemd-localed(8), read by systemd-localed and Xorg. It's\n"
+              "# probably wise not to edit this file manually. Use localectl(1) to\n"
+              "# instruct systemd-localed to update it.\n"
+              "Section \"InputClass\"\n"
+              "        Identifier \"system-keyboard\"\n"
+              "        MatchIsKeyboard \"on\"\n", f);
 
         if (!isempty(c->x11_layout))
                 fprintf(f, "        Option \"XkbLayout\" \"%s\"\n", c->x11_layout);
@@ -380,7 +381,7 @@ int x11_write_data(Context *c) {
         if (!isempty(c->x11_options))
                 fprintf(f, "        Option \"XkbOptions\" \"%s\"\n", c->x11_options);
 
-        fputs_unlocked("EndSection\n", f);
+        fputs("EndSection\n", f);
 
         r = fflush_sync_and_check(f);
         if (r < 0)
index 20ef2a4..371bbf2 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 0bd18a5..f09fe42 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -46,18 +47,6 @@ static BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
 static char *arg_host = NULL;
 static bool arg_convert = true;
 
-static void polkit_agent_open_if_enabled(void) {
-
-        /* Open the polkit agent as a child process if necessary */
-        if (!arg_ask_password)
-                return;
-
-        if (arg_transport != BUS_TRANSPORT_LOCAL)
-                return;
-
-        polkit_agent_open();
-}
-
 typedef struct StatusInfo {
         char **locale;
         char *vconsole_keymap;
@@ -195,7 +184,7 @@ static int set_locale(sd_bus *bus, char **args, unsigned n) {
         assert(bus);
         assert(args);
 
-        polkit_agent_open_if_enabled();
+        polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
 
         r = sd_bus_message_new_method_call(
                         bus,
@@ -253,7 +242,7 @@ static int set_vconsole_keymap(sd_bus *bus, char **args, unsigned n) {
                 return -EINVAL;
         }
 
-        polkit_agent_open_if_enabled();
+        polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
 
         map = args[1];
         toggle_map = n > 2 ? args[2] : "";
@@ -273,68 +262,15 @@ static int set_vconsole_keymap(sd_bus *bus, char **args, unsigned n) {
         return r;
 }
 
-static Set *keymaps = NULL;
-
-static int nftw_cb(
-                const char *fpath,
-                const struct stat *sb,
-                int tflag,
-                struct FTW *ftwbuf) {
-
-        char *p, *e;
-        int r;
-
-        if (tflag != FTW_F)
-                return 0;
-
-        if (!endswith(fpath, ".map") &&
-            !endswith(fpath, ".map.gz"))
-                return 0;
-
-        p = strdup(basename(fpath));
-        if (!p)
-                return log_oom();
-
-        e = endswith(p, ".map");
-        if (e)
-                *e = 0;
-
-        e = endswith(p, ".map.gz");
-        if (e)
-                *e = 0;
-
-        r = set_consume(keymaps, p);
-        if (r < 0 && r != -EEXIST)
-                return log_error_errno(r, "Can't add keymap: %m");
-
-        return 0;
-}
-
 static int list_vconsole_keymaps(sd_bus *bus, char **args, unsigned n) {
         _cleanup_strv_free_ char **l = NULL;
-        const char *dir;
-
-        keymaps = set_new(&string_hash_ops);
-        if (!keymaps)
-                return log_oom();
-
-        NULSTR_FOREACH(dir, KBD_KEYMAP_DIRS)
-                nftw(dir, nftw_cb, 20, FTW_MOUNT|FTW_PHYS);
-
-        l = set_get_strv(keymaps);
-        if (!l) {
-                set_free_free(keymaps);
-                return log_oom();
-        }
-
-        set_free(keymaps);
+        int r;
 
-        if (strv_isempty(l)) {
-                log_error("Couldn't find any console keymaps.");
-                return -ENOENT;
-        }
+        assert(args);
 
-        strv_sort(l);
+        r = get_keymaps(&l);
+        if (r < 0)
+                return log_error_errno(r, "Failed to read list of keymaps: %m");
 
         pager_open(arg_no_pager, false);
 
@@ -356,7 +292,7 @@ static int set_x11_keymap(sd_bus *bus, char **args, unsigned n) {
                 return -EINVAL;
         }
 
-        polkit_agent_open_if_enabled();
+        polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
 
         layout = args[1];
         model = n > 2 ? args[2] : "";
@@ -659,7 +595,7 @@ static int localectl_main(sd_bus *bus, int argc, char *argv[]) {
 }
 
 int main(int argc, char*argv[]) {
-        sd_bus *bus = NULL;
+        _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
         int r;
 
         setlocale(LC_ALL, "");
@@ -679,7 +615,6 @@ int main(int argc, char*argv[]) {
         r = localectl_main(bus, argc, argv);
 
 finish:
-        sd_bus_flush_close_unref(bus);
         pager_close();
 
         return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
index 3c0c167..3e3f03e 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -380,7 +381,7 @@ static int method_set_vc_keyboard(sd_bus_message *m, void *userdata, sd_bus_erro
 
                 if ((keymap && (!filename_is_valid(keymap) || !string_is_safe(keymap))) ||
                     (keymap_toggle && (!filename_is_valid(keymap_toggle) || !string_is_safe(keymap_toggle))))
-                        return sd_bus_error_set_errnof(error, -EINVAL, "Received invalid keymap data");
+                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Received invalid keymap data");
 
                 r = bus_verify_polkit_async(
                                 m,
@@ -559,7 +560,7 @@ static int method_set_x11_keyboard(sd_bus_message *m, void *userdata, sd_bus_err
                     (model && !string_is_safe(model)) ||
                     (variant && !string_is_safe(variant)) ||
                     (options && !string_is_safe(options)))
-                        return sd_bus_error_set_errnof(error, -EINVAL, "Received invalid keyboard data");
+                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Received invalid keyboard data");
 
                 r = bus_verify_polkit_async(
                                 m,
index e9de608..dca2c51 100644 (file)
@@ -1,3 +1,20 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
+# Copyright 2017 Zbigniew Jędrzejewski-Szmek
+#
+# 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.
+#
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
 systemd_localed_sources = files('''
         localed.c
         keymap-util.c
@@ -12,11 +29,12 @@ if conf.get('ENABLE_LOCALED') == 1
         install_data('org.freedesktop.locale1.service',
                      install_dir : dbussystemservicedir)
 
-        custom_target(
+        i18n.merge_file(
                 'org.freedesktop.locale1.policy',
                 input : 'org.freedesktop.locale1.policy.in',
                 output : 'org.freedesktop.locale1.policy',
-                command : intltool_command,
+                po_dir : po_dir,
+                data_dirs : po_dir,
                 install : install_polkit,
                 install_dir : polkitpolicydir)
 endif
index 2c5b2fa..b6cbfaa 100644 (file)
@@ -3,6 +3,8 @@
         "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   systemd is free software; you can redistribute it and/or modify it
index df63845..4c1c34d 100644 (file)
@@ -3,6 +3,8 @@
         "http://www.freedesktop.org/standards/PolicyKit/1/policyconfig.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   systemd is free software; you can redistribute it and/or modify it
@@ -17,8 +19,8 @@
         <vendor_url>http://www.freedesktop.org/wiki/Software/systemd</vendor_url>
 
         <action id="org.freedesktop.locale1.set-locale">
-                <_description>Set system locale</_description>
-                <_message>Authentication is required to set the system locale.</_message>
+                <description>Set system locale</description>
+                <message>Authentication is required to set the system locale.</message>
                 <defaults>
                         <allow_any>auth_admin_keep</allow_any>
                         <allow_inactive>auth_admin_keep</allow_inactive>
@@ -28,8 +30,8 @@
         </action>
 
         <action id="org.freedesktop.locale1.set-keyboard">
-                <_description>Set system keyboard settings</_description>
-                <_message>Authentication is required to set the system keyboard settings.</_message>
+                <description>Set system keyboard settings</description>
+                <message>Authentication is required to set the system keyboard settings.</message>
                 <defaults>
                         <allow_any>auth_admin_keep</allow_any>
                         <allow_inactive>auth_admin_keep</allow_inactive>
index 025f9a0..b15d395 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 2adda3d..fa26a02 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 141dae4..d15a361 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 50dcd2e..f2c838f 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
@@ -43,10 +45,7 @@ SUBSYSTEM=="firewire", ATTR{units}=="*0x00a02d:0x010001*", TAG+="uaccess"
 SUBSYSTEM=="firewire", ATTR{units}=="*0x00a02d:0x014001*", TAG+="uaccess"
 
 # DRI video devices
-SUBSYSTEM=="drm", KERNEL=="card*|renderD*", TAG+="uaccess"
-
-# KVM
-SUBSYSTEM=="misc", KERNEL=="kvm", TAG+="uaccess"
+SUBSYSTEM=="drm", KERNEL=="card*", TAG+="uaccess"
 
 # smart-card readers
 ENV{ID_SMARTCARD_READER}=="?*", TAG+="uaccess"
index de55c9a..0db46ad 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 901df75..d2546c8 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 7e5a093..7b9e3f0 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index a63174c..dfcaff6 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -37,6 +38,7 @@
 #include "pager.h"
 #include "parse-util.h"
 #include "process-util.h"
+#include "sigbus.h"
 #include "signal-util.h"
 #include "spawn-polkit-agent.h"
 #include "strv.h"
@@ -61,25 +63,11 @@ static bool arg_ask_password = true;
 static unsigned arg_lines = 10;
 static OutputMode arg_output = OUTPUT_SHORT;
 
-static void polkit_agent_open_if_enabled(void) {
-
-        /* Open the polkit agent as a child process if necessary */
-
-        if (!arg_ask_password)
-                return;
-
-        if (arg_transport != BUS_TRANSPORT_LOCAL)
-                return;
-
-        polkit_agent_open();
-}
-
 static OutputFlags get_output_flags(void) {
 
         return
                 arg_all * OUTPUT_SHOW_ALL |
-                arg_full * OUTPUT_FULL_WIDTH |
-                (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
+                (arg_full || !on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
                 colors_enabled() * OUTPUT_COLOR;
 }
 
@@ -727,7 +715,7 @@ static int print_seat_status_info(sd_bus *bus, const char *path, bool *new_line)
 
                 printf("\t Devices:\n");
 
-                show_sysfs(i.id, "\t\t  ", c);
+                show_sysfs(i.id, "\t\t  ", c, get_output_flags());
         }
 
         return 0;
@@ -739,7 +727,7 @@ static int print_seat_status_info(sd_bus *bus, const char *path, bool *new_line)
                         printf(fmt "\n", __VA_ARGS__);                  \
                 else                                                    \
                         printf("%s=" fmt "\n", name, __VA_ARGS__);      \
-        } while(0)
+        } while (0)
 
 static int print_property(const char *name, sd_bus_message *m, const char *contents) {
         int r;
@@ -1081,7 +1069,7 @@ static int activate(int argc, char *argv[], void *userdata) {
         assert(bus);
         assert(argv);
 
-        polkit_agent_open_if_enabled();
+        polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
 
         if (argc < 2) {
                 /* No argument? Let's either use $XDG_SESSION_ID (if specified), or an empty
@@ -1125,7 +1113,7 @@ static int kill_session(int argc, char *argv[], void *userdata) {
         assert(bus);
         assert(argv);
 
-        polkit_agent_open_if_enabled();
+        polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
 
         if (!arg_kill_who)
                 arg_kill_who = "all";
@@ -1159,16 +1147,16 @@ static int enable_linger(int argc, char *argv[], void *userdata) {
         assert(bus);
         assert(argv);
 
-        polkit_agent_open_if_enabled();
+        polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
 
         b = streq(argv[0], "enable-linger");
 
         if (argc < 2) {
-                /* No argument? Let's either use $XDG_SESSION_ID (if specified), or an empty
-                 * session name, in which case logind will try to guess our session. */
+                /* No argument? Let's use an empty user name,
+                 * then logind will use our user. */
 
                 short_argv[0] = argv[0];
-                short_argv[1] = getenv("XDG_SESSION_ID") ?: (char*) "";
+                short_argv[1] = (char*) "";
                 short_argv[2] = NULL;
                 argv = short_argv;
                 argc = 2;
@@ -1210,7 +1198,7 @@ static int terminate_user(int argc, char *argv[], void *userdata) {
         assert(bus);
         assert(argv);
 
-        polkit_agent_open_if_enabled();
+        polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
 
         for (i = 1; i < argc; i++) {
                 uid_t uid;
@@ -1244,7 +1232,7 @@ static int kill_user(int argc, char *argv[], void *userdata) {
         assert(bus);
         assert(argv);
 
-        polkit_agent_open_if_enabled();
+        polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
 
         if (!arg_kill_who)
                 arg_kill_who = "all";
@@ -1281,7 +1269,7 @@ static int attach(int argc, char *argv[], void *userdata) {
         assert(bus);
         assert(argv);
 
-        polkit_agent_open_if_enabled();
+        polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
 
         for (i = 2; i < argc; i++) {
 
@@ -1311,7 +1299,7 @@ static int flush_devices(int argc, char *argv[], void *userdata) {
         assert(bus);
         assert(argv);
 
-        polkit_agent_open_if_enabled();
+        polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
 
         r = sd_bus_call_method(
                         bus,
@@ -1335,7 +1323,7 @@ static int lock_sessions(int argc, char *argv[], void *userdata) {
         assert(bus);
         assert(argv);
 
-        polkit_agent_open_if_enabled();
+        polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
 
         r = sd_bus_call_method(
                         bus,
@@ -1359,7 +1347,7 @@ static int terminate_seat(int argc, char *argv[], void *userdata) {
         assert(bus);
         assert(argv);
 
-        polkit_agent_open_if_enabled();
+        polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
 
         for (i = 1; i < argc; i++) {
 
@@ -1596,12 +1584,13 @@ static int loginctl_main(int argc, char *argv[], sd_bus *bus) {
 }
 
 int main(int argc, char *argv[]) {
-        sd_bus *bus = NULL;
+        _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
         int r;
 
         setlocale(LC_ALL, "");
         log_parse_environment();
         log_open();
+        sigbus_install();
 
         r = parse_argv(argc, argv);
         if (r <= 0)
@@ -1618,8 +1607,6 @@ int main(int argc, char *argv[]) {
         r = loginctl_main(argc, argv, bus);
 
 finish:
-        sd_bus_flush_close_unref(bus);
-
         pager_close();
         polkit_agent_close();
 
index 1b69f4b..d785f67 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 606005a..36690da 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 91225a5..852ea9f 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index fb40ae4..8c31ec4 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index e53dd63..94945f0 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index f30cba2..b47eb47 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index ba53855..adeba74 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 2342375..ae36ece 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
 #include "user-util.h"
 #include "utmp-wtmp.h"
 
-int manager_get_session_from_creds(Manager *m, sd_bus_message *message, const char *name, sd_bus_error *error, Session **ret) {
+static int get_sender_session(Manager *m, sd_bus_message *message, sd_bus_error *error, Session **ret) {
+
         _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
+        const char *name;
         Session *session;
         int r;
 
+        /* Get client login session.  This is not what you are looking for these days,
+         * as apps may instead belong to a user service unit.  This includes terminal
+         * emulators and hence command-line apps. */
+        r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_SESSION|SD_BUS_CREDS_AUGMENT, &creds);
+        if (r < 0)
+                return r;
+
+        r = sd_bus_creds_get_session(creds, &name);
+        if (r == -ENXIO)
+                goto err_no_session;
+        if (r < 0)
+                return r;
+
+        session = hashmap_get(m->sessions, name);
+        if (!session)
+                goto err_no_session;
+
+        *ret = session;
+        return 0;
+
+err_no_session:
+        return sd_bus_error_setf(error, BUS_ERROR_NO_SESSION_FOR_PID,
+                                 "Caller does not belong to any known session");
+}
+
+int manager_get_session_from_creds(Manager *m, sd_bus_message *message, const char *name, sd_bus_error *error, Session **ret) {
+        Session *session;
+
         assert(m);
         assert(message);
         assert(ret);
 
-        if (isempty(name)) {
-                r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_SESSION|SD_BUS_CREDS_AUGMENT, &creds);
-                if (r < 0)
-                        return r;
-
-                r = sd_bus_creds_get_session(creds, &name);
-                if (r == -ENXIO)
-                        return sd_bus_error_setf(error, BUS_ERROR_NO_SESSION_FOR_PID,
-                                                 "Caller does not belong to any known session");
-                if (r < 0)
-                        return r;
-        }
+        if (isempty(name))
+                return get_sender_session(m, message, error, ret);
 
         session = hashmap_get(m->sessions, name);
         if (!session)
@@ -80,30 +101,48 @@ int manager_get_session_from_creds(Manager *m, sd_bus_message *message, const ch
         return 0;
 }
 
-int manager_get_user_from_creds(Manager *m, sd_bus_message *message, uid_t uid, sd_bus_error *error, User **ret) {
+static int get_sender_user(Manager *m, sd_bus_message *message, sd_bus_error *error, User **ret) {
+
+        _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
+        uid_t uid;
         User *user;
         int r;
 
+        /* Note that we get the owner UID of the session, not the actual client UID here! */
+        r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_OWNER_UID|SD_BUS_CREDS_AUGMENT, &creds);
+        if (r < 0)
+                return r;
+
+        r = sd_bus_creds_get_owner_uid(creds, &uid);
+        if (r == -ENXIO)
+                goto err_no_user;
+        if (r < 0)
+                return r;
+
+        user = hashmap_get(m->users, UID_TO_PTR(uid));
+        if (!user)
+                goto err_no_user;
+
+        *ret = user;
+        return 0;
+
+err_no_user:
+        return sd_bus_error_setf(error, BUS_ERROR_NO_USER_FOR_PID, "Caller does not belong to any logged in user or lingering user");
+}
+
+int manager_get_user_from_creds(Manager *m, sd_bus_message *message, uid_t uid, sd_bus_error *error, User **ret) {
+        User *user;
+
         assert(m);
         assert(message);
         assert(ret);
 
-        if (!uid_is_valid(uid)) {
-                _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
-
-                /* Note that we get the owner UID of the session, not the actual client UID here! */
-                r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_OWNER_UID|SD_BUS_CREDS_AUGMENT, &creds);
-                if (r < 0)
-                        return r;
-
-                r = sd_bus_creds_get_owner_uid(creds, &uid);
-                if (r < 0)
-                        return r;
-        }
+        if (!uid_is_valid(uid))
+                return get_sender_user(m, message, error, ret);
 
         user = hashmap_get(m->users, UID_TO_PTR(uid));
         if (!user)
-                return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER, "No user "UID_FMT" known or logged in", uid);
+                return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER, "User ID "UID_FMT" is not logged in or lingering", uid);
 
         *ret = user;
         return 0;
@@ -329,6 +368,9 @@ static int method_get_session(sd_bus_message *message, void *userdata, sd_bus_er
         return sd_bus_reply_method_return(message, "o", p);
 }
 
+/* Get login session of a process.  This is not what you are looking for these days,
+ * as apps may instead belong to a user service unit.  This includes terminal
+ * emulators and hence command-line apps. */
 static int method_get_session_by_pid(sd_bus_message *message, void *userdata, sd_bus_error *error) {
         _cleanup_free_ char *p = NULL;
         Session *session = NULL;
@@ -419,7 +461,9 @@ static int method_get_user_by_pid(sd_bus_message *message, void *userdata, sd_bu
                 if (r < 0)
                         return r;
                 if (!user)
-                        return sd_bus_error_setf(error, BUS_ERROR_NO_USER_FOR_PID, "PID "PID_FMT" does not belong to any known or logged in user", pid);
+                        return sd_bus_error_setf(error, BUS_ERROR_NO_USER_FOR_PID,
+                                                 "PID "PID_FMT" does not belong to any logged in user or lingering user",
+                                                 pid);
         }
 
         p = user_bus_path(user);
@@ -1117,13 +1161,13 @@ static int method_terminate_seat(sd_bus_message *message, void *userdata, sd_bus
 }
 
 static int method_set_user_linger(sd_bus_message *message, void *userdata, sd_bus_error *error) {
+        _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
         _cleanup_free_ char *cc = NULL;
         Manager *m = userdata;
         int r, b, interactive;
         struct passwd *pw;
         const char *path;
-        uint32_t uid;
-        bool self = false;
+        uint32_t uid, auth_uid;
 
         assert(message);
         assert(m);
@@ -1132,22 +1176,23 @@ static int method_set_user_linger(sd_bus_message *message, void *userdata, sd_bu
         if (r < 0)
                 return r;
 
-        if (!uid_is_valid(uid)) {
-                _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
-
-                /* Note that we get the owner UID of the session, not the actual client UID here! */
-                r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_OWNER_UID|SD_BUS_CREDS_AUGMENT, &creds);
-                if (r < 0)
-                        return r;
+        r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID |
+                                               SD_BUS_CREDS_OWNER_UID|SD_BUS_CREDS_AUGMENT, &creds);
+        if (r < 0)
+                return r;
 
+        if (!uid_is_valid(uid)) {
+                /* Note that we get the owner UID of the session or user unit,
+                 * not the actual client UID here! */
                 r = sd_bus_creds_get_owner_uid(creds, &uid);
                 if (r < 0)
                         return r;
+        }
 
-                self = true;
-
-        } else if (!uid_is_valid(uid))
-                return -EINVAL;
+        /* owner_uid is racy, so for authorization we must use euid */
+        r = sd_bus_creds_get_euid(creds, &auth_uid);
+        if (r < 0)
+                return r;
 
         errno = 0;
         pw = getpwuid(uid);
@@ -1157,7 +1202,8 @@ static int method_set_user_linger(sd_bus_message *message, void *userdata, sd_bu
         r = bus_verify_polkit_async(
                         message,
                         CAP_SYS_ADMIN,
-                        self ? "org.freedesktop.login1.set-self-linger" : "org.freedesktop.login1.set-user-linger",
+                        uid == auth_uid ? "org.freedesktop.login1.set-self-linger" :
+                                          "org.freedesktop.login1.set-user-linger",
                         NULL,
                         interactive,
                         UID_INVALID,
@@ -1170,7 +1216,7 @@ static int method_set_user_linger(sd_bus_message *message, void *userdata, sd_bu
 
         mkdir_p_label("/var/lib/systemd", 0755);
 
-        r = mkdir_safe_label("/var/lib/systemd/linger", 0755, 0, 0);
+        r = mkdir_safe_label("/var/lib/systemd/linger", 0755, 0, 0, false);
         if (r < 0)
                 return r;
 
@@ -1236,7 +1282,7 @@ static int trigger_device(Manager *m, struct udev_device *d) {
                 if (!t)
                         return -ENOMEM;
 
-                write_string_file(t, "change", WRITE_STRING_FILE_CREATE);
+                (void) write_string_file(t, "change", 0);
         }
 
         return 0;
@@ -1555,7 +1601,7 @@ static int execute_shutdown_or_sleep(
 
 error:
         /* Tell people that they now may take a lock again */
-        send_prepare_for(m, m->action_what, false);
+        (void) send_prepare_for(m, w, false);
 
         return r;
 }
@@ -1666,7 +1712,7 @@ int bus_manager_shutdown_or_sleep_now_or_later(
         assert(!m->action_job);
 
         /* Tell everybody to prepare for shutdown/sleep */
-        send_prepare_for(m, w, true);
+        (void) send_prepare_for(m, w, true);
 
         delayed =
                 m->inhibit_delay_max > 0 &&
@@ -1904,7 +1950,7 @@ static int update_schedule_file(Manager *m) {
 
         assert(m);
 
-        r = mkdir_safe_label("/run/systemd/shutdown", 0755, 0, 0);
+        r = mkdir_safe_label("/run/systemd/shutdown", 0755, 0, 0, false);
         if (r < 0)
                 return log_error_errno(r, "Failed to create shutdown subdirectory: %m");
 
@@ -2351,7 +2397,7 @@ static int property_get_reboot_to_firmware_setup(
 
         r = efi_get_reboot_to_firmware();
         if (r < 0 && r != -EOPNOTSUPP)
-                return r;
+                log_warning_errno(r, "Failed to determine reboot-to-firmware state: %m");
 
         return sd_bus_message_append(reply, "b", r > 0);
 }
@@ -2405,10 +2451,12 @@ static int method_can_reboot_to_firmware_setup(
         assert(m);
 
         r = efi_reboot_to_firmware_supported();
-        if (r == -EOPNOTSUPP)
+        if (r < 0) {
+                if (r != -EOPNOTSUPP)
+                        log_warning_errno(errno, "Failed to determine whether reboot to firmware is supported: %m");
+
                 return sd_bus_reply_method_return(message, "s", "na");
-        else if (r < 0)
-                return r;
+        }
 
         r = bus_test_polkit(message,
                             CAP_SYS_ADMIN,
@@ -2719,7 +2767,7 @@ int match_job_removed(sd_bus_message *message, void *userdata, sd_bus_error *err
                 log_info("Operation '%s' finished.", inhibit_what_to_string(m->action_what));
 
                 /* Tell people that they now may take a lock again */
-                send_prepare_for(m, m->action_what, false);
+                (void) send_prepare_for(m, m->action_what, false);
 
                 m->action_job = mfree(m->action_job);
                 m->action_unit = NULL;
index 6537fa0..758ba73 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 927068e..d091156 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index aca4644..ee62db6 100644 (file)
@@ -1,4 +1,7 @@
 %{
+#if __GNUC__ >= 7
+_Pragma("GCC diagnostic ignored \"-Wimplicit-fallthrough\"")
+#endif
 #include <stddef.h>
 #include "conf-parser.h"
 #include "logind.h"
index 1e6f383..8a6487e 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -86,7 +87,7 @@ int inhibitor_save(Inhibitor *i) {
 
         assert(i);
 
-        r = mkdir_safe_label("/run/systemd/inhibit", 0755, 0, 0);
+        r = mkdir_safe_label("/run/systemd/inhibit", 0755, 0, 0, false);
         if (r < 0)
                 goto fail;
 
@@ -290,7 +291,7 @@ int inhibitor_create_fifo(Inhibitor *i) {
 
         /* Create FIFO */
         if (!i->fifo_path) {
-                r = mkdir_safe_label("/run/systemd/inhibit", 0755, 0, 0);
+                r = mkdir_safe_label("/run/systemd/inhibit", 0755, 0, 0, false);
                 if (r < 0)
                         return r;
 
@@ -357,6 +358,8 @@ static int pid_is_active(Manager *m, pid_t pid) {
         Session *s;
         int r;
 
+        /* Get client session.  This is not what you are looking for these days.
+         * FIXME #6852 */
         r = manager_get_session_by_pid(m, pid, &s);
         if (r < 0)
                 return r;
index 70de199..cc6c62a 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index f934a53..8e4e4ef 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -332,28 +333,15 @@ int seat_object_find(sd_bus *bus, const char *path, const char *interface, void
         assert(m);
 
         if (streq(path, "/org/freedesktop/login1/seat/self")) {
-                _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
                 sd_bus_message *message;
-                Session *session;
-                const char *name;
 
                 message = sd_bus_get_current_message(bus);
                 if (!message)
                         return 0;
 
-                r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_SESSION|SD_BUS_CREDS_AUGMENT, &creds);
-                if (r < 0)
-                        return r;
-
-                r = sd_bus_creds_get_session(creds, &name);
+                r = manager_get_seat_from_creds(m, message, NULL, error, &seat);
                 if (r < 0)
                         return r;
-
-                session = hashmap_get(m->sessions, name);
-                if (!session)
-                        return 0;
-
-                seat = session->seat;
         } else {
                 _cleanup_free_ char *e = NULL;
                 const char *p;
@@ -367,11 +355,10 @@ int seat_object_find(sd_bus *bus, const char *path, const char *interface, void
                         return -ENOMEM;
 
                 seat = hashmap_get(m->seats, e);
+                if (!seat)
+                        return 0;
         }
 
-        if (!seat)
-                return 0;
-
         *found = seat;
         return 1;
 }
index 64a6223..b99e7ab 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -19,6 +20,7 @@
 
 #include <errno.h>
 #include <fcntl.h>
+#include <stdio_ext.h>
 #include <string.h>
 #include <unistd.h>
 
@@ -93,7 +95,7 @@ int seat_save(Seat *s) {
         if (!s->started)
                 return 0;
 
-        r = mkdir_safe_label("/run/systemd/seats", 0755, 0, 0);
+        r = mkdir_safe_label("/run/systemd/seats", 0755, 0, 0, false);
         if (r < 0)
                 goto fail;
 
@@ -101,7 +103,8 @@ int seat_save(Seat *s) {
         if (r < 0)
                 goto fail;
 
-        fchmod(fileno(f), 0644);
+        (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
+        (void) fchmod(fileno(f), 0644);
 
         fprintf(f,
                 "# This is private data. Do not parse.\n"
@@ -127,7 +130,7 @@ int seat_save(Seat *s) {
         if (s->sessions) {
                 Session *i;
 
-                fputs_unlocked("SESSIONS=", f);
+                fputs("SESSIONS=", f);
                 LIST_FOREACH(sessions_by_seat, i, s->sessions) {
                         fprintf(f,
                                 "%s%c",
@@ -135,7 +138,7 @@ int seat_save(Seat *s) {
                                 i->sessions_by_seat_next ? ' ' : '\n');
                 }
 
-                fputs_unlocked("UIDS=", f);
+                fputs("UIDS=", f);
                 LIST_FOREACH(sessions_by_seat, i, s->sessions)
                         fprintf(f,
                                 UID_FMT"%c",
index 9a4fbc5..5427ac2 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 649f3c1..8264a42 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -580,23 +581,15 @@ int session_object_find(sd_bus *bus, const char *path, const char *interface, vo
         assert(m);
 
         if (streq(path, "/org/freedesktop/login1/session/self")) {
-                _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
                 sd_bus_message *message;
-                const char *name;
 
                 message = sd_bus_get_current_message(bus);
                 if (!message)
                         return 0;
 
-                r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_SESSION|SD_BUS_CREDS_AUGMENT, &creds);
-                if (r < 0)
-                        return r;
-
-                r = sd_bus_creds_get_session(creds, &name);
+                r = manager_get_session_from_creds(m, message, NULL, error, &session);
                 if (r < 0)
                         return r;
-
-                session = hashmap_get(m->sessions, name);
         } else {
                 _cleanup_free_ char *e = NULL;
                 const char *p;
@@ -610,11 +603,10 @@ int session_object_find(sd_bus *bus, const char *path, const char *interface, vo
                         return -ENOMEM;
 
                 session = hashmap_get(m->sessions, e);
+                if (!session)
+                        return 0;
         }
 
-        if (!session)
-                return 0;
-
         *found = session;
         return 1;
 }
index 05af204..067e67a 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -409,6 +410,17 @@ error:
 void session_device_free(SessionDevice *sd) {
         assert(sd);
 
+        if (sd->pushed_fd) {
+                const char *m;
+
+                /* Remove the pushed fd again, just in case. */
+
+                m = strjoina("FDSTOREREMOVE=1\n"
+                             "FDNAME=session-", sd->session->id);
+
+                (void) sd_notify(false, m);
+        }
+
         session_device_stop(sd);
         session_device_notify(sd, SESSION_DEVICE_RELEASE);
         close_nointr(sd->fd);
@@ -488,26 +500,30 @@ unsigned int session_device_try_pause_all(Session *s) {
 }
 
 int session_device_save(SessionDevice *sd) {
-        _cleanup_free_ char *state = NULL;
+        const char *m;
         int r;
 
         assert(sd);
 
-        /* Store device fd in PID1. It will send it back to us on
-         * restart so revocation will continue to work. To make things
-         * simple, send fds for all type of devices even if they don't
-         * support the revocation mechanism so we don't have to handle
-         * them differently later.
+        /* Store device fd in PID1. It will send it back to us on restart so revocation will continue to work. To make
+         * things simple, send fds for all type of devices even if they don't support the revocation mechanism so we
+         * don't have to handle them differently later.
          *
-         * Note: for device supporting revocation, PID1 will drop a
-         * stored fd automatically if the corresponding device is
-         * revoked. */
-        r = asprintf(&state, "FDSTORE=1\n"
-                             "FDNAME=session-%s", sd->session->id);
+         * Note: for device supporting revocation, PID1 will drop a stored fd automatically if the corresponding device
+         * is revoked. */
+
+        if (sd->pushed_fd)
+                return 0;
+
+        m = strjoina("FDSTORE=1\n"
+                     "FDNAME=session", sd->session->id);
+
+        r = sd_pid_notify_with_fds(0, false, m, &sd->fd, 1);
         if (r < 0)
-                return -ENOMEM;
+                return r;
 
-        return sd_pid_notify_with_fds(0, false, state, &sd->fd, 1);
+        sd->pushed_fd = true;
+        return 1;
 }
 
 void session_device_attach_fd(SessionDevice *sd, int fd, bool active) {
index 83aef1e..a1cf17a 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -40,6 +41,7 @@ struct SessionDevice {
         int fd;
         bool active;
         DeviceType type;
+        bool pushed_fd;
 
         LIST_FIELDS(struct SessionDevice, sd_by_device);
 };
index 736f7d9..c4bde80 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -179,7 +180,7 @@ int session_save(Session *s) {
         if (!s->started)
                 return 0;
 
-        r = mkdir_safe_label("/run/systemd/sessions", 0755, 0, 0);
+        r = mkdir_safe_label("/run/systemd/sessions", 0755, 0, 0, false);
         if (r < 0)
                 goto fail;
 
@@ -948,7 +949,7 @@ int session_create_fifo(Session *s) {
 
         /* Create FIFO */
         if (!s->fifo_path) {
-                r = mkdir_safe_label("/run/systemd/sessions", 0755, 0, 0);
+                r = mkdir_safe_label("/run/systemd/sessions", 0755, 0, 0, false);
                 if (r < 0)
                         return r;
 
@@ -1136,7 +1137,6 @@ void session_restore_vt(Session *s) {
                 .mode = VT_AUTO,
         };
 
-        _cleanup_free_ char *utf8 = NULL;
         int vt, old_fd;
 
         /* We need to get a fresh handle to the virtual terminal,
index 12b9d86..8491832 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 987c630..9fca5ce 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -270,18 +271,15 @@ int user_object_find(sd_bus *bus, const char *path, const char *interface, void
         assert(m);
 
         if (streq(path, "/org/freedesktop/login1/user/self")) {
-                _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
                 sd_bus_message *message;
 
                 message = sd_bus_get_current_message(bus);
                 if (!message)
                         return 0;
 
-                r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_OWNER_UID|SD_BUS_CREDS_AUGMENT, &creds);
+                r = manager_get_user_from_creds(m, message, UID_INVALID, error, &user);
                 if (r < 0)
                         return r;
-
-                r = sd_bus_creds_get_owner_uid(creds, &uid);
         } else {
                 const char *p;
 
index ddadd61..f5e4799 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -21,6 +22,7 @@
 #include <string.h>
 #include <sys/mount.h>
 #include <unistd.h>
+#include <stdio_ext.h>
 #include <sys/xattr.h>
 
 #include "alloc-util.h"
@@ -142,7 +144,7 @@ static int user_save_internal(User *u) {
         assert(u);
         assert(u->state_file);
 
-        r = mkdir_safe_label("/run/systemd/users", 0755, 0, 0);
+        r = mkdir_safe_label("/run/systemd/users", 0755, 0, 0, false);
         if (r < 0)
                 goto fail;
 
@@ -150,7 +152,8 @@ static int user_save_internal(User *u) {
         if (r < 0)
                 goto fail;
 
-        fchmod(fileno(f), 0644);
+        (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
+        (void) fchmod(fileno(f), 0644);
 
         fprintf(f,
                 "# This is private data. Do not parse.\n"
@@ -183,18 +186,18 @@ static int user_save_internal(User *u) {
                 Session *i;
                 bool first;
 
-                fputs_unlocked("SESSIONS=", f);
+                fputs("SESSIONS=", f);
                 first = true;
                 LIST_FOREACH(sessions_by_user, i, u->sessions) {
                         if (first)
                                 first = false;
                         else
-                                fputc_unlocked(' ', f);
+                                fputc(' ', f);
 
-                        fputs_unlocked(i->id, f);
+                        fputs(i->id, f);
                 }
 
-                fputs_unlocked("\nSEATS=", f);
+                fputs("\nSEATS=", f);
                 first = true;
                 LIST_FOREACH(sessions_by_user, i, u->sessions) {
                         if (!i->seat)
@@ -203,12 +206,12 @@ static int user_save_internal(User *u) {
                         if (first)
                                 first = false;
                         else
-                                fputc_unlocked(' ', f);
+                                fputc(' ', f);
 
-                        fputs_unlocked(i->seat->id, f);
+                        fputs(i->seat->id, f);
                 }
 
-                fputs_unlocked("\nACTIVE_SESSIONS=", f);
+                fputs("\nACTIVE_SESSIONS=", f);
                 first = true;
                 LIST_FOREACH(sessions_by_user, i, u->sessions) {
                         if (!session_is_active(i))
@@ -217,12 +220,12 @@ static int user_save_internal(User *u) {
                         if (first)
                                 first = false;
                         else
-                                fputc_unlocked(' ', f);
+                                fputc(' ', f);
 
-                        fputs_unlocked(i->id, f);
+                        fputs(i->id, f);
                 }
 
-                fputs_unlocked("\nONLINE_SESSIONS=", f);
+                fputs("\nONLINE_SESSIONS=", f);
                 first = true;
                 LIST_FOREACH(sessions_by_user, i, u->sessions) {
                         if (session_get_state(i) == SESSION_CLOSING)
@@ -231,12 +234,12 @@ static int user_save_internal(User *u) {
                         if (first)
                                 first = false;
                         else
-                                fputc_unlocked(' ', f);
+                                fputc(' ', f);
 
-                        fputs_unlocked(i->id, f);
+                        fputs(i->id, f);
                 }
 
-                fputs_unlocked("\nACTIVE_SEATS=", f);
+                fputs("\nACTIVE_SEATS=", f);
                 first = true;
                 LIST_FOREACH(sessions_by_user, i, u->sessions) {
                         if (!session_is_active(i) || !i->seat)
@@ -245,12 +248,12 @@ static int user_save_internal(User *u) {
                         if (first)
                                 first = false;
                         else
-                                fputc_unlocked(' ', f);
+                                fputc(' ', f);
 
-                        fputs_unlocked(i->seat->id, f);
+                        fputs(i->seat->id, f);
                 }
 
-                fputs_unlocked("\nONLINE_SEATS=", f);
+                fputs("\nONLINE_SEATS=", f);
                 first = true;
                 LIST_FOREACH(sessions_by_user, i, u->sessions) {
                         if (session_get_state(i) == SESSION_CLOSING || !i->seat)
@@ -259,11 +262,11 @@ static int user_save_internal(User *u) {
                         if (first)
                                 first = false;
                         else
-                                fputc_unlocked(' ', f);
+                                fputc(' ', f);
 
-                        fputs_unlocked(i->seat->id, f);
+                        fputs(i->seat->id, f);
                 }
-                fputc_unlocked('\n', f);
+                fputc('\n', f);
         }
 
         r = fflush_and_check(f);
@@ -349,7 +352,7 @@ static int user_mkdir_system_share_path(User *u) {
         if (r < 0)
                 return log_oom();
 
-        r = mkdir_safe_label(t, 0750, u->uid, system_share_gid);
+        r = mkdir_safe_label(t, 0750, u->uid, system_share_gid, false);
         if (r < 0)
                 return log_error_errno(r, "Failed to create '%s': %m", t);
 
@@ -367,7 +370,7 @@ static int user_mkdir_runtime_path(User *u) {
 
         assert(u);
 
-        r = mkdir_safe_label("/run/user", 0755, 0, 0);
+        r = mkdir_safe_label("/run/user", 0755, 0, 0, false);
         if (r < 0)
                 return log_error_errno(r, "Failed to create /run/user: %m");
 
@@ -462,12 +465,11 @@ static int user_start_service(User *u) {
                         u->service,
                         &error,
                         &job);
-        if (r < 0) {
+        if (r < 0)
                 /* we don't fail due to this, let's try to continue */
                 log_error_errno(r, "Failed to start user service, ignoring: %s", bus_error_message(&error, r));
-        } else {
+        else
                 u->service_job = job;
-        }
 
         return 0;
 }
@@ -578,7 +580,7 @@ static int user_remove_runtime_path(User *u) {
 
         r = rm_rf(u->runtime_path, 0);
         if (r < 0)
-                log_error_errno(r, "Failed to remove runtime directory %s: %m", u->runtime_path);
+                log_error_errno(r, "Failed to remove runtime directory %s (before unmounting): %m", u->runtime_path);
 
         /* Ignore cases where the directory isn't mounted, as that's
          * quite possible, if we lacked the permissions to mount
@@ -589,7 +591,7 @@ static int user_remove_runtime_path(User *u) {
 
         r = rm_rf(u->runtime_path, REMOVE_ROOT);
         if (r < 0)
-                log_error_errno(r, "Failed to remove runtime directory %s: %m", u->runtime_path);
+                log_error_errno(r, "Failed to remove runtime directory %s (after unmounting): %m", u->runtime_path);
 
         return r;
 }
@@ -654,7 +656,7 @@ int user_finalize(User *u) {
          * cases, as we shouldn't accidentally remove a system service's IPC objects while it is running, just because
          * a cronjob running as the same user just finished. Hence: exclude system users generally from IPC clean-up,
          * and do it only for normal users. */
-        if (u->manager->remove_ipc && u->uid > SYSTEM_UID_MAX) {
+        if (u->manager->remove_ipc && !uid_is_system(u->uid)) {
                 k = clean_ipc_by_uid(u->uid);
                 if (k < 0)
                         r = k;
index 4f0966d..ad1686f 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 00c4cbc..ab35d0e 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 6046596..49ca367 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -1072,7 +1073,7 @@ static int manager_parse_config_file(Manager *m) {
                                         CONF_PATHS_NULSTR("systemd/logind.conf.d"),
                                         "Login\0",
                                         config_item_perf_lookup, logind_gperf_lookup,
-                                        false, m);
+                                        CONFIG_PARSE_WARN, m);
 }
 
 static int manager_dispatch_reload_signal(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
index 2a8c663..8262367 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index d0723f1..33f9ed4 100644 (file)
@@ -1,3 +1,20 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
+# Copyright 2017 Zbigniew Jędrzejewski-Szmek
+#
+# 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.
+#
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
 systemd_logind_sources = files('''
         logind.c
         logind.h
@@ -71,11 +88,12 @@ if conf.get('ENABLE_LOGIND') == 1
         install_data('org.freedesktop.login1.service',
                      install_dir : dbussystemservicedir)
 
-        custom_target(
+        i18n.merge_file(
                 'org.freedesktop.login1.policy',
                 input : 'org.freedesktop.login1.policy.in',
                 output : 'org.freedesktop.login1.policy',
-                command : intltool_command,
+                po_dir : po_dir,
+                data_dirs : po_dir,
                 install : install_polkit,
                 install_dir : polkitpolicydir)
 
index de5ae5a..f10b757 100644 (file)
@@ -3,6 +3,8 @@
         "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   systemd is free software; you can redistribute it and/or modify it
index 3e8a9bb..4716202 100644 (file)
@@ -3,6 +3,8 @@
         "http://www.freedesktop.org/standards/PolicyKit/1/policyconfig.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   systemd is free software; you can redistribute it and/or modify it
@@ -17,8 +19,8 @@
         <vendor_url>http://www.freedesktop.org/wiki/Software/systemd</vendor_url>
 
         <action id="org.freedesktop.login1.inhibit-block-shutdown">
-                <_description>Allow applications to inhibit system shutdown</_description>
-                <_message>Authentication is required for an application to inhibit system shutdown.</_message>
+                <description>Allow applications to inhibit system shutdown</description>
+                <message>Authentication is required for an application to inhibit system shutdown.</message>
                 <defaults>
                         <allow_any>no</allow_any>
                         <allow_inactive>yes</allow_inactive>
@@ -28,8 +30,8 @@
         </action>
 
         <action id="org.freedesktop.login1.inhibit-delay-shutdown">
-                <_description>Allow applications to delay system shutdown</_description>
-                <_message>Authentication is required for an application to delay system shutdown.</_message>
+                <description>Allow applications to delay system shutdown</description>
+                <message>Authentication is required for an application to delay system shutdown.</message>
                 <defaults>
                         <allow_any>yes</allow_any>
                         <allow_inactive>yes</allow_inactive>
@@ -39,8 +41,8 @@
         </action>
 
         <action id="org.freedesktop.login1.inhibit-block-sleep">
-                <_description>Allow applications to inhibit system sleep</_description>
-                <_message>Authentication is required for an application to inhibit system sleep.</_message>
+                <description>Allow applications to inhibit system sleep</description>
+                <message>Authentication is required for an application to inhibit system sleep.</message>
                 <defaults>
                         <allow_any>no</allow_any>
                         <allow_inactive>yes</allow_inactive>
@@ -50,8 +52,8 @@
         </action>
 
         <action id="org.freedesktop.login1.inhibit-delay-sleep">
-                <_description>Allow applications to delay system sleep</_description>
-                <_message>Authentication is required for an application to delay system sleep.</_message>
+                <description>Allow applications to delay system sleep</description>
+                <message>Authentication is required for an application to delay system sleep.</message>
                 <defaults>
                         <allow_any>yes</allow_any>
                         <allow_inactive>yes</allow_inactive>
@@ -60,8 +62,8 @@
         </action>
 
         <action id="org.freedesktop.login1.inhibit-block-idle">
-                <_description>Allow applications to inhibit automatic system suspend</_description>
-                <_message>Authentication is required for an application to inhibit automatic system suspend.</_message>
+                <description>Allow applications to inhibit automatic system suspend</description>
+                <message>Authentication is required for an application to inhibit automatic system suspend.</message>
                 <defaults>
                         <allow_any>yes</allow_any>
                         <allow_inactive>yes</allow_inactive>
@@ -70,8 +72,8 @@
         </action>
 
         <action id="org.freedesktop.login1.inhibit-handle-power-key">
-                <_description>Allow applications to inhibit system handling of the power key</_description>
-                <_message>Authentication is required for an application to inhibit system handling of the power key.</_message>
+                <description>Allow applications to inhibit system handling of the power key</description>
+                <message>Authentication is required for an application to inhibit system handling of the power key.</message>
                 <defaults>
                         <allow_any>no</allow_any>
                         <allow_inactive>yes</allow_inactive>
@@ -81,8 +83,8 @@
         </action>
 
         <action id="org.freedesktop.login1.inhibit-handle-suspend-key">
-                <_description>Allow applications to inhibit system handling of the suspend key</_description>
-                <_message>Authentication is required for an application to inhibit system handling of the suspend key.</_message>
+                <description>Allow applications to inhibit system handling of the suspend key</description>
+                <message>Authentication is required for an application to inhibit system handling of the suspend key.</message>
                 <defaults>
                         <allow_any>no</allow_any>
                         <allow_inactive>yes</allow_inactive>
@@ -92,8 +94,8 @@
         </action>
 
         <action id="org.freedesktop.login1.inhibit-handle-hibernate-key">
-                <_description>Allow applications to inhibit system handling of the hibernate key</_description>
-                <_message>Authentication is required for an application to inhibit system handling of the hibernate key.</_message>
+                <description>Allow applications to inhibit system handling of the hibernate key</description>
+                <message>Authentication is required for an application to inhibit system handling of the hibernate key.</message>
                 <defaults>
                         <allow_any>no</allow_any>
                         <allow_inactive>yes</allow_inactive>
         </action>
 
         <action id="org.freedesktop.login1.inhibit-handle-lid-switch">
-                <_description>Allow applications to inhibit system handling of the lid switch</_description>
-                <_message>Authentication is required for an application to inhibit system handling of the lid switch.</_message>
+                <description>Allow applications to inhibit system handling of the lid switch</description>
+                <message>Authentication is required for an application to inhibit system handling of the lid switch.</message>
                 <defaults>
                         <allow_any>no</allow_any>
                         <allow_inactive>yes</allow_inactive>
         </action>
 
         <action id="org.freedesktop.login1.set-self-linger">
-                <_description>Allow non-logged-in user to run programs</_description>
-                <_message>Explicit request is required to run programs as a non-logged-in user.</_message>
+                <description>Allow non-logged-in user to run programs</description>
+                <message>Explicit request is required to run programs as a non-logged-in user.</message>
                 <defaults>
                         <allow_any>yes</allow_any>
                         <allow_inactive>yes</allow_inactive>
         </action>
 
         <action id="org.freedesktop.login1.set-user-linger">
-                <_description>Allow non-logged-in users to run programs</_description>
-                <_message>Authentication is required to run programs as a non-logged-in user.</_message>
+                <description>Allow non-logged-in users to run programs</description>
+                <message>Authentication is required to run programs as a non-logged-in user.</message>
                 <defaults>
                         <allow_any>auth_admin_keep</allow_any>
                         <allow_inactive>auth_admin_keep</allow_inactive>
         </action>
 
         <action id="org.freedesktop.login1.attach-device">
-                <_description>Allow attaching devices to seats</_description>
-                <_message>Authentication is required for attaching a device to a seat.</_message>
+                <description>Allow attaching devices to seats</description>
+                <message>Authentication is required for attaching a device to a seat.</message>
                 <defaults>
                         <allow_any>auth_admin_keep</allow_any>
                         <allow_inactive>auth_admin_keep</allow_inactive>
         </action>
 
         <action id="org.freedesktop.login1.flush-devices">
-                <_description>Flush device to seat attachments</_description>
-                <_message>Authentication is required for resetting how devices are attached to seats.</_message>
+                <description>Flush device to seat attachments</description>
+                <message>Authentication is required for resetting how devices are attached to seats.</message>
                 <defaults>
                         <allow_any>auth_admin_keep</allow_any>
                         <allow_inactive>auth_admin_keep</allow_inactive>
         </action>
 
         <action id="org.freedesktop.login1.power-off">
-                <_description>Power off the system</_description>
-                <_message>Authentication is required for powering off the system.</_message>
+                <description>Power off the system</description>
+                <message>Authentication is required for powering off the system.</message>
                 <defaults>
                         <allow_any>auth_admin_keep</allow_any>
                         <allow_inactive>auth_admin_keep</allow_inactive>
         </action>
 
         <action id="org.freedesktop.login1.power-off-multiple-sessions">
-                <_description>Power off the system while other users are logged in</_description>
-                <_message>Authentication is required for powering off the system while other users are logged in.</_message>
+                <description>Power off the system while other users are logged in</description>
+                <message>Authentication is required for powering off the system while other users are logged in.</message>
                 <defaults>
                         <allow_any>auth_admin_keep</allow_any>
                         <allow_inactive>auth_admin_keep</allow_inactive>
         </action>
 
         <action id="org.freedesktop.login1.power-off-ignore-inhibit">
-                <_description>Power off the system while an application asked to inhibit it</_description>
-                <_message>Authentication is required for powering off the system while an application asked to inhibit it.</_message>
+                <description>Power off the system while an application asked to inhibit it</description>
+                <message>Authentication is required for powering off the system while an application asked to inhibit it.</message>
                 <defaults>
                         <allow_any>auth_admin_keep</allow_any>
                         <allow_inactive>auth_admin_keep</allow_inactive>
         </action>
 
         <action id="org.freedesktop.login1.reboot">
-                <_description>Reboot the system</_description>
-                <_message>Authentication is required for rebooting the system.</_message>
+                <description>Reboot the system</description>
+                <message>Authentication is required for rebooting the system.</message>
                 <defaults>
                         <allow_any>auth_admin_keep</allow_any>
                         <allow_inactive>auth_admin_keep</allow_inactive>
         </action>
 
         <action id="org.freedesktop.login1.reboot-multiple-sessions">
-                <_description>Reboot the system while other users are logged in</_description>
-                <_message>Authentication is required for rebooting the system while other users are logged in.</_message>
+                <description>Reboot the system while other users are logged in</description>
+                <message>Authentication is required for rebooting the system while other users are logged in.</message>
                 <defaults>
                         <allow_any>auth_admin_keep</allow_any>
                         <allow_inactive>auth_admin_keep</allow_inactive>
         </action>
 
         <action id="org.freedesktop.login1.reboot-ignore-inhibit">
-                <_description>Reboot the system while an application asked to inhibit it</_description>
-                <_message>Authentication is required for rebooting the system while an application asked to inhibit it.</_message>
+                <description>Reboot the system while an application asked to inhibit it</description>
+                <message>Authentication is required for rebooting the system while an application asked to inhibit it.</message>
                 <defaults>
                         <allow_any>auth_admin_keep</allow_any>
                         <allow_inactive>auth_admin_keep</allow_inactive>
         </action>
 
         <action id="org.freedesktop.login1.halt">
-                <_description>Halt the system</_description>
-                <_message>Authentication is required for halting the system.</_message>
+                <description>Halt the system</description>
+                <message>Authentication is required for halting the system.</message>
                 <defaults>
                         <allow_any>auth_admin_keep</allow_any>
                         <allow_inactive>auth_admin_keep</allow_inactive>
         </action>
 
         <action id="org.freedesktop.login1.halt-multiple-sessions">
-                <_description>Halt the system while other users are logged in</_description>
-                <_message>Authentication is required for halting the system while other users are logged in.</_message>
+                <description>Halt the system while other users are logged in</description>
+                <message>Authentication is required for halting the system while other users are logged in.</message>
                 <defaults>
                         <allow_any>auth_admin_keep</allow_any>
                         <allow_inactive>auth_admin_keep</allow_inactive>
         </action>
 
         <action id="org.freedesktop.login1.halt-ignore-inhibit">
-                <_description>Halt the system while an application asked to inhibit it</_description>
-                <_message>Authentication is required for halting the system while an application asked to inhibit it.</_message>
+                <description>Halt the system while an application asked to inhibit it</description>
+                <message>Authentication is required for halting the system while an application asked to inhibit it.</message>
                 <defaults>
                         <allow_any>auth_admin_keep</allow_any>
                         <allow_inactive>auth_admin_keep</allow_inactive>
         </action>
 
         <action id="org.freedesktop.login1.suspend">
-                <_description>Suspend the system</_description>
-                <_message>Authentication is required for suspending the system.</_message>
+                <description>Suspend the system</description>
+                <message>Authentication is required for suspending the system.</message>
                 <defaults>
                         <allow_any>auth_admin_keep</allow_any>
                         <allow_inactive>auth_admin_keep</allow_inactive>
         </action>
 
         <action id="org.freedesktop.login1.suspend-multiple-sessions">
-                <_description>Suspend the system while other users are logged in</_description>
-                <_message>Authentication is required for suspending the system while other users are logged in.</_message>
+                <description>Suspend the system while other users are logged in</description>
+                <message>Authentication is required for suspending the system while other users are logged in.</message>
                 <defaults>
                         <allow_any>auth_admin_keep</allow_any>
                         <allow_inactive>auth_admin_keep</allow_inactive>
         </action>
 
         <action id="org.freedesktop.login1.suspend-ignore-inhibit">
-                <_description>Suspend the system while an application asked to inhibit it</_description>
-                <_message>Authentication is required for suspending the system while an application asked to inhibit it.</_message>
+                <description>Suspend the system while an application asked to inhibit it</description>
+                <message>Authentication is required for suspending the system while an application asked to inhibit it.</message>
                 <defaults>
                         <allow_any>auth_admin_keep</allow_any>
                         <allow_inactive>auth_admin_keep</allow_inactive>
         </action>
 
         <action id="org.freedesktop.login1.hibernate">
-                <_description>Hibernate the system</_description>
-                <_message>Authentication is required for hibernating the system.</_message>
+                <description>Hibernate the system</description>
+                <message>Authentication is required for hibernating the system.</message>
                 <defaults>
                         <allow_any>auth_admin_keep</allow_any>
                         <allow_inactive>auth_admin_keep</allow_inactive>
         </action>
 
         <action id="org.freedesktop.login1.hibernate-multiple-sessions">
-                <_description>Hibernate the system while other users are logged in</_description>
-                <_message>Authentication is required for hibernating the system while other users are logged in.</_message>
+                <description>Hibernate the system while other users are logged in</description>
+                <message>Authentication is required for hibernating the system while other users are logged in.</message>
                 <defaults>
                         <allow_any>auth_admin_keep</allow_any>
                         <allow_inactive>auth_admin_keep</allow_inactive>
         </action>
 
         <action id="org.freedesktop.login1.hibernate-ignore-inhibit">
-                <_description>Hibernate the system while an application asked to inhibit it</_description>
-                <_message>Authentication is required for hibernating the system while an application asked to inhibit it.</_message>
+                <description>Hibernate the system while an application asked to inhibit it</description>
+                <message>Authentication is required for hibernating the system while an application asked to inhibit it.</message>
                 <defaults>
                         <allow_any>auth_admin_keep</allow_any>
                         <allow_inactive>auth_admin_keep</allow_inactive>
         </action>
 
         <action id="org.freedesktop.login1.manage">
-                <_description>Manage active sessions, users and seats</_description>
-                <_message>Authentication is required for managing active sessions, users and seats.</_message>
+                <description>Manage active sessions, users and seats</description>
+                <message>Authentication is required for managing active sessions, users and seats.</message>
                 <defaults>
                         <allow_any>auth_admin_keep</allow_any>
                         <allow_inactive>auth_admin_keep</allow_inactive>
         </action>
 
         <action id="org.freedesktop.login1.lock-sessions">
-                <_description>Lock or unlock active sessions</_description>
-                <_message>Authentication is required to lock or unlock active sessions.</_message>
+                <description>Lock or unlock active sessions</description>
+                <message>Authentication is required to lock or unlock active sessions.</message>
                 <defaults>
                         <allow_any>auth_admin_keep</allow_any>
                         <allow_inactive>auth_admin_keep</allow_inactive>
         </action>
 
         <action id="org.freedesktop.login1.set-reboot-to-firmware-setup">
-                <_description>Allow indication to the firmware to boot to setup interface</_description>
-                <_message>Authentication is required to indicate to the firmware to boot to setup interface.</_message>
+                <description>Allow indication to the firmware to boot to setup interface</description>
+                <message>Authentication is required to indicate to the firmware to boot to setup interface.</message>
                 <defaults>
                         <allow_any>auth_admin_keep</allow_any>
                         <allow_inactive>auth_admin_keep</allow_inactive>
         </action>
 
         <action id="org.freedesktop.login1.set-wall-message">
-                <_description>Set a wall message</_description>
-                <_message>Authentication is required to set a wall message</_message>
+                <description>Set a wall message</description>
+                <message>Authentication is required to set a wall message</message>
                 <defaults>
                         <allow_any>auth_admin_keep</allow_any>
                         <allow_inactive>auth_admin_keep</allow_inactive>
index 762dae2..68f1ed0 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 2337426..d999461 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 23ff75f..d48b9e8 100644 (file)
@@ -1,4 +1,6 @@
 /***
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   systemd is free software; you can redistribute it and/or modify it
index 29785e2..ca8bfa2 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -37,13 +38,23 @@ static int show_sysfs_one(
                 struct udev_list_entry **item,
                 const char *sub,
                 const char *prefix,
-                unsigned n_columns) {
+                unsigned n_columns,
+                OutputFlags flags) {
+
+        size_t max_width;
 
         assert(udev);
         assert(seat);
         assert(item);
         assert(prefix);
 
+        if (flags & OUTPUT_FULL_WIDTH)
+                max_width = (size_t) -1;
+        else if (n_columns < 10)
+                max_width = 10;
+        else
+                max_width = n_columns;
+
         while (*item) {
                 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
                 struct udev_list_entry *next, *lookahead;
@@ -106,7 +117,7 @@ static int show_sysfs_one(
                         lookahead = udev_list_entry_get_next(lookahead);
                 }
 
-                k = ellipsize(sysfs, n_columns, 20);
+                k = ellipsize(sysfs, max_width, 20);
                 if (!k)
                         return -ENOMEM;
 
@@ -120,7 +131,7 @@ static int show_sysfs_one(
                         return -ENOMEM;
 
                 free(k);
-                k = ellipsize(l, n_columns, 70);
+                k = ellipsize(l, max_width, 70);
                 if (!k)
                         return -ENOMEM;
 
@@ -134,14 +145,16 @@ static int show_sysfs_one(
                         if (!p)
                                 return -ENOMEM;
 
-                        show_sysfs_one(udev, seat, item, sysfs, p, n_columns - 2);
+                        show_sysfs_one(udev, seat, item, sysfs, p,
+                                       n_columns == (unsigned) -1 || n_columns < 2 ? n_columns : n_columns - 2,
+                                       flags);
                 }
         }
 
         return 0;
 }
 
-int show_sysfs(const char *seat, const char *prefix, unsigned n_columns) {
+int show_sysfs(const char *seat, const char *prefix, unsigned n_columns, OutputFlags flags) {
         _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
         _cleanup_udev_unref_ struct udev *udev = NULL;
         struct udev_list_entry *first = NULL;
@@ -150,8 +163,7 @@ int show_sysfs(const char *seat, const char *prefix, unsigned n_columns) {
         if (n_columns <= 0)
                 n_columns = columns();
 
-        if (!prefix)
-                prefix = "";
+        prefix = strempty(prefix);
 
         if (isempty(seat))
                 seat = "seat0";
@@ -181,7 +193,7 @@ int show_sysfs(const char *seat, const char *prefix, unsigned n_columns) {
 
         first = udev_enumerate_get_list_entry(e);
         if (first)
-                show_sysfs_one(udev, seat, &first, "/", prefix, n_columns);
+                show_sysfs_one(udev, seat, &first, "/", prefix, n_columns, flags);
         else
                 printf("%s%s%s\n", prefix, special_glyph(TREE_RIGHT), "(none)");
 
index 3e94bc3..15c902c 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -19,4 +20,8 @@
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
-int show_sysfs(const char *seat, const char *prefix, unsigned columns);
+#include <sys/types.h>
+
+#include "output-mode.h"
+
+int show_sysfs(const char *seat, const char *prefix, unsigned columns, OutputFlags flags);
index a3cf9d2..ad4700f 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 3d233f0..bf08b6e 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 4fbc893..7772f4b 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd
 
index 2244b1c..de6d869 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 18e0e34..10d1b06 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -289,158 +290,84 @@ int bus_image_method_set_limit(
         return sd_bus_reply_method_return(message, NULL);
 }
 
-#define EXIT_NOT_FOUND 2
-
-static int directory_image_get_os_release(Image *image, char ***ret, sd_bus_error *error) {
+int bus_image_method_get_hostname(
+                sd_bus_message *message,
+                void *userdata,
+                sd_bus_error *error) {
 
-        _cleanup_free_ char *path = NULL;
+        Image *image = userdata;
         int r;
 
-        assert(image);
-        assert(ret);
-
-        r = chase_symlinks("/etc/os-release", image->path, CHASE_PREFIX_ROOT, &path);
-        if (r == -ENOENT)
-                r = chase_symlinks("/usr/lib/os-release", image->path, CHASE_PREFIX_ROOT, &path);
-        if (r == -ENOENT)
-                return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Image does not contain OS release information");
-        if (r < 0)
-                return sd_bus_error_set_errnof(error, r, "Failed to resolve %s: %m", image->path);
-
-        r = load_env_file_pairs(NULL, path, NULL, ret);
-        if (r < 0)
-                return sd_bus_error_set_errnof(error, r, "Failed to open %s: %m", path);
+        if (!image->metadata_valid) {
+                r = image_read_metadata(image);
+                if (r < 0)
+                        return sd_bus_error_set_errnof(error, r, "Failed to read image metadata: %m");
+        }
 
-        return 0;
+        return sd_bus_reply_method_return(message, "s", image->hostname);
 }
 
-static int raw_image_get_os_release(Image *image, char ***ret, sd_bus_error *error) {
-        _cleanup_(rmdir_and_freep) char *t = NULL;
-        _cleanup_(loop_device_unrefp) LoopDevice *d = NULL;
-        _cleanup_(dissected_image_unrefp) DissectedImage *m = NULL;
-        _cleanup_(sigkill_waitp) pid_t child = 0;
-        _cleanup_close_pair_ int pair[2] = { -1, -1 };
-        _cleanup_fclose_ FILE *f = NULL;
-        _cleanup_strv_free_ char **v = NULL;
-        siginfo_t si;
-        int r;
-
-        assert(image);
-        assert(ret);
-
-        r = mkdtemp_malloc("/tmp/machined-root-XXXXXX", &t);
-        if (r < 0)
-                return sd_bus_error_set_errnof(error, r, "Failed to create temporary directory: %m");
-
-        r = loop_device_make_by_path(image->path, O_RDONLY, &d);
-        if (r < 0)
-                return sd_bus_error_set_errnof(error, r, "Failed to set up loop block device for %s: %m", image->path);
-
-        r = dissect_image(d->fd, NULL, 0, DISSECT_IMAGE_REQUIRE_ROOT, &m);
-        if (r == -ENOPKG)
-                return sd_bus_error_set_errnof(error, r, "Disk image %s not understood: %m", image->path);
-        if (r < 0)
-                return sd_bus_error_set_errnof(error, r, "Failed to dissect image %s: %m", image->path);
-
-        if (pipe2(pair, O_CLOEXEC) < 0)
-                return sd_bus_error_set_errnof(error, errno, "Failed to create communication pipe: %m");
-
-        child = raw_clone(SIGCHLD|CLONE_NEWNS);
-        if (child < 0)
-                return sd_bus_error_set_errnof(error, errno, "Failed to fork(): %m");
-
-        if (child == 0) {
-                int fd;
-
-                pair[0] = safe_close(pair[0]);
-
-                /* Make sure we never propagate to the host */
-                if (mount(NULL, "/", NULL, MS_SLAVE | MS_REC, NULL) < 0)
-                        _exit(EXIT_FAILURE);
-
-                r = dissected_image_mount(m, t, DISSECT_IMAGE_READ_ONLY);
-                if (r < 0)
-                        _exit(EXIT_FAILURE);
-
-                r = mount_move_root(t);
-                if (r < 0)
-                        _exit(EXIT_FAILURE);
+int bus_image_method_get_machine_id(
+                sd_bus_message *message,
+                void *userdata,
+                sd_bus_error *error) {
 
-                fd = open("/etc/os-release", O_RDONLY|O_CLOEXEC|O_NOCTTY);
-                if (fd < 0 && errno == ENOENT) {
-                        fd = open("/usr/lib/os-release", O_RDONLY|O_CLOEXEC|O_NOCTTY);
-                        if (fd < 0 && errno == ENOENT)
-                                _exit(EXIT_NOT_FOUND);
-                }
-                if (fd < 0)
-                        _exit(EXIT_FAILURE);
+        _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
+        Image *image = userdata;
+        int r;
 
-                r = copy_bytes(fd, pair[1], (uint64_t) -1, 0);
+        if (!image->metadata_valid) {
+                r = image_read_metadata(image);
                 if (r < 0)
-                        _exit(EXIT_FAILURE);
-
-                _exit(EXIT_SUCCESS);
+                        return sd_bus_error_set_errnof(error, r, "Failed to read image metadata: %m");
         }
 
-        pair[1] = safe_close(pair[1]);
-
-        f = fdopen(pair[0], "re");
-        if (!f)
-                return -errno;
-
-        pair[0] = -1;
-
-        r = load_env_file_pairs(f, "os-release", NULL, &v);
+        r = sd_bus_message_new_method_return(message, &reply);
         if (r < 0)
                 return r;
 
-        r = wait_for_terminate(child, &si);
+        if (sd_id128_is_null(image->machine_id)) /* Add an empty array if the ID is zero */
+                r = sd_bus_message_append(reply, "ay", 0);
+        else
+                r = sd_bus_message_append_array(reply, 'y', image->machine_id.bytes, 16);
         if (r < 0)
-                return sd_bus_error_set_errnof(error, r, "Failed to wait for child: %m");
-        child = 0;
-        if (si.si_code == CLD_EXITED && si.si_status == EXIT_NOT_FOUND)
-                return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Image does not contain OS release information");
-        if (si.si_code != CLD_EXITED || si.si_status != EXIT_SUCCESS)
-                return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Child died abnormally.");
-
-        *ret = v;
-        v = NULL;
+                return r;
 
-        return 0;
+        return sd_bus_send(NULL, reply, NULL);
 }
 
-int bus_image_method_get_os_release(
+int bus_image_method_get_machine_info(
                 sd_bus_message *message,
                 void *userdata,
                 sd_bus_error *error) {
 
-        _cleanup_release_lock_file_ LockFile tree_global_lock = LOCK_FILE_INIT, tree_local_lock = LOCK_FILE_INIT;
-        _cleanup_strv_free_ char **v = NULL;
         Image *image = userdata;
         int r;
 
-        r = image_path_lock(image->path, LOCK_SH|LOCK_NB, &tree_global_lock, &tree_local_lock);
-        if (r < 0)
-                return sd_bus_error_set_errnof(error, r, "Failed to lock image: %m");
+        if (!image->metadata_valid) {
+                r = image_read_metadata(image);
+                if (r < 0)
+                        return sd_bus_error_set_errnof(error, r, "Failed to read image metadata: %m");
+        }
 
-        switch (image->type) {
+        return bus_reply_pair_array(message, image->machine_info);
+}
 
-        case IMAGE_DIRECTORY:
-        case IMAGE_SUBVOLUME:
-                r = directory_image_get_os_release(image, &v, error);
-                break;
+int bus_image_method_get_os_release(
+                sd_bus_message *message,
+                void *userdata,
+                sd_bus_error *error) {
 
-        case IMAGE_RAW:
-                r = raw_image_get_os_release(image, &v, error);
-                break;
+        Image *image = userdata;
+        int r;
 
-        default:
-                assert_not_reached("Unknown image type");
+        if (!image->metadata_valid) {
+                r = image_read_metadata(image);
+                if (r < 0)
+                        return sd_bus_error_set_errnof(error, r, "Failed to read image metadata: %m");
         }
-        if (r < 0)
-                return r;
 
-        return bus_reply_pair_array(message, v);
+        return bus_reply_pair_array(message, image->os_release);
 }
 
 const sd_bus_vtable image_vtable[] = {
@@ -460,20 +387,20 @@ const sd_bus_vtable image_vtable[] = {
         SD_BUS_METHOD("Clone", "sb", NULL, bus_image_method_clone, SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD("MarkReadOnly", "b", NULL, bus_image_method_mark_read_only, SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD("SetLimit", "t", NULL, bus_image_method_set_limit, SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD("GetHostname", NULL, "s", bus_image_method_get_hostname, SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD("GetMachineID", NULL, "ay", bus_image_method_get_machine_id, SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD("GetMachineInfo", NULL, "a{ss}", bus_image_method_get_machine_info, SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD("GetOSRelease", NULL, "a{ss}", bus_image_method_get_os_release, SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_VTABLE_END
 };
 
 static int image_flush_cache(sd_event_source *s, void *userdata) {
         Manager *m = userdata;
-        Image *i;
 
         assert(s);
         assert(m);
 
-        while ((i = hashmap_steal_first(m->image_cache)))
-                image_unref(i);
-
+        hashmap_clear_with_destructor(m->image_cache, image_unref);
         return 0;
 }
 
index bc8a6c3..119c69c 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -33,4 +34,7 @@ int bus_image_method_rename(sd_bus_message *message, void *userdata, sd_bus_erro
 int bus_image_method_clone(sd_bus_message *message, void *userdata, sd_bus_error *error);
 int bus_image_method_mark_read_only(sd_bus_message *message, void *userdata, sd_bus_error *error);
 int bus_image_method_set_limit(sd_bus_message *message, void *userdata, sd_bus_error *error);
+int bus_image_method_get_hostname(sd_bus_message *message, void *userdata, sd_bus_error *error);
+int bus_image_method_get_machine_id(sd_bus_message *message, void *userdata, sd_bus_error *error);
+int bus_image_method_get_machine_info(sd_bus_message *message, void *userdata, sd_bus_error *error);
 int bus_image_method_get_os_release(sd_bus_message *message, void *userdata, sd_bus_error *error);
index 36568b6..3761267 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -836,11 +837,13 @@ int bus_machine_method_bind_mount(sd_bus_message *message, void *userdata, sd_bu
         bool mount_slave_created = false, mount_slave_mounted = false,
                 mount_tmp_created = false, mount_tmp_mounted = false,
                 mount_outside_created = false, mount_outside_mounted = false;
+        _cleanup_free_ char *chased_src = NULL;
+        int read_only, make_file_or_directory;
         const char *dest, *src;
         Machine *m = userdata;
-        int read_only, make_directory;
-        pid_t child;
+        struct stat st;
         siginfo_t si;
+        pid_t child;
         uid_t uid;
         int r;
 
@@ -850,16 +853,16 @@ int bus_machine_method_bind_mount(sd_bus_message *message, void *userdata, sd_bu
         if (m->class != MACHINE_CONTAINER)
                 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Bind mounting is only supported on container machines.");
 
-        r = sd_bus_message_read(message, "ssbb", &src, &dest, &read_only, &make_directory);
+        r = sd_bus_message_read(message, "ssbb", &src, &dest, &read_only, &make_file_or_directory);
         if (r < 0)
                 return r;
 
-        if (!path_is_absolute(src) || !path_is_safe(src))
+        if (!path_is_absolute(src) || !path_is_normalized(src))
                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Source path must be absolute and not contain ../.");
 
         if (isempty(dest))
                 dest = src;
-        else if (!path_is_absolute(dest) || !path_is_safe(dest))
+        else if (!path_is_absolute(dest) || !path_is_normalized(dest))
                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Destination path must be absolute and not contain ../.");
 
         r = bus_verify_polkit_async(
@@ -890,6 +893,15 @@ int bus_machine_method_bind_mount(sd_bus_message *message, void *userdata, sd_bu
         if (laccess(p, F_OK) < 0)
                 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Container does not allow propagation of mount points.");
 
+        r = chase_symlinks(src, NULL, 0, &chased_src);
+        if (r < 0)
+                return sd_bus_error_set_errnof(error, r, "Failed to resolve source path: %m");
+
+        if (lstat(chased_src, &st) < 0)
+                return sd_bus_error_set_errnof(error, errno, "Failed to stat() source path: %m");
+        if (S_ISLNK(st.st_mode)) /* This shouldn't really happen, given that we just chased the symlinks above, but let's better be safe… */
+                return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Source directory can't be a symbolic link");
+
         /* Our goal is to install a new bind mount into the container,
            possibly read-only. This is irritatingly complex
            unfortunately, currently.
@@ -916,18 +928,21 @@ int bus_machine_method_bind_mount(sd_bus_message *message, void *userdata, sd_bu
                 goto finish;
         }
 
-        /* Second, we mount the source directory to a directory inside
-           of our MS_SLAVE playground. */
+        /* Second, we mount the source file or directory to a directory inside of our MS_SLAVE playground. */
         mount_tmp = strjoina(mount_slave, "/mount");
-        if (mkdir(mount_tmp, 0700) < 0) {
-                r = sd_bus_error_set_errnof(error, errno, "Failed to create temporary mount point %s: %m", mount_tmp);
+        if (S_ISDIR(st.st_mode))
+                r = mkdir(mount_tmp, 0700) < 0 ? -errno : 0;
+        else
+                r = touch(mount_tmp);
+        if (r < 0) {
+                sd_bus_error_set_errnof(error, errno, "Failed to create temporary mount point %s: %m", mount_tmp);
                 goto finish;
         }
 
         mount_tmp_created = true;
 
-        if (mount(src, mount_tmp, NULL, MS_BIND, NULL) < 0) {
-                r = sd_bus_error_set_errnof(error, errno, "Failed to overmount %s: %m", mount_tmp);
+        if (mount(chased_src, mount_tmp, NULL, MS_BIND, NULL) < 0) {
+                r = sd_bus_error_set_errnof(error, errno, "Failed to mount %s: %m", chased_src);
                 goto finish;
         }
 
@@ -940,13 +955,18 @@ int bus_machine_method_bind_mount(sd_bus_message *message, void *userdata, sd_bu
                         goto finish;
                 }
 
-        /* Fourth, we move the new bind mount into the propagation
-         * directory. This way it will appear there read-only
+        /* Fourth, we move the new bind mount into the propagation directory. This way it will appear there read-only
          * right-away. */
 
         mount_outside = strjoina("/run/systemd/nspawn/propagate/", m->name, "/XXXXXX");
-        if (!mkdtemp(mount_outside)) {
-                r = sd_bus_error_set_errnof(error, errno, "Cannot create propagation directory %s: %m", mount_outside);
+        if (S_ISDIR(st.st_mode))
+                r = mkdtemp(mount_outside) ? 0 : -errno;
+        else {
+                r = mkostemp_safe(mount_outside);
+                safe_close(r);
+        }
+        if (r < 0) {
+                sd_bus_error_set_errnof(error, errno, "Cannot create propagation file or directory %s: %m", mount_outside);
                 goto finish;
         }
 
@@ -960,7 +980,10 @@ int bus_machine_method_bind_mount(sd_bus_message *message, void *userdata, sd_bu
         mount_outside_mounted = true;
         mount_tmp_mounted = false;
 
-        (void) rmdir(mount_tmp);
+        if (S_ISDIR(st.st_mode))
+                (void) rmdir(mount_tmp);
+        else
+                (void) unlink(mount_tmp);
         mount_tmp_created = false;
 
         (void) umount(mount_slave);
@@ -999,8 +1022,14 @@ int bus_machine_method_bind_mount(sd_bus_message *message, void *userdata, sd_bu
                         goto child_fail;
                 }
 
-                if (make_directory)
-                        (void) mkdir_p(dest, 0755);
+                if (make_file_or_directory) {
+                        if (S_ISDIR(st.st_mode))
+                                (void) mkdir_p(dest, 0755);
+                        else {
+                                (void) mkdir_parents(dest, 0755);
+                                safe_close(open(dest, O_CREAT|O_EXCL|O_WRONLY|O_CLOEXEC|O_NOCTTY, 0600));
+                        }
+                }
 
                 /* Fifth, move the mount to the right place inside */
                 mount_inside = strjoina("/run/systemd/nspawn/incoming/", basename(mount_outside));
@@ -1042,19 +1071,27 @@ int bus_machine_method_bind_mount(sd_bus_message *message, void *userdata, sd_bu
 
 finish:
         if (mount_outside_mounted)
-                umount(mount_outside);
-        if (mount_outside_created)
-                rmdir(mount_outside);
+                (void) umount(mount_outside);
+        if (mount_outside_created) {
+                if (S_ISDIR(st.st_mode))
+                        (void) rmdir(mount_outside);
+                else
+                        (void) unlink(mount_outside);
+        }
 
         if (mount_tmp_mounted)
-                umount(mount_tmp);
-        if (mount_tmp_created)
-                rmdir(mount_tmp);
+                (void) umount(mount_tmp);
+        if (mount_tmp_created) {
+                if (S_ISDIR(st.st_mode))
+                        (void) rmdir(mount_tmp);
+                else
+                        (void) unlink(mount_tmp);
+        }
 
         if (mount_slave_mounted)
-                umount(mount_slave);
+                (void) umount(mount_slave);
         if (mount_slave_created)
-                rmdir(mount_slave);
+                (void) rmdir(mount_slave);
 
         return r;
 }
index 2aa7b4c..f8c931f 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 399e41f..7375d83 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -20,6 +21,7 @@
 #include <errno.h>
 #include <string.h>
 #include <unistd.h>
+#include <stdio_ext.h>
 
 #include "sd-messages.h"
 
@@ -42,6 +44,7 @@
 #include "string-table.h"
 #include "terminal-util.h"
 #include "unit-name.h"
+#include "user-util.h"
 #include "util.h"
 
 Machine* machine_new(Manager *manager, MachineClass class, const char *name) {
@@ -128,7 +131,7 @@ int machine_save(Machine *m) {
         if (!m->started)
                 return 0;
 
-        r = mkdir_safe_label("/run/systemd/machines", 0755, 0, 0);
+        r = mkdir_safe_label("/run/systemd/machines", 0755, 0, 0, false);
         if (r < 0)
                 goto fail;
 
@@ -136,6 +139,7 @@ int machine_save(Machine *m) {
         if (r < 0)
                 goto fail;
 
+        (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
         (void) fchmod(fileno(f), 0644);
 
         fprintf(f,
@@ -199,16 +203,16 @@ int machine_save(Machine *m) {
         if (m->n_netif > 0) {
                 unsigned i;
 
-                fputs_unlocked("NETIF=", f);
+                fputs("NETIF=", f);
 
                 for (i = 0; i < m->n_netif; i++) {
                         if (i != 0)
-                                fputc_unlocked(' ', f);
+                                fputc(' ', f);
 
                         fprintf(f, "%i", m->netif[i]);
                 }
 
-                fputc_unlocked('\n', f);
+                fputc('\n', f);
         }
 
         r = fflush_and_check(f);
@@ -606,7 +610,7 @@ void machine_release_unit(Machine *m) {
 }
 
 int machine_get_uid_shift(Machine *m, uid_t *ret) {
-        char p[strlen("/proc//uid_map") + DECIMAL_STR_MAX(pid_t) + 1];
+        char p[STRLEN("/proc//uid_map") + DECIMAL_STR_MAX(pid_t) + 1];
         uid_t uid_base, uid_shift, uid_range;
         gid_t gid_base, gid_shift, gid_range;
         _cleanup_fclose_ FILE *f = NULL;
@@ -655,7 +659,7 @@ int machine_get_uid_shift(Machine *m, uid_t *ret) {
         if (uid_base != 0)
                 return -ENXIO;
         /* Insist that at least the nobody user is mapped, everything else is weird, and hence complex, and we don't support it */
-        if (uid_range < (uid_t) 65534U)
+        if (uid_range < UID_NOBODY)
                 return -ENXIO;
 
         /* If there's more than one line, then we don't support this mapping. */
index 6bdb204..1ee82ff 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 2447e73..c435bb9 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
 #include "path-util.h"
 #include "process-util.h"
 #include "ptyfwd.h"
+#include "sigbus.h"
 #include "signal-util.h"
 #include "spawn-polkit-agent.h"
+#include "stdio-util.h"
 #include "strv.h"
 #include "terminal-util.h"
 #include "unit-name.h"
 #include "util.h"
 #include "verbs.h"
 #include "web-util.h"
-#include "stdio-util.h"
 
 #define ALL_IP_ADDRESSES -1
 
@@ -89,24 +91,10 @@ static int arg_addrs = 1;
 
 static int print_addresses(sd_bus *bus, const char *name, int, const char *pr1, const char *pr2, int n_addr);
 
-static void polkit_agent_open_if_enabled(void) {
-
-        /* Open the polkit agent as a child process if necessary */
-
-        if (!arg_ask_password)
-                return;
-
-        if (arg_transport != BUS_TRANSPORT_LOCAL)
-                return;
-
-        polkit_agent_open();
-}
-
 static OutputFlags get_output_flags(void) {
         return
                 arg_all * OUTPUT_SHOW_ALL |
-                arg_full * OUTPUT_FULL_WIDTH |
-                (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
+                (arg_full || !on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
                 colors_enabled() * OUTPUT_COLOR |
                 !arg_quiet * OUTPUT_WARN_CUTOFF;
 }
@@ -206,8 +194,8 @@ static int call_get_os_release(sd_bus *bus, const char *method, const char *name
 
 static int list_machines(int argc, char *argv[], void *userdata) {
 
-        size_t max_name = strlen("MACHINE"), max_class = strlen("CLASS"),
-               max_service = strlen("SERVICE"), max_os = strlen("OS"), max_version_id = strlen("VERSION");
+        size_t max_name = STRLEN("MACHINE"), max_class = STRLEN("CLASS"),
+               max_service = STRLEN("SERVICE"), max_os = STRLEN("OS"), max_version_id = STRLEN("VERSION");
         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
         _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
         _cleanup_free_ char *prefix = NULL;
@@ -296,13 +284,13 @@ static int list_machines(int argc, char *argv[], void *userdata) {
 
         qsort_safe(machines, n_machines, sizeof(MachineInfo), compare_machine_info);
 
-        /* Allocate for prefix max characters for all fields + spaces between them + strlen(",\n") */
+        /* Allocate for prefix max characters for all fields + spaces between them + STRLEN(",\n") */
         r = asprintf(&prefix, "%-*s",
                         (int) (max_name +
                         max_class +
                         max_service +
                         max_os +
-                        max_version_id + 5 + strlen(",\n")),
+                        max_version_id + 5 + STRLEN(",\n")),
                         ",\n");
         if (r < 0) {
                 r = log_oom();
@@ -364,7 +352,7 @@ static int compare_image_info(const void *a, const void *b) {
 static int list_images(int argc, char *argv[], void *userdata) {
 
         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
-        size_t max_name = strlen("NAME"), max_type = strlen("TYPE"), max_size = strlen("USAGE"), max_crtime = strlen("CREATED"), max_mtime = strlen("MODIFIED");
+        size_t max_name = STRLEN("NAME"), max_type = STRLEN("TYPE"), max_size = STRLEN("USAGE"), max_crtime = STRLEN("CREATED"), max_mtime = STRLEN("MODIFIED");
         _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
         _cleanup_free_ ImageInfo *images = NULL;
         size_t n_images = 0, n_allocated = 0, j;
@@ -912,6 +900,99 @@ static int show_machine(int argc, char *argv[], void *userdata) {
         return r;
 }
 
+static int print_image_hostname(sd_bus *bus, const char *name) {
+        _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
+        const char *hn;
+        int r;
+
+        r = sd_bus_call_method(
+                        bus,
+                        "org.freedesktop.machine1",
+                        "/org/freedesktop/machine1",
+                        "org.freedesktop.machine1.Manager",
+                        "GetImageHostname",
+                        NULL, &reply, "s", name);
+        if (r < 0)
+                return r;
+
+        r = sd_bus_message_read(reply, "s", &hn);
+        if (r < 0)
+                return r;
+
+        if (!isempty(hn))
+                printf("\tHostname: %s\n", hn);
+
+        return 0;
+}
+
+static int print_image_machine_id(sd_bus *bus, const char *name) {
+        _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
+        sd_id128_t id = SD_ID128_NULL;
+        const void *p;
+        size_t size;
+        int r;
+
+        r = sd_bus_call_method(
+                        bus,
+                        "org.freedesktop.machine1",
+                        "/org/freedesktop/machine1",
+                        "org.freedesktop.machine1.Manager",
+                        "GetImageMachineID",
+                        NULL, &reply, "s", name);
+        if (r < 0)
+                return r;
+
+        r = sd_bus_message_read_array(reply, 'y', &p, &size);
+        if (r < 0)
+                return r;
+
+        if (size == sizeof(sd_id128_t))
+                memcpy(&id, p, size);
+
+        if (!sd_id128_is_null(id))
+                printf("      Machine ID: " SD_ID128_FORMAT_STR "\n", SD_ID128_FORMAT_VAL(id));
+
+        return 0;
+}
+
+static int print_image_machine_info(sd_bus *bus, const char *name) {
+        _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
+        int r;
+
+        r = sd_bus_call_method(
+                        bus,
+                        "org.freedesktop.machine1",
+                        "/org/freedesktop/machine1",
+                        "org.freedesktop.machine1.Manager",
+                        "GetImageMachineInfo",
+                        NULL, &reply, "s", name);
+        if (r < 0)
+                return r;
+
+        r = sd_bus_message_enter_container(reply, 'a', "{ss}");
+        if (r < 0)
+                return r;
+
+        for (;;) {
+                const char *p, *q;
+
+                r = sd_bus_message_read(reply, "{ss}", &p, &q);
+                if (r < 0)
+                        return r;
+                if (r == 0)
+                        break;
+
+                if (streq(p, "DEPLOYMENT"))
+                        printf("      Deployment: %s\n", q);
+        }
+
+        r = sd_bus_message_exit_container(reply);
+        if (r < 0)
+                return r;
+
+        return 0;
+}
+
 typedef struct ImageStatusInfo {
         char *name;
         char *path;
@@ -926,12 +1007,13 @@ typedef struct ImageStatusInfo {
 } ImageStatusInfo;
 
 static void image_status_info_clear(ImageStatusInfo *info) {
-        if (info) {
-                free(info->name);
-                free(info->path);
-                free(info->type);
-                zero(*info);
-        }
+        if (!info)
+                return;
+
+        free(info->name);
+        free(info->path);
+        free(info->type);
+        zero(*info);
 }
 
 static void print_image_status_info(sd_bus *bus, ImageStatusInfo *i) {
@@ -954,6 +1036,10 @@ static void print_image_status_info(sd_bus *bus, ImageStatusInfo *i) {
         if (i->path)
                 printf("\t    Path: %s\n", i->path);
 
+        (void) print_image_hostname(bus, i->name);
+        (void) print_image_machine_id(bus, i->name);
+        (void) print_image_machine_info(bus, i->name);
+
         print_os_release(bus, "GetImageOSRelease", i->name, "\t      OS: ");
 
         printf("\t      RO: %s%s%s\n",
@@ -1179,7 +1265,7 @@ static int kill_machine(int argc, char *argv[], void *userdata) {
 
         assert(bus);
 
-        polkit_agent_open_if_enabled();
+        polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
 
         if (!arg_kill_who)
                 arg_kill_who = "all";
@@ -1224,7 +1310,7 @@ static int terminate_machine(int argc, char *argv[], void *userdata) {
 
         assert(bus);
 
-        polkit_agent_open_if_enabled();
+        polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
 
         for (i = 1; i < argc; i++) {
                 r = sd_bus_call_method(
@@ -1256,7 +1342,7 @@ static int copy_files(int argc, char *argv[], void *userdata) {
 
         assert(bus);
 
-        polkit_agent_open_if_enabled();
+        polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
 
         copy_from = streq(argv[0], "copy-from");
         dest = argv[3] ?: argv[2];
@@ -1305,7 +1391,7 @@ static int bind_mount(int argc, char *argv[], void *userdata) {
 
         assert(bus);
 
-        polkit_agent_open_if_enabled();
+        polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
 
         r = sd_bus_call_method(
                         bus,
@@ -1463,7 +1549,7 @@ static int login_machine(int argc, char *argv[], void *userdata) {
                 return -EOPNOTSUPP;
         }
 
-        polkit_agent_open_if_enabled();
+        polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
 
         r = sd_event_default(&event);
         if (r < 0)
@@ -1536,7 +1622,7 @@ static int shell_machine(int argc, char *argv[], void *userdata) {
                 }
         }
 
-        polkit_agent_open_if_enabled();
+        polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
 
         r = sd_event_default(&event);
         if (r < 0)
@@ -1604,7 +1690,7 @@ static int remove_image(int argc, char *argv[], void *userdata) {
 
         assert(bus);
 
-        polkit_agent_open_if_enabled();
+        polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
 
         for (i = 1; i < argc; i++) {
                 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
@@ -1638,7 +1724,7 @@ static int rename_image(int argc, char *argv[], void *userdata) {
         sd_bus *bus = userdata;
         int r;
 
-        polkit_agent_open_if_enabled();
+        polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
 
         r = sd_bus_call_method(
                         bus,
@@ -1663,7 +1749,7 @@ static int clone_image(int argc, char *argv[], void *userdata) {
         sd_bus *bus = userdata;
         int r;
 
-        polkit_agent_open_if_enabled();
+        polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
 
         r = sd_bus_message_new_method_call(
                         bus,
@@ -1700,7 +1786,7 @@ static int read_only_image(int argc, char *argv[], void *userdata) {
                 }
         }
 
-        polkit_agent_open_if_enabled();
+        polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
 
         r = sd_bus_call_method(
                         bus,
@@ -1771,7 +1857,7 @@ static int start_machine(int argc, char *argv[], void *userdata) {
 
         assert(bus);
 
-        polkit_agent_open_if_enabled();
+        polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
 
         r = bus_wait_for_jobs_new(bus, &w);
         if (r < 0)
@@ -1836,7 +1922,7 @@ static int enable_machine(int argc, char *argv[], void *userdata) {
 
         assert(bus);
 
-        polkit_agent_open_if_enabled();
+        polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
 
         method = streq(argv[0], "enable") ? "EnableUnitFiles" : "DisableUnitFiles";
 
@@ -1991,7 +2077,7 @@ static int transfer_image_common(sd_bus *bus, sd_bus_message *m) {
         assert(bus);
         assert(m);
 
-        polkit_agent_open_if_enabled();
+        polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
 
         r = sd_event_default(&event);
         if (r < 0)
@@ -2441,7 +2527,7 @@ static int compare_transfer_info(const void *a, const void *b) {
 }
 
 static int list_transfers(int argc, char *argv[], void *userdata) {
-        size_t max_type = strlen("TYPE"), max_local = strlen("LOCAL"), max_remote = strlen("REMOTE");
+        size_t max_type = STRLEN("TYPE"), max_local = STRLEN("LOCAL"), max_remote = STRLEN("REMOTE");
         _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
         _cleanup_free_ TransferInfo *transfers = NULL;
@@ -2542,7 +2628,7 @@ static int cancel_transfer(int argc, char *argv[], void *userdata) {
 
         assert(bus);
 
-        polkit_agent_open_if_enabled();
+        polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
 
         for (i = 1; i < argc; i++) {
                 uint32_t id;
@@ -3058,12 +3144,13 @@ static int machinectl_main(int argc, char *argv[], sd_bus *bus) {
 }
 
 int main(int argc, char*argv[]) {
-        sd_bus *bus = NULL;
+        _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
         int r;
 
         setlocale(LC_ALL, "");
         log_parse_environment();
         log_open();
+        sigbus_install();
 
         r = parse_argv(argc, argv);
         if (r <= 0)
@@ -3080,7 +3167,6 @@ int main(int argc, char*argv[]) {
         r = machinectl_main(argc, argv, bus);
 
 finish:
-        sd_bus_flush_close_unref(bus);
         pager_close();
         polkit_agent_close();
 
index c9b92d2..330d6b3 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -845,6 +846,78 @@ static int method_mark_image_read_only(sd_bus_message *message, void *userdata,
         return bus_image_method_mark_read_only(message, i, error);
 }
 
+static int method_get_image_hostname(sd_bus_message *message, void *userdata, sd_bus_error *error) {
+        _cleanup_(image_unrefp) Image *i = NULL;
+        const char *name;
+        int r;
+
+        assert(message);
+
+        r = sd_bus_message_read(message, "s", &name);
+        if (r < 0)
+                return r;
+
+        if (!image_name_is_valid(name))
+                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", name);
+
+        r = image_find(name, &i);
+        if (r < 0)
+                return r;
+        if (r == 0)
+                return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "No image '%s' known", name);
+
+        i->userdata = userdata;
+        return bus_image_method_get_hostname(message, i, error);
+}
+
+static int method_get_image_machine_id(sd_bus_message *message, void *userdata, sd_bus_error *error) {
+        _cleanup_(image_unrefp) Image *i = NULL;
+        const char *name;
+        int r;
+
+        assert(message);
+
+        r = sd_bus_message_read(message, "s", &name);
+        if (r < 0)
+                return r;
+
+        if (!image_name_is_valid(name))
+                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", name);
+
+        r = image_find(name, &i);
+        if (r < 0)
+                return r;
+        if (r == 0)
+                return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "No image '%s' known", name);
+
+        i->userdata = userdata;
+        return bus_image_method_get_machine_id(message, i, error);
+}
+
+static int method_get_image_machine_info(sd_bus_message *message, void *userdata, sd_bus_error *error) {
+        _cleanup_(image_unrefp) Image *i = NULL;
+        const char *name;
+        int r;
+
+        assert(message);
+
+        r = sd_bus_message_read(message, "s", &name);
+        if (r < 0)
+                return r;
+
+        if (!image_name_is_valid(name))
+                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", name);
+
+        r = image_find(name, &i);
+        if (r < 0)
+                return r;
+        if (r == 0)
+                return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "No image '%s' known", name);
+
+        i->userdata = userdata;
+        return bus_image_method_get_machine_info(message, i, error);
+}
+
 static int method_get_image_os_release(sd_bus_message *message, void *userdata, sd_bus_error *error) {
         _cleanup_(image_unrefp) Image *i = NULL;
         const char *name;
@@ -1247,7 +1320,7 @@ static int method_map_to_machine_user(sd_bus_message *message, void *userdata, s
 
         HASHMAP_FOREACH(machine, m->machines, i) {
                 _cleanup_fclose_ FILE *f = NULL;
-                char p[strlen("/proc//uid_map") + DECIMAL_STR_MAX(pid_t) + 1];
+                char p[STRLEN("/proc//uid_map") + DECIMAL_STR_MAX(pid_t) + 1];
 
                 if (machine->class != MACHINE_CONTAINER)
                         continue;
@@ -1365,7 +1438,7 @@ static int method_map_to_machine_group(sd_bus_message *message, void *groupdata,
 
         HASHMAP_FOREACH(machine, m->machines, i) {
                 _cleanup_fclose_ FILE *f = NULL;
-                char p[strlen("/proc//gid_map") + DECIMAL_STR_MAX(pid_t) + 1];
+                char p[STRLEN("/proc//gid_map") + DECIMAL_STR_MAX(pid_t) + 1];
 
                 if (machine->class != MACHINE_CONTAINER)
                         continue;
@@ -1441,6 +1514,9 @@ const sd_bus_vtable manager_vtable[] = {
         SD_BUS_METHOD("RenameImage", "ss", NULL, method_rename_image, SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD("CloneImage", "ssb", NULL, method_clone_image, SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD("MarkImageReadOnly", "sb", NULL, method_mark_image_read_only, SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD("GetImageHostname", "s", "s", method_get_image_hostname, SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD("GetImageMachineID", "s", "ay", method_get_image_machine_id, SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD("GetImageMachineInfo", "s", "a{ss}", method_get_image_machine_info, SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD("GetImageOSRelease", "s", "a{ss}", method_get_image_os_release, SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD("SetPoolLimit", "t", NULL, method_set_pool_limit, SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD("SetImageLimit", "st", NULL, method_set_image_limit, SD_BUS_VTABLE_UNPRIVILEGED),
index d8ddbec..d481020 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -67,7 +68,6 @@ Manager *manager_new(void) {
 
 void manager_free(Manager *m) {
         Machine *machine;
-        Image *i;
 
         assert(m);
 
@@ -83,10 +83,7 @@ void manager_free(Manager *m) {
         hashmap_free(m->machine_units);
         hashmap_free(m->machine_leaders);
 
-        while ((i = hashmap_steal_first(m->image_cache)))
-                image_unref(i);
-
-        hashmap_free(m->image_cache);
+        hashmap_free_with_destructor(m->image_cache, image_unref);
 
         sd_event_source_unref(m->image_cache_defer_event);
 
index 7b9b148..b00c4c1 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 693503d..7ea5d9d 100644 (file)
@@ -1,3 +1,20 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
+# Copyright 2017 Zbigniew Jędrzejewski-Szmek
+#
+# 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.
+#
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
 systemd_machined_sources = files('''
         machined.c
         machined.h
@@ -27,11 +44,12 @@ if conf.get('ENABLE_MACHINED') == 1
         install_data('org.freedesktop.machine1.service',
                      install_dir : dbussystemservicedir)
 
-        custom_target(
+        i18n.merge_file(
                 'org.freedesktop.machine1.policy',
                 input : 'org.freedesktop.machine1.policy.in',
                 output : 'org.freedesktop.machine1.policy',
-                command : intltool_command,
+                po_dir : po_dir,
+                data_dirs : po_dir,
                 install : install_polkit,
                 install_dir : polkitpolicydir)
 endif
index 9b2d13d..6aba1a2 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 9831b12..361bf1f 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index daa365a..73b7e07 100644 (file)
 
                 <allow send_destination="org.freedesktop.machine1"
                        send_interface="org.freedesktop.machine1.Manager"
+                       send_member="GetImageHostname"/>
+
+                <allow send_destination="org.freedesktop.machine1"
+                       send_interface="org.freedesktop.machine1.Manager"
+                       send_member="GetImageMachineID"/>
+
+                <allow send_destination="org.freedesktop.machine1"
+                       send_interface="org.freedesktop.machine1.Manager"
+                       send_member="GetImageMachineInfo"/>
+
+                <allow send_destination="org.freedesktop.machine1"
+                       send_interface="org.freedesktop.machine1.Manager"
                        send_member="GetImageOSRelease"/>
 
                 <allow send_destination="org.freedesktop.machine1"
 
                 <allow send_destination="org.freedesktop.machine1"
                        send_interface="org.freedesktop.machine1.Image"
+                       send_member="GetHostname"/>
+
+                <allow send_destination="org.freedesktop.machine1"
+                       send_interface="org.freedesktop.machine1.Image"
+                       send_member="GetMachineID"/>
+
+                <allow send_destination="org.freedesktop.machine1"
+                       send_interface="org.freedesktop.machine1.Image"
+                       send_member="GetMachineInfo"/>
+
+                <allow send_destination="org.freedesktop.machine1"
+                       send_interface="org.freedesktop.machine1.Image"
                        send_member="GetOSRelease"/>
 
                 <allow receive_sender="org.freedesktop.machine1"/>
index 69f78a5..eeeeb4c 100644 (file)
@@ -3,6 +3,8 @@
         "http://www.freedesktop.org/standards/PolicyKit/1/policyconfig.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   systemd is free software; you can redistribute it and/or modify it
@@ -17,8 +19,8 @@
         <vendor_url>http://www.freedesktop.org/wiki/Software/systemd</vendor_url>
 
         <action id="org.freedesktop.machine1.login">
-                <_description>Log into a local container</_description>
-                <_message>Authentication is required to log into a local container.</_message>
+                <description>Log into a local container</description>
+                <message>Authentication is required to log into a local container.</message>
                 <defaults>
                         <allow_any>auth_admin</allow_any>
                         <allow_inactive>auth_admin</allow_inactive>
@@ -27,8 +29,8 @@
         </action>
 
         <action id="org.freedesktop.machine1.host-login">
-                <_description>Log into the local host</_description>
-                <_message>Authentication is required to log into the local host.</_message>
+                <description>Log into the local host</description>
+                <message>Authentication is required to log into the local host.</message>
                 <defaults>
                         <allow_any>auth_admin</allow_any>
                         <allow_inactive>auth_admin</allow_inactive>
@@ -37,8 +39,8 @@
         </action>
 
         <action id="org.freedesktop.machine1.shell">
-                <_description>Acquire a shell in a local container</_description>
-                <_message>Authentication is required to acquire a shell in a local container.</_message>
+                <description>Acquire a shell in a local container</description>
+                <message>Authentication is required to acquire a shell in a local container.</message>
                 <defaults>
                         <allow_any>auth_admin</allow_any>
                         <allow_inactive>auth_admin</allow_inactive>
@@ -48,8 +50,8 @@
         </action>
 
         <action id="org.freedesktop.machine1.host-shell">
-                <_description>Acquire a shell on the local host</_description>
-                <_message>Authentication is required to acquire a shell on the local host.</_message>
+                <description>Acquire a shell on the local host</description>
+                <message>Authentication is required to acquire a shell on the local host.</message>
                 <defaults>
                         <allow_any>auth_admin</allow_any>
                         <allow_inactive>auth_admin</allow_inactive>
@@ -59,8 +61,8 @@
         </action>
 
         <action id="org.freedesktop.machine1.open-pty">
-                <_description>Acquire a pseudo TTY in a local container</_description>
-                <_message>Authentication is required to acquire a pseudo TTY in a local container.</_message>
+                <description>Acquire a pseudo TTY in a local container</description>
+                <message>Authentication is required to acquire a pseudo TTY in a local container.</message>
                 <defaults>
                         <allow_any>auth_admin</allow_any>
                         <allow_inactive>auth_admin</allow_inactive>
@@ -69,8 +71,8 @@
         </action>
 
         <action id="org.freedesktop.machine1.host-open-pty">
-                <_description>Acquire a pseudo TTY on the local host</_description>
-                <_message>Authentication is required to acquire a pseudo TTY on the local host.</_message>
+                <description>Acquire a pseudo TTY on the local host</description>
+                <message>Authentication is required to acquire a pseudo TTY on the local host.</message>
                 <defaults>
                         <allow_any>auth_admin</allow_any>
                         <allow_inactive>auth_admin</allow_inactive>
@@ -79,8 +81,8 @@
         </action>
 
         <action id="org.freedesktop.machine1.manage-machines">
-                <_description>Manage local virtual machines and containers</_description>
-                <_message>Authentication is required to manage local virtual machines and containers.</_message>
+                <description>Manage local virtual machines and containers</description>
+                <message>Authentication is required to manage local virtual machines and containers.</message>
                 <defaults>
                         <allow_any>auth_admin</allow_any>
                         <allow_inactive>auth_admin</allow_inactive>
@@ -90,8 +92,8 @@
         </action>
 
         <action id="org.freedesktop.machine1.manage-images">
-                <_description>Manage local virtual machine and container images</_description>
-                <_message>Authentication is required to manage local virtual machine and container images.</_message>
+                <description>Manage local virtual machine and container images</description>
+                <message>Authentication is required to manage local virtual machine and container images.</message>
                 <defaults>
                         <allow_any>auth_admin</allow_any>
                         <allow_inactive>auth_admin</allow_inactive>
index d3dc998..d07bcae 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index f851a4d..fc08785 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd
 
index 6efebcd..c5f5768 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -29,6 +30,7 @@
 #include "fd-util.h"
 #include "fileio.h"
 #include "log.h"
+#include "module-util.h"
 #include "proc-cmdline.h"
 #include "string-util.h"
 #include "strv.h"
@@ -77,7 +79,8 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
 
 static int load_module(struct kmod_ctx *ctx, const char *m) {
         const int probe_flags = KMOD_PROBE_APPLY_BLACKLIST;
-        struct kmod_list *itr, *modlist = NULL;
+        struct kmod_list *itr;
+        _cleanup_(kmod_module_unref_listp) struct kmod_list *modlist = NULL;
         int r = 0;
 
         log_debug("load: %s", m);
@@ -92,7 +95,7 @@ static int load_module(struct kmod_ctx *ctx, const char *m) {
         }
 
         kmod_list_foreach(itr, modlist) {
-                struct kmod_module *mod;
+                _cleanup_(kmod_module_unrefp) struct kmod_module *mod = NULL;
                 int state, err;
 
                 mod = kmod_module_get_module(itr);
@@ -116,16 +119,20 @@ static int load_module(struct kmod_ctx *ctx, const char *m) {
                         else if (err == KMOD_PROBE_APPLY_BLACKLIST)
                                 log_info("Module '%s' is blacklisted", kmod_module_get_name(mod));
                         else {
-                                log_error_errno(err, "Failed to insert '%s': %m", kmod_module_get_name(mod));
-                                r = err;
+                                assert(err < 0);
+
+                                log_full_errno(err == ENODEV ? LOG_NOTICE :
+                                               err == ENOENT ? LOG_WARNING :
+                                                               LOG_ERR,
+                                               err,
+                                               "Failed to insert '%s': %m",
+                                               kmod_module_get_name(mod));
+                                if (!IN_SET(err, ENODEV, ENOENT))
+                                        r = err;
                         }
                 }
-
-                kmod_module_unref(mod);
         }
 
-        kmod_module_unref_list(modlist);
-
         return r;
 }
 
@@ -218,7 +225,7 @@ static int parse_argv(int argc, char *argv[]) {
 
 int main(int argc, char *argv[]) {
         int r, k;
-        struct kmod_ctx *ctx;
+        _cleanup_(kmod_unrefp) struct kmod_ctx *ctx = NULL;
 
         r = parse_argv(argc, argv);
         if (r <= 0)
@@ -280,7 +287,6 @@ int main(int argc, char *argv[]) {
         }
 
 finish:
-        kmod_unref(ctx);
         strv_free(arg_proc_cmdline_modules);
 
         return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
index 64438cd..da3647e 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -29,6 +30,7 @@
 #include "escape.h"
 #include "fd-util.h"
 #include "fileio.h"
+#include "fs-util.h"
 #include "fstab-util.h"
 #include "mount-util.h"
 #include "pager.h"
@@ -68,18 +70,7 @@ static bool arg_timeout_idle_set = false;
 static char **arg_automount_property = NULL;
 static int arg_bind_device = -1;
 static bool arg_fsck = true;
-
-static void polkit_agent_open_if_enabled(void) {
-
-        /* Open the polkit agent as a child process if necessary */
-        if (!arg_ask_password)
-                return;
-
-        if (arg_transport != BUS_TRANSPORT_LOCAL)
-                return;
-
-        polkit_agent_open();
-}
+static bool arg_aggressive_gc = false;
 
 static void help(void) {
         printf("systemd-mount [OPTIONS...] WHAT [WHERE]\n"
@@ -107,7 +98,8 @@ static void help(void) {
                "                                  Set automount unit property\n"
                "     --bind-device                Bind automount unit to device\n"
                "     --list                       List mountable block devices\n"
-               "  -u --umount                     Unmount mount points\n",
+               "  -u --umount                     Unmount mount points\n"
+               "  -G --collect                    Unload unit after it stopped, even when failed\n",
                program_invocation_short_name,
                streq(program_invocation_short_name, "systemd-umount") ? "" : "--umount ");
 }
@@ -157,6 +149,7 @@ static int parse_argv(int argc, char *argv[]) {
                 { "list",               no_argument,       NULL, ARG_LIST               },
                 { "umount",             no_argument,       NULL, 'u'                    },
                 { "unmount",            no_argument,       NULL, 'u'                    },
+                { "collect",            no_argument,       NULL, 'G'                    },
                 {},
         };
 
@@ -168,7 +161,7 @@ static int parse_argv(int argc, char *argv[]) {
         if (strstr(program_invocation_short_name, "systemd-umount"))
                         arg_action = ACTION_UMOUNT;
 
-        while ((c = getopt_long(argc, argv, "hqH:M:t:o:p:Au", options, NULL)) >= 0)
+        while ((c = getopt_long(argc, argv, "hqH:M:t:o:p:AuG", options, NULL)) >= 0)
 
                 switch (c) {
 
@@ -283,6 +276,10 @@ static int parse_argv(int argc, char *argv[]) {
                         arg_action = ACTION_UMOUNT;
                         break;
 
+                case 'G':
+                        arg_aggressive_gc = true;
+                        break;
+
                 case '?':
                         return -EINVAL;
 
@@ -337,19 +334,15 @@ static int parse_argv(int argc, char *argv[]) {
                                 return log_oom();
 
                 } else if (arg_transport == BUS_TRANSPORT_LOCAL) {
-                        _cleanup_free_ char *u = NULL, *p = NULL;
+                        _cleanup_free_ char *u = NULL;
 
                         u = fstab_node_to_udev_node(argv[optind]);
                         if (!u)
                                 return log_oom();
 
-                        r = path_make_absolute_cwd(u, &p);
+                        r = chase_symlinks(u, NULL, 0, &arg_mount_what);
                         if (r < 0)
-                                return log_error_errno(r, "Failed to make path absolute: %m");
-
-                        arg_mount_what = canonicalize_file_name(p);
-                        if (!arg_mount_what)
-                                return log_error_errno(errno, "Failed to canonicalize path: %m");
+                                return log_error_errno(r, "Failed to make path %s absolute: %m", u);
                 } else {
                         arg_mount_what = strdup(argv[optind]);
                         if (!arg_mount_what)
@@ -365,16 +358,9 @@ static int parse_argv(int argc, char *argv[]) {
 
                 if (argc > optind+1) {
                         if (arg_transport == BUS_TRANSPORT_LOCAL) {
-                                _cleanup_free_ char *p = NULL;
-
-                                r = path_make_absolute_cwd(argv[optind+1], &p);
+                                r = chase_symlinks(argv[optind+1], NULL, CHASE_NONEXISTENT, &arg_mount_where);
                                 if (r < 0)
-                                        return log_error_errno(r, "Failed to make path absolute: %m");
-
-                                arg_mount_where = canonicalize_file_name(p);
-                                if (!arg_mount_where)
-                                        return log_error_errno(errno, "Failed to canonicalize path: %m");
-
+                                        return log_error_errno(r, "Failed to make path %s absolute: %m", argv[optind+1]);
                         } else {
                                 arg_mount_where = strdup(argv[optind+1]);
                                 if (!arg_mount_where)
@@ -422,6 +408,12 @@ static int transient_unit_set_properties(sd_bus_message *m, char **properties) {
                         return r;
         }
 
+        if (arg_aggressive_gc) {
+                r = sd_bus_message_append(m, "(sv)", "CollectMode", "s", "inactive-or-failed");
+                if (r < 0)
+                        return r;
+        }
+
         r = bus_append_unit_property_assignment_many(m, properties);
         if (r < 0)
                 return r;
@@ -549,7 +541,7 @@ static int start_transient_mount(
         if (r < 0)
                 return bus_log_create_error(r);
 
-        polkit_agent_open_if_enabled();
+        polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
 
         r = sd_bus_call(bus, m, 0, &error, &reply);
         if (r < 0)
@@ -664,7 +656,7 @@ static int start_transient_automount(
         if (r < 0)
                 return bus_log_create_error(r);
 
-        polkit_agent_open_if_enabled();
+        polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
 
         r = sd_bus_call(bus, m, 0, &error, &reply);
         if (r < 0)
@@ -827,7 +819,7 @@ static int stop_mount(
 
         r = unit_name_from_path(where, suffix, &mount_unit);
         if (r < 0)
-                return log_error_errno(r, "Failed to make mount unit name from path %s: %m", where);
+                return log_error_errno(r, "Failed to make %s unit name from path %s: %m", suffix + 1, where);
 
         r = sd_bus_message_new_method_call(
                         bus,
@@ -848,11 +840,15 @@ static int stop_mount(
         if (r < 0)
                 return bus_log_create_error(r);
 
-        polkit_agent_open_if_enabled();
+        polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
 
         r = sd_bus_call(bus, m, 0, &error, &reply);
-        if (r < 0)
-                return log_error_errno(r, "Failed to stop mount unit: %s", bus_error_message(&error, r));
+        if (r < 0) {
+                if (streq(suffix, ".automount") &&
+                    sd_bus_error_has_name(&error, "org.freedesktop.systemd1.NoSuchUnit"))
+                        return 0;
+                return log_error_errno(r, "Failed to stop %s unit: %s", suffix + 1, bus_error_message(&error, r));
+        }
 
         if (w) {
                 const char *object;
@@ -885,8 +881,8 @@ static int stop_mounts(
                 return -EINVAL;
         }
 
-        if (!path_is_safe(where)) {
-                log_error("Path contains unsafe components: %s", where);
+        if (!path_is_normalized(where)) {
+                log_error("Path contains non-normalized components: %s", where);
                 return -EINVAL;
         }
 
@@ -989,26 +985,19 @@ static int action_umount(
         }
 
         for (i = optind; i < argc; i++) {
-                _cleanup_free_ char *u = NULL, *a = NULL, *p = NULL;
+                _cleanup_free_ char *u = NULL, *p = NULL;
                 struct stat st;
 
                 u = fstab_node_to_udev_node(argv[i]);
                 if (!u)
                         return log_oom();
 
-                r = path_make_absolute_cwd(u, &a);
+                r = chase_symlinks(u, NULL, 0, &p);
                 if (r < 0) {
                         r2 = log_error_errno(r, "Failed to make path %s absolute: %m", argv[i]);
                         continue;
                 }
 
-                p = canonicalize_file_name(a);
-
-                if (!p) {
-                        r2 = log_error_errno(errno, "Failed to canonicalize path %s: %m", argv[i]);
-                        continue;
-                }
-
                 if (stat(p, &st) < 0)
                         return log_error_errno(errno, "Can't stat %s (from %s): %m", p, argv[i]);
 
@@ -1567,8 +1556,8 @@ int main(int argc, char* argv[]) {
                 goto finish;
         }
 
-        if (!path_is_safe(arg_mount_what)) {
-                log_error("Path contains unsafe components: %s", arg_mount_what);
+        if (!path_is_normalized(arg_mount_what)) {
+                log_error("Path contains non-normalized components: %s", arg_mount_what);
                 r = -EINVAL;
                 goto finish;
         }
@@ -1591,8 +1580,8 @@ int main(int argc, char* argv[]) {
                 goto finish;
         }
 
-        if (!path_is_safe(arg_mount_where)) {
-                log_error("Path contains unsafe components: %s", arg_mount_where);
+        if (!path_is_normalized(arg_mount_where)) {
+                log_error("Path contains non-normalized components: %s", arg_mount_where);
                 r = -EINVAL;
                 goto finish;
         }
@@ -1631,8 +1620,6 @@ int main(int argc, char* argv[]) {
         }
 
 finish:
-        bus = sd_bus_flush_close_unref(bus);
-
         pager_close();
 
         free(arg_mount_what);
index 38c2220..f97484e 100644 (file)
@@ -1,3 +1,20 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
+# Copyright 2017 Zbigniew Jędrzejewski-Szmek
+#
+# 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.
+#
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
 sources = files('''
         netdev/bond.c
         netdev/bond.h
@@ -27,6 +44,8 @@ sources = files('''
         netdev/vxlan.h
         netdev/geneve.c
         netdev/geneve.h
+        netdev/vxcan.c
+        netdev/vxcan.h
         networkd-address-label.c
         networkd-address-label.h
         networkd-address-pool.c
@@ -137,6 +156,12 @@ if conf.get('ENABLE_NETWORKD') == 1
       libshared],
      [threads]],
 
+    [['src/network/test-routing-policy-rule.c'],
+     [libnetworkd_core,
+      libsystemd_network,
+      libudev],
+     []],
+
     [['src/network/test-network-tables.c',
       'src/network/test-network-tables.c',
       test_tables_h],
index 19b0e8d..f6c9ceb 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
     This file is part of systemd.
 
index fb88b53..31be5b8 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 16fff78..00d4d30 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
     This file is part of systemd.
 
@@ -91,7 +92,7 @@ static int netdev_bridge_post_create(NetDev *netdev, Link *link, sd_netlink_mess
                         return log_netdev_error_errno(netdev, r, "Could not append IFLA_BR_MAX_AGE attribute: %m");
         }
 
-        if (b->ageing_time > 0) {
+        if (b->ageing_time != USEC_INFINITY) {
                 r = sd_netlink_message_append_u32(req, IFLA_BR_AGEING_TIME, usec_to_jiffies(b->ageing_time));
                 if (r < 0)
                         return log_netdev_error_errno(netdev, r, "Could not append IFLA_BR_AGEING_TIME attribute: %m");
@@ -169,6 +170,7 @@ static void bridge_init(NetDev *n) {
         b->stp = -1;
         b->default_pvid = VLANID_INVALID;
         b->forward_delay = USEC_INFINITY;
+        b->ageing_time = USEC_INFINITY;
 }
 
 const NetDevVTable bridge_vtable = {
index b303cfd..7fc993b 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 5e6e162..c550090 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
     This file is part of systemd.
 
index a908400..abfb7c7 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index e71ea58..1d50963 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
     This file is part of systemd.
 
index bde28ba..9aec8f5 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 3b5c30f..df94874 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 7d7d018..cb43db4 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 93f650d..9924e16 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 118d556..7d6d346 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 002efd7..628e664 100644 (file)
@@ -1,4 +1,7 @@
 %{
+#if __GNUC__ >= 7
+_Pragma("GCC diagnostic ignored \"-Wimplicit-fallthrough\"")
+#endif
 #include <stddef.h>
 #include "conf-parser.h"
 #include "network-internal.h"
@@ -14,6 +17,7 @@
 #include "netdev/vxlan.h"
 #include "netdev/vrf.h"
 #include "netdev/netdev.h"
+#include "netdev/vxcan.h"
 #include "vlan-util.h"
 %}
 struct ConfigPerfItem;
@@ -59,6 +63,7 @@ Tunnel.EncapsulationLimit,   config_parse_encap_limit,             0,
 Tunnel.Independent,          config_parse_bool,                    0,                             offsetof(Tunnel, independent)
 Peer.Name,                   config_parse_ifname,                  0,                             offsetof(Veth, ifname_peer)
 Peer.MACAddress,             config_parse_hwaddr,                  0,                             offsetof(Veth, mac_peer)
+VXCAN.Peer,                  config_parse_ifname,                  0,                             offsetof(VxCan, ifname_peer)
 VXLAN.Id,                    config_parse_uint64,                  0,                             offsetof(VxLan, id)
 VXLAN.Group,                 config_parse_vxlan_address,           0,                             offsetof(VxLan, remote)
 VXLAN.Local,                 config_parse_vxlan_address,           0,                             offsetof(VxLan, local)
index 0e1a7d1..5530760 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -47,6 +48,7 @@
 #include "netdev/dummy.h"
 #include "netdev/vrf.h"
 #include "netdev/vcan.h"
+#include "netdev/vxcan.h"
 
 const NetDevVTable * const netdev_vtable[_NETDEV_KIND_MAX] = {
         [NETDEV_KIND_BRIDGE] = &bridge_vtable,
@@ -72,6 +74,7 @@ const NetDevVTable * const netdev_vtable[_NETDEV_KIND_MAX] = {
         [NETDEV_KIND_VRF] = &vrf_vtable,
         [NETDEV_KIND_VCAN] = &vcan_vtable,
         [NETDEV_KIND_GENEVE] = &geneve_vtable,
+        [NETDEV_KIND_VXCAN] = &vxcan_vtable,
 };
 
 static const char* const netdev_kind_table[_NETDEV_KIND_MAX] = {
@@ -98,6 +101,7 @@ static const char* const netdev_kind_table[_NETDEV_KIND_MAX] = {
         [NETDEV_KIND_VRF] = "vrf",
         [NETDEV_KIND_VCAN] = "vcan",
         [NETDEV_KIND_GENEVE] = "geneve",
+        [NETDEV_KIND_VXCAN] = "vxcan",
 };
 
 DEFINE_STRING_TABLE_LOOKUP(netdev_kind, NetDevKind);
@@ -630,7 +634,7 @@ static int netdev_load_one(Manager *manager, const char *filename) {
         r = config_parse_many(filename, network_dirs, dropin_dirname,
                               "Match\0NetDev\0",
                               config_item_perf_lookup, network_netdev_gperf_lookup,
-                              true, netdev_raw);
+                              CONFIG_PARSE_WARN, netdev_raw);
         if (r < 0)
                 return r;
 
@@ -671,7 +675,7 @@ static int netdev_load_one(Manager *manager, const char *filename) {
         r = config_parse(NULL, filename, file,
                          NETDEV_VTABLE(netdev)->sections,
                          config_item_perf_lookup, network_netdev_gperf_lookup,
-                         false, false, false, netdev);
+                         CONFIG_PARSE_WARN, netdev);
         if (r < 0)
                 return r;
 
index a961e2a..ec65251 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -58,6 +59,7 @@ typedef enum NetDevKind {
         NETDEV_KIND_VRF,
         NETDEV_KIND_VCAN,
         NETDEV_KIND_GENEVE,
+        NETDEV_KIND_VXCAN,
         _NETDEV_KIND_MAX,
         _NETDEV_KIND_INVALID = -1
 } NetDevKind;
index 64d87e5..8d6d54d 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
     This file is part of systemd.
 
@@ -243,7 +244,6 @@ static int netdev_vti_fill_message_create(NetDev *netdev, Link *link, sd_netlink
         int r;
 
         assert(netdev);
-        assert(link);
         assert(m);
         assert(t);
         assert(t->family == AF_INET);
index 53690d9..67f8fe3 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 3d62808..4597a7f 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
     This file is part of systemd.
 
index 95d3fcf..dbfa3de 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 7f56702..780cf91 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 00838b7..6c4d68e 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 350b59b..9220b32 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
     This file is part of systemd.
 
index b00ce47..bb2139f 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 6f41633..3a0100d 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 780d612..c4688d9 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index a3b271c..5e04bbd 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
     This file is part of systemd.
 
index 06f3c17..58f4ef3 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
diff --git a/src/network/netdev/vxcan.c b/src/network/netdev/vxcan.c
new file mode 100644 (file)
index 0000000..a41ca7e
--- /dev/null
@@ -0,0 +1,89 @@
+/***
+  This file is part of systemd.
+
+  Copyright 2017 Susant Sahani
+
+  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.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "netdev/vxcan.h"
+#include "missing.h"
+
+static int netdev_vxcan_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
+        VxCan *v;
+        int r;
+
+        assert(netdev);
+        assert(!link);
+        assert(m);
+
+        v = VXCAN(netdev);
+
+        assert(v);
+
+        r = sd_netlink_message_open_container(m, VXCAN_INFO_PEER);
+        if (r < 0)
+                return log_netdev_error_errno(netdev, r, "Could not append VXCAN_INFO_PEER attribute: %m");
+
+        if (v->ifname_peer) {
+                r = sd_netlink_message_append_string(m, IFLA_IFNAME, v->ifname_peer);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to add vxcan netlink interface peer name: %m");
+        }
+
+        r = sd_netlink_message_close_container(m);
+        if (r < 0)
+                return log_netdev_error_errno(netdev, r, "Could not append VXCAN_INFO_PEER attribute: %m");
+
+        return r;
+}
+
+static int netdev_vxcan_verify(NetDev *netdev, const char *filename) {
+        VxCan *v;
+
+        assert(netdev);
+        assert(filename);
+
+        v = VXCAN(netdev);
+
+        assert(v);
+
+        if (!v->ifname_peer) {
+                log_warning("VxCan NetDev without peer name configured in %s. Ignoring", filename);
+                return -EINVAL;
+        }
+
+        return 0;
+}
+
+static void vxcan_done(NetDev *n) {
+        VxCan *v;
+
+        assert(n);
+
+        v = VXCAN(n);
+
+        assert(v);
+
+        free(v->ifname_peer);
+}
+
+const NetDevVTable vxcan_vtable = {
+        .object_size = sizeof(VxCan),
+        .sections = "Match\0NetDev\0VXCAN\0",
+        .done = vxcan_done,
+        .fill_message_create = netdev_vxcan_fill_message_create,
+        .create_type = NETDEV_CREATE_INDEPENDENT,
+        .config_verify = netdev_vxcan_verify,
+};
diff --git a/src/network/netdev/vxcan.h b/src/network/netdev/vxcan.h
new file mode 100644 (file)
index 0000000..f372135
--- /dev/null
@@ -0,0 +1,38 @@
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2017 Susant Sahani
+
+  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.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+typedef struct VxCan VxCan;
+
+#if HAVE_VXCAN_INFO_PEER
+#include <linux/can/vxcan.h>
+#endif
+
+#include "netdev/netdev.h"
+
+struct VxCan {
+        NetDev meta;
+
+        char *ifname_peer;
+};
+
+DEFINE_NETDEV_CAST(VXCAN, VxCan);
+
+extern const NetDevVTable vxcan_vtable;
index b5b7aec..580e5e6 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
     This file is part of systemd.
 
index 1eeda02..3bb8884 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index e4b95e4..59ce098 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -339,7 +340,7 @@ static int list_links(int argc, char *argv[], void *userdata) {
 /* IEEE Organizationally Unique Identifier vendor string */
 static int ieee_oui(sd_hwdb *hwdb, const struct ether_addr *mac, char **ret) {
         const char *description;
-        char modalias[strlen("OUI:XXYYXXYYXXYY") + 1], *desc;
+        char modalias[STRLEN("OUI:XXYYXXYYXXYY") + 1], *desc;
         int r;
 
         assert(ret);
index b89995e..4fd5fa4 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 8724ea8..9ddf707 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index a63b925..22582ab 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index af30dec..1fcff09 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 214192f..ff125e3 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -151,7 +152,7 @@ static void address_hash_func(const void *b, struct siphash *state) {
                         siphash24_compress(&prefix, sizeof(prefix), state);
                 }
 
-                /* fallthrough */
+                _fallthrough_;
         case AF_INET6:
                 /* local address */
                 siphash24_compress(&a->in_addr, FAMILY_ADDRESS_SIZE(a->family), state);
@@ -201,7 +202,7 @@ static int address_compare_func(const void *c1, const void *c2) {
                                 return 1;
                 }
 
-                /* fall-through */
+                _fallthrough_;
         case AF_INET6:
                 return memcmp(&a1->in_addr, &a2->in_addr, FAMILY_ADDRESS_SIZE(a1->family));
         default:
@@ -513,7 +514,10 @@ static int address_acquire(Link *link, Address *original, Address **ret) {
                 in_addr.in.s_addr = in_addr.in.s_addr | htobe32(1);
 
                 /* .. and use last as broadcast address */
-                broadcast.s_addr = in_addr.in.s_addr | htobe32(0xFFFFFFFFUL >> original->prefixlen);
+                if (original->prefixlen > 30)
+                        broadcast.s_addr = 0;
+                else
+                        broadcast.s_addr = in_addr.in.s_addr | htobe32(0xFFFFFFFFUL >> original->prefixlen);
         } else if (original->family == AF_INET6)
                 in_addr.in6.s6_addr[15] |= 1;
 
@@ -628,9 +632,11 @@ int address_configure(
                         return log_error_errno(r, "Could not append IFA_ADDRESS attribute: %m");
         } else {
                 if (address->family == AF_INET) {
-                        r = sd_netlink_message_append_in_addr(req, IFA_BROADCAST, &address->broadcast);
-                        if (r < 0)
-                                return log_error_errno(r, "Could not append IFA_BROADCAST attribute: %m");
+                        if (address->prefixlen <= 30) {
+                                r = sd_netlink_message_append_in_addr(req, IFA_BROADCAST, &address->broadcast);
+                                if (r < 0)
+                                        return log_error_errno(r, "Could not append IFA_BROADCAST attribute: %m");
+                        }
                 }
         }
 
@@ -973,7 +979,10 @@ int config_parse_address_scope(const char *unit,
 bool address_is_ready(const Address *a) {
         assert(a);
 
-        return !(a->flags & (IFA_F_TENTATIVE | IFA_F_DEPRECATED));
+        if (a->family == AF_INET6)
+                return !(a->flags & IFA_F_TENTATIVE);
+        else
+                return !(a->flags & (IFA_F_TENTATIVE | IFA_F_DEPRECATED));
 }
 
 int config_parse_router_preference(const char *unit,
@@ -1026,7 +1035,7 @@ void prefix_free(Prefix *prefix) {
 }
 
 int prefix_new(Prefix **ret) {
-        Prefix *prefix = NULL;
+        _cleanup_prefix_free_ Prefix *prefix = NULL;
 
         prefix = new0(Prefix, 1);
         if (!prefix)
index 3281c6d..3f5dffa 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index fa5d3ee..99dd416 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -141,7 +142,7 @@ static int append_vlan_info_data(Link *const link, sd_netlink_message *req, uint
 
                 next:
                         i = j;
-                } while(!done);
+                } while (!done);
         }
         if (!cnt)
                 return -EINVAL;
index b37633f..be99436 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 0256624..1f791fc 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -35,7 +36,7 @@ int manager_parse_config_file(Manager *m) {
                                         CONF_PATHS_NULSTR("systemd/networkd.conf.d"),
                                         "DHCP\0",
                                         config_item_perf_lookup, networkd_gperf_lookup,
-                                        false, m);
+                                        CONFIG_PARSE_WARN, m);
 }
 
 static const char* const duid_type_table[_DUID_TYPE_MAX] = {
index 1136975..8d93cff 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index e1e3e88..0b46deb 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
 #include "alloc-util.h"
 #include "dhcp-lease-internal.h"
 #include "hostname-util.h"
+#include "parse-util.h"
 #include "netdev/vrf.h"
 #include "network-internal.h"
 #include "networkd-link.h"
 #include "networkd-manager.h"
 #include "networkd-network.h"
+#include "string-util.h"
+#include "sysctl-util.h"
 
 static int dhcp4_route_handler(sd_netlink *rtnl, sd_netlink_message *m,
                                void *userdata) {
@@ -93,11 +97,42 @@ static int link_set_dhcp_routes(Link *link) {
         if (r < 0)
                 return log_link_warning_errno(link, r, "DHCP error: could not get address: %m");
 
-        r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
-        if (r < 0 && r != -ENODATA)
-                return log_link_warning_errno(link, r, "DHCP error: could not get gateway: %m");
+        n = sd_dhcp_lease_get_routes(link->dhcp_lease, &static_routes);
+        if (n < 0)
+                log_link_debug_errno(link, n, "DHCP error: could not get routes: %m");
 
-        if (r >= 0) {
+        for (i = 0; i < n; i++) {
+                _cleanup_route_free_ Route *route = NULL;
+
+                r = route_new(&route);
+                if (r < 0)
+                        return log_link_error_errno(link, r, "Could not allocate route: %m");
+
+                route->family = AF_INET;
+                route->protocol = RTPROT_DHCP;
+                assert_se(sd_dhcp_route_get_gateway(static_routes[i], &route->gw.in) >= 0);
+                assert_se(sd_dhcp_route_get_destination(static_routes[i], &route->dst.in) >= 0);
+                assert_se(sd_dhcp_route_get_destination_prefix_length(static_routes[i], &route->dst_prefixlen) >= 0);
+                route->priority = link->network->dhcp_route_metric;
+                route->table = table;
+                route->scope = route_scope_from_address(route, &address);
+
+                r = route_configure(route, link, dhcp4_route_handler);
+                if (r < 0)
+                        return log_link_warning_errno(link, r, "Could not set host route: %m");
+
+                link->dhcp4_messages++;
+        }
+
+        r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
+        if (r == -ENODATA)
+                log_link_info_errno(link, r, "DHCP: No routes received from DHCP server: %m");
+        else if (r < 0)
+                log_link_warning_errno(link, r, "DHCP error: could not get gateway: %m");
+
+        /* According to RFC 3442: If the DHCP server returns both a Classless Static Routes option and
+           a Router option, the DHCP client MUST ignore the Router option. */
+        if (r >= 0 && link->dhcp4_messages <= 0) {
                 _cleanup_route_free_ Route *route = NULL;
                 _cleanup_route_free_ Route *route_gw = NULL;
 
@@ -145,35 +180,6 @@ static int link_set_dhcp_routes(Link *link) {
                 link->dhcp4_messages++;
         }
 
-        n = sd_dhcp_lease_get_routes(link->dhcp_lease, &static_routes);
-        if (n == -ENODATA)
-                return 0;
-        if (n < 0)
-                return log_link_warning_errno(link, n, "DHCP error: could not get routes: %m");
-
-        for (i = 0; i < n; i++) {
-                _cleanup_route_free_ Route *route = NULL;
-
-                r = route_new(&route);
-                if (r < 0)
-                        return log_link_error_errno(link, r, "Could not allocate route: %m");
-
-                route->family = AF_INET;
-                route->protocol = RTPROT_DHCP;
-                assert_se(sd_dhcp_route_get_gateway(static_routes[i], &route->gw.in) >= 0);
-                assert_se(sd_dhcp_route_get_destination(static_routes[i], &route->dst.in) >= 0);
-                assert_se(sd_dhcp_route_get_destination_prefix_length(static_routes[i], &route->dst_prefixlen) >= 0);
-                route->priority = link->network->dhcp_route_metric;
-                route->table = table;
-                route->scope = route_scope_from_address(route, &address);
-
-                r = route_configure(route, link, dhcp4_route_handler);
-                if (r < 0)
-                        return log_link_warning_errno(link, r, "Could not set host route: %m");
-
-                link->dhcp4_messages++;
-        }
-
         return 0;
 }
 
@@ -456,12 +462,21 @@ static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
         }
 
         if (link->network->dhcp_use_hostname) {
-                const char *hostname = NULL;
+                const char *dhcpname = NULL;
+                _cleanup_free_ char *hostname = NULL;
 
                 if (link->network->dhcp_hostname)
-                        hostname = link->network->dhcp_hostname;
+                        dhcpname = link->network->dhcp_hostname;
                 else
-                        (void) sd_dhcp_lease_get_hostname(lease, &hostname);
+                        (void) sd_dhcp_lease_get_hostname(lease, &dhcpname);
+
+                if (dhcpname) {
+                        r = shorten_overlong(dhcpname, &hostname);
+                        if (r < 0)
+                                log_link_warning_errno(link, r, "Unable to shorten overlong DHCP hostname '%s', ignoring: %m", dhcpname);
+                        if (r == 1)
+                                log_link_notice(link, "Overlong DCHP hostname received, shortened from '%s' to '%s'", dhcpname, hostname);
+                }
 
                 if (hostname) {
                         r = manager_set_hostname(link->manager, hostname);
@@ -583,6 +598,59 @@ static int dhcp4_set_hostname(Link *link) {
         return sd_dhcp_client_set_hostname(link->dhcp_client, hn);
 }
 
+static bool promote_secondaries_enabled(const char *ifname) {
+        _cleanup_free_ char *promote_secondaries_sysctl = NULL;
+        char *promote_secondaries_path;
+        int r;
+
+        promote_secondaries_path = strjoina("net/ipv4/conf/", ifname, "/promote_secondaries");
+        r = sysctl_read(promote_secondaries_path, &promote_secondaries_sysctl);
+        if (r < 0) {
+                log_debug_errno(r, "Cannot read sysctl %s", promote_secondaries_path);
+                return false;
+        }
+
+        truncate_nl(promote_secondaries_sysctl);
+        r = parse_boolean(promote_secondaries_sysctl);
+        if (r < 0)
+                log_warning_errno(r, "Cannot parse sysctl %s with content %s as boolean", promote_secondaries_path, promote_secondaries_sysctl);
+        return r > 0;
+}
+
+/* dhcp4_set_promote_secondaries will ensure this interface has
+ * the "promote_secondaries" option in the kernel set. If this sysctl
+ * is not set DHCP will work only as long as the IP address does not
+ * changes between leases. The kernel will remove all secondary IP
+ * addresses of an interface otherwise. The way systemd-network works
+ * is that the new IP of a lease is added as a secondary IP and when
+ * the primary one expires it relies on the kernel to promote the
+ * secondary IP. See also https://github.com/systemd/systemd/issues/7163
+ */
+int dhcp4_set_promote_secondaries(Link *link) {
+        int r;
+
+        assert(link);
+        assert(link->network);
+        assert(link->network->dhcp & ADDRESS_FAMILY_IPV4);
+
+        /* check if the kernel has promote_secondaries enabled for our
+         * interface. If it is not globally enabled or enabled for the
+         * specific interface we must either enable it.
+         */
+        if (!(promote_secondaries_enabled("all") || promote_secondaries_enabled(link->ifname))) {
+                char *promote_secondaries_path = NULL;
+
+                log_link_debug(link, "promote_secondaries is unset, setting it");
+                promote_secondaries_path = strjoina("net/ipv4/conf/", link->ifname, "/promote_secondaries");
+                r = sysctl_write(promote_secondaries_path, "1");
+                if (r < 0)
+                        log_link_warning_errno(link, r, "cannot set sysctl %s to 1", promote_secondaries_path);
+                return r > 0;
+        }
+
+        return 0;
+}
+
 int dhcp4_configure(Link *link) {
         int r;
 
@@ -632,11 +700,11 @@ int dhcp4_configure(Link *link) {
                         return r;
         }
 
-        /* NOTE: when using Anonymity Profiles, routes PRL options are sent
-         * by default, so they should not be added again here. */
         /* NOTE: even if this variable is called "use", it also "sends" PRL
          * options, maybe there should be a different configuration variable
          * to send or not route options?. */
+        /* NOTE: when using Anonymize=yes, routes PRL options are sent
+         * by default, so they don't need to be added here. */
         if (link->network->dhcp_use_routes && !link->network->dhcp_anonymize) {
                 r = sd_dhcp_client_set_request_option(link->dhcp_client,
                                                       SD_DHCP_OPTION_STATIC_ROUTE);
index 6ba2d17..a46a11b 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -22,6 +23,7 @@
 
 #include "sd-dhcp6-client.h"
 
+#include "hostname-util.h"
 #include "network-internal.h"
 #include "networkd-link.h"
 #include "networkd-manager.h"
@@ -147,7 +149,7 @@ static void dhcp6_handler(sd_dhcp6_client *client, int event, void *userdata) {
                         return;
                 }
 
-                /* fall through */
+                _fallthrough_;
         case SD_DHCP6_CLIENT_EVENT_INFORMATION_REQUEST:
                 r = dhcp6_lease_information_acquired(client, link);
                 if (r < 0) {
@@ -211,6 +213,28 @@ int dhcp6_request_address(Link *link, int ir) {
         return 0;
 }
 
+static int dhcp6_set_hostname(sd_dhcp6_client *client, Link *link) {
+        _cleanup_free_ char *hostname = NULL;
+        const char *hn;
+        int r;
+
+        assert(link);
+
+        if (!link->network->dhcp_send_hostname)
+                hn = NULL;
+        else if (link->network->dhcp_hostname)
+                hn = link->network->dhcp_hostname;
+        else {
+                r = gethostname_strict(&hostname);
+                if (r < 0 && r != -ENXIO) /* ENXIO: no hostname set or hostname is "localhost" */
+                        return r;
+
+                hn = hostname;
+        }
+
+        return sd_dhcp6_client_set_fqdn(client, hn);
+}
+
 int dhcp6_configure(Link *link) {
         sd_dhcp6_client *client = NULL;
         int r;
@@ -247,6 +271,10 @@ int dhcp6_configure(Link *link) {
         if (r < 0)
                 goto error;
 
+        r = dhcp6_set_hostname(client, link);
+        if (r < 0)
+                goto error;
+
         r = sd_dhcp6_client_set_ifindex(client, link->ifindex);
         if (r < 0)
                 goto error;
index 3d7f4d2..380581e 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 2d7d287..d34d3e5 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index eca436d..5416144 100644 (file)
@@ -1,4 +1,7 @@
 %{
+#if __GNUC__ >= 7
+_Pragma("GCC diagnostic ignored \"-Wimplicit-fallthrough\"")
+#endif
 #include <stddef.h>
 #include "conf-parser.h"
 #include "networkd-conf.h"
index d2b1010..e3ebbdd 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 00790c0..31b7c6b 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -28,6 +29,7 @@
 #include "networkd-manager.h"
 #include "networkd-network.h"
 #include "string-util.h"
+#include "socket-util.h"
 
 static bool ipv6_proxy_ndp_is_needed(Link *link) {
         assert(link);
@@ -38,7 +40,7 @@ static bool ipv6_proxy_ndp_is_needed(Link *link) {
         if (!link->network)
                 return false;
 
-        if (link->network->ipv6_proxy_ndp != -1)
+        if (link->network->ipv6_proxy_ndp >= 0)
                 return link->network->ipv6_proxy_ndp;
 
         if (link->network->n_ipv6_proxy_ndp_addresses == 0)
@@ -53,6 +55,9 @@ static int ipv6_proxy_ndp_set(Link *link) {
 
         assert(link);
 
+        if (!socket_ipv6_is_supported())
+                return 0;
+
         v = ipv6_proxy_ndp_is_needed(link);
         p = strjoina("/proc/sys/net/ipv6/conf/", link->ifname, "/proxy_ndp");
 
@@ -198,6 +203,8 @@ int ipv6_proxy_ndp_addresses_configure(Link *link) {
         IPv6ProxyNDPAddress *ipv6_proxy_ndp_address;
         int r;
 
+        assert(link);
+
         /* enable or disable proxy_ndp itself depending on whether ipv6_proxy_ndp_addresses are set or not */
         r = ipv6_proxy_ndp_set(link);
         if (r != 0)
index f09169f..ac24c58 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index c39c648..2f4850b 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 6b59127..60ac980 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -20,6 +21,7 @@
 #include <netinet/ether.h>
 #include <linux/if.h>
 #include <unistd.h>
+#include <stdio_ext.h>
 
 #include "alloc-util.h"
 #include "bus-util.h"
@@ -226,6 +228,9 @@ static bool link_ipv6_accept_ra_enabled(Link *link) {
         if (!link->network)
                 return false;
 
+        if (!link_ipv6ll_enabled(link))
+                return false;
+
         /* If unset use system default (enabled if local forwarding is disabled.
          * disabled if local forwarding is enabled).
          * If set, ignore or enforce RA independent of local forwarding state.
@@ -735,7 +740,10 @@ void link_check_ready(Link *link) {
         if (!link->network)
                 return;
 
-        if (!link->static_configured)
+        if (!link->static_routes_configured)
+                return;
+
+        if (!link->routing_policy_rules_configured)
                 return;
 
         if (link_ipv4ll_enabled(link))
@@ -743,20 +751,23 @@ void link_check_ready(Link *link) {
                     !link->ipv4ll_route)
                         return;
 
-        if (link_ipv6ll_enabled(link))
-                if (in_addr_is_null(AF_INET6, (const union in_addr_union*) &link->ipv6ll_address) > 0)
-                        return;
+        if (!link->network->bridge) {
 
-        if ((link_dhcp4_enabled(link) && !link_dhcp6_enabled(link) &&
-             !link->dhcp4_configured) ||
-            (link_dhcp6_enabled(link) && !link_dhcp4_enabled(link) &&
-             !link->dhcp6_configured) ||
-            (link_dhcp4_enabled(link) && link_dhcp6_enabled(link) &&
-             !link->dhcp4_configured && !link->dhcp6_configured))
-                return;
+                if (link_ipv6ll_enabled(link))
+                        if (in_addr_is_null(AF_INET6, (const union in_addr_union*) &link->ipv6ll_address) > 0)
+                                return;
 
-        if (link_ipv6_accept_ra_enabled(link) && !link->ndisc_configured)
-                return;
+                if ((link_dhcp4_enabled(link) && !link_dhcp6_enabled(link) &&
+                     !link->dhcp4_configured) ||
+                    (link_dhcp6_enabled(link) && !link_dhcp4_enabled(link) &&
+                     !link->dhcp6_configured) ||
+                    (link_dhcp4_enabled(link) && link_dhcp6_enabled(link) &&
+                     !link->dhcp4_configured && !link->dhcp6_configured))
+                        return;
+
+                if (link_ipv6_accept_ra_enabled(link) && !link->ndisc_configured)
+                        return;
+        }
 
         SET_FOREACH(a, link->addresses, i)
                 if (!address_is_ready(a))
@@ -768,16 +779,51 @@ void link_check_ready(Link *link) {
         return;
 }
 
+static int link_set_routing_policy_rule(Link *link) {
+        RoutingPolicyRule *rule, *rrule = NULL;
+        int r;
+
+        assert(link);
+        assert(link->network);
+
+        LIST_FOREACH(rules, rule, link->network->rules) {
+                r = routing_policy_rule_get(link->manager, rule->family, &rule->from, rule->from_prefixlen, &rule->to,
+                                            rule->to_prefixlen, rule->tos, rule->fwmark, rule->table, rule->iif, rule->oif, &rrule);
+                if (r == 1) {
+                        (void) routing_policy_rule_make_local(link->manager, rrule);
+                        continue;
+                }
+
+                r = routing_policy_rule_configure(rule, link, link_routing_policy_rule_handler, false);
+                if (r < 0) {
+                        log_link_warning_errno(link, r, "Could not set routing policy rules: %m");
+                        link_enter_failed(link);
+                        return r;
+                }
+
+                link->routing_policy_rule_messages++;
+        }
+
+        routing_policy_rule_purge(link->manager, link);
+        if (link->routing_policy_rule_messages == 0) {
+                link->routing_policy_rules_configured = true;
+                link_check_ready(link);
+        } else
+                log_link_debug(link, "Setting routing policy rules");
+
+        return 0;
+}
+
 static int route_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
         _cleanup_link_unref_ Link *link = userdata;
         int r;
 
-        assert(link->link_messages > 0);
+        assert(link->route_messages > 0);
         assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
                       LINK_STATE_SETTING_ROUTES, LINK_STATE_FAILED,
                       LINK_STATE_LINGER));
 
-        link->link_messages--;
+        link->route_messages--;
 
         if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
                 return 1;
@@ -786,9 +832,9 @@ static int route_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata
         if (r < 0 && r != -EEXIST)
                 log_link_warning_errno(link, r, "Could not set route: %m");
 
-        if (link->link_messages == 0) {
+        if (link->route_messages == 0) {
                 log_link_debug(link, "Routes set");
-                link->static_configured = true;
+                link->static_routes_configured = true;
                 link_check_ready(link);
         }
 
@@ -813,11 +859,13 @@ static int link_enter_set_routes(Link *link) {
                         return r;
                 }
 
-                link->link_messages++;
+                link->route_messages++;
         }
 
-        if (link->link_messages == 0) {
-                link->static_configured = true;
+        (void) link_set_routing_policy_rule(link);
+
+        if (link->route_messages == 0) {
+                link->static_routes_configured = true;
                 link_check_ready(link);
         } else
                 log_link_debug(link, "Setting routes");
@@ -851,11 +899,11 @@ static int address_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userda
         assert(m);
         assert(link);
         assert(link->ifname);
-        assert(link->link_messages > 0);
+        assert(link->address_messages > 0);
         assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
                LINK_STATE_FAILED, LINK_STATE_LINGER));
 
-        link->link_messages--;
+        link->address_messages--;
 
         if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
                 return 1;
@@ -866,7 +914,7 @@ static int address_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userda
         else if (r >= 0)
                 manager_rtnl_process_address(rtnl, m, link->manager);
 
-        if (link->link_messages == 0) {
+        if (link->address_messages == 0) {
                 log_link_debug(link, "Addresses set");
                 link_enter_set_routes(link);
         }
@@ -882,9 +930,9 @@ static int address_label_handler(sd_netlink *rtnl, sd_netlink_message *m, void *
         assert(m);
         assert(link);
         assert(link->ifname);
-        assert(link->link_messages > 0);
+        assert(link->address_label_messages > 0);
 
-        link->link_messages--;
+        link->address_label_messages--;
 
         if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
                 return 1;
@@ -895,10 +943,8 @@ static int address_label_handler(sd_netlink *rtnl, sd_netlink_message *m, void *
         else if (r >= 0)
                 manager_rtnl_process_address(rtnl, m, link->manager);
 
-        if (link->link_messages == 0) {
+        if (link->address_label_messages == 0)
                 log_link_debug(link, "Addresses label set");
-                link_enter_set_routes(link);
-        }
 
         return 1;
 }
@@ -1015,7 +1061,6 @@ static int link_set_bridge_fdb(Link *link) {
 }
 
 static int link_enter_set_addresses(Link *link) {
-        RoutingPolicyRule *rule, *rrule = NULL;
         AddressLabel *label;
         Address *ad;
         int r;
@@ -1038,7 +1083,7 @@ static int link_enter_set_addresses(Link *link) {
                         return r;
                 }
 
-                link->link_messages++;
+                link->address_messages++;
         }
 
         LIST_FOREACH(labels, label, link->network->address_labels) {
@@ -1049,29 +1094,9 @@ static int link_enter_set_addresses(Link *link) {
                         return r;
                 }
 
-                link->link_messages++;
-        }
-
-        LIST_FOREACH(rules, rule, link->network->rules) {
-                r = routing_policy_rule_get(link->manager, rule->family, &rule->from, rule->from_prefixlen, &rule->to,
-                                            rule->to_prefixlen, rule->tos, rule->fwmark, rule->table, &rrule);
-                if (r == 1) {
-                        (void) routing_policy_rule_make_local(link->manager, rrule);
-                        continue;
-                }
-
-                r = routing_policy_rule_configure(rule, link, link_routing_policy_rule_handler, false);
-                if (r < 0) {
-                        log_link_warning_errno(link, r, "Could not set routing policy rules: %m");
-                        link_enter_failed(link);
-                        return r;
-                }
-
-                link->link_messages++;
+                link->address_label_messages++;
         }
 
-        routing_policy_rule_purge(link->manager, link);
-
         /* now that we can figure out a default address for the dhcp server,
            start it */
         if (link_dhcp4_server_enabled(link)) {
@@ -1192,7 +1217,7 @@ static int link_enter_set_addresses(Link *link) {
                 log_link_debug(link, "Offering DHCPv4 leases");
         }
 
-        if (link->link_messages == 0)
+        if (link->address_messages == 0)
                 link_enter_set_routes(link);
         else
                 log_link_debug(link, "Setting addresses");
@@ -1300,6 +1325,8 @@ int link_set_mtu(Link *link, uint32_t mtu) {
         if (r < 0)
                 return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
 
+        link->setting_mtu = true;
+
         link_ref(link);
 
         return 0;
@@ -1646,6 +1673,11 @@ static int link_acquire_conf(Link *link) {
 
         assert(link);
 
+        if (link->setting_mtu) {
+                link->setting_mtu = false;
+                return 0;
+        }
+
         r = link_acquire_ipv4_conf(link);
         if (r < 0)
                 return r;
@@ -2276,6 +2308,11 @@ static int link_enter_join_netdev(Link *link) {
 
         HASHMAP_FOREACH(netdev, link->network->stacked_netdevs, i) {
 
+                if (netdev->ifindex > 0) {
+                        link_joined(link);
+                        continue;
+                }
+
                 log_struct(LOG_DEBUG,
                            LOG_LINK_INTERFACE(link),
                            LOG_NETDEV_INTERFACE(netdev),
@@ -2602,6 +2639,10 @@ static int link_configure(Link *link) {
         }
 
         if (link_dhcp4_enabled(link)) {
+                r = dhcp4_set_promote_secondaries(link);
+                if (r < 0)
+                        return r;
+
                 r = dhcp4_configure(link);
                 if (r < 0)
                         return r;
@@ -2770,7 +2811,7 @@ int link_initialized(Link *link, struct udev_device *device) {
                 return r;
 
         r = sd_netlink_call_async(link->manager->rtnl, req,
-                               link_initialized_and_synced, link, 0, NULL);
+                                  link_initialized_and_synced, link, 0, NULL);
         if (r < 0)
                 return r;
 
@@ -3076,13 +3117,20 @@ static int link_carrier_lost(Link *link) {
 
         assert(link);
 
+        /* Some devices reset itself while setting the MTU. This causes the DHCP client fall into a loop.
+           setting_mtu keep track whether the device got reset because of setting MTU and does not drop the
+           configuration and stop the clients as well. */
+        if (link->setting_mtu)
+                return 0;
+
         r = link_stop_clients(link);
         if (r < 0) {
                 link_enter_failed(link);
                 return r;
         }
 
-        (void) sd_dhcp_server_stop(link->dhcp_server);
+        if (link_dhcp4_server_enabled(link))
+                (void) sd_dhcp_server_stop(link->dhcp_server);
 
         r = link_drop_config(link);
         if (r < 0)
@@ -3145,7 +3193,7 @@ int link_update(Link *link, sd_netlink_message *m) {
 
         r = sd_netlink_message_read_string(m, IFLA_IFNAME, &ifname);
         if (r >= 0 && !streq(ifname, link->ifname)) {
-                log_link_info(link, "Renamed to %s", ifname);
+                log_link_info(link, "Interface name change detected, %s has been renamed to %s.", link->ifname, ifname);
 
                 link_free_carrier_maps(link);
 
@@ -3233,7 +3281,7 @@ int link_update(Link *link, sd_netlink_message *m) {
                                                                          ARPHRD_ETHER,
                                                                          (const uint8_t *)&link->mac,
                                                                          sizeof(link->mac));
-                                        if(r < 0)
+                                        if (r < 0)
                                                 return log_link_warning_errno(link, r, "Could not update MAC client id in DHCP client: %m");
                                         break;
                                 default:
@@ -3313,16 +3361,16 @@ static void print_link_hashmap(FILE *f, const char *prefix, Hashmap* h) {
         if (hashmap_isempty(h))
                 return;
 
-        fputs_unlocked(prefix, f);
+        fputs(prefix, f);
         HASHMAP_FOREACH(link, h, i) {
                 if (space)
-                        fputc_unlocked(' ', f);
+                        fputc(' ', f);
 
                 fprintf(f, "%i", link->ifindex);
                 space = true;
         }
 
-        fputc_unlocked('\n', f);
+        fputc('\n', f);
 }
 
 int link_save(Link *link) {
@@ -3356,6 +3404,7 @@ int link_save(Link *link) {
         if (r < 0)
                 goto fail;
 
+        (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
         (void) fchmod(fileno(f), 0644);
 
         fprintf(f,
@@ -3372,6 +3421,9 @@ int link_save(Link *link) {
                 char **dhcp_domains = NULL;
                 unsigned j;
 
+                fprintf(f, "REQUIRED_FOR_ONLINE=%s\n",
+                        yes_no(link->network->required_for_online));
+
                 if (link->dhcp6_client) {
                         r = sd_dhcp6_client_get_lease(link->dhcp6_client, &dhcp6_lease);
                         if (r < 0 && r != -ENOMSG)
@@ -3380,7 +3432,7 @@ int link_save(Link *link) {
 
                 fprintf(f, "NETWORK_FILE=%s\n", link->network->filename);
 
-                fputs_unlocked("DNS=", f);
+                fputs("DNS=", f);
                 space = false;
 
                 for (j = 0; j < link->network->n_dns; j++) {
@@ -3394,8 +3446,8 @@ int link_save(Link *link) {
                         }
 
                         if (space)
-                                fputc_unlocked(' ', f);
-                        fputs_unlocked(b, f);
+                                fputc(' ', f);
+                        fputs(b, f);
                         space = true;
                 }
 
@@ -3406,7 +3458,7 @@ int link_save(Link *link) {
                         r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses);
                         if (r > 0) {
                                 if (space)
-                                        fputc_unlocked(' ', f);
+                                        fputc(' ', f);
                                 serialize_in_addrs(f, addresses, r);
                                 space = true;
                         }
@@ -3418,7 +3470,7 @@ int link_save(Link *link) {
                         r = sd_dhcp6_lease_get_dns(dhcp6_lease, &in6_addrs);
                         if (r > 0) {
                                 if (space)
-                                        fputc_unlocked(' ', f);
+                                        fputc(' ', f);
                                 serialize_in6_addrs(f, in6_addrs, r);
                                 space = true;
                         }
@@ -3432,16 +3484,16 @@ int link_save(Link *link) {
 
                         SET_FOREACH(dd, link->ndisc_rdnss, i) {
                                 if (space)
-                                        fputc_unlocked(' ', f);
+                                        fputc(' ', f);
 
                                 serialize_in6_addrs(f, &dd->address, 1);
                                 space = true;
                         }
                 }
 
-                fputc_unlocked('\n', f);
+                fputc('\n', f);
 
-                fputs_unlocked("NTP=", f);
+                fputs("NTP=", f);
                 space = false;
                 fputstrv(f, link->network->ntp, NULL, &space);
 
@@ -3452,7 +3504,7 @@ int link_save(Link *link) {
                         r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses);
                         if (r > 0) {
                                 if (space)
-                                        fputc_unlocked(' ', f);
+                                        fputc(' ', f);
                                 serialize_in_addrs(f, addresses, r);
                                 space = true;
                         }
@@ -3466,7 +3518,7 @@ int link_save(Link *link) {
                                                          &in6_addrs);
                         if (r > 0) {
                                 if (space)
-                                        fputc_unlocked(' ', f);
+                                        fputc(' ', f);
                                 serialize_in6_addrs(f, in6_addrs, r);
                                 space = true;
                         }
@@ -3476,7 +3528,7 @@ int link_save(Link *link) {
                                 fputstrv(f, hosts, NULL, &space);
                 }
 
-                fputc_unlocked('\n', f);
+                fputc('\n', f);
 
                 if (link->network->dhcp_use_domains != DHCP_USE_DOMAINS_NO) {
                         if (link->dhcp_lease) {
@@ -3487,7 +3539,7 @@ int link_save(Link *link) {
                                 (void) sd_dhcp6_lease_get_domains(dhcp6_lease, &dhcp6_domains);
                 }
 
-                fputs_unlocked("DOMAINS=", f);
+                fputs("DOMAINS=", f);
                 space = false;
                 fputstrv(f, link->network->search_domains, NULL, &space);
 
@@ -3505,9 +3557,9 @@ int link_save(Link *link) {
                                 fputs_with_space(f, NDISC_DNSSL_DOMAIN(dd), NULL, &space);
                 }
 
-                fputc_unlocked('\n', f);
+                fputc('\n', f);
 
-                fputs_unlocked("ROUTE_DOMAINS=", f);
+                fputs("ROUTE_DOMAINS=", f);
                 space = false;
                 fputstrv(f, link->network->route_domains, NULL, &space);
 
@@ -3525,7 +3577,7 @@ int link_save(Link *link) {
                                 fputs_with_space(f, NDISC_DNSSL_DOMAIN(dd), NULL, &space);
                 }
 
-                fputc_unlocked('\n', f);
+                fputc('\n', f);
 
                 fprintf(f, "LLMNR=%s\n",
                         resolve_support_to_string(link->network->llmnr));
@@ -3539,14 +3591,14 @@ int link_save(Link *link) {
                 if (!set_isempty(link->network->dnssec_negative_trust_anchors)) {
                         const char *n;
 
-                        fputs_unlocked("DNSSEC_NTA=", f);
+                        fputs("DNSSEC_NTA=", f);
                         space = false;
                         SET_FOREACH(n, link->network->dnssec_negative_trust_anchors, i)
                                 fputs_with_space(f, n, NULL, &space);
-                        fputc_unlocked('\n', f);
+                        fputc('\n', f);
                 }
 
-                fputs_unlocked("ADDRESSES=", f);
+                fputs("ADDRESSES=", f);
                 space = false;
                 SET_FOREACH(a, link->addresses, i) {
                         _cleanup_free_ char *address_str = NULL;
@@ -3558,9 +3610,9 @@ int link_save(Link *link) {
                         fprintf(f, "%s%s/%u", space ? " " : "", address_str, a->prefixlen);
                         space = true;
                 }
-                fputc_unlocked('\n', f);
+                fputc('\n', f);
 
-                fputs_unlocked("ROUTES=", f);
+                fputs("ROUTES=", f);
                 space = false;
                 SET_FOREACH(route, link->routes, i) {
                         _cleanup_free_ char *route_str = NULL;
@@ -3569,12 +3621,13 @@ int link_save(Link *link) {
                         if (r < 0)
                                 goto fail;
 
-                        fprintf(f, "%s%s/%hhu/%hhu/%"PRIu32"/%hhu/"USEC_FMT, space ? " " : "", route_str,
+                        fprintf(f, "%s%s/%hhu/%hhu/%"PRIu32"/%"PRIu32"/"USEC_FMT,
+                                space ? " " : "", route_str,
                                 route->dst_prefixlen, route->tos, route->priority, route->table, route->lifetime);
                         space = true;
                 }
 
-                fputc_unlocked('\n', f);
+                fputc('\n', f);
         }
 
         print_link_hashmap(f, "CARRIER_BOUND_TO=", link->bound_to_links);
@@ -3592,9 +3645,9 @@ int link_save(Link *link) {
 
                 r = sd_dhcp_lease_get_address(link->dhcp_lease, &address);
                 if (r >= 0) {
-                        fputs_unlocked("DHCP4_ADDRESS=", f);
+                        fputs("DHCP4_ADDRESS=", f);
                         serialize_in_addrs(f, &address, 1);
-                        fputc_unlocked('\n', f);
+                        fputc('\n', f);
                 }
 
                 r = dhcp_lease_save(link->dhcp_lease, link->lease_file);
@@ -3612,9 +3665,9 @@ int link_save(Link *link) {
 
                 r = sd_ipv4ll_get_address(link->ipv4ll, &address);
                 if (r >= 0) {
-                        fputs_unlocked("IPV4LL_ADDRESS=", f);
+                        fputs("IPV4LL_ADDRESS=", f);
                         serialize_in_addrs(f, &address, 1);
-                        fputc_unlocked('\n', f);
+                        fputc('\n', f);
                 }
         }
 
index 6479f4a..8aaaa67 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -85,7 +86,11 @@ typedef struct Link {
         LinkState state;
         LinkOperationalState operstate;
 
-        unsigned link_messages;
+        unsigned address_messages;
+        unsigned address_label_messages;
+        unsigned route_messages;
+        unsigned routing_policy_rule_messages;
+        unsigned routing_policy_rule_remove_messages;
         unsigned enslaving;
 
         Set *addresses;
@@ -108,7 +113,9 @@ typedef struct Link {
         bool ipv4ll_address:1;
         bool ipv4ll_route:1;
 
-        bool static_configured;
+        bool static_routes_configured;
+        bool routing_policy_rules_configured;
+        bool setting_mtu;
 
         LIST_HEAD(Address, pool_addresses);
 
@@ -168,6 +175,7 @@ int link_set_mtu(Link *link, uint32_t mtu);
 
 int ipv4ll_configure(Link *link);
 int dhcp4_configure(Link *link);
+int dhcp4_set_promote_secondaries(Link *link);
 int dhcp6_configure(Link *link);
 int dhcp6_request_address(Link *link, int ir);
 
index 2de63ce..b8d160a 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 4680c9d..be7a989 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index cbb1b93..6d57036 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 71445d5..cc17af9 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -20,6 +21,7 @@
 #include <sys/socket.h>
 #include <linux/if.h>
 #include <linux/fib_rules.h>
+#include <stdio_ext.h>
 
 #include "sd-daemon.h"
 #include "sd-netlink.h"
@@ -150,9 +152,6 @@ int manager_connect_bus(Manager *m) {
                 return 0;
         }
 
-        if (r < 0)
-                return r;
-
         r = sd_bus_add_match(m->bus, &m->prepare_for_sleep_slot,
                              "type='signal',"
                              "sender='org.freedesktop.login1',"
@@ -470,7 +469,7 @@ int manager_rtnl_process_route(sd_netlink *rtnl, sd_netlink_message *message, vo
                                 return 0;
                 }
 
-                route_update(route, &src, src_prefixlen, &gw, &prefsrc, scope, rt_type, protocol);
+                route_update(route, &src, src_prefixlen, &gw, &prefsrc, scope, protocol, rt_type);
 
                 break;
 
@@ -605,7 +604,7 @@ int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message,
         case RTM_NEWADDR:
                 if (address)
                         log_link_debug(link, "Updating address: %s/%u (valid %s%s)", buf, prefixlen,
-                                       valid_str ? "for " : "forever", valid_str ?: "");
+                                       valid_str ? "for " : "forever", strempty(valid_str));
                 else {
                         /* An address appeared that we did not request */
                         r = address_add_foreign(link, family, &in_addr, prefixlen, &address);
@@ -614,7 +613,7 @@ int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message,
                                 return 0;
                         } else
                                 log_link_debug(link, "Adding address: %s/%u (valid %s%s)", buf, prefixlen,
-                                               valid_str ? "for " : "forever", valid_str ?: "");
+                                               valid_str ? "for " : "forever", strempty(valid_str));
                 }
 
                 address_update(address, flags, scope, &cinfo);
@@ -625,11 +624,11 @@ int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message,
 
                 if (address) {
                         log_link_debug(link, "Removing address: %s/%u (valid %s%s)", buf, prefixlen,
-                                       valid_str ? "for " : "forever", valid_str ?: "");
+                                       valid_str ? "for " : "forever", strempty(valid_str));
                         address_drop(address);
                 } else
                         log_link_warning(link, "Removing non-existent address: %s/%u (valid %s%s)", buf, prefixlen,
-                                         valid_str ? "for " : "forever", valid_str ?: "");
+                                         valid_str ? "for " : "forever", strempty(valid_str));
 
                 break;
         default:
@@ -731,6 +730,7 @@ int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, voi
         union in_addr_union to, from;
         uint32_t fwmark = 0, table = 0;
         Manager *m = userdata;
+        char *iif, *oif;
         uint16_t type;
         int family;
         int r;
@@ -810,13 +810,15 @@ int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, voi
         (void) sd_netlink_message_read_u32(message, FRA_FWMARK, &fwmark);
         (void) sd_netlink_message_read_u32(message, FRA_TABLE, &table);
         (void) sd_rtnl_message_routing_policy_rule_get_tos(message, &tos);
+        (void) sd_netlink_message_read_string(message, FRA_IIFNAME, (const char **) &iif);
+        (void) sd_netlink_message_read_string(message, FRA_OIFNAME, (const char **) &oif);
 
-        (void) routing_policy_rule_get(m, family, &from, from_prefixlen, &to, to_prefixlen, tos, fwmark, table, &rule);
+        (void) routing_policy_rule_get(m, family, &from, from_prefixlen, &to, to_prefixlen, tos, fwmark, table, iif, oif, &rule);
 
         switch (type) {
         case RTM_NEWRULE:
-                if(!rule) {
-                        r = routing_policy_rule_add_foreign(m, family, &from, from_prefixlen, &to, to_prefixlen, tos, fwmark, table, &rule);
+                if (!rule) {
+                        r = routing_policy_rule_add_foreign(m, family, &from, from_prefixlen, &to, to_prefixlen, tos, fwmark, table, iif, oif, &rule);
                         if (r < 0) {
                                 log_warning_errno(r, "Could not add rule: %m");
                                 return 0;
@@ -990,18 +992,16 @@ static void print_string_set(FILE *f, const char *field, OrderedSet *s) {
         if (ordered_set_isempty(s))
                 return;
 
-        fputs_unlocked(field, f);
+        fputs(field, f);
 
         ORDERED_SET_FOREACH(p, s, i)
                 fputs_with_space(f, p, NULL, &space);
 
-        fputc_unlocked('\n', f);
+        fputc('\n', f);
 }
 
 static int manager_save(Manager *m) {
         _cleanup_ordered_set_free_free_ OrderedSet *dns = NULL, *ntp = NULL, *search_domains = NULL, *route_domains = NULL;
-        RoutingPolicyRule *rule = NULL;
-        bool space = false;
         Link *link;
         Iterator i;
         _cleanup_free_ char *temp_path = NULL;
@@ -1115,6 +1115,7 @@ static int manager_save(Manager *m) {
         if (r < 0)
                 return r;
 
+        (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
         (void) fchmod(fileno(f), 0644);
 
         fprintf(f,
@@ -1126,27 +1127,9 @@ static int manager_save(Manager *m) {
         print_string_set(f, "DOMAINS=", search_domains);
         print_string_set(f, "ROUTE_DOMAINS=", route_domains);
 
-        SET_FOREACH(rule, m->rules, i) {
-                _cleanup_free_ char *from_str = NULL, *to_str = NULL;
-                fputs("RULE=", f);
-
-                if (!in_addr_is_null(rule->family, &rule->from)) {
-                        r = in_addr_to_string(rule->family, &rule->from, &from_str);
-                        if (r < 0)
-                                goto fail;
-                }
-
-                if (!in_addr_is_null(rule->family, &rule->to)) {
-                        r = in_addr_to_string(rule->family, &rule->to, &to_str);
-                        if (r < 0)
-                                goto fail;
-                }
-
-                fprintf(f, "from=%s%s/%hhu to=%s%s/%hhu tos=%hhu fwmark=%"PRIu32"/%"PRIu32" table=%hhu", space ? " " : "", from_str,
-                        rule->from_prefixlen, space ? " " : "", to_str, rule->to_prefixlen, rule->tos, rule->fwmark, rule->fwmask, rule->table);
-
-                fputc('\n', f);
-        }
+        r = routing_policy_serialize_rules(m->rules, f);
+        if (r < 0)
+                goto fail;
 
         r = fflush_and_check(f);
         if (r < 0)
@@ -1233,7 +1216,7 @@ int manager_new(Manager **ret, sd_event *event) {
 
         m->duid.type = DUID_TYPE_EN;
 
-        (void) routing_policy_rule_load(m);
+        (void) routing_policy_load_rules(m->state_file, &m->rules_saved);
 
         *ret = m;
         m = NULL;
@@ -1242,7 +1225,6 @@ int manager_new(Manager **ret, sd_event *event) {
 }
 
 void manager_free(Manager *m) {
-        RoutingPolicyRule *rule;
         Network *network;
         NetDev *netdev;
         Link *link;
@@ -1272,10 +1254,7 @@ void manager_free(Manager *m) {
         set_free(m->rules);
         set_free(m->rules_foreign);
 
-        while ((rule = set_steal_first(m->rules_saved)))
-                free(rule);
-
-        set_free(m->rules_saved);
+        set_free_with_destructor(m->rules_saved, routing_policy_rule_free);
 
         sd_netlink_unref(m->rtnl);
         sd_event_unref(m->event);
@@ -1454,8 +1433,14 @@ int manager_rtnl_enumerate_rules(Manager *m) {
                 return r;
 
         r = sd_netlink_call(m->rtnl, req, 0, &reply);
-        if (r < 0)
+        if (r < 0) {
+                if (r == -EOPNOTSUPP) {
+                        log_debug("FIB Rules are not supported by the kernel. Ignoring.");
+                        return 0;
+                }
+
                 return r;
+        }
 
         for (rule = reply; rule; rule = sd_netlink_message_next(rule)) {
                 int k;
index 254aab8..186cb41 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index d52b511..df4630b 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -39,10 +40,8 @@ static int ndisc_netlink_handler(sd_netlink *rtnl, sd_netlink_message *m, void *
         link->ndisc_messages--;
 
         r = sd_netlink_message_get_errno(m);
-        if (r < 0 && r != -EEXIST) {
+        if (r < 0 && r != -EEXIST)
                 log_link_error_errno(link, r, "Could not set NDisc route or address: %m");
-                link_enter_failed(link);
-        }
 
         if (link->ndisc_messages == 0) {
                 link->ndisc_configured = true;
@@ -186,6 +185,10 @@ static void ndisc_router_process_autonomous_prefix(Link *link, sd_ndisc_router *
                 return;
         }
 
+        /* The preferred lifetime is never greater than the valid lifetime */
+        if (lifetime_preferred > lifetime_valid)
+                return;
+
         r = address_new(&address);
         if (r < 0) {
                 log_link_error_errno(link, r, "Could not allocate address: %m");
index 1271261..f5eb8cd 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 3b835b5..8d3d723 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index af39d77..57a96af 100644 (file)
@@ -1,4 +1,7 @@
 %{
+#if __GNUC__ >= 7
+_Pragma("GCC diagnostic ignored \"-Wimplicit-fallthrough\"")
+#endif
 #include <stddef.h>
 #include "conf-parser.h"
 #include "networkd-conf.h"
@@ -30,6 +33,7 @@ Link.MACAddress,                        config_parse_hwaddr,
 Link.MTUBytes,                          config_parse_iec_size,                          0,                             offsetof(Network, mtu)
 Link.ARP,                               config_parse_tristate,                          0,                             offsetof(Network, arp)
 Link.Unmanaged,                         config_parse_bool,                              0,                             offsetof(Network, unmanaged)
+Link.RequiredForOnline,                 config_parse_bool,                              0,                             offsetof(Network, required_for_online)
 Network.Description,                    config_parse_string,                            0,                             offsetof(Network, description)
 Network.Bridge,                         config_parse_netdev,                            0,                             offsetof(Network, bridge)
 Network.Bond,                           config_parse_netdev,                            0,                             offsetof(Network, bond)
@@ -90,6 +94,8 @@ RoutingPolicyRule.Table,                config_parse_routing_policy_rule_table,
 RoutingPolicyRule.FirewallMark,         config_parse_routing_policy_rule_fwmark_mask,   0,                             0
 RoutingPolicyRule.From,                 config_parse_routing_policy_rule_prefix,        0,                             0
 RoutingPolicyRule.To,                   config_parse_routing_policy_rule_prefix,        0,                             0
+RoutingPolicyRule.IncomingInterface,    config_parse_routing_policy_rule_device,        0,                             0
+RoutingPolicyRule.OutgoingInterface,    config_parse_routing_policy_rule_device,        0,                             0
 Route.Gateway,                          config_parse_gateway,                           0,                             0
 Route.Destination,                      config_parse_destination,                       0,                             0
 Route.Source,                           config_parse_destination,                       0,                             0
@@ -123,7 +129,7 @@ DHCP.IAID,                              config_parse_iaid,
 DHCP.ListenPort,                        config_parse_uint16,                            0,                             offsetof(Network, dhcp_client_port)
 IPv6AcceptRA.UseDNS,                    config_parse_bool,                              0,                             offsetof(Network, ipv6_accept_ra_use_dns)
 IPv6AcceptRA.UseDomains,                config_parse_dhcp_use_domains,                  0,                             offsetof(Network, ipv6_accept_ra_use_domains)
-IPv6AcceptRA.RouteTable,                config_parse_dhcp_route_table,                  0,                             offsetof(Network, ipv6_accept_ra_route_table)
+IPv6AcceptRA.RouteTable,                config_parse_uint32,                            0,                             offsetof(Network, ipv6_accept_ra_route_table)
 DHCPServer.MaxLeaseTimeSec,             config_parse_sec,                               0,                             offsetof(Network, dhcp_server_max_lease_time_usec)
 DHCPServer.DefaultLeaseTimeSec,         config_parse_sec,                               0,                             offsetof(Network, dhcp_server_default_lease_time_usec)
 DHCPServer.EmitDNS,                     config_parse_bool,                              0,                             offsetof(Network, dhcp_server_emit_dns)
@@ -152,7 +158,9 @@ IPv6PrefixDelegation.RouterLifetimeSec, config_parse_sec,
 IPv6PrefixDelegation.Managed,           config_parse_bool,                              0,                             offsetof(Network, router_managed)
 IPv6PrefixDelegation.OtherInformation,  config_parse_bool,                              0,                             offsetof(Network, router_other_information)
 IPv6PrefixDelegation.RouterPreference,  config_parse_router_preference,                 0,                             0
+IPv6PrefixDelegation.EmitDNS,           config_parse_bool,                              0,                             offsetof(Network, router_emit_dns)
 IPv6PrefixDelegation.DNS,               config_parse_radv_dns,                          0,                             0
+IPv6PrefixDelegation.EmitDomains,       config_parse_bool,                              0,                             offsetof(Network, router_emit_domains)
 IPv6PrefixDelegation.Domains,           config_parse_radv_search_domains,               0,                             0
 IPv6PrefixDelegation.DNSLifetimeSec,    config_parse_sec,                               0,                             offsetof(Network, router_dns_lifetime_usec)
 IPv6Prefix.Prefix,                      config_parse_prefix,                            0,                             0
index 3a7eb2c..8e37a0a 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -113,9 +114,9 @@ void network_apply_anonymize_if_set(Network *network) {
         * (to use the MTU sent by the server but to do not send
         * the option in the PRL). */
         network->dhcp_use_mtu = false;
-        /* RFC7844 section 3.6.
-        * same comments as previous option */
-        network->dhcp_use_routes = false;
+        /* NOTE: when Anonymize=yes, the PRL route options are sent by default,
+         * but this is needed to use them. */
+        network->dhcp_use_routes = true;
         /* RFC7844 section 3.6.
         * same comments as previous option */
         network->dhcp_use_timezone = false;
@@ -204,11 +205,11 @@ static int network_load_one(Manager *manager, const char *filename) {
 
         *d = '\0';
 
+        network->required_for_online = true;
         network->dhcp = ADDRESS_FAMILY_NO;
         network->dhcp_use_ntp = true;
         network->dhcp_use_dns = true;
         network->dhcp_use_hostname = true;
-        /* NOTE: this var might be overwriten by network_apply_anonymize_if_set */
         network->dhcp_use_routes = true;
         /* NOTE: this var might be overwriten by network_apply_anonymize_if_set */
         network->dhcp_send_hostname = true;
@@ -233,6 +234,9 @@ static int network_load_one(Manager *manager, const char *filename) {
         network->dhcp_server_emit_router = true;
         network->dhcp_server_emit_timezone = true;
 
+        network->router_emit_dns = true;
+        network->router_emit_domains = true;
+
         network->use_bpdu = true;
         network->allow_port_to_be_root = true;
         network->unicast_flood = true;
@@ -278,7 +282,7 @@ static int network_load_one(Manager *manager, const char *filename) {
                               "IPv6PrefixDelegation\0"
                               "IPv6Prefix\0",
                               config_item_perf_lookup, network_network_gperf_lookup,
-                              false, network);
+                              CONFIG_PARSE_WARN, network);
         if (r < 0)
                 return r;
 
index 9fb0eae..49c6265 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -167,6 +168,8 @@ struct Network {
         uint8_t router_preference;
         bool router_managed;
         bool router_other_information;
+        bool router_emit_dns;
+        bool router_emit_domains;
         usec_t router_dns_lifetime_usec;
         struct in6_addr *router_dns;
         unsigned n_router_dns;
@@ -212,6 +215,8 @@ struct Network {
         uint32_t iaid;
         DUID duid;
 
+        bool required_for_online; /* Is this network required to be considered online? */
+
         LLDPMode lldp_mode; /* LLDP reception */
         LLDPEmit lldp_emit; /* LLDP transmission */
 
index 6768208..535454c 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
 #include <arpa/inet.h>
 
 #include "networkd-address.h"
+#include "networkd-manager.h"
 #include "networkd-radv.h"
 #include "sd-radv.h"
 
+static int radv_get_ip6dns(Network *network, struct in6_addr **dns,
+                           size_t *n_dns) {
+        _cleanup_free_ struct in6_addr *addresses = NULL;
+        size_t i, n_addresses = 0, n_allocated = 0;
+
+        assert(network);
+        assert(dns);
+        assert(n_dns);
+
+        for (i = 0; i < network->n_dns; i++) {
+                union in_addr_union *addr;
+
+                if (network->dns[i].family != AF_INET6)
+                        continue;
+
+                addr = &network->dns[i].address;
+
+                if (in_addr_is_null(AF_INET6, addr) ||
+                    in_addr_is_link_local(AF_INET6, addr) ||
+                    in_addr_is_localhost(AF_INET6, addr))
+                        continue;
+
+                if (!GREEDY_REALLOC(addresses, n_allocated, n_addresses + 1))
+                        return -ENOMEM;
+
+                addresses[n_addresses++] = addr->in6;
+        }
+
+        if (addresses) {
+                *dns = addresses;
+                addresses = NULL;
+
+                *n_dns = n_addresses;
+        }
+
+        return n_addresses;
+}
+
+static int radv_set_dns(Link *link, Link *uplink) {
+        _cleanup_free_ struct in6_addr *dns = NULL;
+        size_t n_dns;
+        usec_t lifetime_usec;
+        int r;
+
+        if (!link->network->router_emit_dns)
+                return 0;
+
+        if (link->network->router_dns) {
+                dns = newdup(struct in6_addr, link->network->router_dns,
+                             link->network->n_router_dns);
+                if (dns == NULL)
+                        return -ENOMEM;
+
+                n_dns = link->network->n_router_dns;
+                lifetime_usec = link->network->router_dns_lifetime_usec;
+
+                goto set_dns;
+        }
+
+        lifetime_usec = SD_RADV_DEFAULT_DNS_LIFETIME_USEC;
+
+        r = radv_get_ip6dns(link->network, &dns, &n_dns);
+        if (r > 0)
+                goto set_dns;
+
+        if (uplink) {
+                if (uplink->network == NULL) {
+                        log_link_debug(uplink, "Cannot fetch DNS servers as uplink interface is not managed by us");
+                        return 0;
+                }
+
+                r = radv_get_ip6dns(uplink->network, &dns, &n_dns);
+                if (r > 0)
+                        goto set_dns;
+        }
+
+        return 0;
+
+ set_dns:
+        return sd_radv_set_rdnss(link->radv,
+                                 DIV_ROUND_UP(lifetime_usec, USEC_PER_SEC),
+                                 dns, n_dns);
+}
+
+static int radv_set_domains(Link *link, Link *uplink) {
+        char **search_domains;
+        usec_t lifetime_usec;
+
+        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;
+
+        if (uplink) {
+                if (uplink->network == NULL) {
+                        log_link_debug(uplink, "Cannot fetch DNS search domains as uplink interface is not managed by us");
+                        return 0;
+                }
+
+                search_domains = uplink->network->search_domains;
+                if (search_domains)
+                        goto set_domains;
+        }
+
+        return 0;
+
+ set_domains:
+        return sd_radv_set_dnssl(link->radv,
+                                 DIV_ROUND_UP(lifetime_usec, USEC_PER_SEC),
+                                 search_domains);
+
+}
+
+int radv_emit_dns(Link *link) {
+        Link *uplink;
+        int r;
+
+        uplink = manager_find_uplink(link->manager, link);
+
+        r = radv_set_dns(link, uplink);
+        if (r < 0)
+                log_link_warning_errno(link, r, "Could not set RA DNS: %m");
+
+        r = radv_set_domains(link, uplink);
+        if (r < 0)
+                log_link_warning_errno(link, r, "Could not set RA Domains: %m");
+
+        return 0;
+}
+
 int radv_configure(Link *link) {
         int r;
         Prefix *p;
@@ -75,24 +217,5 @@ int radv_configure(Link *link) {
                         return r;
         }
 
-        if (link->network->router_dns) {
-                r = sd_radv_set_rdnss(link->radv,
-                                      DIV_ROUND_UP(link->network->router_dns_lifetime_usec,
-                                                   USEC_PER_SEC),
-                                      link->network->router_dns,
-                                      link->network->n_router_dns);
-                if (r < 0)
-                        return r;
-        }
-
-        if (link->network->router_search_domains) {
-                r = sd_radv_set_dnssl(link->radv,
-                                      DIV_ROUND_UP(link->network->router_dns_lifetime_usec,
-                                                   USEC_PER_SEC),
-                                      link->network->router_search_domains);
-                if (r < 0)
-                        return r;
-        }
-
-        return 0;
+        return radv_emit_dns(link);
 }
index a186b11..f230299 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -21,4 +22,5 @@
 
 #include "networkd-link.h"
 
+int radv_emit_dns(Link *link);
 int radv_configure(Link *link);
index cf42037..b0ad707 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -367,7 +368,7 @@ int route_add(
         return 0;
 }
 
-int route_update(Route *route,
+void route_update(Route *route,
                  const union in_addr_union *src,
                  unsigned char src_prefixlen,
                  const union in_addr_union *gw,
@@ -388,8 +389,6 @@ int route_update(Route *route,
         route->scope = scope;
         route->protocol = protocol;
         route->type = type;
-
-        return 0;
 }
 
 int route_remove(Route *route, Link *link,
@@ -461,10 +460,6 @@ int route_remove(Route *route, Link *link,
         if (r < 0)
                 return log_error_errno(r, "Could not append RTA_PRIORITY attribute: %m");
 
-        r = sd_rtnl_message_route_set_type(req, route->type);
-        if (r < 0)
-                return log_error_errno(r, "Could not set route type: %m");
-
         if (!IN_SET(route->type, RTN_UNREACHABLE, RTN_PROHIBIT, RTN_BLACKHOLE)) {
                 r = sd_netlink_message_append_u32(req, RTA_OIF, link->ifindex);
                 if (r < 0)
index 89d32e9..cfb85cb 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -63,7 +64,7 @@ int route_remove(Route *route, Link *link, sd_netlink_message_handler_t callback
 int route_get(Link *link, int family, const union in_addr_union *dst, unsigned char dst_prefixlen, unsigned char tos, uint32_t priority, uint32_t table, Route **ret);
 int route_add(Link *link, int family, const union in_addr_union *dst, unsigned char dst_prefixlen, unsigned char tos, uint32_t priority, uint32_t table, Route **ret);
 int route_add_foreign(Link *link, int family, const union in_addr_union *dst, unsigned char dst_prefixlen, unsigned char tos, uint32_t priority, uint32_t table, Route **ret);
-int route_update(Route *route, const union in_addr_union *src, unsigned char src_prefixlen, const union in_addr_union *gw, const union in_addr_union *prefsrc, unsigned char scope, unsigned char protocol, unsigned char type);
+void route_update(Route *route, const union in_addr_union *src, unsigned char src_prefixlen, const union in_addr_union *gw, const union in_addr_union *prefsrc, unsigned char scope, unsigned char protocol, unsigned char type);
 
 int route_expire_handler(sd_event_source *s, uint64_t usec, void *userdata);
 
index 6850135..1314564 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -65,6 +66,8 @@ void routing_policy_rule_free(RoutingPolicyRule *rule) {
                 }
         }
 
+        free(rule->iif);
+        free(rule->oif);
         free(rule);
 }
 
@@ -89,6 +92,12 @@ static void routing_policy_rule_hash_func(const void *b, struct siphash *state)
                 siphash24_compress(&rule->fwmark, sizeof(rule->fwmark), state);
                 siphash24_compress(&rule->table, sizeof(rule->table), state);
 
+                if (rule->iif)
+                        siphash24_compress(&rule->iif, strlen(rule->iif), state);
+
+                if (rule->oif)
+                        siphash24_compress(&rule->oif, strlen(rule->oif), state);
+
                 break;
         default:
                 /* treat any other address family as AF_UNSPEC */
@@ -133,6 +142,14 @@ static int routing_policy_rule_compare_func(const void *_a, const void *_b) {
                 if (a->table > b->table)
                         return 1;
 
+                r = strcmp_ptr(a->iif, b->iif);
+                if (!r)
+                        return r;
+
+                r = strcmp_ptr(a->oif, b->oif);
+                if (!r)
+                        return r;
+
                 r = memcmp(&a->from, &b->from, FAMILY_ADDRESS_SIZE(a->family));
                 if (r != 0)
                         return r;
@@ -159,6 +176,8 @@ int routing_policy_rule_get(Manager *m,
                             uint8_t tos,
                             uint32_t fwmark,
                             uint32_t table,
+                            char *iif,
+                            char *oif,
                             RoutingPolicyRule **ret) {
 
         RoutingPolicyRule rule, *existing;
@@ -174,6 +193,8 @@ int routing_policy_rule_get(Manager *m,
                 .tos = tos,
                 .fwmark = fwmark,
                 .table = table,
+                .iif = iif,
+                .oif = oif
         };
 
         if (m->rules) {
@@ -224,6 +245,8 @@ static int routing_policy_rule_add_internal(Set **rules,
                                             uint8_t tos,
                                             uint32_t fwmark,
                                             uint32_t table,
+                                            char *iif,
+                                            char *oif,
                                             RoutingPolicyRule **ret) {
 
         _cleanup_routing_policy_rule_free_ RoutingPolicyRule *rule = NULL;
@@ -243,6 +266,8 @@ static int routing_policy_rule_add_internal(Set **rules,
         rule->tos = tos;
         rule->fwmark = fwmark;
         rule->table = table;
+        rule->iif = iif;
+        rule->oif = oif;
 
         r = set_ensure_allocated(rules, &routing_policy_rule_hash_ops);
         if (r < 0)
@@ -269,9 +294,11 @@ int routing_policy_rule_add(Manager *m,
                             uint8_t tos,
                             uint32_t fwmark,
                             uint32_t table,
+                            char *iif,
+                            char *oif,
                             RoutingPolicyRule **ret) {
 
-        return routing_policy_rule_add_internal(&m->rules, family, from, from_prefixlen, to, to_prefixlen, tos, fwmark, table, ret);
+        return routing_policy_rule_add_internal(&m->rules, family, from, from_prefixlen, to, to_prefixlen, tos, fwmark, table, iif, oif, ret);
 }
 
 int routing_policy_rule_add_foreign(Manager *m,
@@ -283,8 +310,10 @@ int routing_policy_rule_add_foreign(Manager *m,
                                     uint8_t tos,
                                     uint32_t fwmark,
                                     uint32_t table,
+                                    char *iif,
+                                    char *oif,
                                     RoutingPolicyRule **ret) {
-        return routing_policy_rule_add_internal(&m->rules_foreign, family, from, from_prefixlen, to, to_prefixlen, tos, fwmark, table, ret);
+        return routing_policy_rule_add_internal(&m->rules_foreign, family, from, from_prefixlen, to, to_prefixlen, tos, fwmark, table, iif, oif, ret);
 }
 
 static int routing_policy_rule_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
@@ -295,7 +324,7 @@ static int routing_policy_rule_remove_handler(sd_netlink *rtnl, sd_netlink_messa
         assert(link);
         assert(link->ifname);
 
-        link->link_messages--;
+        link->routing_policy_rule_remove_messages--;
 
         if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
                 return 1;
@@ -409,9 +438,9 @@ int link_routing_policy_rule_handler(sd_netlink *rtnl, sd_netlink_message *m, vo
         assert(m);
         assert(link);
         assert(link->ifname);
-        assert(link->link_messages > 0);
+        assert(link->routing_policy_rule_messages > 0);
 
-        link->link_messages--;
+        link->routing_policy_rule_messages--;
 
         if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
                 return 1;
@@ -420,8 +449,11 @@ int link_routing_policy_rule_handler(sd_netlink *rtnl, sd_netlink_message *m, vo
         if (r < 0 && r != -EEXIST)
                 log_link_warning_errno(link, r, "Could not add routing policy rule: %m");
 
-        if (link->link_messages == 0)
+        if (link->routing_policy_rule_messages == 0) {
                 log_link_debug(link, "Routing policy rule configured");
+                link->routing_policy_rules_configured = true;
+                link_check_ready(link);
+        }
 
         return 1;
 }
@@ -504,6 +536,18 @@ int routing_policy_rule_configure(RoutingPolicyRule *rule, Link *link, sd_netlin
                         return log_error_errno(r, "Could not append FRA_FWMASK attribute: %m");
         }
 
+        if (rule->iif) {
+                r = sd_netlink_message_append_string(m, FRA_IFNAME, rule->iif);
+                if (r < 0)
+                        return log_error_errno(r, "Could not append FRA_IFNAME attribute: %m");
+        }
+
+        if (rule->oif) {
+                r = sd_netlink_message_append_string(m, FRA_OIFNAME, rule->oif);
+                if (r < 0)
+                        return log_error_errno(r, "Could not append FRA_OIFNAME attribute: %m");
+        }
+
         rule->link = link;
 
         r = sd_netlink_call_async(link->manager->rtnl, m, callback, link, 0, NULL);
@@ -513,7 +557,7 @@ int routing_policy_rule_configure(RoutingPolicyRule *rule, Link *link, sd_netlin
         link_ref(link);
 
         r = routing_policy_rule_add(link->manager, rule->family, &rule->from, rule->from_prefixlen, &rule->to,
-                                    rule->to_prefixlen, rule->tos, rule->fwmark, rule->table, NULL);
+                                    rule->to_prefixlen, rule->tos, rule->fwmark, rule->table, rule->iif, rule->oif, NULL);
         if (r < 0)
                 return log_error_errno(r, "Could not add rule : %m");
 
@@ -672,7 +716,6 @@ int config_parse_routing_policy_rule_fwmark_mask(
                 void *userdata) {
 
         _cleanup_routing_policy_rule_free_ RoutingPolicyRule *n = NULL;
-        _cleanup_free_ char *fwmark = NULL;
         Network *network = userdata;
         int r;
 
@@ -750,8 +793,54 @@ int config_parse_routing_policy_rule_prefix(
         return 0;
 }
 
-static int routing_policy_rule_read_full_file(char *state_file, char **ret) {
-        _cleanup_free_ char *s = NULL, *p = NULL;
+int config_parse_routing_policy_rule_device(
+                const char *unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        _cleanup_routing_policy_rule_free_ RoutingPolicyRule *n = NULL;
+        Network *network = userdata;
+        int r;
+
+        assert(filename);
+        assert(section);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        r = routing_policy_rule_new_static(network, filename, section_line, &n);
+        if (r < 0)
+                return r;
+
+        if (!ifname_valid(rvalue)) {
+                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse '%s' interface name, ignoring: %s", lvalue, rvalue);
+                return 0;
+        }
+
+        if (streq(lvalue, "IncomingInterface")) {
+                r = free_and_strdup(&n->iif, rvalue);
+                if (r < 0)
+                        return log_oom();
+        } else {
+                r = free_and_strdup(&n->oif, rvalue);
+                if (r < 0)
+                        return log_oom();
+        }
+
+        n = NULL;
+
+        return 0;
+}
+
+static int routing_policy_rule_read_full_file(const char *state_file, char **ret) {
+        _cleanup_free_ char *s = NULL;
         size_t size;
         int r;
 
@@ -771,16 +860,87 @@ static int routing_policy_rule_read_full_file(char *state_file, char **ret) {
         return size;
 }
 
-int routing_policy_rule_load(Manager *m) {
+int routing_policy_serialize_rules(Set *rules, FILE *f) {
+        RoutingPolicyRule *rule = NULL;
+        Iterator i;
+        int r;
+
+        assert(f);
+
+        SET_FOREACH(rule, rules, i) {
+                _cleanup_free_ char *from_str = NULL, *to_str = NULL;
+                bool space = false;
+
+                fputs("RULE=", f);
+
+                if (!in_addr_is_null(rule->family, &rule->from)) {
+                        r = in_addr_to_string(rule->family, &rule->from, &from_str);
+                        if (r < 0)
+                                return r;
+
+                        fprintf(f, "from=%s/%hhu",
+                                from_str, rule->from_prefixlen);
+                        space = true;
+                }
+
+                if (!in_addr_is_null(rule->family, &rule->to)) {
+                        r = in_addr_to_string(rule->family, &rule->to, &to_str);
+                        if (r < 0)
+                                return r;
+
+                        fprintf(f, "%sto=%s/%hhu",
+                                space ? " " : "",
+                                to_str, rule->to_prefixlen);
+                        space = true;
+                }
+
+                if (rule->tos != 0) {
+                        fprintf(f, "%stos=%hhu",
+                                space ? " " : "",
+                                rule->tos);
+                        space = true;
+                }
+
+                if (rule->fwmark != 0) {
+                        fprintf(f, "%sfwmark=%"PRIu32"/%"PRIu32,
+                                space ? " " : "",
+                                rule->fwmark, rule->fwmask);
+                        space = true;
+                }
+
+                if (rule->iif) {
+                        fprintf(f, "%siif=%s",
+                                space ? " " : "",
+                                rule->iif);
+                        space = true;
+                }
+
+                if (rule->oif) {
+                        fprintf(f, "%soif=%s",
+                                space ? " " : "",
+                                rule->oif);
+                        space = true;
+                }
+
+                fprintf(f, "%stable=%"PRIu32 "\n",
+                        space ? " " : "",
+                        rule->table);
+        }
+
+        return 0;
+}
+
+int routing_policy_load_rules(const char *state_file, Set **rules) {
         _cleanup_strv_free_ char **l = NULL;
         _cleanup_free_ char *data = NULL;
         const char *p;
         char **i;
         int r;
 
-        assert(m);
+        assert(state_file);
+        assert(rules);
 
-        r = routing_policy_rule_read_full_file(m->state_file, &data);
+        r = routing_policy_rule_read_full_file(state_file, &data);
         if (r <= 0)
                 return r;
 
@@ -788,7 +948,7 @@ int routing_policy_rule_load(Manager *m) {
         if (!l)
                 return -ENOMEM;
 
-        r = set_ensure_allocated(&m->rules_saved, &routing_policy_rule_hash_ops);
+        r = set_ensure_allocated(rules, &routing_policy_rule_hash_ops);
         if (r < 0)
                 return r;
 
@@ -799,9 +959,6 @@ int routing_policy_rule_load(Manager *m) {
                 if (!p)
                         continue;
 
-                p = strchr(*i, '=');
-                p++;
-
                 r = routing_policy_rule_new(&rule);
                 if (r < 0)
                         return r;
@@ -856,15 +1013,24 @@ int routing_policy_rule_load(Manager *m) {
                                 }
                         } else if (streq(a, "fwmark")) {
 
-                                r = parse_fwmark_fwmask(a, &rule->fwmark, &rule->fwmask);
+                                r = parse_fwmark_fwmask(b, &rule->fwmark, &rule->fwmask);
                                 if (r < 0) {
                                         log_error_errno(r, "Failed to parse RPDB rule firewall mark or mask, ignoring: %s", a);
                                         continue;
                                 }
+                        } else if (streq(a, "iif")) {
+
+                                if (free_and_strdup(&rule->iif, b) < 0)
+                                        return log_oom();
+
+                        } else if (streq(a, "oif")) {
+
+                                if (free_and_strdup(&rule->oif, b) < 0)
+                                        return log_oom();
                         }
                 }
 
-                r = set_put(m->rules_saved, rule);
+                r = set_put(*rules, rule);
                 if (r < 0) {
                         log_warning_errno(r, "Failed to add RPDB rule to saved DB, ignoring: %s", p);
                         continue;
@@ -894,7 +1060,7 @@ void routing_policy_rule_purge(Manager *m, Link *link) {
                                 continue;
                         }
 
-                        link->link_messages++;
+                        link->routing_policy_rule_remove_messages++;
                 }
         }
 }
index d9fd93b..70a8617 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -49,6 +50,9 @@ struct RoutingPolicyRule {
         unsigned char to_prefixlen;
         unsigned char from_prefixlen;
 
+        char *iif;
+        char *oif;
+
         union in_addr_union to;
         union in_addr_union from;
 
@@ -67,13 +71,14 @@ int link_routing_policy_rule_remove_handler(sd_netlink *rtnl, sd_netlink_message
 int link_routing_policy_rule_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata);
 
 int routing_policy_rule_add(Manager *m, int family, const union in_addr_union *from, uint8_t from_prefixlen, const union in_addr_union *to, uint8_t to_prefixlen,
-                            uint8_t tos, uint32_t fwmark, uint32_t table, RoutingPolicyRule **ret);
+                            uint8_t tos, uint32_t fwmark, uint32_t table, char *iif, char *oif, RoutingPolicyRule **ret);
 int routing_policy_rule_add_foreign(Manager *m, int family, const union in_addr_union *from, uint8_t from_prefixlen, const union in_addr_union *to, uint8_t to_prefixlen,
-                                    uint8_t tos, uint32_t fwmark, uint32_t table, RoutingPolicyRule **ret);
+                                    uint8_t tos, uint32_t fwmark, uint32_t table, char *iif, char *oif, RoutingPolicyRule **ret);
 int routing_policy_rule_get(Manager *m, int family, const union in_addr_union *from, uint8_t from_prefixlen, const union in_addr_union *to, uint8_t to_prefixlen, uint8_t tos,
-                            uint32_t fwmark, uint32_t table, RoutingPolicyRule **ret);
+                            uint32_t fwmark, uint32_t table, char *iif, char *oif, RoutingPolicyRule **ret);
 int routing_policy_rule_make_local(Manager *m, RoutingPolicyRule *rule);
-int routing_policy_rule_load(Manager *m);
+int routing_policy_serialize_rules(Set *rules, FILE *f);
+int routing_policy_load_rules(const char *state_file, Set **rules);
 void routing_policy_rule_purge(Manager *m, Link *link);
 
 int config_parse_routing_policy_rule_tos(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data,void *userdata);
@@ -81,3 +86,4 @@ int config_parse_routing_policy_rule_table(const char *unit, const char *filenam
 int config_parse_routing_policy_rule_fwmark_mask(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_routing_policy_rule_prefix(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_routing_policy_rule_priority(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data,void *userdata);
+int config_parse_routing_policy_rule_device(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data,void *userdata);
index 8856e76..b9c533f 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index d5c385b..69ea93a 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index d5ba689..9243384 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -54,19 +55,19 @@ int main(int argc, char *argv[]) {
 
         /* Always create the directories people can create inotify
          * watches in. */
-        r = mkdir_safe_label("/run/systemd/netif", 0755, uid, gid);
+        r = mkdir_safe_label("/run/systemd/netif", 0755, uid, gid, false);
         if (r < 0)
                 log_warning_errno(r, "Could not create runtime directory: %m");
 
-        r = mkdir_safe_label("/run/systemd/netif/links", 0755, uid, gid);
+        r = mkdir_safe_label("/run/systemd/netif/links", 0755, uid, gid, false);
         if (r < 0)
                 log_warning_errno(r, "Could not create runtime directory 'links': %m");
 
-        r = mkdir_safe_label("/run/systemd/netif/leases", 0755, uid, gid);
+        r = mkdir_safe_label("/run/systemd/netif/leases", 0755, uid, gid, false);
         if (r < 0)
                 log_warning_errno(r, "Could not create runtime directory 'leases': %m");
 
-        r = mkdir_safe_label("/run/systemd/netif/lldp", 0755, uid, gid);
+        r = mkdir_safe_label("/run/systemd/netif/lldp", 0755, uid, gid, false);
         if (r < 0)
                 log_warning_errno(r, "Could not create runtime directory 'lldp': %m");
 
index bea885f..641a1a5 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 64d2f23..f3e8f50 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
+#include <sys/param.h>
+
 #include "alloc-util.h"
 #include "dhcp-lease-internal.h"
+#include "hostname-util.h"
 #include "network-internal.h"
 #include "networkd-manager.h"
+#include "string-util.h"
+#include "udev-util.h"
 
 static void test_deserialize_in_addr(void) {
         _cleanup_free_ struct in_addr *addresses = NULL;
@@ -184,27 +190,70 @@ static void test_address_equality(void) {
         assert_se(!address_equal(a1, a2));
 }
 
+static void test_dhcp_hostname_shorten_overlong(void) {
+        int r;
+
+        {
+                /* simple hostname, no actions, no errors */
+                _cleanup_free_ char *shortened = NULL;
+                r = shorten_overlong("name1", &shortened);
+                assert_se(r == 0);
+                assert_se(streq("name1", shortened));
+        }
+
+        {
+                /* simple fqdn, no actions, no errors */
+                _cleanup_free_ char *shortened = NULL;
+                r = shorten_overlong("name1.example.com", &shortened);
+                assert_se(r == 0);
+                assert_se(streq("name1.example.com", shortened));
+        }
+
+        {
+                /* overlong fqdn, cut to first dot, no errors */
+                _cleanup_free_ char *shortened = NULL;
+                r = shorten_overlong("name1.test-dhcp-this-one-here-is-a-very-very-long-domain.example.com", &shortened);
+                assert_se(r == 1);
+                assert_se(streq("name1", shortened));
+        }
+
+        {
+                /* overlong hostname, cut to HOST_MAX_LEN, no errors */
+                _cleanup_free_ char *shortened = NULL;
+                r = shorten_overlong("test-dhcp-this-one-here-is-a-very-very-long-hostname-without-domainname", &shortened);
+                assert_se(r == 1);
+                assert_se(streq("test-dhcp-this-one-here-is-a-very-very-long-hostname-without-dom", shortened));
+        }
+
+        {
+                /* overlong fqdn, cut to first dot, empty result error */
+                _cleanup_free_ char *shortened = NULL;
+                r = shorten_overlong(".test-dhcp-this-one-here-is-a-very-very-long-hostname.example.com", &shortened);
+                assert_se(r == -EDOM);
+                assert_se(shortened == NULL);
+        }
+
+}
+
 int main(void) {
         _cleanup_manager_free_ Manager *manager = NULL;
-        sd_event *event;
-        struct udev *udev;
-        struct udev_device *loopback;
+        _cleanup_(sd_event_unrefp) sd_event *event = NULL;
+        _cleanup_udev_unref_ struct udev *udev = NULL;
+        _cleanup_udev_device_unref_ struct udev_device *loopback = NULL;
         int r;
 
         test_deserialize_in_addr();
         test_deserialize_dhcp_routes();
         test_address_equality();
+        test_dhcp_hostname_shorten_overlong();
 
-        r = sd_event_default(&event);
-        assert_se(r >= 0);
+        assert_se(sd_event_default(&event) >= 0);
 
         assert_se(manager_new(&manager, event) >= 0);
 
         r = test_load_config(manager);
-        if (r == -EPERM) {
-                sd_event_unref(event);
+        if (r == -EPERM)
                 return EXIT_TEST_SKIP;
-        }
 
         udev = udev_new();
         assert_se(udev);
@@ -216,8 +265,4 @@ int main(void) {
         test_network_get(manager, loopback);
 
         assert_se(manager_rtnl_enumerate_links(manager) >= 0);
-
-        udev_device_unref(loopback);
-        udev_unref(udev);
-        sd_event_unref(event);
 }
index 0e1a184..530bbf8 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
diff --git a/src/network/test-routing-policy-rule.c b/src/network/test-routing-policy-rule.c
new file mode 100644 (file)
index 0000000..c29d134
--- /dev/null
@@ -0,0 +1,106 @@
+/***
+  SPDX-License-Identifier: LGPL-2.1+
+
+  This file is part of systemd.
+
+  Copyright 2017 Zbigniew Jędrzejewski-Szmek
+
+  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.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "fd-util.h"
+#include "fileio.h"
+#include "log.h"
+#include "macro.h"
+#include "network-internal.h"
+#include "networkd-manager.h"
+#include "string-util.h"
+
+static void test_rule_serialization(const char *title, const char *ruleset, const char *expected) {
+        char pattern[] = "/tmp/systemd-test-routing-policy-rule.XXXXXX",
+             pattern2[] = "/tmp/systemd-test-routing-policy-rule.XXXXXX",
+             pattern3[] = "/tmp/systemd-test-routing-policy-rule.XXXXXX";
+        const char *cmd;
+        int fd, fd2, fd3;
+        _cleanup_fclose_ FILE *f = NULL, *f2 = NULL, *f3 = NULL;
+        Set *rules = NULL;
+        _cleanup_free_ char *buf = NULL;
+        size_t buf_size;
+
+        log_info("========== %s ==========", title);
+        log_info("put:\n%s\n", ruleset);
+
+        assert_se((fd = mkostemp_safe(pattern)) >= 0);
+        assert_se(f = fdopen(fd, "a+e"));
+        assert_se(write_string_stream(f, ruleset, 0) == 0);
+
+        assert_se(routing_policy_load_rules(pattern, &rules) == 0);
+
+        assert_se((fd2 = mkostemp_safe(pattern2)) >= 0);
+        assert_se(f2 = fdopen(fd2, "a+e"));
+
+        assert_se(routing_policy_serialize_rules(rules, f2) == 0);
+        assert_se(fflush_and_check(f2) == 0);
+
+        assert_se(read_full_file(pattern2, &buf, &buf_size) == 0);
+
+        log_info("got:\n%s", buf);
+
+        assert_se((fd3 = mkostemp_safe(pattern3)) >= 0);
+        assert_se(f3 = fdopen(fd3, "we"));
+        assert_se(write_string_stream(f3, expected ?: ruleset, 0) == 0);
+
+        cmd = strjoina("diff -u ", pattern3, " ", pattern2);
+        log_info("$ %s", cmd);
+        assert_se(system(cmd) == 0);
+
+        set_free_with_destructor(rules, routing_policy_rule_free);
+}
+
+int main(int argc, char **argv) {
+        _cleanup_free_ char *p = NULL;
+
+        log_set_max_level(LOG_DEBUG);
+        log_parse_environment();
+        log_open();
+
+        test_rule_serialization("basic parsing",
+                                "RULE=from=1.2.3.4/32 to=2.3.4.5/32 tos=5 fwmark=1/2 table=10", NULL);
+
+        test_rule_serialization("ignored values",
+                                "RULE=something=to=ignore from=1.2.3.4/32 from=1.2.3.4/32"
+                                "   \t  to=2.3.4.5/24 to=2.3.4.5/32 tos=5 fwmark=2 fwmark=1 table=10 table=20",
+                                "RULE=from=1.2.3.4/32"
+                                " to=2.3.4.5/32 tos=5 fwmark=1/0 table=20");
+
+        test_rule_serialization("ipv6",
+                                "RULE=from=1::2/64 to=2::3/64 table=6", NULL);
+
+        assert_se(asprintf(&p, "RULE=from=1::2/64 to=2::3/64 table=%d", RT_TABLE_MAIN) >= 0);
+        test_rule_serialization("default table",
+                                "RULE=from=1::2/64 to=2::3/64", p);
+
+        test_rule_serialization("incoming interface",
+                                "RULE=from=1::2/64 to=2::3/64 table=1 iif=lo",
+                                "RULE=from=1::2/64 to=2::3/64 iif=lo table=1");
+
+        test_rule_serialization("outgoing interface",
+                                "RULE=from=1::2/64 to=2::3/64 oif=eth0 table=1", NULL);
+
+        test_rule_serialization("freeing interface names",
+                                "RULE=from=1::2/64 to=2::3/64 iif=e0 iif=e1 oif=e0 oif=e1 table=1",
+                                "RULE=from=1::2/64 to=2::3/64 iif=e1 oif=e1 table=1");
+
+        return 0;
+}
index bd8578c..f0cb70a 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -120,6 +121,8 @@ int link_update_rtnl(Link *l, sd_netlink_message *m) {
 int link_update_monitor(Link *l) {
         assert(l);
 
+        l->required_for_online = sd_network_link_get_required_for_online(l->ifindex) != 0;
+
         l->operational_state = mfree(l->operational_state);
 
         sd_network_link_get_operational_state(l->ifindex, &l->operational_state);
index c846e60..ab623ff 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -32,6 +33,7 @@ struct Link {
         char *ifname;
         unsigned flags;
 
+        bool required_for_online;
         char *operational_state;
         char *state;
 };
@@ -40,6 +42,5 @@ int link_new(Manager *m, Link **ret, int ifindex, const char *ifname);
 Link *link_free(Link *l);
 int link_update_rtnl(Link *l, sd_netlink_message *m);
 int link_update_monitor(Link *l);
-bool link_relevant(Link *l);
 
 DEFINE_TRIVIAL_CLEANUP_FUNC(Link*, link_free);
index d51b0a5..05f030d 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -41,6 +42,9 @@ bool manager_ignore_link(Manager *m, Link *link) {
         if (m->interfaces && !strv_contains(m->interfaces, link->ifname))
                 return true;
 
+        if (!link->required_for_online)
+                return true;
+
         /* ignore interfaces we explicitly are asked to ignore */
         return strv_fnmatch(m->ignore, link->ifname, 0);
 }
index 052f6b9..7a8c4ea 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 268cbdb..7b13a5d 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 
 /***
   This file is part of systemd.
index 81a5f0a..523ca91 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index b6ac600..b1e7134 100644 (file)
@@ -1,25 +1,43 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
+# Copyright 2017 Zbigniew Jędrzejewski-Szmek
+#
+# 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.
+#
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
 systemd_nspawn_sources = files('''
-        nspawn.c
-        nspawn-settings.c
-        nspawn-settings.h
+        nspawn-cgroup.c
+        nspawn-cgroup.h
+        nspawn-def.h
+        nspawn-expose-ports.c
+        nspawn-expose-ports.h
         nspawn-mount.c
         nspawn-mount.h
         nspawn-network.c
         nspawn-network.h
-        nspawn-expose-ports.c
-        nspawn-expose-ports.h
-        nspawn-cgroup.c
-        nspawn-cgroup.h
-        nspawn-seccomp.c
-        nspawn-seccomp.h
+        nspawn-patch-uid.c
+        nspawn-patch-uid.h
         nspawn-register.c
         nspawn-register.h
+        nspawn-seccomp.c
+        nspawn-seccomp.h
+        nspawn-settings.c
+        nspawn-settings.h
         nspawn-setuid.c
         nspawn-setuid.h
         nspawn-stub-pid1.c
         nspawn-stub-pid1.h
-        nspawn-patch-uid.c
-        nspawn-patch-uid.h
+        nspawn.c
 '''.split())
 
 nspawn_gperf_c = custom_target(
index fd565c0..d51585a 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -40,13 +41,15 @@ static int chown_cgroup_path(const char *path, uid_t uid_shift) {
 
         FOREACH_STRING(fn,
                        ".",
-                       "tasks",
-                       "notify_on_release",
-                       "cgroup.procs",
-                       "cgroup.events",
                        "cgroup.clone_children",
                        "cgroup.controllers",
-                       "cgroup.subtree_control")
+                       "cgroup.events",
+                       "cgroup.procs",
+                       "cgroup.stat",
+                       "cgroup.subtree_control",
+                       "cgroup.threads",
+                       "notify_on_release",
+                       "tasks")
                 if (fchownat(fd, fn, uid_shift, uid_shift, 0) < 0)
                         log_full_errno(errno == ENOENT ? LOG_DEBUG :  LOG_WARNING, errno,
                                        "Failed to chown \"%s/%s\", ignoring: %m", path, fn);
@@ -54,7 +57,7 @@ static int chown_cgroup_path(const char *path, uid_t uid_shift) {
         return 0;
 }
 
-int chown_cgroup(pid_t pid, uid_t uid_shift) {
+int chown_cgroup(pid_t pid, CGroupUnified unified_requested, uid_t uid_shift) {
         _cleanup_free_ char *path = NULL, *fs = NULL;
         int r;
 
@@ -70,6 +73,19 @@ int chown_cgroup(pid_t pid, uid_t uid_shift) {
         if (r < 0)
                 return log_error_errno(r, "Failed to chown() cgroup %s: %m", fs);
 
+        if (unified_requested == CGROUP_UNIFIED_SYSTEMD) {
+                _cleanup_free_ char *lfs = NULL;
+                /* Always propagate access rights from unified to legacy controller */
+
+                r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER_LEGACY, path, NULL, &lfs);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to get file system path for container cgroup: %m");
+
+                r = chown_cgroup_path(lfs, uid_shift);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to chown() cgroup %s: %m", lfs);
+        }
+
         return 0;
 }
 
index fa4321a..3855e5b 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -24,6 +25,6 @@
 
 #include "cgroup-util.h"
 
-int chown_cgroup(pid_t pid, uid_t uid_shift);
+int chown_cgroup(pid_t pid, CGroupUnified unified_requested, uid_t uid_shift);
 int sync_cgroup(pid_t pid, CGroupUnified unified_requested, uid_t uid_shift);
 int create_subcgroup(pid_t pid, CGroupUnified unified_requested);
diff --git a/src/nspawn/nspawn-def.h b/src/nspawn/nspawn-def.h
new file mode 100644 (file)
index 0000000..43a19d8
--- /dev/null
@@ -0,0 +1,27 @@
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2017 Lennart Poettering
+
+  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.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/types.h>
+
+/* While we are chmod()ing a directory tree, we set the top-level UID base to this "busy" base, so that we can always
+ * recognize trees we are were chmod()ing recursively and got interrupted in */
+#define UID_BUSY_BASE ((uid_t) UINT32_C(0xFFFE0000))
+#define UID_BUSY_MASK ((uid_t) UINT32_C(0xFFFF0000))
index bcaf0aa..98eb850 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 741ad97..bd88343 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index b61b347..ea66971 100644 (file)
@@ -1,4 +1,7 @@
 %{
+#if __GNUC__ >= 7
+_Pragma("GCC diagnostic ignored \"-Wimplicit-fallthrough\"")
+#endif
 #include <stddef.h>
 #include "conf-parser.h"
 #include "nspawn-settings.h"
index 531f29c..920e114 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -367,7 +368,7 @@ static int tmpfs_patch_options(
                 assert(uid_shift != UID_INVALID);
 
                 if (asprintf(&buf, "%s%suid=" UID_FMT ",gid=" UID_FMT,
-                             options ?: "", options ? "," : "",
+                             strempty(options), options ? "," : "",
                              uid_shift, uid_shift) < 0)
                         return -ENOMEM;
 
@@ -378,7 +379,7 @@ static int tmpfs_patch_options(
         if (selinux_apifs_context) {
                 char *t;
 
-                t = strjoin(options ?: "", options ? "," : "",
+                t = strjoin(strempty(options), options ? "," : "",
                             "context=\"", selinux_apifs_context, "\"");
                 free(buf);
                 if (!t)
@@ -404,7 +405,7 @@ int mount_sysfs(const char *dest, MountSettingsMask mount_settings) {
         unsigned long extra_flags = 0;
 
         top = prefix_roota(dest, "/sys");
-        r = path_check_fstype(top, SYSFS_MAGIC);
+        r = path_is_fs_type(top, SYSFS_MAGIC);
         if (r < 0)
                 return log_error_errno(r, "Failed to determine filesystem type of %s: %m", top);
         /* /sys might already be mounted as sysfs by the outer child in the
@@ -598,11 +599,15 @@ int mount_all(const char *dest,
 
                 r = mkdir_userns_p(dest, where, 0755, mount_settings, uid_shift);
                 if (r < 0 && r != -EEXIST) {
-                        if (fatal)
+                        if (fatal && r != -EROFS)
                                 return log_error_errno(r, "Failed to create directory %s: %m", where);
 
                         log_debug_errno(r, "Failed to create directory %s: %m", where);
-                        continue;
+                        /* If we failed mkdir() or chown() due to the root
+                         * directory being read only, attempt to mount this fs
+                         * anyway and let mount_verbose log any errors */
+                        if (r != -EROFS)
+                                continue;
                 }
 
                 o = mount_table[k].options;
@@ -862,19 +867,30 @@ int mount_custom(
 /* Retrieve existing subsystems. This function is called in a new cgroup
  * namespace.
  */
-static int get_controllers(Set *subsystems) {
+static int get_process_controllers(Set **ret) {
+        _cleanup_set_free_free_ Set *controllers = NULL;
         _cleanup_fclose_ FILE *f = NULL;
-        char line[LINE_MAX];
+        int r;
 
-        assert(subsystems);
+        assert(ret);
+
+        controllers = set_new(&string_hash_ops);
+        if (!controllers)
+                return -ENOMEM;
 
         f = fopen("/proc/self/cgroup", "re");
         if (!f)
                 return errno == ENOENT ? -ESRCH : -errno;
 
-        FOREACH_LINE(line, f, return -errno) {
-                int r;
-                char *e, *l, *p;
+        for (;;) {
+                _cleanup_free_ char *line = NULL;
+                char *e, *l;
+
+                r = read_line(f, LONG_LINE_MAX, &line);
+                if (r < 0)
+                        return r;
+                if (r == 0)
+                        break;
 
                 l = strchr(line, ':');
                 if (!l)
@@ -890,15 +906,14 @@ static int get_controllers(Set *subsystems) {
                 if (STR_IN_SET(l, "", "name=systemd", "name=unified"))
                         continue;
 
-                p = strdup(l);
-                if (!p)
-                        return -ENOMEM;
-
-                r = set_consume(subsystems, p);
+                r = set_put_strdup(controllers, l);
                 if (r < 0)
                         return r;
         }
 
+        *ret = controllers;
+        controllers = NULL;
+
         return 0;
 }
 
@@ -994,11 +1009,7 @@ static int mount_legacy_cgns_supported(
         if (r > 0)
                 goto skip_controllers;
 
-        controllers = set_new(&string_hash_ops);
-        if (!controllers)
-                return log_oom();
-
-        r = get_controllers(controllers);
+        r = get_process_controllers(&controllers);
         if (r < 0)
                 return log_error_errno(r, "Failed to determine cgroup controllers: %m");
 
@@ -1027,13 +1038,13 @@ static int mount_legacy_cgns_supported(
                         if (r == 0)
                                 break;
 
-                        target = prefix_root("/sys/fs/cgroup", tok);
-                        if (!target)
-                                return log_oom();
-
                         if (streq(controller, tok))
                                 break;
 
+                        target = prefix_root("/sys/fs/cgroup/", tok);
+                        if (!target)
+                                return log_oom();
+
                         r = symlink_idempotent(controller, target);
                         if (r == -EINVAL)
                                 return log_error_errno(r, "Invalid existing symlink for combined hierarchy: %m");
@@ -1100,11 +1111,7 @@ static int mount_legacy_cgns_unsupported(
         if (r > 0)
                 goto skip_controllers;
 
-        controllers = set_new(&string_hash_ops);
-        if (!controllers)
-                return log_oom();
-
-        r = cg_kernel_controllers(controllers);
+        r = cg_kernel_controllers(&controllers);
         if (r < 0)
                 return log_error_errno(r, "Failed to determine cgroup controllers: %m");
 
@@ -1208,23 +1215,25 @@ int mount_cgroups(
 
         if (unified_requested >= CGROUP_UNIFIED_ALL)
                 return mount_unified_cgroups(dest);
-        else if (use_cgns)
+        if (use_cgns)
                 return mount_legacy_cgns_supported(dest, unified_requested, userns, uid_shift, uid_range, selinux_apifs_context);
 
         return mount_legacy_cgns_unsupported(dest, unified_requested, userns, uid_shift, uid_range, selinux_apifs_context);
 }
 
-static int mount_systemd_cgroup_writable_one(const char *systemd_own, const char *systemd_root)
-{
+static int mount_systemd_cgroup_writable_one(const char *root, const char *own) {
         int r;
 
+        assert(root);
+        assert(own);
+
         /* Make our own cgroup a (writable) bind mount */
-        r = mount_verbose(LOG_ERR, systemd_own, systemd_own,  NULL, MS_BIND, NULL);
+        r = mount_verbose(LOG_ERR, own, own, NULL, MS_BIND, NULL);
         if (r < 0)
                 return r;
 
         /* And then remount the systemd cgroup root read-only */
-        return mount_verbose(LOG_ERR, NULL, systemd_root, NULL,
+        return mount_verbose(LOG_ERR, NULL, root, NULL,
                              MS_BIND|MS_REMOUNT|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RDONLY, NULL);
 }
 
@@ -1233,6 +1242,7 @@ int mount_systemd_cgroup_writable(
                 CGroupUnified unified_requested) {
 
         _cleanup_free_ char *own_cgroup_path = NULL;
+        const char *root, *own;
         int r;
 
         assert(dest);
@@ -1245,19 +1255,27 @@ int mount_systemd_cgroup_writable(
         if (path_equal(own_cgroup_path, "/"))
                 return 0;
 
-        if (unified_requested >= CGROUP_UNIFIED_ALL)
-                return mount_systemd_cgroup_writable_one(strjoina(dest, "/sys/fs/cgroup", own_cgroup_path),
-                                                         prefix_roota(dest, "/sys/fs/cgroup"));
+        if (unified_requested >= CGROUP_UNIFIED_ALL) {
 
-        if (unified_requested >= CGROUP_UNIFIED_SYSTEMD) {
-                r = mount_systemd_cgroup_writable_one(strjoina(dest, "/sys/fs/cgroup/unified", own_cgroup_path),
-                                                      prefix_roota(dest, "/sys/fs/cgroup/unified"));
-                if (r < 0)
-                        return r;
+                root = prefix_roota(dest, "/sys/fs/cgroup");
+                own = strjoina(root, own_cgroup_path);
+
+        } else {
+
+                if (unified_requested >= CGROUP_UNIFIED_SYSTEMD) {
+                        root = prefix_roota(dest, "/sys/fs/cgroup/unified");
+                        own = strjoina(root, own_cgroup_path);
+
+                        r = mount_systemd_cgroup_writable_one(root, own);
+                        if (r < 0)
+                                return r;
+                }
+
+                root = prefix_roota(dest, "/sys/fs/cgroup/systemd");
+                own = strjoina(root, own_cgroup_path);
         }
 
-        return mount_systemd_cgroup_writable_one(strjoina(dest, "/sys/fs/cgroup/systemd", own_cgroup_path),
-                                                 prefix_roota(dest, "/sys/fs/cgroup/systemd"));
+        return mount_systemd_cgroup_writable_one(root, own);
 }
 
 int setup_volatile_state(
index 2777d21..79c2390 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index aa61aaa..ef1da33 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 3d8861e..b79e139 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 063fdb1..7081ed0 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
 #include <sys/acl.h>
 #endif
 #include <sys/stat.h>
+#include <sys/statvfs.h>
 #include <sys/vfs.h>
 #include <unistd.h>
 
 #include "acl-util.h"
 #include "dirent-util.h"
 #include "fd-util.h"
+#include "fs-util.h"
 #include "missing.h"
+#include "nspawn-def.h"
 #include "nspawn-patch-uid.h"
 #include "stat-util.h"
 #include "stdio-util.h"
@@ -40,7 +44,7 @@
 #if HAVE_ACL
 
 static int get_acl(int fd, const char *name, acl_type_t type, acl_t *ret) {
-        char procfs_path[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(int) + 1];
+        char procfs_path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int) + 1];
         acl_t acl;
 
         assert(fd >= 0);
@@ -69,7 +73,7 @@ static int get_acl(int fd, const char *name, acl_type_t type, acl_t *ret) {
 }
 
 static int set_acl(int fd, const char *name, acl_type_t type, acl_t acl) {
-        char procfs_path[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(int) + 1];
+        char procfs_path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int) + 1];
         int r;
 
         assert(fd >= 0);
@@ -289,42 +293,44 @@ static int patch_fd(int fd, const char *name, const struct stat *st, uid_t shift
  * user namespaces, however their inodes may relate to host resources or only
  * valid in the global user namespace, therefore no patching should be applied.
  */
-static int is_fs_fully_userns_compatible(int fd) {
-        struct statfs sfs;
-
-        assert(fd >= 0);
-
-        if (fstatfs(fd, &sfs) < 0)
-                return -errno;
-
-        return F_TYPE_EQUAL(sfs.f_type, BINFMTFS_MAGIC) ||
-               F_TYPE_EQUAL(sfs.f_type, CGROUP_SUPER_MAGIC) ||
-               F_TYPE_EQUAL(sfs.f_type, CGROUP2_SUPER_MAGIC) ||
-               F_TYPE_EQUAL(sfs.f_type, DEBUGFS_MAGIC) ||
-               F_TYPE_EQUAL(sfs.f_type, DEVPTS_SUPER_MAGIC) ||
-               F_TYPE_EQUAL(sfs.f_type, EFIVARFS_MAGIC) ||
-               F_TYPE_EQUAL(sfs.f_type, HUGETLBFS_MAGIC) ||
-               F_TYPE_EQUAL(sfs.f_type, MQUEUE_MAGIC) ||
-               F_TYPE_EQUAL(sfs.f_type, PROC_SUPER_MAGIC) ||
-               F_TYPE_EQUAL(sfs.f_type, PSTOREFS_MAGIC) ||
-               F_TYPE_EQUAL(sfs.f_type, SELINUX_MAGIC) ||
-               F_TYPE_EQUAL(sfs.f_type, SMACK_MAGIC) ||
-               F_TYPE_EQUAL(sfs.f_type, SECURITYFS_MAGIC) ||
-               F_TYPE_EQUAL(sfs.f_type, BPF_FS_MAGIC) ||
-               F_TYPE_EQUAL(sfs.f_type, TRACEFS_MAGIC) ||
-               F_TYPE_EQUAL(sfs.f_type, SYSFS_MAGIC);
+static int is_fs_fully_userns_compatible(const struct statfs *sfs) {
+
+        assert(sfs);
+
+        return F_TYPE_EQUAL(sfs->f_type, BINFMTFS_MAGIC) ||
+               F_TYPE_EQUAL(sfs->f_type, CGROUP_SUPER_MAGIC) ||
+               F_TYPE_EQUAL(sfs->f_type, CGROUP2_SUPER_MAGIC) ||
+               F_TYPE_EQUAL(sfs->f_type, DEBUGFS_MAGIC) ||
+               F_TYPE_EQUAL(sfs->f_type, DEVPTS_SUPER_MAGIC) ||
+               F_TYPE_EQUAL(sfs->f_type, EFIVARFS_MAGIC) ||
+               F_TYPE_EQUAL(sfs->f_type, HUGETLBFS_MAGIC) ||
+               F_TYPE_EQUAL(sfs->f_type, MQUEUE_MAGIC) ||
+               F_TYPE_EQUAL(sfs->f_type, PROC_SUPER_MAGIC) ||
+               F_TYPE_EQUAL(sfs->f_type, PSTOREFS_MAGIC) ||
+               F_TYPE_EQUAL(sfs->f_type, SELINUX_MAGIC) ||
+               F_TYPE_EQUAL(sfs->f_type, SMACK_MAGIC) ||
+               F_TYPE_EQUAL(sfs->f_type, SECURITYFS_MAGIC) ||
+               F_TYPE_EQUAL(sfs->f_type, BPF_FS_MAGIC) ||
+               F_TYPE_EQUAL(sfs->f_type, TRACEFS_MAGIC) ||
+               F_TYPE_EQUAL(sfs->f_type, SYSFS_MAGIC);
 }
 
 static int recurse_fd(int fd, bool donate_fd, const struct stat *st, uid_t shift, bool is_toplevel) {
+        _cleanup_closedir_ DIR *d = NULL;
         bool changed = false;
+        struct statfs sfs;
         int r;
 
         assert(fd >= 0);
 
-        /* We generally want to permit crossing of mount boundaries when patching the UIDs/GIDs. However, we
-         * probably shouldn't do this for /proc and /sys if that is already mounted into place. Hence, let's
-         * stop the recursion when we hit procfs, sysfs or some other special file systems. */
-        r = is_fs_fully_userns_compatible(fd);
+        if (fstatfs(fd, &sfs) < 0)
+                return -errno;
+
+        /* We generally want to permit crossing of mount boundaries when patching the UIDs/GIDs. However, we probably
+         * shouldn't do this for /proc and /sys if that is already mounted into place. Hence, let's stop the recursion
+         * when we hit procfs, sysfs or some other special file systems. */
+
+        r = is_fs_fully_userns_compatible(&sfs);
         if (r < 0)
                 goto finish;
         if (r > 0) {
@@ -332,26 +338,12 @@ static int recurse_fd(int fd, bool donate_fd, const struct stat *st, uid_t shift
                 goto finish;
         }
 
-        r = patch_fd(fd, NULL, st, shift);
-        if (r == -EROFS) {
-                _cleanup_free_ char *name = NULL;
-
-                if (!is_toplevel) {
-                        /* When we hit a ready-only subtree we simply skip it, but log about it. */
-                        (void) fd_get_path(fd, &name);
-                        log_debug("Skippping read-only file or directory %s.", strna(name));
-                        r = 0;
-                }
-
-                goto finish;
-        }
-        if (r < 0)
-                goto finish;
-        if (r > 0)
-                changed = true;
+        /* Also, if we hit a read-only file system, then don't bother, skip the whole subtree */
+        if ((sfs.f_flags & ST_RDONLY) ||
+            access_fd(fd, W_OK) == -EROFS)
+                goto read_only;
 
         if (S_ISDIR(st->st_mode)) {
-                _cleanup_closedir_ DIR *d = NULL;
                 struct dirent *de;
 
                 if (!donate_fd) {
@@ -411,7 +403,27 @@ static int recurse_fd(int fd, bool donate_fd, const struct stat *st, uid_t shift
                 }
         }
 
+        /* After we descended, also patch the directory itself. It's key to do this in this order so that the top-level
+         * directory is patched as very last object in the tree, so that we can use it as quick indicator whether the
+         * tree is properly chown()ed already. */
+        r = patch_fd(d ? dirfd(d) : fd, NULL, st, shift);
+        if (r == -EROFS)
+                goto read_only;
+        if (r > 0)
+                changed = true;
+
         r = changed;
+        goto finish;
+
+read_only:
+        if (!is_toplevel) {
+                _cleanup_free_ char *name = NULL;
+
+                /* When we hit a ready-only subtree we simply skip it, but log about it. */
+                (void) fd_get_path(fd, &name);
+                log_debug("Skippping read-only file or directory %s.", strna(name));
+                r = changed;
+        }
 
 finish:
         if (donate_fd)
@@ -437,6 +449,11 @@ static int fd_patch_uid_internal(int fd, bool donate_fd, uid_t shift, uid_t rang
                 goto finish;
         }
 
+        if (shift == UID_BUSY_BASE) {
+                r = -EINVAL;
+                goto finish;
+        }
+
         if (range != 0x10000) {
                 /* We only support containers with 16bit UID ranges for the patching logic */
                 r = -EOPNOTSUPP;
@@ -459,6 +476,19 @@ static int fd_patch_uid_internal(int fd, bool donate_fd, uid_t shift, uid_t rang
         if (((uint32_t) (st.st_uid ^ shift) >> 16) == 0)
                 return 0;
 
+        /* Before we start recursively chowning, mark the top-level dir as "busy" by chowning it to the "busy"
+         * range. Should we be interrupted in the middle of our work, we'll see it owned by this user and will start
+         * chown()ing it again, unconditionally, as the busy UID is not a valid UID we'd everpick for ourselves. */
+
+        if ((st.st_uid & UID_BUSY_MASK) != UID_BUSY_BASE) {
+                if (fchown(fd,
+                           UID_BUSY_BASE | (st.st_uid & ~UID_BUSY_MASK),
+                           (gid_t) UID_BUSY_BASE | (st.st_gid & ~(gid_t) UID_BUSY_MASK)) < 0) {
+                        r = -errno;
+                        goto finish;
+                }
+        }
+
         return recurse_fd(fd, donate_fd, &st, shift, true);
 
 finish:
index 55d0990..fc1d22b 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -17,6 +18,8 @@
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
+#pragma once
+
 #include <sys/types.h>
 
 int fd_patch_uid(int fd, uid_t shift, uid_t range);
index 5b0faf8..ef9db31 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -98,7 +99,26 @@ static int append_machine_properties(
         return 0;
 }
 
+static int append_controller_property(sd_bus *bus, sd_bus_message *m) {
+        const char *unique;
+        int r;
+
+        assert(bus);
+        assert(m);
+
+        r = sd_bus_get_unique_name(bus, &unique);
+        if (r < 0)
+                return log_error_errno(r, "Failed to get unique name: %m");
+
+        r = sd_bus_message_append(m, "(sv)", "Controller", "s", unique);
+        if (r < 0)
+                return bus_log_create_error(r);
+
+        return 0;
+}
+
 int register_machine(
+                sd_bus *bus,
                 const char *machine_name,
                 pid_t pid,
                 const char *directory,
@@ -113,12 +133,9 @@ int register_machine(
                 const char *service) {
 
         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
-        _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
         int r;
 
-        r = sd_bus_default_system(&bus);
-        if (r < 0)
-                return log_error_errno(r, "Failed to open system bus: %m");
+        assert(bus);
 
         if (keep_unit) {
                 r = sd_bus_call_method(
@@ -173,6 +190,10 @@ int register_machine(
                                 return bus_log_create_error(r);
                 }
 
+                r = append_controller_property(bus, m);
+                if (r < 0)
+                        return r;
+
                 r = append_machine_properties(
                                 m,
                                 mounts,
@@ -201,16 +222,13 @@ int register_machine(
         return 0;
 }
 
-int terminate_machine(pid_t pid) {
+int terminate_machine(sd_bus *bus, pid_t pid) {
         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
         _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
-        _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
         const char *path;
         int r;
 
-        r = sd_bus_default_system(&bus);
-        if (r < 0)
-                return log_error_errno(r, "Failed to open system bus: %m");
+        assert(bus);
 
         r = sd_bus_call_method(
                         bus,
@@ -252,6 +270,7 @@ int terminate_machine(pid_t pid) {
 }
 
 int allocate_scope(
+                sd_bus *bus,
                 const char *machine_name,
                 pid_t pid,
                 const char *slice,
@@ -262,16 +281,13 @@ int allocate_scope(
 
         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
         _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
-        _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
         _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
         _cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *w = NULL;
         _cleanup_free_ char *scope = NULL;
         const char *description, *object;
         int r;
 
-        r = sd_bus_default_system(&bus);
-        if (r < 0)
-                return log_error_errno(r, "Failed to open system bus: %m");
+        assert(bus);
 
         r = bus_wait_for_jobs_new(bus, &w);
         if (r < 0)
@@ -310,6 +326,10 @@ int allocate_scope(
         if (r < 0)
                 return bus_log_create_error(r);
 
+        r = append_controller_property(bus, m);
+        if (r < 0)
+                return r;
+
         r = append_machine_properties(
                         m,
                         mounts,
index 6694b3f..fa3644c 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -25,7 +26,7 @@
 
 #include "nspawn-mount.h"
 
-int register_machine(const char *machine_name, pid_t pid, const char *directory, sd_id128_t uuid, int local_ifindex, const char *slice, CustomMount *mounts, unsigned n_mounts, int kill_signal, char **properties, bool keep_unit, const char *service);
-int terminate_machine(pid_t pid);
+int register_machine(sd_bus *bus, const char *machine_name, pid_t pid, const char *directory, sd_id128_t uuid, int local_ifindex, const char *slice, CustomMount *mounts, unsigned n_mounts, int kill_signal, char **properties, bool keep_unit, const char *service);
+int terminate_machine(sd_bus *bus, pid_t pid);
 
-int allocate_scope(const char *machine_name, pid_t pid, const char *slice, CustomMount *mounts, unsigned n_mounts, int kill_signal, char **properties);
+int allocate_scope(sd_bus *bus, const char *machine_name, pid_t pid, const char *slice, CustomMount *mounts, unsigned n_mounts, int kill_signal, char **properties);
index 1890dd8..92e5ff9 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 5cf5ad1..2421b00 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index c02c1ea..a1518a6 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -59,9 +60,7 @@ int settings_load(FILE *f, const char *path, Settings **ret) {
                          "Network\0"
                          "Files\0",
                          config_item_perf_lookup, nspawn_gperf_lookup,
-                         false,
-                         false,
-                         true,
+                         CONFIG_PARSE_WARN,
                          s);
         if (r < 0)
                 return r;
@@ -202,7 +201,7 @@ int config_parse_capability(
                         continue;
                 }
 
-                u |= 1 << ((uint64_t) cap);
+                u |= UINT64_C(1) << cap;
         }
 
         if (u == 0)
@@ -404,9 +403,7 @@ int config_parse_network_zone(
                 return 0;
         }
 
-        free(settings->network_zone);
-        settings->network_zone = j;
-        j = NULL;
+        free_and_replace(settings->network_zone, j);
 
         return 0;
 }
index 75d68ce..c0c5a15 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index b8e8e09..31f5dd3 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -244,7 +245,7 @@ int change_uid_gid(const char *user, char **_home) {
         if (r < 0)
                 return log_error_errno(r, "Failed to make home root directory: %m");
 
-        r = mkdir_safe(home, 0755, uid, gid);
+        r = mkdir_safe(home, 0755, uid, gid, false);
         if (r < 0 && r != -EEXIST)
                 return log_error_errno(r, "Failed to make home directory: %m");
 
index b4968ba..20fc885 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 0c48434..7f2f8f1 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 7ca8307..fef2252 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 4e3803b..71b14e2 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -77,6 +78,7 @@
 #include "mount-util.h"
 #include "netlink-util.h"
 #include "nspawn-cgroup.h"
+#include "nspawn-def.h"
 #include "nspawn-expose-ports.h"
 #include "nspawn-mount.h"
 #include "nspawn-network.h"
 #include "user-util.h"
 #include "util.h"
 
-/* Note that devpts's gid= parameter parses GIDs as signed values, hence we stay away from the upper half of the 32bit
- * UID range here. We leave a bit of room at the lower end and a lot of room at the upper end, so that other subsystems
- * may have their own allocation ranges too. */
-#define UID_SHIFT_PICK_MIN ((uid_t) UINT32_C(0x00080000))
-#define UID_SHIFT_PICK_MAX ((uid_t) UINT32_C(0x6FFF0000))
+#if HAVE_SPLIT_USR
+#define STATIC_RESOLV_CONF "/lib/systemd/resolv.conf"
+#else
+#define STATIC_RESOLV_CONF "/usr/lib/systemd/resolv.conf"
+#endif
 
 /* nspawn is listening on the socket at the path in the constant nspawn_notify_socket_path
  * nspawn_notify_socket_path is relative to the container
@@ -188,6 +190,7 @@ static bool arg_network_veth = false;
 static char **arg_network_veth_extra = NULL;
 static char *arg_network_bridge = NULL;
 static char *arg_network_zone = NULL;
+static char *arg_network_namespace_path = NULL;
 static unsigned long arg_personality = PERSONALITY_INVALID;
 static char *arg_image = NULL;
 static VolatileMode arg_volatile_mode = VOLATILE_NO;
@@ -258,6 +261,9 @@ static void help(void) {
                "                            and attach it to an existing bridge on the host\n"
                "     --network-zone=NAME    Similar, but attach the new interface to an\n"
                "                            an automatically managed bridge interface\n"
+               "     --network-namespace-path=PATH\n"
+               "                            Set network namespace to the one represented by\n"
+               "                            the specified kernel namespace file node\n"
                "  -p --port=[PROTOCOL:]HOSTPORT[:CONTAINERPORT]\n"
                "                            Expose a container IP port on the host\n"
                "  -Z --selinux-context=SECLABEL\n"
@@ -318,7 +324,7 @@ static int custom_mount_check_all(void) {
         return 0;
 }
 
-static int detect_unified_cgroup_hierarchy(const char *directory) {
+static int detect_unified_cgroup_hierarchy_from_environment(void) {
         const char *e;
         int r;
 
@@ -332,11 +338,16 @@ static int detect_unified_cgroup_hierarchy(const char *directory) {
                         arg_unified_cgroup_hierarchy = CGROUP_UNIFIED_ALL;
                 else
                         arg_unified_cgroup_hierarchy = CGROUP_UNIFIED_NONE;
-
-                return 0;
         }
 
-        /* Otherwise inherit the default from the host system */
+        return 0;
+}
+
+static int detect_unified_cgroup_hierarchy_from_image(const char *directory) {
+        int r;
+
+        /* Let's inherit the mode to use from the host system, but let's take into consideration what systemd in the
+         * image actually supports. */
         r = cg_all_unified();
         if (r < 0)
                 return log_error_errno(r, "Failed to determine whether we are in all unified mode.");
@@ -362,6 +373,10 @@ static int detect_unified_cgroup_hierarchy(const char *directory) {
         } else
                 arg_unified_cgroup_hierarchy = CGROUP_UNIFIED_NONE;
 
+        log_debug("Using %s hierarchy for container.",
+                  arg_unified_cgroup_hierarchy == CGROUP_UNIFIED_NONE ? "legacy" :
+                  arg_unified_cgroup_hierarchy == CGROUP_UNIFIED_SYSTEMD ? "hybrid" : "unified");
+
         return 0;
 }
 
@@ -423,6 +438,7 @@ static int parse_argv(int argc, char *argv[]) {
                 ARG_NETWORK_BRIDGE,
                 ARG_NETWORK_ZONE,
                 ARG_NETWORK_VETH_EXTRA,
+                ARG_NETWORK_NAMESPACE_PATH,
                 ARG_PERSONALITY,
                 ARG_VOLATILE,
                 ARG_TEMPLATE,
@@ -439,55 +455,56 @@ static int parse_argv(int argc, char *argv[]) {
         };
 
         static const struct option options[] = {
-                { "help",                  no_argument,       NULL, 'h'                     },
-                { "version",               no_argument,       NULL, ARG_VERSION             },
-                { "directory",             required_argument, NULL, 'D'                     },
-                { "template",              required_argument, NULL, ARG_TEMPLATE            },
-                { "ephemeral",             no_argument,       NULL, 'x'                     },
-                { "user",                  required_argument, NULL, 'u'                     },
-                { "private-network",       no_argument,       NULL, ARG_PRIVATE_NETWORK     },
-                { "as-pid2",               no_argument,       NULL, 'a'                     },
-                { "boot",                  no_argument,       NULL, 'b'                     },
-                { "uuid",                  required_argument, NULL, ARG_UUID                },
-                { "read-only",             no_argument,       NULL, ARG_READ_ONLY           },
-                { "capability",            required_argument, NULL, ARG_CAPABILITY          },
-                { "drop-capability",       required_argument, NULL, ARG_DROP_CAPABILITY     },
-                { "link-journal",          required_argument, NULL, ARG_LINK_JOURNAL        },
-                { "bind",                  required_argument, NULL, ARG_BIND                },
-                { "bind-ro",               required_argument, NULL, ARG_BIND_RO             },
-                { "tmpfs",                 required_argument, NULL, ARG_TMPFS               },
-                { "overlay",               required_argument, NULL, ARG_OVERLAY             },
-                { "overlay-ro",            required_argument, NULL, ARG_OVERLAY_RO          },
-                { "machine",               required_argument, NULL, 'M'                     },
-                { "slice",                 required_argument, NULL, 'S'                     },
-                { "setenv",                required_argument, NULL, 'E'                     },
-                { "selinux-context",       required_argument, NULL, 'Z'                     },
-                { "selinux-apifs-context", required_argument, NULL, 'L'                     },
-                { "quiet",                 no_argument,       NULL, 'q'                     },
-                { "share-system",          no_argument,       NULL, ARG_SHARE_SYSTEM        }, /* not documented */
-                { "register",              required_argument, NULL, ARG_REGISTER            },
-                { "keep-unit",             no_argument,       NULL, ARG_KEEP_UNIT           },
-                { "network-interface",     required_argument, NULL, ARG_NETWORK_INTERFACE   },
-                { "network-macvlan",       required_argument, NULL, ARG_NETWORK_MACVLAN     },
-                { "network-ipvlan",        required_argument, NULL, ARG_NETWORK_IPVLAN      },
-                { "network-veth",          no_argument,       NULL, 'n'                     },
-                { "network-veth-extra",    required_argument, NULL, ARG_NETWORK_VETH_EXTRA  },
-                { "network-bridge",        required_argument, NULL, ARG_NETWORK_BRIDGE      },
-                { "network-zone",          required_argument, NULL, ARG_NETWORK_ZONE        },
-                { "personality",           required_argument, NULL, ARG_PERSONALITY         },
-                { "image",                 required_argument, NULL, 'i'                     },
-                { "volatile",              optional_argument, NULL, ARG_VOLATILE            },
-                { "port",                  required_argument, NULL, 'p'                     },
-                { "property",              required_argument, NULL, ARG_PROPERTY            },
-                { "private-users",         optional_argument, NULL, ARG_PRIVATE_USERS       },
-                { "private-users-chown",   optional_argument, NULL, ARG_PRIVATE_USERS_CHOWN },
-                { "kill-signal",           required_argument, NULL, ARG_KILL_SIGNAL         },
-                { "settings",              required_argument, NULL, ARG_SETTINGS            },
-                { "chdir",                 required_argument, NULL, ARG_CHDIR               },
-                { "pivot-root",            required_argument, NULL, ARG_PIVOT_ROOT          },
-                { "notify-ready",          required_argument, NULL, ARG_NOTIFY_READY        },
-                { "root-hash",             required_argument, NULL, ARG_ROOT_HASH           },
-                { "system-call-filter",    required_argument, NULL, ARG_SYSTEM_CALL_FILTER  },
+                { "help",                   no_argument,       NULL, 'h'                        },
+                { "version",                no_argument,       NULL, ARG_VERSION                },
+                { "directory",              required_argument, NULL, 'D'                        },
+                { "template",               required_argument, NULL, ARG_TEMPLATE               },
+                { "ephemeral",              no_argument,       NULL, 'x'                        },
+                { "user",                   required_argument, NULL, 'u'                        },
+                { "private-network",        no_argument,       NULL, ARG_PRIVATE_NETWORK        },
+                { "as-pid2",                no_argument,       NULL, 'a'                        },
+                { "boot",                   no_argument,       NULL, 'b'                        },
+                { "uuid",                   required_argument, NULL, ARG_UUID                   },
+                { "read-only",              no_argument,       NULL, ARG_READ_ONLY              },
+                { "capability",             required_argument, NULL, ARG_CAPABILITY             },
+                { "drop-capability",        required_argument, NULL, ARG_DROP_CAPABILITY        },
+                { "link-journal",           required_argument, NULL, ARG_LINK_JOURNAL           },
+                { "bind",                   required_argument, NULL, ARG_BIND                   },
+                { "bind-ro",                required_argument, NULL, ARG_BIND_RO                },
+                { "tmpfs",                  required_argument, NULL, ARG_TMPFS                  },
+                { "overlay",                required_argument, NULL, ARG_OVERLAY                },
+                { "overlay-ro",             required_argument, NULL, ARG_OVERLAY_RO             },
+                { "machine",                required_argument, NULL, 'M'                        },
+                { "slice",                  required_argument, NULL, 'S'                        },
+                { "setenv",                 required_argument, NULL, 'E'                        },
+                { "selinux-context",        required_argument, NULL, 'Z'                        },
+                { "selinux-apifs-context",  required_argument, NULL, 'L'                        },
+                { "quiet",                  no_argument,       NULL, 'q'                        },
+                { "share-system",           no_argument,       NULL, ARG_SHARE_SYSTEM           }, /* not documented */
+                { "register",               required_argument, NULL, ARG_REGISTER               },
+                { "keep-unit",              no_argument,       NULL, ARG_KEEP_UNIT              },
+                { "network-interface",      required_argument, NULL, ARG_NETWORK_INTERFACE      },
+                { "network-macvlan",        required_argument, NULL, ARG_NETWORK_MACVLAN        },
+                { "network-ipvlan",         required_argument, NULL, ARG_NETWORK_IPVLAN         },
+                { "network-veth",           no_argument,       NULL, 'n'                        },
+                { "network-veth-extra",     required_argument, NULL, ARG_NETWORK_VETH_EXTRA     },
+                { "network-bridge",         required_argument, NULL, ARG_NETWORK_BRIDGE         },
+                { "network-zone",           required_argument, NULL, ARG_NETWORK_ZONE           },
+                { "network-namespace-path", required_argument, NULL, ARG_NETWORK_NAMESPACE_PATH },
+                { "personality",            required_argument, NULL, ARG_PERSONALITY            },
+                { "image",                  required_argument, NULL, 'i'                        },
+                { "volatile",               optional_argument, NULL, ARG_VOLATILE               },
+                { "port",                   required_argument, NULL, 'p'                        },
+                { "property",               required_argument, NULL, ARG_PROPERTY               },
+                { "private-users",          optional_argument, NULL, ARG_PRIVATE_USERS          },
+                { "private-users-chown",    optional_argument, NULL, ARG_PRIVATE_USERS_CHOWN    },
+                { "kill-signal",            required_argument, NULL, ARG_KILL_SIGNAL            },
+                { "settings",               required_argument, NULL, ARG_SETTINGS               },
+                { "chdir",                  required_argument, NULL, ARG_CHDIR                  },
+                { "pivot-root",             required_argument, NULL, ARG_PIVOT_ROOT             },
+                { "notify-ready",           required_argument, NULL, ARG_NOTIFY_READY           },
+                { "root-hash",              required_argument, NULL, ARG_ROOT_HASH              },
+                { "system-call-filter",     required_argument, NULL, ARG_SYSTEM_CALL_FILTER     },
                 {}
         };
 
@@ -573,8 +590,7 @@ static int parse_argv(int argc, char *argv[]) {
                         if (r < 0)
                                 return log_oom();
 
-                        /* fall through */
-
+                        _fallthrough_;
                 case 'n':
                         arg_network_veth = true;
                         arg_private_network = true;
@@ -628,13 +644,19 @@ static int parse_argv(int argc, char *argv[]) {
                         if (strv_extend(&arg_network_ipvlan, optarg) < 0)
                                 return log_oom();
 
-                        /* fall through */
-
+                        _fallthrough_;
                 case ARG_PRIVATE_NETWORK:
                         arg_private_network = true;
                         arg_settings_mask |= SETTING_NETWORK;
                         break;
 
+                case ARG_NETWORK_NAMESPACE_PATH:
+                        r = parse_path_argument_and_warn(optarg, false, &arg_network_namespace_path);
+                        if (r < 0)
+                                return r;
+
+                        break;
+
                 case 'b':
                         if (arg_start_mode == START_PID2) {
                                 log_error("--boot and --as-pid2 may not be combined.");
@@ -1094,6 +1116,17 @@ static int parse_argv(int argc, char *argv[]) {
                         assert_not_reached("Unhandled option");
                 }
 
+        /* If --network-namespace-path is given with any other network-related option,
+         * we need to error out, to avoid conflicts between different network options. */
+        if (arg_network_namespace_path &&
+                (arg_network_interfaces || arg_network_macvlan ||
+                 arg_network_ipvlan || arg_network_veth_extra ||
+                 arg_network_bridge || arg_network_zone ||
+                 arg_network_veth || arg_private_network)) {
+                log_error("--network-namespace-path cannot be combined with other network options.");
+                return -EINVAL;
+        }
+
         parse_share_ns_env("SYSTEMD_NSPAWN_SHARE_NS_IPC", CLONE_NEWIPC);
         parse_share_ns_env("SYSTEMD_NSPAWN_SHARE_NS_PID", CLONE_NEWPID);
         parse_share_ns_env("SYSTEMD_NSPAWN_SHARE_NS_UTS", CLONE_NEWUTS);
@@ -1120,6 +1153,8 @@ static int parse_argv(int argc, char *argv[]) {
                 arg_userns_chown = true;
 
         if (arg_keep_unit && arg_register && cg_pid_get_owner_uid(0, NULL) >= 0) {
+                /* Save the user from accidentally registering either user-$SESSION.scope or user@.service.
+                 * The latter is not technically a user session, but we don't need to labour the point. */
                 log_error("--keep-unit --register=yes may not be used when invoked from a user session.");
                 return -EINVAL;
         }
@@ -1410,7 +1445,7 @@ static int setup_resolv_conf(const char *dest) {
                 return 0;
         }
 
-        if (access("/usr/lib/systemd/resolv.conf", F_OK) >= 0 &&
+        if (access(STATIC_RESOLV_CONF, F_OK) >= 0 &&
             resolved_listening() > 0) {
 
                 /* resolved is enabled on the host. In this, case bind mount its static resolv.conf file into the
@@ -1422,7 +1457,7 @@ static int setup_resolv_conf(const char *dest) {
                 if (found == 0) /* missing? */
                         (void) touch(resolved);
 
-                r = mount_verbose(LOG_DEBUG, "/usr/lib/systemd/resolv.conf", resolved, NULL, MS_BIND, NULL);
+                r = mount_verbose(LOG_DEBUG, STATIC_RESOLV_CONF, resolved, NULL, MS_BIND, NULL);
                 if (r >= 0)
                         return mount_verbose(LOG_ERR, NULL, resolved, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY|MS_NOSUID|MS_NODEV, NULL);
         }
@@ -2015,8 +2050,7 @@ static int wait_for_container(pid_t pid, ContainerStatus *container) {
                         return 0;
                 }
 
-                /* fall through */
-
+                _fallthrough_;
         case CLD_DUMPED:
                 log_error("Container %s terminated by signal %s.", arg_machine, signal_to_string(status.si_status));
                 return -EIO;
@@ -2044,18 +2078,27 @@ static int on_orderly_shutdown(sd_event_source *s, const struct signalfd_siginfo
 }
 
 static int on_sigchld(sd_event_source *s, const struct signalfd_siginfo *ssi, void *userdata) {
+        pid_t pid;
+
+        assert(s);
+        assert(ssi);
+
+        pid = PTR_TO_PID(userdata);
+
         for (;;) {
                 siginfo_t si = {};
+
                 if (waitid(P_ALL, 0, &si, WNOHANG|WNOWAIT|WEXITED) < 0)
                         return log_error_errno(errno, "Failed to waitid(): %m");
                 if (si.si_pid == 0) /* No pending children. */
                         break;
-                if (si.si_pid == PTR_TO_PID(userdata)) {
+                if (si.si_pid == pid) {
                         /* The main process we care for has exited. Return from
                          * signal handler but leave the zombie. */
                         sd_event_exit(sd_event_source_get_event(s), 0);
                         break;
                 }
+
                 /* Reap all other children. */
                 (void) waitid(P_PID, si.si_pid, &si, WNOHANG|WEXITED);
         }
@@ -2063,6 +2106,24 @@ static int on_sigchld(sd_event_source *s, const struct signalfd_siginfo *ssi, vo
         return 0;
 }
 
+static int on_request_stop(sd_bus_message *m, void *userdata, sd_bus_error *error) {
+        pid_t pid;
+
+        assert(m);
+
+        pid = PTR_TO_PID(userdata);
+
+        if (arg_kill_signal > 0) {
+                log_info("Container termination requested. Attempting to halt container.");
+                (void) kill(pid, arg_kill_signal);
+        } else {
+                log_info("Container termination requested. Exiting.");
+                sd_event_exit(sd_bus_get_event(sd_bus_message_get_bus(m)), 0);
+        }
+
+        return 0;
+}
+
 static int determine_names(void) {
         int r;
 
@@ -2089,7 +2150,7 @@ static int determine_names(void) {
                                 return -ENOENT;
                         }
 
-                        if (i->type == IMAGE_RAW)
+                        if (IN_SET(i->type, IMAGE_RAW, IMAGE_BLOCK))
                                 r = free_and_strdup(&arg_image, i->path);
                         else
                                 r = free_and_strdup(&arg_directory, i->path);
@@ -2494,12 +2555,15 @@ static int outer_child(
                 int kmsg_socket,
                 int rtnl_socket,
                 int uid_shift_socket,
-                FDSet *fds) {
+                int unified_cgroup_hierarchy_socket,
+                FDSet *fds,
+                int netns_fd) {
 
         pid_t pid;
         ssize_t l;
         int r;
         _cleanup_close_ int fd = -1;
+        bool create_netns;
 
         assert(barrier);
         assert(directory);
@@ -2544,7 +2608,13 @@ static int outer_child(
                 return r;
 
         if (dissected_image) {
-                r = dissected_image_mount(dissected_image, directory, DISSECT_IMAGE_DISCARD_ON_LOOP|(arg_read_only ? DISSECT_IMAGE_READ_ONLY : 0));
+                /* If we are operating on a disk image, then mount its root directory now, but leave out the rest. We
+                 * can read the UID shift from it if we need to. Further down we'll mount the rest, but then with the
+                 * uid shift known. That way we can mount VFAT file systems shifted to the right place right away. This
+                 * makes sure ESP partitions and userns are compatible. */
+
+                r = dissected_image_mount(dissected_image, directory, arg_uid_shift,
+                                          DISSECT_IMAGE_MOUNT_ROOT_ONLY|DISSECT_IMAGE_DISCARD_ON_LOOP|(arg_read_only ? DISSECT_IMAGE_READ_ONLY : 0));
                 if (r < 0)
                         return r;
         }
@@ -2580,6 +2650,32 @@ static int outer_child(
                 log_info("Selected user namespace base " UID_FMT " and range " UID_FMT ".", arg_uid_shift, arg_uid_range);
         }
 
+        if (dissected_image) {
+                /* Now we know the uid shift, let's now mount everything else that might be in the image. */
+                r = dissected_image_mount(dissected_image, directory, arg_uid_shift,
+                                          DISSECT_IMAGE_MOUNT_NON_ROOT_ONLY|DISSECT_IMAGE_DISCARD_ON_LOOP|(arg_read_only ? DISSECT_IMAGE_READ_ONLY : 0));
+                if (r < 0)
+                        return r;
+        }
+
+        if (arg_unified_cgroup_hierarchy == CGROUP_UNIFIED_UNKNOWN) {
+                /* OK, we don't know yet which cgroup mode to use yet. Let's figure it out, and tell the parent. */
+
+                r = detect_unified_cgroup_hierarchy_from_image(directory);
+                if (r < 0)
+                        return r;
+
+                l = send(unified_cgroup_hierarchy_socket, &arg_unified_cgroup_hierarchy, sizeof(arg_unified_cgroup_hierarchy), MSG_NOSIGNAL);
+                if (l < 0)
+                        return log_error_errno(errno, "Failed to send cgroup mode: %m");
+                if (l != sizeof(arg_unified_cgroup_hierarchy)) {
+                        log_error("Short write while sending cgroup mode: %m");
+                        return -EIO;
+                }
+
+                unified_cgroup_hierarchy_socket = safe_close(unified_cgroup_hierarchy_socket);
+        }
+
         /* Turn directory into bind mount */
         r = mount_verbose(LOG_ERR, directory, directory, NULL, MS_BIND|MS_REC, NULL);
         if (r < 0)
@@ -2718,9 +2814,11 @@ static int outer_child(
         if (fd < 0)
                 return fd;
 
+        create_netns = !arg_network_namespace_path && arg_private_network;
+
         pid = raw_clone(SIGCHLD|CLONE_NEWNS|
                         arg_clone_ns_flags |
-                        (arg_private_network ? CLONE_NEWNET : 0) |
+                        (create_netns ? CLONE_NEWNET : 0) |
                         (arg_userns_mode != USER_NAMESPACE_NO ? CLONE_NEWUSER : 0));
         if (pid < 0)
                 return log_error_errno(errno, "Failed to fork inner child: %m");
@@ -2734,6 +2832,12 @@ static int outer_child(
                  * requested, so that we all are owned by the user if
                  * user namespaces are turned on. */
 
+                if (arg_network_namespace_path) {
+                        r = namespace_enter(-1, -1, netns_fd, -1, -1);
+                        if (r < 0)
+                                return r;
+                }
+
                 r = inner_child(barrier, directory, secondary, kmsg_socket, rtnl_socket, fds);
                 if (r < 0)
                         _exit(EXIT_FAILURE);
@@ -2766,11 +2870,13 @@ static int outer_child(
         notify_socket = safe_close(notify_socket);
         kmsg_socket = safe_close(kmsg_socket);
         rtnl_socket = safe_close(rtnl_socket);
+        netns_fd = safe_close(netns_fd);
 
         return 0;
 }
 
 static int uid_shift_pick(uid_t *shift, LockFile *ret_lock_file) {
+        bool tried_hashed = false;
         unsigned n_tries = 100;
         uid_t candidate;
         int r;
@@ -2785,13 +2891,13 @@ static int uid_shift_pick(uid_t *shift, LockFile *ret_lock_file) {
         (void) mkdir("/run/systemd/nspawn-uid", 0755);
 
         for (;;) {
-                char lock_path[strlen("/run/systemd/nspawn-uid/") + DECIMAL_STR_MAX(uid_t) + 1];
+                char lock_path[STRLEN("/run/systemd/nspawn-uid/") + DECIMAL_STR_MAX(uid_t) + 1];
                 _cleanup_release_lock_file_ LockFile lf = LOCK_FILE_INIT;
 
                 if (--n_tries <= 0)
                         return -EBUSY;
 
-                if (candidate < UID_SHIFT_PICK_MIN || candidate > UID_SHIFT_PICK_MAX)
+                if (candidate < CONTAINER_UID_BASE_MIN || candidate > CONTAINER_UID_BASE_MAX)
                         goto next;
                 if ((candidate & UINT32_C(0xFFFF)) != 0)
                         goto next;
@@ -2819,14 +2925,27 @@ static int uid_shift_pick(uid_t *shift, LockFile *ret_lock_file) {
                 return 0;
 
         next:
-                random_bytes(&candidate, sizeof(candidate));
-                candidate = (candidate % (UID_SHIFT_PICK_MAX - UID_SHIFT_PICK_MIN)) + UID_SHIFT_PICK_MIN;
+                if (arg_machine && !tried_hashed) {
+                        /* Try to hash the base from the container name */
+
+                        static const uint8_t hash_key[] = {
+                                0xe1, 0x56, 0xe0, 0xf0, 0x4a, 0xf0, 0x41, 0xaf,
+                                0x96, 0x41, 0xcf, 0x41, 0x33, 0x94, 0xff, 0x72
+                        };
+
+                        candidate = (uid_t) siphash24(arg_machine, strlen(arg_machine), hash_key);
+
+                        tried_hashed = true;
+                } else
+                        random_bytes(&candidate, sizeof(candidate));
+
+                candidate = (candidate % (CONTAINER_UID_BASE_MAX - CONTAINER_UID_BASE_MIN)) + CONTAINER_UID_BASE_MIN;
                 candidate &= (uid_t) UINT32_C(0xFFFF0000);
         }
 }
 
 static int setup_uid_map(pid_t pid) {
-        char uid_map[strlen("/proc//uid_map") + DECIMAL_STR_MAX(uid_t) + 1], line[DECIMAL_STR_MAX(uid_t)*3+3+1];
+        char uid_map[STRLEN("/proc//uid_map") + DECIMAL_STR_MAX(uid_t) + 1], line[DECIMAL_STR_MAX(uid_t)*3+3+1];
         int r;
 
         assert(pid > 1);
@@ -3212,18 +3331,22 @@ static int run(int master,
                 pid_socket_pair[2] = { -1, -1 },
                 uuid_socket_pair[2] = { -1, -1 },
                 notify_socket_pair[2] = { -1, -1 },
-                uid_shift_socket_pair[2] = { -1, -1 };
+                uid_shift_socket_pair[2] = { -1, -1 },
+                unified_cgroup_hierarchy_socket_pair[2] = { -1, -1};
+
         _cleanup_close_ int notify_socket= -1;
         _cleanup_(barrier_destroy) Barrier barrier = BARRIER_NULL;
         _cleanup_(sd_event_source_unrefp) sd_event_source *notify_event_source = NULL;
         _cleanup_(sd_event_unrefp) sd_event *event = NULL;
         _cleanup_(pty_forward_freep) PTYForward *forward = NULL;
         _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
+        _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
         ContainerStatus container_status = 0;
         char last_char = 0;
         int ifi = 0, r;
         ssize_t l;
         sigset_t mask_chld;
+        _cleanup_close_ int netns_fd = -1;
 
         assert_se(sigemptyset(&mask_chld) == 0);
         assert_se(sigaddset(&mask_chld, SIGCHLD) == 0);
@@ -3264,6 +3387,10 @@ static int run(int master,
                 if (socketpair(AF_UNIX, SOCK_SEQPACKET|SOCK_CLOEXEC, 0, uid_shift_socket_pair) < 0)
                         return log_error_errno(errno, "Failed to create uid shift socket pair: %m");
 
+        if (arg_unified_cgroup_hierarchy == CGROUP_UNIFIED_UNKNOWN)
+                if (socketpair(AF_UNIX, SOCK_SEQPACKET|SOCK_CLOEXEC, 0, unified_cgroup_hierarchy_socket_pair) < 0)
+                        return log_error_errno(errno, "Failed to create unified cgroup socket pair: %m");
+
         /* Child can be killed before execv(), so handle SIGCHLD in order to interrupt
          * parent's blocking calls and give it a chance to call wait() and terminate. */
         r = sigprocmask(SIG_UNBLOCK, &mask_chld, NULL);
@@ -3274,6 +3401,20 @@ static int run(int master,
         if (r < 0)
                 return log_error_errno(errno, "Failed to install SIGCHLD handler: %m");
 
+        if (arg_network_namespace_path) {
+                netns_fd = open(arg_network_namespace_path, O_RDONLY|O_NOCTTY|O_CLOEXEC);
+                if (netns_fd < 0)
+                        return log_error_errno(errno, "Cannot open file %s: %m", arg_network_namespace_path);
+
+                r = fd_is_network_ns(netns_fd);
+                if (r < 0 && r != -ENOTTY)
+                        return log_error_errno(r, "Failed to check %s fs type: %m", arg_network_namespace_path);
+                if (r == 0) {
+                        log_error("Path %s doesn't refer to a network namespace", arg_network_namespace_path);
+                        return -EINVAL;
+                }
+        }
+
         *pid = raw_clone(SIGCHLD|CLONE_NEWNS);
         if (*pid < 0)
                 return log_error_errno(errno, "clone() failed%s: %m",
@@ -3292,6 +3433,7 @@ static int run(int master,
                 uuid_socket_pair[0] = safe_close(uuid_socket_pair[0]);
                 notify_socket_pair[0] = safe_close(notify_socket_pair[0]);
                 uid_shift_socket_pair[0] = safe_close(uid_shift_socket_pair[0]);
+                unified_cgroup_hierarchy_socket_pair[0] = safe_close(unified_cgroup_hierarchy_socket_pair[0]);
 
                 (void) reset_all_signal_handlers();
                 (void) reset_signal_mask();
@@ -3308,7 +3450,9 @@ static int run(int master,
                                 kmsg_socket_pair[1],
                                 rtnl_socket_pair[1],
                                 uid_shift_socket_pair[1],
-                                fds);
+                                unified_cgroup_hierarchy_socket_pair[1],
+                                fds,
+                                netns_fd);
                 if (r < 0)
                         _exit(EXIT_FAILURE);
 
@@ -3325,6 +3469,7 @@ static int run(int master,
         uuid_socket_pair[1] = safe_close(uuid_socket_pair[1]);
         notify_socket_pair[1] = safe_close(notify_socket_pair[1]);
         uid_shift_socket_pair[1] = safe_close(uid_shift_socket_pair[1]);
+        unified_cgroup_hierarchy_socket_pair[1] = safe_close(unified_cgroup_hierarchy_socket_pair[1]);
 
         if (arg_userns_mode != USER_NAMESPACE_NO) {
                 /* The child just let us know the UID shift it might have read from the image. */
@@ -3355,6 +3500,17 @@ static int run(int master,
                 }
         }
 
+        if (arg_unified_cgroup_hierarchy == CGROUP_UNIFIED_UNKNOWN) {
+                /* The child let us know the support cgroup mode it might have read from the image. */
+                l = recv(unified_cgroup_hierarchy_socket_pair[0], &arg_unified_cgroup_hierarchy, sizeof(arg_unified_cgroup_hierarchy), 0);
+                if (l < 0)
+                        return log_error_errno(errno, "Failed to read cgroup mode: %m");
+                if (l != sizeof(arg_unified_cgroup_hierarchy)) {
+                        log_error("Short read while reading cgroup mode.");
+                        return -EIO;
+                }
+        }
+
         /* Wait for the outer child. */
         r = wait_for_terminate_and_warn("namespace helper", *pid, NULL);
         if (r != 0)
@@ -3449,8 +3605,31 @@ static int run(int master,
                         return r;
         }
 
+        if (arg_register || !arg_keep_unit) {
+                r = sd_bus_default_system(&bus);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to open system bus: %m");
+        }
+
+        if (!arg_keep_unit) {
+                /* When a new scope is created for this container, then we'll be registered as its controller, in which
+                 * case PID 1 will send us a friendly RequestStop signal, when it is asked to terminate the
+                 * scope. Let's hook into that, and cleanly shut down the container, and print a friendly message. */
+
+                r = sd_bus_add_match(bus, NULL,
+                                     "type='signal',"
+                                     "sender='org.freedesktop.systemd1',"
+                                     "interface='org.freedesktop.systemd1.Scope',"
+                                     "member='RequestStop'",
+                                     on_request_stop, PID_TO_PTR(*pid));
+                if (r < 0)
+                        return log_error_errno(r, "Failed to install request stop match: %m");
+        }
+
         if (arg_register) {
+
                 r = register_machine(
+                                bus,
                                 arg_machine,
                                 *pid,
                                 arg_directory,
@@ -3464,8 +3643,11 @@ static int run(int master,
                                 arg_container_service_name);
                 if (r < 0)
                         return r;
+
         } else if (!arg_keep_unit) {
+
                 r = allocate_scope(
+                                bus,
                                 arg_machine,
                                 *pid,
                                 arg_slice,
@@ -3488,7 +3670,7 @@ static int run(int master,
                         return r;
         }
 
-        r = chown_cgroup(*pid, arg_uid_shift);
+        r = chown_cgroup(*pid, arg_unified_cgroup_hierarchy, arg_uid_shift);
         if (r < 0)
                 return r;
 
@@ -3511,6 +3693,14 @@ static int run(int master,
         if (r < 0)
                 return log_error_errno(r, "Failed to get default event source: %m");
 
+        (void) sd_event_set_watchdog(event, true);
+
+        if (bus) {
+                r = sd_bus_attach_event(bus, event, 0);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to attach bus to event loop: %m");
+        }
+
         r = setup_sd_notify_parent(event, notify_socket, PID_TO_PTR(*pid), &notify_event_source);
         if (r < 0)
                 return r;
@@ -3572,8 +3762,8 @@ static int run(int master,
                 putc('\n', stdout);
 
         /* Kill if it is not dead yet anyway */
-        if (arg_register && !arg_keep_unit)
-                terminate_machine(*pid);
+        if (arg_register && !arg_keep_unit && bus)
+                terminate_machine(bus, *pid);
 
         /* Normally redundant, but better safe than sorry */
         (void) kill(*pid, SIGKILL);
@@ -3644,11 +3834,10 @@ int main(int argc, char *argv[]) {
         if (r <= 0)
                 goto finish;
 
-        if (geteuid() != 0) {
-                log_error("Need to be root.");
-                r = -EPERM;
+        r = must_be_root();
+        if (r < 0)
                 goto finish;
-        }
+
         r = determine_names();
         if (r < 0)
                 goto finish;
@@ -3661,6 +3850,10 @@ int main(int argc, char *argv[]) {
         if (r < 0)
                 goto finish;
 
+        r = detect_unified_cgroup_hierarchy_from_environment();
+        if (r < 0)
+                goto finish;
+
         n_fd_passed = sd_listen_fds(false);
         if (n_fd_passed > 0) {
                 r = fdset_new_listen_fds(&fds, false);
@@ -3883,6 +4076,10 @@ int main(int argc, char *argv[]) {
                         log_error_errno(r, "--image= is not supported, compiled without blkid support.");
                         goto finish;
                 }
+                if (r == -EPROTONOSUPPORT) {
+                        log_error_errno(r, "Device is loopback block device with partition scanning turned off, please turn it on.");
+                        goto finish;
+                }
                 if (r < 0) {
                         log_error_errno(r, "Failed to dissect image: %m");
                         goto finish;
@@ -3904,10 +4101,6 @@ int main(int argc, char *argv[]) {
         if (r < 0)
                 goto finish;
 
-        r = detect_unified_cgroup_hierarchy(arg_directory);
-        if (r < 0)
-                goto finish;
-
         interactive =
                 isatty(STDIN_FILENO) > 0 &&
                 isatty(STDOUT_FILENO) > 0;
index 11c5321..cdc438f 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 96ed161..39714fe 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 78646c3..0dcdb9b 100644 (file)
@@ -1,4 +1,6 @@
 /***
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   systemd is free software; you can redistribute it and/or modify it
index 6e46885..b2f46e3 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -479,7 +480,7 @@ enum nss_status _nss_mymachines_getpwnam_r(
 
         pwd->pw_name = buffer;
         pwd->pw_uid = mapped;
-        pwd->pw_gid = 65534; /* nobody */
+        pwd->pw_gid = GID_NOBODY;
         pwd->pw_gecos = buffer;
         pwd->pw_passwd = (char*) "*"; /* locked */
         pwd->pw_dir = (char*) "/";
@@ -556,7 +557,7 @@ enum nss_status _nss_mymachines_getpwuid_r(
 
         pwd->pw_name = buffer;
         pwd->pw_uid = uid;
-        pwd->pw_gid = 65534; /* nobody */
+        pwd->pw_gid = GID_NOBODY;
         pwd->pw_gecos = buffer;
         pwd->pw_passwd = (char*) "*"; /* locked */
         pwd->pw_dir = (char*) "/";
index 0728ac3..056d427 100644 (file)
@@ -1,4 +1,6 @@
 /***
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   systemd is free software; you can redistribute it and/or modify it
index 17d125c..cab3c22 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index df8dff2..27570df 100644 (file)
@@ -1,4 +1,6 @@
 /***
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   systemd is free software; you can redistribute it and/or modify it
index d856c4c..cc641e1 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -46,8 +47,8 @@ static const struct passwd root_passwd = {
 static const struct passwd nobody_passwd = {
         .pw_name = (char*) NOBODY_USER_NAME,
         .pw_passwd = (char*) "*", /* locked */
-        .pw_uid = 65534,
-        .pw_gid = 65534,
+        .pw_uid = UID_NOBODY,
+        .pw_gid = GID_NOBODY,
         .pw_gecos = (char*) "User Nobody",
         .pw_dir = (char*) "/",
         .pw_shell = (char*) "/sbin/nologin",
@@ -62,7 +63,7 @@ static const struct group root_group = {
 
 static const struct group nobody_group = {
         .gr_name = (char*) NOBODY_GROUP_NAME,
-        .gr_gid = 65534,
+        .gr_gid = GID_NOBODY,
         .gr_passwd = (char*) "*", /* locked */
         .gr_mem = (char*[]) { NULL },
 };
@@ -91,7 +92,7 @@ static int direct_lookup_name(const char *name, uid_t *ret) {
 }
 
 static int direct_lookup_uid(uid_t uid, char **ret) {
-        char path[strlen("/run/systemd/dynamic-uid/direct:") + DECIMAL_STR_MAX(uid_t) + 1], *s;
+        char path[STRLEN("/run/systemd/dynamic-uid/direct:") + DECIMAL_STR_MAX(uid_t) + 1], *s;
         int r;
 
         xsprintf(path, "/run/systemd/dynamic-uid/direct:" UID_FMT, uid);
@@ -250,7 +251,7 @@ enum nss_status _nss_systemd_getpwuid_r(
                 }
         }
 
-        if (uid <= SYSTEM_UID_MAX)
+        if (!uid_is_dynamic(uid))
                 goto not_found;
 
         if (getenv_bool_secure("SYSTEMD_NSS_DYNAMIC_BYPASS") > 0)
@@ -462,7 +463,7 @@ enum nss_status _nss_systemd_getgrgid_r(
                 }
         }
 
-        if (gid <= SYSTEM_GID_MAX)
+        if (!gid_is_dynamic(gid))
                 goto not_found;
 
         if (getenv_bool_secure("SYSTEMD_NSS_DYNAMIC_BYPASS") > 0)
@@ -499,7 +500,6 @@ enum nss_status _nss_systemd_getgrgid_r(
 
 direct_lookup:
         if (bypass > 0) {
-
                 r = direct_lookup_uid(gid, &direct);
                 if (r == -ENOENT)
                         goto not_found;
index 9550787..e3fe56f 100644 (file)
@@ -1,4 +1,6 @@
 /***
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   systemd is free software; you can redistribute it and/or modify it
diff --git a/src/partition/growfs.c b/src/partition/growfs.c
new file mode 100644 (file)
index 0000000..901b33e
--- /dev/null
@@ -0,0 +1,323 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+/***
+  This file is part of systemd.
+
+  Copyright 2017 Zbigniew Jędrzejewski-Szmek
+
+  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.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <linux/magic.h>
+#include <sys/ioctl.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/vfs.h>
+
+#include "crypt-util.h"
+#include "device-nodes.h"
+#include "dissect-image.h"
+#include "escape.h"
+#include "fd-util.h"
+#include "format-util.h"
+#include "log.h"
+#include "missing.h"
+#include "mount-util.h"
+#include "parse-util.h"
+#include "path-util.h"
+#include "strv.h"
+
+const char *arg_target = NULL;
+bool arg_dry_run = false;
+
+static int resize_ext4(const char *path, int mountfd, int devfd, uint64_t numblocks, uint64_t blocksize) {
+        assert((uint64_t) (int) blocksize == blocksize);
+
+        if (arg_dry_run)
+                return 0;
+
+        if (ioctl(mountfd, EXT4_IOC_RESIZE_FS, &numblocks) != 0)
+                return log_error_errno(errno, "Failed to resize \"%s\" to %"PRIu64" blocks (ext4): %m",
+                                       path, numblocks);
+
+        return 0;
+}
+
+static int resize_btrfs(const char *path, int mountfd, int devfd, uint64_t numblocks, uint64_t blocksize) {
+        struct btrfs_ioctl_vol_args args = {};
+        int r;
+
+        assert((uint64_t) (int) blocksize == blocksize);
+
+        /* https://bugzilla.kernel.org/show_bug.cgi?id=118111 */
+        if (numblocks * blocksize < 256*1024*1024) {
+                log_warning("%s: resizing of btrfs volumes smaller than 256M is not supported", path);
+                return -EOPNOTSUPP;
+        }
+
+        r = snprintf(args.name, sizeof(args.name), "%"PRIu64, numblocks * blocksize);
+        /* The buffer is large enough for any number to fit... */
+        assert((size_t) r < sizeof(args.name));
+
+        if (arg_dry_run)
+                return 0;
+
+        if (ioctl(mountfd, BTRFS_IOC_RESIZE, &args) != 0)
+                return log_error_errno(errno, "Failed to resize \"%s\" to %"PRIu64" blocks (btrfs): %m",
+                                       path, numblocks);
+
+        return 0;
+}
+
+#if HAVE_LIBCRYPTSETUP
+static int resize_crypt_luks_device(dev_t devno, const char *fstype, dev_t main_devno) {
+        char devpath[DEV_NUM_PATH_MAX], main_devpath[DEV_NUM_PATH_MAX];
+        _cleanup_close_ int main_devfd = -1;
+        _cleanup_(crypt_freep) struct crypt_device *cd = NULL;
+        uint64_t size;
+        int r;
+
+        xsprintf_dev_num_path(main_devpath, "block", main_devno);
+        main_devfd = open(main_devpath, O_RDONLY|O_CLOEXEC);
+        if (main_devfd < 0)
+                return log_error_errno(errno, "Failed to open \"%s\": %m", main_devpath);
+
+        if (ioctl(main_devfd, BLKGETSIZE64, &size) != 0)
+                return log_error_errno(errno, "Failed to query size of \"%s\" (before resize): %m",
+                                       main_devpath);
+
+        log_debug("%s is %"PRIu64" bytes", main_devpath, size);
+
+        xsprintf_dev_num_path(devpath, "block", devno);
+        r = crypt_init(&cd, devpath);
+        if (r < 0)
+                return log_error_errno(r, "crypt_init(\"%s\") failed: %m", devpath);
+
+        crypt_set_log_callback(cd, cryptsetup_log_glue, NULL);
+
+        r = crypt_load(cd, CRYPT_LUKS, NULL);
+        if (r < 0)
+                return log_debug_errno(r, "Failed to load LUKS metadata for %s: %m", devpath);
+
+        if (arg_dry_run)
+                return 0;
+
+        r = crypt_resize(cd, main_devpath, 0);
+        if (r < 0)
+                return log_error_errno(r, "crypt_resize() of %s failed: %m", devpath);
+
+        if (ioctl(main_devfd, BLKGETSIZE64, &size) != 0)
+                log_warning_errno(errno, "Failed to query size of \"%s\" (after resize): %m",
+                                  devpath);
+        else
+                log_debug("%s is now %"PRIu64" bytes", main_devpath, size);
+
+        return 1;
+}
+#endif
+
+static int maybe_resize_slave_device(const char *mountpath, dev_t main_devno) {
+        dev_t devno;
+        char devpath[DEV_NUM_PATH_MAX];
+        _cleanup_free_ char *fstype = NULL;
+        int r;
+
+#if HAVE_LIBCRYPTSETUP
+        crypt_set_log_callback(NULL, cryptsetup_log_glue, NULL);
+        crypt_set_debug_level(1);
+#endif
+
+        r = get_block_device_harder(mountpath, &devno);
+        if (r < 0)
+                return log_error_errno(r, "Failed to determine underlying block device of \"%s\": %m",
+                                       mountpath);
+
+        log_debug("Underlying device %d:%d, main dev %d:%d, %s",
+                  major(devno), minor(devno),
+                  major(main_devno), minor(main_devno),
+                  devno == main_devno ? "same" : "different");
+        if (devno == main_devno)
+                return 0;
+
+        xsprintf_dev_num_path(devpath, "block", devno);
+        r = probe_filesystem(devpath, &fstype);
+        if (r == -EUCLEAN)
+                return log_warning_errno(r, "Cannot reliably determine probe \"%s\", refusing to proceed.", devpath);
+        if (r < 0)
+                return log_warning_errno(r, "Failed to probe \"%s\": %m", devpath);
+
+#if HAVE_LIBCRYPTSETUP
+        if (streq_ptr(fstype, "crypto_LUKS"))
+                return resize_crypt_luks_device(devno, fstype, main_devno);
+#endif
+
+        log_debug("Don't know how to resize %s of type %s, ignoring", devpath, strnull(fstype));
+        return 0;
+}
+
+static void help(void) {
+        printf("%s [OPTIONS...] /path/to/mountpoint\n\n"
+               "Grow filesystem or encrypted payload to device size.\n\n"
+               "Options:\n"
+               "  -h --help          Show this help and exit\n"
+               "     --version       Print version string and exit\n"
+               "  -n --dry-run       Just print what would be done\n"
+               , program_invocation_short_name);
+}
+
+static int parse_argv(int argc, char *argv[]) {
+        enum {
+                ARG_VERSION = 0x100,
+        };
+
+        int c;
+
+        static const struct option options[] = {
+                { "help",         no_argument,       NULL, 'h'           },
+                { "version" ,     no_argument,       NULL, ARG_VERSION   },
+                { "dry-run",      no_argument,       NULL, 'n'           },
+                {}
+        };
+
+        assert(argc >= 0);
+        assert(argv);
+
+        while ((c = getopt_long(argc, argv, "hn", options, NULL)) >= 0)
+                switch(c) {
+                case 'h':
+                        help();
+                        return 0;
+
+                case ARG_VERSION:
+                        version();
+                        return 0;
+
+                case 'n':
+                        arg_dry_run = true;
+                        break;
+
+                case '?':
+                        return -EINVAL;
+
+                default:
+                        assert_not_reached("Unhandled option");
+                }
+
+        if (optind + 1 != argc) {
+                log_error("%s excepts exactly one argument (the mount point).",
+                          program_invocation_short_name);
+                return -EINVAL;
+        }
+
+        arg_target = argv[optind];
+
+        return 1;
+}
+
+int main(int argc, char *argv[]) {
+        dev_t devno;
+        _cleanup_close_ int mountfd = -1, devfd = -1;
+        int blocksize;
+        uint64_t size, numblocks;
+        char devpath[DEV_NUM_PATH_MAX], fb[FORMAT_BYTES_MAX];
+        struct statfs sfs;
+        int r;
+
+        log_set_target(LOG_TARGET_AUTO);
+        log_parse_environment();
+        log_open();
+
+        r = parse_argv(argc, argv);
+        if (r < 0)
+                return EXIT_FAILURE;
+        if (r == 0)
+                return EXIT_SUCCESS;
+
+        r = path_is_mount_point(arg_target, NULL, 0);
+        if (r < 0) {
+                log_error_errno(r, "Failed to check if \"%s\" is a mount point: %m", arg_target);
+                return EXIT_FAILURE;
+        }
+        if (r == 0) {
+                log_error_errno(r, "\"%s\" is not a mount point: %m", arg_target);
+                return EXIT_FAILURE;
+        }
+
+        r = get_block_device(arg_target, &devno);
+        if (r < 0) {
+                log_error_errno(r, "Failed to determine block device of \"%s\": %m", arg_target);
+                return EXIT_FAILURE;
+        }
+
+        r = maybe_resize_slave_device(arg_target, devno);
+        if (r < 0)
+                return EXIT_FAILURE;
+
+        mountfd = open(arg_target, O_RDONLY|O_CLOEXEC);
+        if (mountfd < 0) {
+                log_error_errno(errno, "Failed to open \"%s\": %m", arg_target);
+                return EXIT_FAILURE;
+        }
+
+        xsprintf_dev_num_path(devpath, "block", devno);
+        devfd = open(devpath, O_RDONLY|O_CLOEXEC);
+        if (devfd < 0) {
+                log_error_errno(errno, "Failed to open \"%s\": %m", devpath);
+                return EXIT_FAILURE;
+        }
+
+        if (ioctl(devfd, BLKBSZGET, &blocksize) != 0) {
+                log_error_errno(errno, "Failed to query block size of \"%s\": %m", devpath);
+                return EXIT_FAILURE;
+        }
+
+        if (ioctl(devfd, BLKGETSIZE64, &size) != 0) {
+                log_error_errno(errno, "Failed to query size of \"%s\": %m", devpath);
+                return EXIT_FAILURE;
+        }
+
+        if (size % blocksize != 0)
+                log_notice("Partition size %"PRIu64" is not a multiple of the blocksize %d,"
+                           " ignoring %"PRIu64" bytes", size, blocksize, size % blocksize);
+
+        numblocks = size / blocksize;
+
+        if (fstatfs(mountfd, &sfs) < 0) {
+                log_error_errno(errno, "Failed to stat file system \"%s\": %m", arg_target);
+                return EXIT_FAILURE;
+        }
+
+        switch(sfs.f_type) {
+        case EXT4_SUPER_MAGIC:
+                r = resize_ext4(arg_target, mountfd, devfd, numblocks, blocksize);
+                break;
+        case BTRFS_SUPER_MAGIC:
+                r = resize_btrfs(arg_target, mountfd, devfd, numblocks, blocksize);
+                break;
+        default:
+                log_error("Don't know how to resize fs %llx on \"%s\"",
+                          (long long unsigned) sfs.f_type, arg_target);
+                return EXIT_FAILURE;
+        }
+
+        if (r < 0)
+                return EXIT_FAILURE;
+
+        log_info("Successfully resized \"%s\" to %s bytes (%"PRIu64" blocks of %d bytes).",
+                 arg_target, format_bytes(fb, sizeof fb, size), numblocks, blocksize);
+        return EXIT_SUCCESS;
+}
diff --git a/src/partition/makefs.c b/src/partition/makefs.c
new file mode 100644 (file)
index 0000000..e5e1252
--- /dev/null
@@ -0,0 +1,110 @@
+/***
+  SPDX-License-Identifier: LGPL-2.1+
+
+  This file is part of systemd.
+
+  Copyright 2017 Zbigniew Jędrzejewski-Szmek
+
+  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.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <fcntl.h>
+#include <signal.h>
+#include <sys/prctl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "alloc-util.h"
+#include "dissect-image.h"
+#include "signal-util.h"
+#include "string-util.h"
+
+static int makefs(const char *type, const char *device) {
+        const char *mkfs;
+        pid_t pid;
+
+        if (streq(type, "swap"))
+                mkfs = "/sbin/mkswap";
+        else
+                mkfs = strjoina("/sbin/mkfs.", type);
+        if (access(mkfs, X_OK) != 0)
+                return log_error_errno(errno, "%s is not executable: %m", mkfs);
+
+        pid = fork();
+        if (pid < 0)
+                return log_error_errno(errno, "fork(): %m");
+
+        if (pid == 0) {
+                const char *cmdline[3] = { mkfs, device, NULL };
+
+                /* Child */
+
+                (void) reset_all_signal_handlers();
+                (void) reset_signal_mask();
+                assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
+
+                execv(cmdline[0], (char**) cmdline);
+                _exit(EXIT_FAILURE);
+        }
+
+        return wait_for_terminate_and_warn(mkfs, pid, true);
+}
+
+int main(int argc, char *argv[]) {
+        const char *device, *type;
+        _cleanup_free_ char *detected = NULL;
+        struct stat st;
+        int r;
+
+        log_set_target(LOG_TARGET_AUTO);
+        log_parse_environment();
+        log_open();
+
+        if (argc != 3) {
+                log_error("This program expects two arguments.");
+                return EXIT_FAILURE;
+        }
+
+        type = argv[1];
+        device = argv[2];
+
+        if (stat(device, &st) < 0) {
+                r = log_error_errno(errno, "Failed to stat \"%s\": %m", device);
+                goto finish;
+        }
+
+        if (!S_ISBLK(st.st_mode))
+                log_info("%s is not a block device.", device);
+
+        r = probe_filesystem(device, &detected);
+        if (r < 0) {
+                log_warning_errno(r,
+                                  r == -EUCLEAN ?
+                                  "Cannot reliably determine probe \"%s\", refusing to proceed." :
+                                  "Failed to probe \"%s\": %m",
+                                  device);
+                goto finish;
+        }
+
+        if (detected) {
+                log_info("%s is not empty (type %s), exiting", device, detected);
+                goto finish;
+        }
+
+        r = makefs(type, device);
+
+finish:
+        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+}
index 61d877f..0f029c4 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 1339564..ec5be21 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 6748bb9..23a6fda 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index db3bf5b..196947c 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 0cb9bd9..2d7cf72 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index a17c8a6..6f82bf7 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 09c85f9..7190c16 100644 (file)
@@ -53,6 +53,7 @@ Y https://tools.ietf.org/html/rfc6975 → Signaling Cryptographic Algorithm Unde
 Y https://tools.ietf.org/html/rfc7129 → Authenticated Denial of Existence in the DNS
 Y https://tools.ietf.org/html/rfc7646 → Definition and Use of DNSSEC Negative Trust Anchors
 ~ https://tools.ietf.org/html/rfc7719 → DNS Terminology
+Y https://tools.ietf.org/html/rfc8080 → Edwards-Curve Digital Security Algorithm (EdDSA) for DNSSEC
 
 Also relevant:
 
index d89ae28..347252a 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index e675fe4..583ceee 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 8a0b43c..d4f7b94 100755 (executable)
@@ -8,6 +8,12 @@ import sys
 name, prefix, input = sys.argv[1:]
 
 print("""\
+%{
+#if __GNUC__ >= 7
+_Pragma("GCC diagnostic ignored \\"-Wimplicit-fallthrough\\"")
+#endif
+%}""")
+print("""\
 struct {}_name {{ const char* name; int id; }};
 %null-strings
 %%""".format(name))
index 75e654e..ee1acb5 100644 (file)
@@ -1,3 +1,20 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
+# Copyright 2017 Zbigniew Jędrzejewski-Szmek
+#
+# 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.
+#
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
 basic_dns_sources = files('''
         resolved-dns-dnssec.c
         resolved-dns-dnssec.h
@@ -18,6 +35,10 @@ systemd_resolved_only_sources = files('''
         resolved.c
         resolved-manager.c
         resolved-manager.h
+        resolved-dnssd.c
+        resolved-dnssd.h
+        resolved-dnssd-bus.c
+        resolved-dnssd-bus.h
         resolved-conf.c
         resolved-conf.h
         resolved-resolv-conf.c
@@ -114,8 +135,14 @@ resolved_gperf_c = custom_target(
         output : 'resolved-gperf.c',
         command : [gperf, '@INPUT@', '--output-file', '@OUTPUT@'])
 
+resolved_dnssd_gperf_c = custom_target(
+        'resolved_dnssd_gperf.c',
+        input : 'resolved-dnssd-gperf.gperf',
+        output : 'resolved-dnssd-gperf.c',
+        command : [gperf, '@INPUT@', '--output-file', '@OUTPUT@'])
+
 systemd_resolved_sources = (basic_dns_sources +
-                            [resolved_gperf_c] +
+                            [resolved_gperf_c, resolved_dnssd_gperf_c] +
                             systemd_resolved_only_sources +
                             dns_type_headers)
 
@@ -138,6 +165,15 @@ if conf.get('ENABLE_RESOLVE') == 1
 
         install_data('resolv.conf',
                      install_dir : rootlibexecdir)
+
+        i18n.merge_file(
+                'org.freedesktop.resolve1.policy',
+                input : 'org.freedesktop.resolve1.policy.in',
+                output : 'org.freedesktop.resolve1.policy',
+                po_dir : po_dir,
+                data_dirs : po_dir,
+                install : install_polkit,
+                install_dir : polkitpolicydir)
 endif
 
 tests += [
diff --git a/src/resolve/org.freedesktop.resolve1.policy.in b/src/resolve/org.freedesktop.resolve1.policy.in
new file mode 100644 (file)
index 0000000..da948eb
--- /dev/null
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?> <!--*-nxml-*-->
+<!DOCTYPE policyconfig PUBLIC "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
+        "http://www.freedesktop.org/standards/PolicyKit/1/policyconfig.dtd">
+
+<!--
+  SPDX-License-Identifier: LGPL-2.1+
+
+  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.
+-->
+
+<policyconfig>
+
+        <vendor>The systemd Project</vendor>
+        <vendor_url>http://www.freedesktop.org/wiki/Software/systemd</vendor_url>
+
+        <action id="org.freedesktop.resolve1.register-service">
+                <description>Register a DNS-SD service</description>
+                <message>Authentication is required to register a DNS-SD service</message>
+                <defaults>
+                        <allow_any>auth_admin</allow_any>
+                        <allow_inactive>auth_admin</allow_inactive>
+                        <allow_active>auth_admin_keep</allow_active>
+                </defaults>
+                <annotate key="org.freedesktop.policykit.owner">unix-user:systemd-resolve</annotate>
+        </action>
+
+        <action id="org.freedesktop.resolve1.unregister-service">
+                <description>Unregister a DNS-SD service</description>
+                <message>Authentication is required to unregister a DNS-SD service</message>
+                <defaults>
+                        <allow_any>auth_admin</allow_any>
+                        <allow_inactive>auth_admin</allow_inactive>
+                        <allow_active>auth_admin_keep</allow_active>
+                </defaults>
+                <annotate key="org.freedesktop.policykit.owner">unix-user:systemd-resolve</annotate>
+        </action>
+
+</policyconfig>
index 7ac5c32..2c25a61 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index b8034d6..34a6b92 100644 (file)
@@ -1,11 +1,17 @@
-# This is a static resolv.conf file for connecting local clients to
-# systemd-resolved via its DNS stub listener on 127.0.0.53.
+# This file belongs to man:systemd-resolved(8). Do not edit.
+#
+# This is a static resolv.conf file for connecting local clients to the
+# internal DNS stub resolver of systemd-resolved. This file lists no search
+# domains.
+#
+# Run "systemd-resolve --status" to see details about the uplink DNS servers
+# currently in use.
 #
 # Third party programs must not access this file directly, but only through the
-# symlink at /etc/resolv.conf. To manage resolv.conf(5) in a different way,
+# symlink at /etc/resolv.conf. To manage man:resolv.conf(5) in a different way,
 # replace this symlink by a static file or a different symlink.
 #
-# See systemd-resolved.service(8) for details about the supported modes of
+# See man:systemd-resolved.service(8) for details about the supported modes of
 # operation for /etc/resolv.conf.
 
 nameserver 127.0.0.53
index 7083785..0252bdf 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
 
 #include "af-list.h"
 #include "alloc-util.h"
+#include "bus-common-errors.h"
 #include "bus-error.h"
 #include "bus-util.h"
+#include "dns-domain.h"
 #include "escape.h"
 #include "gcrypt-util.h"
 #include "in-addr-util.h"
@@ -74,8 +77,18 @@ static enum {
         MODE_FLUSH_CACHES,
         MODE_RESET_SERVER_FEATURES,
         MODE_STATUS,
+        MODE_SET_LINK,
+        MODE_REVERT_LINK,
 } arg_mode = MODE_RESOLVE_HOST;
 
+static struct in_addr_data *arg_set_dns = NULL;
+static size_t arg_n_set_dns = 0;
+static char **arg_set_domain = NULL;
+static char *arg_set_llmnr = NULL;
+static char *arg_set_mdns = NULL;
+static char *arg_set_dnssec = NULL;
+static char **arg_set_nta = NULL;
+
 static ServiceFamily service_family_from_string(const char *s) {
         if (s == NULL || streq(s, "tcp"))
                 return SERVICE_FAMILY_TCP;
@@ -1544,10 +1557,238 @@ static int status_all(sd_bus *bus) {
         return r;
 }
 
+static int set_link(sd_bus *bus) {
+        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+        int r = 0, q;
+
+        assert(bus);
+
+        if (arg_n_set_dns > 0) {
+                _cleanup_(sd_bus_message_unrefp) sd_bus_message *req = NULL;
+                size_t i;
+
+                q = sd_bus_message_new_method_call(
+                                bus,
+                                &req,
+                                "org.freedesktop.resolve1",
+                                "/org/freedesktop/resolve1",
+                                "org.freedesktop.resolve1.Manager",
+                                "SetLinkDNS");
+                if (q < 0)
+                        return bus_log_create_error(q);
+
+                q = sd_bus_message_append(req, "i", arg_ifindex);
+                if (q < 0)
+                        return bus_log_create_error(q);
+
+                q = sd_bus_message_open_container(req, 'a', "(iay)");
+                if (q < 0)
+                        return bus_log_create_error(q);
+
+                for (i = 0; i < arg_n_set_dns; i++) {
+                        q = sd_bus_message_open_container(req, 'r', "iay");
+                        if (q < 0)
+                                return bus_log_create_error(q);
+
+                        q = sd_bus_message_append(req, "i", arg_set_dns[i].family);
+                        if (q < 0)
+                                return bus_log_create_error(q);
+
+                        q = sd_bus_message_append_array(req, 'y', &arg_set_dns[i].address, FAMILY_ADDRESS_SIZE(arg_set_dns[i].family));
+                        if (q < 0)
+                                return bus_log_create_error(q);
+
+                        q = sd_bus_message_close_container(req);
+                        if (q < 0)
+                                return bus_log_create_error(q);
+                }
+
+                q = sd_bus_message_close_container(req);
+                if (q < 0)
+                        return bus_log_create_error(q);
+
+                q = sd_bus_call(bus, req, 0, &error, NULL);
+                if (q < 0) {
+                        if (sd_bus_error_has_name(&error, BUS_ERROR_LINK_BUSY))
+                                goto is_managed;
+
+                        log_error_errno(q, "Failed to set DNS configuration: %s", bus_error_message(&error, q));
+                        if (r == 0)
+                                r = q;
+                }
+        }
+
+        if (!strv_isempty(arg_set_domain)) {
+                _cleanup_(sd_bus_message_unrefp) sd_bus_message *req = NULL;
+                char **p;
+
+                q = sd_bus_message_new_method_call(
+                                bus,
+                                &req,
+                                "org.freedesktop.resolve1",
+                                "/org/freedesktop/resolve1",
+                                "org.freedesktop.resolve1.Manager",
+                                "SetLinkDomains");
+                if (q < 0)
+                        return bus_log_create_error(q);
+
+                q = sd_bus_message_append(req, "i", arg_ifindex);
+                if (q < 0)
+                        return bus_log_create_error(q);
+
+                q = sd_bus_message_open_container(req, 'a', "(sb)");
+                if (q < 0)
+                        return bus_log_create_error(q);
+
+                STRV_FOREACH(p, arg_set_domain) {
+                        const char *n;
+
+                        n = **p == '~' ? *p + 1 : *p;
+                        q = sd_bus_message_append(req, "(sb)", n, **p == '~');
+                        if (q < 0)
+                                return bus_log_create_error(q);
+                }
+
+                q = sd_bus_message_close_container(req);
+                if (q < 0)
+                        return bus_log_create_error(q);
+
+                q = sd_bus_call(bus, req, 0, &error, NULL);
+                if (q < 0) {
+                        if (sd_bus_error_has_name(&error, BUS_ERROR_LINK_BUSY))
+                                goto is_managed;
+
+                        log_error_errno(q, "Failed to set domain configuration: %s", bus_error_message(&error, q));
+                        if (r == 0)
+                                r = q;
+                }
+        }
+
+        if (arg_set_llmnr) {
+                q = sd_bus_call_method(bus,
+                                       "org.freedesktop.resolve1",
+                                       "/org/freedesktop/resolve1",
+                                       "org.freedesktop.resolve1.Manager",
+                                       "SetLinkLLMNR",
+                                       &error,
+                                       NULL,
+                                       "is", arg_ifindex, arg_set_llmnr);
+                if (q < 0) {
+                        if (sd_bus_error_has_name(&error, BUS_ERROR_LINK_BUSY))
+                                goto is_managed;
+
+                        log_error_errno(q, "Failed to set LLMNR configuration: %s", bus_error_message(&error, q));
+                        if (r == 0)
+                                r = q;
+                }
+        }
+
+        if (arg_set_mdns) {
+                q = sd_bus_call_method(bus,
+                                       "org.freedesktop.resolve1",
+                                       "/org/freedesktop/resolve1",
+                                       "org.freedesktop.resolve1.Manager",
+                                       "SetLinkMulticastDNS",
+                                       &error,
+                                       NULL,
+                                       "is", arg_ifindex, arg_set_mdns);
+                if (q < 0) {
+                        if (sd_bus_error_has_name(&error, BUS_ERROR_LINK_BUSY))
+                                goto is_managed;
+
+                        log_error_errno(q, "Failed to set MulticastDNS configuration: %s", bus_error_message(&error, q));
+                        if (r == 0)
+                                r = q;
+                }
+        }
+
+        if (arg_set_dnssec) {
+                q = sd_bus_call_method(bus,
+                                       "org.freedesktop.resolve1",
+                                       "/org/freedesktop/resolve1",
+                                       "org.freedesktop.resolve1.Manager",
+                                       "SetLinkDNSSEC",
+                                       &error,
+                                       NULL,
+                                       "is", arg_ifindex, arg_set_dnssec);
+                if (q < 0) {
+                        if (sd_bus_error_has_name(&error, BUS_ERROR_LINK_BUSY))
+                                goto is_managed;
+
+                        log_error_errno(q, "Failed to set DNSSEC configuration: %s", bus_error_message(&error, q));
+                        if (r == 0)
+                                r = q;
+                }
+        }
+
+        if (!strv_isempty(arg_set_nta)) {
+                _cleanup_(sd_bus_message_unrefp) sd_bus_message *req = NULL;
+
+                q = sd_bus_message_new_method_call(
+                                bus,
+                                &req,
+                                "org.freedesktop.resolve1",
+                                "/org/freedesktop/resolve1",
+                                "org.freedesktop.resolve1.Manager",
+                                "SetLinkDNSSECNegativeTrustAnchors");
+                if (q < 0)
+                        return bus_log_create_error(q);
+
+                q = sd_bus_message_append(req, "i", arg_ifindex);
+                if (q < 0)
+                        return bus_log_create_error(q);
+
+                q = sd_bus_message_append_strv(req, arg_set_nta);
+                if (q < 0)
+                        return bus_log_create_error(q);
+
+                q = sd_bus_call(bus, req, 0, &error, NULL);
+                if (q < 0) {
+                        if (sd_bus_error_has_name(&error, BUS_ERROR_LINK_BUSY))
+                                goto is_managed;
+
+                        log_error_errno(q, "Failed to set DNSSEC NTA configuration: %s", bus_error_message(&error, q));
+                        if (r == 0)
+                                r = q;
+                }
+        }
+
+        return r;
+
+is_managed:
+        {
+                char ifname[IFNAMSIZ];
+
+                return log_error_errno(q,
+                                       "The specified interface %s is managed by systemd-networkd. Operation refused.\n"
+                                       "Please configure DNS settings for systemd-networkd managed interfaces directly in their .network files.", strna(if_indextoname(arg_ifindex, ifname)));
+        }
+}
+
+static int revert_link(sd_bus *bus) {
+        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+        int r;
+
+        assert(bus);
+
+        r = sd_bus_call_method(bus,
+                               "org.freedesktop.resolve1",
+                               "/org/freedesktop/resolve1",
+                               "org.freedesktop.resolve1.Manager",
+                               "RevertLink",
+                               &error,
+                               NULL,
+                               "i", arg_ifindex);
+        if (r < 0)
+                return log_error_errno(r, "Failed to revert interface configuration: %s", bus_error_message(&error, r));
+
+        return 0;
+}
+
 static void help_protocol_types(void) {
         if (arg_legend)
                 puts("Known protocol types:");
-        puts("dns\nllmnr\nllmnr-ipv4\nllmnr-ipv6\nmdns\nmnds-ipv4\nmdns-ipv6");
+        puts("dns\nllmnr\nllmnr-ipv4\nllmnr-ipv6\nmdns\nmdns-ipv4\nmdns-ipv6");
 }
 
 static void help_dns_types(void) {
@@ -1609,6 +1850,13 @@ static void help(void) {
                "     --flush-caches         Flush all local DNS caches\n"
                "     --reset-server-features\n"
                "                            Forget learnt DNS server feature levels\n"
+               "     --set-dns=SERVER       Set per-interface DNS server address\n"
+               "     --set-domain=DOMAIN    Set per-interface search domain\n"
+               "     --set-llmnr=MODE       Set per-interface LLMNR mode\n"
+               "     --set-mdns=MODE        Set per-interface MulticastDNS mode\n"
+               "     --set-dnssec=MODE      Set per-interface DNSSEC mode\n"
+               "     --set-nta=DOMAIN       Set per-interface DNSSEC NTA\n"
+               "     --revert               Revert per-interface configuration\n"
                , program_invocation_short_name);
 }
 
@@ -1630,6 +1878,13 @@ static int parse_argv(int argc, char *argv[]) {
                 ARG_FLUSH_CACHES,
                 ARG_RESET_SERVER_FEATURES,
                 ARG_NO_PAGER,
+                ARG_SET_DNS,
+                ARG_SET_DOMAIN,
+                ARG_SET_LLMNR,
+                ARG_SET_MDNS,
+                ARG_SET_DNSSEC,
+                ARG_SET_NTA,
+                ARG_REVERT_LINK,
         };
 
         static const struct option options[] = {
@@ -1654,6 +1909,13 @@ static int parse_argv(int argc, char *argv[]) {
                 { "flush-caches",          no_argument,       NULL, ARG_FLUSH_CACHES          },
                 { "reset-server-features", no_argument,       NULL, ARG_RESET_SERVER_FEATURES },
                 { "no-pager",              no_argument,       NULL, ARG_NO_PAGER              },
+                { "set-dns",               required_argument, NULL, ARG_SET_DNS               },
+                { "set-domain",            required_argument, NULL, ARG_SET_DOMAIN            },
+                { "set-llmnr",             required_argument, NULL, ARG_SET_LLMNR             },
+                { "set-mdns",              required_argument, NULL, ARG_SET_MDNS              },
+                { "set-dnssec",            required_argument, NULL, ARG_SET_DNSSEC            },
+                { "set-nta",               required_argument, NULL, ARG_SET_NTA               },
+                { "revert",                no_argument,       NULL, ARG_REVERT_LINK           },
                 {}
         };
 
@@ -1849,6 +2111,84 @@ static int parse_argv(int argc, char *argv[]) {
                         arg_no_pager = true;
                         break;
 
+                case ARG_SET_DNS: {
+                        struct in_addr_data data, *n;
+
+                        r = in_addr_from_string_auto(optarg, &data.family, &data.address);
+                        if (r < 0)
+                                return log_error_errno(r, "Failed to parse DNS server address: %s", optarg);
+
+                        n = realloc(arg_set_dns, sizeof(struct in_addr_data) * (arg_n_set_dns + 1));
+                        if (!n)
+                                return log_oom();
+                        arg_set_dns = n;
+
+                        arg_set_dns[arg_n_set_dns++] = data;
+                        arg_mode = MODE_SET_LINK;
+                        break;
+                }
+
+                case ARG_SET_DOMAIN: {
+                        const char *p;
+
+                        p = optarg[0] == '~' ? optarg + 1 : optarg;
+
+                        r = dns_name_is_valid(p);
+                        if (r < 0)
+                                return log_error_errno(r, "Failed to validate specified domain %s: %m", p);
+                        if (r == 0)
+                                return log_error_errno(r, "Domain not valid: %s", p);
+
+                        r = strv_extend(&arg_set_domain, optarg);
+                        if (r < 0)
+                                return log_oom();
+
+                        arg_mode = MODE_SET_LINK;
+                        break;
+                }
+
+                case ARG_SET_LLMNR:
+                        r = free_and_strdup(&arg_set_llmnr, optarg);
+                        if (r < 0)
+                                return log_oom();
+
+                        arg_mode = MODE_SET_LINK;
+                        break;
+
+                case ARG_SET_MDNS:
+                        r = free_and_strdup(&arg_set_mdns, optarg);
+                        if (r < 0)
+                                return log_oom();
+
+                        arg_mode = MODE_SET_LINK;
+                        break;
+
+                case ARG_SET_DNSSEC:
+                        r = free_and_strdup(&arg_set_dnssec, optarg);
+                        if (r < 0)
+                                return log_oom();
+
+                        arg_mode = MODE_SET_LINK;
+                        break;
+
+                case ARG_SET_NTA:
+                        r = dns_name_is_valid(optarg);
+                        if (r < 0)
+                                return log_error_errno(r, "Failed to validate specified domain %s: %m", optarg);
+                        if (r == 0)
+                                return log_error_errno(r, "Domain not valid: %s", optarg);
+
+                        r = strv_extend(&arg_set_nta, optarg);
+                        if (r < 0)
+                                return log_oom();
+
+                        arg_mode = MODE_SET_LINK;
+                        break;
+
+                case ARG_REVERT_LINK:
+                        arg_mode = MODE_REVERT_LINK;
+                        break;
+
                 case '?':
                         return -EINVAL;
 
@@ -1872,6 +2212,19 @@ static int parse_argv(int argc, char *argv[]) {
         if (arg_class != 0 && arg_type == 0)
                 arg_type = DNS_TYPE_A;
 
+        if (IN_SET(arg_mode, MODE_SET_LINK, MODE_REVERT_LINK)) {
+
+                if (arg_ifindex <= 0) {
+                        log_error("--set-dns=, --set-domain=, --set-llmnr=, --set-mdns=, --set-dnssec=, --set-nta= and --revert require --interface=.");
+                        return -EINVAL;
+                }
+
+                if (arg_ifindex == LOOPBACK_IFINDEX) {
+                        log_error("Interface can't be the loopback interface (lo). Sorry.");
+                        return -EINVAL;
+                }
+        }
+
         return 1 /* work to do */;
 }
 
@@ -2063,10 +2416,38 @@ int main(int argc, char **argv) {
                         r = status_all(bus);
 
                 break;
+
+
+        case MODE_SET_LINK:
+                if (argc > optind) {
+                        log_error("Too many arguments.");
+                        r = -EINVAL;
+                        goto finish;
+                }
+
+                r = set_link(bus);
+                break;
+
+        case MODE_REVERT_LINK:
+                if (argc > optind) {
+                        log_error("Too many arguments.");
+                        r = -EINVAL;
+                        goto finish;
+                }
+
+                r = revert_link(bus);
+                break;
         }
 
 finish:
         pager_close();
 
+        free(arg_set_dns);
+        strv_free(arg_set_domain);
+        free(arg_set_llmnr);
+        free(arg_set_mdns);
+        free(arg_set_dnssec);
+        strv_free(arg_set_nta);
+
         return r == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
 }
index c6f14eb..9157d9e 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
 #include "resolved-bus.h"
 #include "resolved-def.h"
 #include "resolved-dns-synthesize.h"
+#include "resolved-dnssd.h"
+#include "resolved-dnssd-bus.h"
 #include "resolved-link-bus.h"
+#include "user-util.h"
+#include "utf8.h"
 
 static int reply_query_state(DnsQuery *q) {
 
@@ -1580,6 +1585,232 @@ static int bus_method_reset_server_features(sd_bus_message *message, void *userd
         return sd_bus_reply_method_return(message, NULL);
 }
 
+static int on_bus_track(sd_bus_track *t, void *userdata) {
+        DnssdService *s = userdata;
+
+        assert(t);
+        assert(s);
+
+        log_debug("Client of active request vanished, destroying DNS-SD service.");
+        dnssd_service_free(s);
+
+        return 0;
+}
+
+static int bus_method_register_service(sd_bus_message *message, void *userdata, sd_bus_error *error) {
+        _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
+        _cleanup_(dnssd_service_freep) DnssdService *service = NULL;
+        _cleanup_(sd_bus_track_unrefp) sd_bus_track *bus_track = NULL;
+        _cleanup_free_ char *path = NULL;
+        _cleanup_free_ char *instance_name = NULL;
+        Manager *m = userdata;
+        DnssdService *s = NULL;
+        const char *name;
+        const char *name_template;
+        const char *type;
+        uid_t euid;
+        int r;
+
+        assert(message);
+        assert(m);
+
+        if (m->mdns_support != RESOLVE_SUPPORT_YES)
+                return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Support for MulticastDNS is disabled");
+
+        r = bus_verify_polkit_async(message, CAP_SYS_ADMIN,
+                                    "org.freedesktop.resolve1.register-service",
+                                    NULL, false, UID_INVALID,
+                                    &m->polkit_registry, error);
+        if (r < 0)
+                return r;
+        if (r == 0)
+                return 1; /* Polkit will call us back */
+
+        service = new0(DnssdService, 1);
+        if (!service)
+                return log_oom();
+
+        r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
+        if (r < 0)
+                return r;
+
+        r = sd_bus_creds_get_euid(creds, &euid);
+        if (r < 0)
+                return r;
+        service->originator = euid;
+
+        r = sd_bus_message_read(message, "sssqqq", &name, &name_template, &type,
+                                &service->port, &service->priority,
+                                &service->weight);
+        if (r < 0)
+                return r;
+
+        s = hashmap_get(m->dnssd_services, name);
+        if (s)
+                return sd_bus_error_setf(error, BUS_ERROR_DNSSD_SERVICE_EXISTS, "DNS-SD service '%s' exists already", name);
+
+        if (!dnssd_srv_type_is_valid(type))
+                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "DNS-SD service type '%s' is invalid", type);
+
+        service->name = strdup(name);
+        if (!service->name)
+                return log_oom();
+
+        service->name_template = strdup(name_template);
+        if (!service->name_template)
+                return log_oom();
+
+        service->type = strdup(type);
+        if (!service->type)
+                return log_oom();
+
+        r = dnssd_render_instance_name(service, &instance_name);
+        if (r < 0)
+                return r;
+
+        r = sd_bus_message_enter_container(message, SD_BUS_TYPE_ARRAY, "a{say}");
+        if (r < 0)
+                return r;
+
+        while ((r = sd_bus_message_enter_container(message, SD_BUS_TYPE_ARRAY, "{say}")) > 0) {
+                _cleanup_(dnssd_txtdata_freep) DnssdTxtData *txt_data = NULL;
+                DnsTxtItem *last = NULL;
+
+                txt_data = new0(DnssdTxtData, 1);
+                if (!txt_data)
+                        return log_oom();
+
+                while ((r = sd_bus_message_enter_container(message, SD_BUS_TYPE_DICT_ENTRY, "say")) > 0) {
+                        const char *key;
+                        const void *value;
+                        size_t size;
+                        DnsTxtItem *i;
+
+                        r = sd_bus_message_read(message, "s", &key);
+                        if (r < 0)
+                                return r;
+
+                        if (isempty(key))
+                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Keys in DNS-SD TXT RRs can't be empty");
+
+                        if (!ascii_is_valid(key))
+                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "TXT key '%s' contains non-ASCII symbols", key);
+
+                        r = sd_bus_message_read_array(message, 'y', &value, &size);
+                        if (r < 0)
+                                return r;
+
+                        r = dnssd_txt_item_new_from_data(key, value, size, &i);
+                        if (r < 0)
+                                return r;
+
+                        LIST_INSERT_AFTER(items, txt_data->txt, last, i);
+                        last = i;
+
+                        r = sd_bus_message_exit_container(message);
+                        if (r < 0)
+                                return r;
+
+                }
+                if (r < 0)
+                        return r;
+
+                r = sd_bus_message_exit_container(message);
+                if (r < 0)
+                        return r;
+
+                if (txt_data->txt) {
+                        LIST_PREPEND(items, service->txt_data_items, txt_data);
+                        txt_data = NULL;
+                }
+        }
+        if (r < 0)
+                return r;
+
+        r = sd_bus_message_exit_container(message);
+        if (r < 0)
+                return r;
+
+        if (!service->txt_data_items) {
+                _cleanup_(dnssd_txtdata_freep) DnssdTxtData *txt_data = NULL;
+
+                txt_data = new0(DnssdTxtData, 1);
+                if (!txt_data)
+                        return log_oom();
+
+                r = dns_txt_item_new_empty(&txt_data->txt);
+                if (r < 0)
+                        return r;
+
+                LIST_PREPEND(items, service->txt_data_items, txt_data);
+                txt_data = NULL;
+        }
+
+        r = sd_bus_path_encode("/org/freedesktop/resolve1/dnssd", service->name, &path);
+        if (r < 0)
+                return r;
+
+        r = hashmap_ensure_allocated(&m->dnssd_services, &string_hash_ops);
+        if (r < 0)
+                return r;
+
+        r = hashmap_put(m->dnssd_services, service->name, service);
+        if (r < 0)
+                return r;
+
+        r = sd_bus_track_new(sd_bus_message_get_bus(message), &bus_track, on_bus_track, service);
+        if (r < 0)
+                return r;
+
+        r = sd_bus_track_add_sender(bus_track, message);
+        if (r < 0)
+                return r;
+
+        service->manager = m;
+
+        service = NULL;
+
+        manager_refresh_rrs(m);
+
+        return sd_bus_reply_method_return(message, "o", path);
+}
+
+static int call_dnssd_method(Manager *m, sd_bus_message *message, sd_bus_message_handler_t handler, sd_bus_error *error) {
+        _cleanup_free_ char *name = NULL;
+        DnssdService *s = NULL;
+        const char *path;
+        int r;
+
+        assert(m);
+        assert(message);
+        assert(handler);
+
+        r = sd_bus_message_read(message, "o", &path);
+        if (r < 0)
+                return r;
+
+        r = sd_bus_path_decode(path, "/org/freedesktop/resolve1/dnssd", &name);
+        if (r == 0)
+                return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_DNSSD_SERVICE, "DNS-SD service with object path '%s' does not exist", path);
+        if (r < 0)
+                return r;
+
+        s = hashmap_get(m->dnssd_services, name);
+        if (!s)
+                return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_DNSSD_SERVICE, "DNS-SD service '%s' not known", name);
+
+        return handler(message, s, error);
+}
+
+static int bus_method_unregister_service(sd_bus_message *message, void *userdata, sd_bus_error *error) {
+        Manager *m = userdata;
+
+        assert(message);
+        assert(m);
+
+        return call_dnssd_method(m, message, bus_dnssd_method_unregister, error);
+}
+
 static const sd_bus_vtable resolve_vtable[] = {
         SD_BUS_VTABLE_START(0),
         SD_BUS_PROPERTY("LLMNRHostname", "s", NULL, offsetof(Manager, llmnr_hostname), 0),
@@ -1608,6 +1839,8 @@ static const sd_bus_vtable resolve_vtable[] = {
         SD_BUS_METHOD("SetLinkDNSSECNegativeTrustAnchors", "ias", NULL, bus_method_set_link_dnssec_negative_trust_anchors, 0),
         SD_BUS_METHOD("RevertLink", "i", NULL, bus_method_revert_link, 0),
 
+        SD_BUS_METHOD("RegisterService", "sssqqqaa{say}", "o", bus_method_register_service, SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD("UnregisterService", "o", NULL, bus_method_unregister_service, SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_VTABLE_END,
 };
 
@@ -1680,6 +1913,14 @@ int manager_connect_bus(Manager *m) {
         if (r < 0)
                 return log_error_errno(r, "Failed to register link enumerator: %m");
 
+        r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/resolve1/dnssd", "org.freedesktop.resolve1.DnssdService", dnssd_vtable, dnssd_object_find, m);
+        if (r < 0)
+                return log_error_errno(r, "Failed to register dnssd objects: %m");
+
+        r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/resolve1/dnssd", dnssd_node_enumerator, m);
+        if (r < 0)
+                return log_error_errno(r, "Failed to register dnssd enumerator: %m");
+
         r = sd_bus_request_name(m->bus, "org.freedesktop.resolve1", 0);
         if (r < 0)
                 return log_error_errno(r, "Failed to register name: %m");
index f49e133..11ddae9 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 3cf4261..ca69d70 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
 #include "conf-parser.h"
 #include "def.h"
 #include "extract-word.h"
+#include "hexdecoct.h"
 #include "parse-util.h"
 #include "resolved-conf.h"
+#include "resolved-dnssd.h"
+#include "specifier.h"
 #include "string-table.h"
 #include "string-util.h"
+#include "utf8.h"
 
 DEFINE_CONFIG_PARSE_ENUM(config_parse_dns_stub_listener_mode, dns_stub_listener_mode, DnsStubListenerMode, "Failed to parse DNS stub listener mode setting");
 
@@ -227,6 +232,160 @@ int config_parse_search_domains(
         return 0;
 }
 
+int config_parse_dnssd_service_name(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata) {
+        static const Specifier specifier_table[] = {
+                { 'b', specifier_boot_id,         NULL },
+                { 'H', specifier_host_name, NULL },
+                { 'm', specifier_machine_id, NULL },
+                { 'v', specifier_kernel_release,  NULL },
+                {}
+        };
+        DnssdService *s = userdata;
+        _cleanup_free_ char *name = NULL;
+        int r;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(s);
+
+        if (isempty(rvalue)) {
+                log_syntax(unit, LOG_ERR, filename, line, 0, "Service instance name can't be empty. Ignoring.");
+                return -EINVAL;
+        }
+
+        r = free_and_strdup(&s->name_template, rvalue);
+        if (r < 0)
+                return log_oom();
+
+        r = specifier_printf(s->name_template, specifier_table, NULL, &name);
+        if (r < 0)
+                return log_debug_errno(r, "Failed to replace specifiers: %m");
+
+        if (!dns_service_name_is_valid(name)) {
+                log_syntax(unit, LOG_ERR, filename, line, 0, "Service instance name template renders to invalid name '%s'. Ignoring.", name);
+                return -EINVAL;
+        }
+
+        return 0;
+}
+
+int config_parse_dnssd_service_type(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata) {
+        DnssdService *s = userdata;
+        int r;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(s);
+
+        if (isempty(rvalue)) {
+                log_syntax(unit, LOG_ERR, filename, line, 0, "Service type can't be empty. Ignoring.");
+                return -EINVAL;
+        }
+
+        if (!dnssd_srv_type_is_valid(rvalue)) {
+                log_syntax(unit, LOG_ERR, filename, line, 0, "Service type is invalid. Ignoring.");
+                return -EINVAL;
+        }
+
+        r = free_and_strdup(&s->type, rvalue);
+        if (r < 0)
+                return log_oom();
+
+        return 0;
+}
+
+int config_parse_dnssd_txt(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata) {
+        _cleanup_(dnssd_txtdata_freep) DnssdTxtData *txt_data = NULL;
+        DnssdService *s = userdata;
+        DnsTxtItem *last = NULL;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(s);
+
+        if (isempty(rvalue)) {
+                /* Flush out collected items */
+                s->txt_data_items = dnssd_txtdata_free_all(s->txt_data_items);
+                return 0;
+        }
+
+        txt_data = new0(DnssdTxtData, 1);
+        if (!txt_data)
+                return log_oom();
+
+        for (;;) {
+                _cleanup_free_ char *word = NULL;
+                _cleanup_free_ char *key = NULL;
+                _cleanup_free_ char *value = NULL;
+                _cleanup_free_ void *decoded = NULL;
+                size_t length = 0;
+                DnsTxtItem *i;
+                int r;
+
+                r = extract_first_word(&rvalue, &word, NULL,
+                                       EXTRACT_QUOTES|EXTRACT_CUNESCAPE|EXTRACT_CUNESCAPE_RELAX);
+                if (r == 0)
+                        break;
+                if (r == -ENOMEM)
+                        return log_oom();
+                if (r < 0)
+                        return log_syntax(unit, LOG_ERR, filename, line, r, "Invalid syntax, ignoring: %s", rvalue);
+
+                r = split_pair(word, "=", &key, &value);
+                if (r == -ENOMEM)
+                        return log_oom();
+                if (r == -EINVAL) {
+                        key = word;
+                        word = NULL;
+                }
+
+                if (!ascii_is_valid(key)) {
+                        log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid syntax, ignoring: %s", key);
+                        return -EINVAL;
+                }
+
+                switch (ltype) {
+
+                case DNS_TXT_ITEM_DATA:
+                        if (value) {
+                                r = unbase64mem(value, strlen(value), &decoded, &length);
+                                if (r == -ENOMEM)
+                                        return log_oom();
+                                if (r < 0)
+                                        return log_syntax(unit, LOG_ERR, filename, line, r,
+                                                          "Invalid base64 encoding, ignoring: %s", value);
+                        }
+
+                        r = dnssd_txt_item_new_from_data(key, decoded, length, &i);
+                        if (r < 0)
+                                return log_oom();
+                        break;
+
+                case DNS_TXT_ITEM_TEXT:
+                        r = dnssd_txt_item_new_from_string(key, value, &i);
+                        if (r < 0)
+                                return log_oom();
+                        break;
+
+                default:
+                        assert_not_reached("Unknown type of Txt config");
+                }
+
+                LIST_INSERT_AFTER(items, txt_data->txt, last, i);
+                last = i;
+        }
+
+        if (!LIST_IS_EMPTY(txt_data->txt)) {
+                LIST_PREPEND(items, s->txt_data_items, txt_data);
+                txt_data = NULL;
+        }
+
+        return 0;
+}
+
 int manager_parse_config_file(Manager *m) {
         int r;
 
@@ -236,7 +395,7 @@ int manager_parse_config_file(Manager *m) {
                                      CONF_PATHS_NULSTR("systemd/resolved.conf.d"),
                                      "Resolve\0",
                                      config_item_perf_lookup, resolved_gperf_lookup,
-                                     false, m);
+                                     CONFIG_PARSE_WARN, m);
         if (r < 0)
                 return r;
 
index 8184d6c..4ebb45f 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -43,9 +44,14 @@ int manager_parse_dns_server_string_and_warn(Manager *m, DnsServerType type, con
 
 const struct ConfigPerfItem* resolved_gperf_lookup(const char *key, GPERF_LEN_TYPE length);
 
+const struct ConfigPerfItem* resolved_dnssd_gperf_lookup(const char *key, GPERF_LEN_TYPE length);
+
 int config_parse_dns_servers(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_search_domains(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_dns_stub_listener_mode(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_dnssd_service_name(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_dnssd_service_type(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_dnssd_txt(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 
 const char* dns_stub_listener_mode_to_string(DnsStubListenerMode p) _const_;
 DnsStubListenerMode dns_stub_listener_mode_from_string(const char *s) _pure_;
index c4c1915..64c2b15 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index db86b4d..ecc6143 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 11d2e25..af33787 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index f8dab01..942956d 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 22a7c17..a5ace2c 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 33bb5a1..e3eca7e 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
+#include <stdio_ext.h>
+
 #if HAVE_GCRYPT
 #include <gcrypt.h>
 #endif
 
 #include "alloc-util.h"
 #include "dns-domain.h"
+#include "fd-util.h"
+#include "fileio.h"
 #include "gcrypt-util.h"
 #include "hexdecoct.h"
 #include "resolved-dns-dnssec.h"
@@ -435,6 +440,99 @@ static int dnssec_ecdsa_verify(
                         q, key_size*2+1);
 }
 
+#if GCRYPT_VERSION_NUMBER >= 0x010600
+static int dnssec_eddsa_verify_raw(
+                const char *curve,
+                const void *signature_r, size_t signature_r_size,
+                const void *signature_s, size_t signature_s_size,
+                const void *data, size_t data_size,
+                const void *key, size_t key_size) {
+
+        gcry_sexp_t public_key_sexp = NULL, data_sexp = NULL, signature_sexp = NULL;
+        gcry_error_t ge;
+        int k;
+
+        ge = gcry_sexp_build(&signature_sexp,
+                             NULL,
+                             "(sig-val (eddsa (r %b) (s %b)))",
+                             (int) signature_r_size,
+                             signature_r,
+                             (int) signature_s_size,
+                             signature_s);
+        if (ge != 0) {
+                k = -EIO;
+                goto finish;
+        }
+
+        ge = gcry_sexp_build(&data_sexp,
+                             NULL,
+                             "(data (flags eddsa) (hash-algo sha512) (value %b))",
+                             (int) data_size,
+                             data);
+        if (ge != 0) {
+                k = -EIO;
+                goto finish;
+        }
+
+        ge = gcry_sexp_build(&public_key_sexp,
+                             NULL,
+                             "(public-key (ecc (curve %s) (flags eddsa) (q %b)))",
+                             curve,
+                             (int) key_size,
+                             key);
+        if (ge != 0) {
+                k = -EIO;
+                goto finish;
+        }
+
+        ge = gcry_pk_verify(signature_sexp, data_sexp, public_key_sexp);
+        if (gpg_err_code(ge) == GPG_ERR_BAD_SIGNATURE)
+                k = 0;
+        else if (ge != 0) {
+                log_debug("EdDSA signature check failed: %s", gpg_strerror(ge));
+                k = -EIO;
+        } else
+                k = 1;
+finish:
+        if (public_key_sexp)
+                gcry_sexp_release(public_key_sexp);
+        if (signature_sexp)
+                gcry_sexp_release(signature_sexp);
+        if (data_sexp)
+                gcry_sexp_release(data_sexp);
+
+        return k;
+}
+
+static int dnssec_eddsa_verify(
+                int algorithm,
+                const void *data, size_t data_size,
+                DnsResourceRecord *rrsig,
+                DnsResourceRecord *dnskey) {
+        const char *curve;
+        size_t key_size;
+
+        if (algorithm == DNSSEC_ALGORITHM_ED25519) {
+                curve = "Ed25519";
+                key_size = 32;
+        } else
+                return -EOPNOTSUPP;
+
+        if (dnskey->dnskey.key_size != key_size)
+                return -EINVAL;
+
+        if (rrsig->rrsig.signature_size != key_size * 2)
+                return -EINVAL;
+
+        return dnssec_eddsa_verify_raw(
+                        curve,
+                        rrsig->rrsig.signature, key_size,
+                        (uint8_t*) rrsig->rrsig.signature + key_size, key_size,
+                        data, data_size,
+                        dnskey->dnskey.key, key_size);
+}
+#endif
+
 static void md_add_uint8(gcry_md_hd_t md, uint8_t v) {
         gcry_md_write(md, &v, sizeof(v));
 }
@@ -444,9 +542,18 @@ static void md_add_uint16(gcry_md_hd_t md, uint16_t v) {
         gcry_md_write(md, &v, sizeof(v));
 }
 
-static void md_add_uint32(gcry_md_hd_t md, uint32_t v) {
+static void fwrite_uint8(FILE *fp, uint8_t v) {
+        fwrite(&v, sizeof(v), 1, fp);
+}
+
+static void fwrite_uint16(FILE *fp, uint16_t v) {
+        v = htobe16(v);
+        fwrite(&v, sizeof(v), 1, fp);
+}
+
+static void fwrite_uint32(FILE *fp, uint32_t v) {
         v = htobe32(v);
-        gcry_md_write(md, &v, sizeof(v));
+        fwrite(&v, sizeof(v), 1, fp);
 }
 
 static int dnssec_rrsig_prepare(DnsResourceRecord *rrsig) {
@@ -612,6 +719,9 @@ int dnssec_verify_rrset(
         gcry_md_hd_t md = NULL;
         int r, md_algorithm;
         size_t k, n = 0;
+        size_t sig_size = 0;
+        _cleanup_free_ char *sig_data = NULL;
+        _cleanup_fclose_ FILE *f = NULL;
         size_t hash_size;
         void *hash;
         bool wildcard;
@@ -627,14 +737,6 @@ int dnssec_verify_rrset(
          * using the signature "rrsig" and the key "dnskey". It's
          * assumed that RRSIG and DNSKEY match. */
 
-        md_algorithm = algorithm_to_gcrypt_md(rrsig->rrsig.algorithm);
-        if (md_algorithm == -EOPNOTSUPP) {
-                *result = DNSSEC_UNSUPPORTED_ALGORITHM;
-                return 0;
-        }
-        if (md_algorithm < 0)
-                return md_algorithm;
-
         r = dnssec_rrsig_prepare(rrsig);
         if (r == -EINVAL) {
                 *result = DNSSEC_INVALID;
@@ -724,28 +826,23 @@ int dnssec_verify_rrset(
         /* Bring the RRs into canonical order */
         qsort_safe(list, n, sizeof(DnsResourceRecord*), rr_compare);
 
-        /* OK, the RRs are now in canonical order. Let's calculate the digest */
-        initialize_libgcrypt(false);
-
-        hash_size = gcry_md_get_algo_dlen(md_algorithm);
-        assert(hash_size > 0);
-
-        gcry_md_open(&md, md_algorithm, 0);
-        if (!md)
-                return -EIO;
+        f = open_memstream(&sig_data, &sig_size);
+        if (!f)
+                return -ENOMEM;
+        __fsetlocking(f, FSETLOCKING_BYCALLER);
 
-        md_add_uint16(md, rrsig->rrsig.type_covered);
-        md_add_uint8(md, rrsig->rrsig.algorithm);
-        md_add_uint8(md, rrsig->rrsig.labels);
-        md_add_uint32(md, rrsig->rrsig.original_ttl);
-        md_add_uint32(md, rrsig->rrsig.expiration);
-        md_add_uint32(md, rrsig->rrsig.inception);
-        md_add_uint16(md, rrsig->rrsig.key_tag);
+        fwrite_uint16(f, rrsig->rrsig.type_covered);
+        fwrite_uint8(f, rrsig->rrsig.algorithm);
+        fwrite_uint8(f, rrsig->rrsig.labels);
+        fwrite_uint32(f, rrsig->rrsig.original_ttl);
+        fwrite_uint32(f, rrsig->rrsig.expiration);
+        fwrite_uint32(f, rrsig->rrsig.inception);
+        fwrite_uint16(f, rrsig->rrsig.key_tag);
 
         r = dns_name_to_wire_format(rrsig->rrsig.signer, wire_format_name, sizeof(wire_format_name), true);
         if (r < 0)
                 goto finish;
-        gcry_md_write(md, wire_format_name, r);
+        fwrite(wire_format_name, 1, r, f);
 
         /* Convert the source of synthesis into wire format */
         r = dns_name_to_wire_format(source, wire_format_name, sizeof(wire_format_name), true);
@@ -759,24 +856,66 @@ int dnssec_verify_rrset(
 
                 /* Hash the source of synthesis. If this is a wildcard, then prefix it with the *. label */
                 if (wildcard)
-                        gcry_md_write(md, (uint8_t[]) { 1, '*'}, 2);
-                gcry_md_write(md, wire_format_name, r);
+                        fwrite((uint8_t[]) { 1, '*'}, sizeof(uint8_t), 2, f);
+                fwrite(wire_format_name, 1, r, f);
 
-                md_add_uint16(md, rr->key->type);
-                md_add_uint16(md, rr->key->class);
-                md_add_uint32(md, rrsig->rrsig.original_ttl);
+                fwrite_uint16(f, rr->key->type);
+                fwrite_uint16(f, rr->key->class);
+                fwrite_uint32(f, rrsig->rrsig.original_ttl);
 
                 l = DNS_RESOURCE_RECORD_RDATA_SIZE(rr);
                 assert(l <= 0xFFFF);
 
-                md_add_uint16(md, (uint16_t) l);
-                gcry_md_write(md, DNS_RESOURCE_RECORD_RDATA(rr), l);
+                fwrite_uint16(f, (uint16_t) l);
+                fwrite(DNS_RESOURCE_RECORD_RDATA(rr), 1, l, f);
         }
 
-        hash = gcry_md_read(md, 0);
-        if (!hash) {
-                r = -EIO;
+        r = fflush_and_check(f);
+        if (r < 0)
+                return r;
+
+        initialize_libgcrypt(false);
+
+        switch (rrsig->rrsig.algorithm) {
+#if GCRYPT_VERSION_NUMBER >= 0x010600
+        case DNSSEC_ALGORITHM_ED25519:
+                break;
+#else
+        case DNSSEC_ALGORITHM_ED25519:
+#endif
+        case DNSSEC_ALGORITHM_ED448:
+                *result = DNSSEC_UNSUPPORTED_ALGORITHM;
+                r = 0;
                 goto finish;
+        default:
+                /* OK, the RRs are now in canonical order. Let's calculate the digest */
+                md_algorithm = algorithm_to_gcrypt_md(rrsig->rrsig.algorithm);
+                if (md_algorithm == -EOPNOTSUPP) {
+                        *result = DNSSEC_UNSUPPORTED_ALGORITHM;
+                        r = 0;
+                        goto finish;
+                }
+                if (md_algorithm < 0) {
+                        r = md_algorithm;
+                        goto finish;
+                }
+
+                gcry_md_open(&md, md_algorithm, 0);
+                if (!md) {
+                        r = -EIO;
+                        goto finish;
+                }
+
+                hash_size = gcry_md_get_algo_dlen(md_algorithm);
+                assert(hash_size > 0);
+
+                gcry_md_write(md, sig_data, sig_size);
+
+                hash = gcry_md_read(md, 0);
+                if (!hash) {
+                        r = -EIO;
+                        goto finish;
+                }
         }
 
         switch (rrsig->rrsig.algorithm) {
@@ -801,6 +940,15 @@ int dnssec_verify_rrset(
                                 rrsig,
                                 dnskey);
                 break;
+#if GCRYPT_VERSION_NUMBER >= 0x010600
+        case DNSSEC_ALGORITHM_ED25519:
+                r = dnssec_eddsa_verify(
+                                rrsig->rrsig.algorithm,
+                                sig_data, sig_size,
+                                rrsig,
+                                dnskey);
+                break;
+#endif
         }
 
         if (r < 0)
@@ -820,7 +968,9 @@ int dnssec_verify_rrset(
         r = 0;
 
 finish:
-        gcry_md_close(md);
+        if (md)
+                gcry_md_close(md);
+
         return r;
 }
 
index 77bd4d7..25e3e08 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index e2f227b..d7a839a 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -1514,7 +1515,7 @@ static int dns_packet_read_type_window(DnsPacket *p, Bitmap **types, size_t *sta
 
                 found = true;
 
-                while (bitmask) {
+                for (; bitmask; bit++, bitmask >>= 1)
                         if (bitmap[i] & bitmask) {
                                 uint16_t n;
 
@@ -1528,10 +1529,6 @@ static int dns_packet_read_type_window(DnsPacket *p, Bitmap **types, size_t *sta
                                 if (r < 0)
                                         return r;
                         }
-
-                        bit++;
-                        bitmask >>= 1;
-                }
         }
 
         if (!found)
@@ -1701,16 +1698,9 @@ int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, bool *ret_cache_fl
         case DNS_TYPE_SPF: /* exactly the same as TXT */
         case DNS_TYPE_TXT:
                 if (rdlength <= 0) {
-                        DnsTxtItem *i;
-                        /* RFC 6763, section 6.1 suggests to treat
-                         * empty TXT RRs as equivalent to a TXT record
-                         * with a single empty string. */
-
-                        i = malloc0(offsetof(DnsTxtItem, data) + 1); /* for safety reasons we add an extra NUL byte */
-                        if (!i)
-                                return -ENOMEM;
-
-                        rr->txt.items = i;
+                        r = dns_txt_item_new_empty(&rr->txt.items);
+                        if (r < 0)
+                                return r;
                 } else {
                         DnsTxtItem *last = NULL;
 
index b873c0f..15994d2 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index c2b29bc..227d0b5 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index b8ea48f..c01dc35 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 24f3e8e..4dc3de4 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index a9a1863..666eb92 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index e8c05ed..eb5592d 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -181,6 +182,19 @@ bool dns_resource_key_is_address(const DnsResourceKey *key) {
         return key->class == DNS_CLASS_IN && IN_SET(key->type, DNS_TYPE_A, DNS_TYPE_AAAA);
 }
 
+bool dns_resource_key_is_dnssd_ptr(const DnsResourceKey *key) {
+        assert(key);
+
+        /* Check if this is a PTR resource key used in
+           Service Instance Enumeration as described in RFC6763 p4.1. */
+
+        if (key->type != DNS_TYPE_PTR)
+                return false;
+
+        return dns_name_endswith(dns_resource_key_name(key), "_tcp.local") ||
+                dns_name_endswith(dns_resource_key_name(key), "_udp.local");
+}
+
 int dns_resource_key_equal(const DnsResourceKey *a, const DnsResourceKey *b) {
         int r;
 
@@ -334,8 +348,8 @@ char* dns_resource_key_to_string(const DnsResourceKey *key, char *buf, size_t bu
 
         snprintf(buf, buf_size, "%s %s%s%.0u %s%s%.0u",
                  dns_resource_key_name(key),
-                 c ?: "", c ? "" : "CLASS", c ? 0 : key->class,
-                 t ?: "", t ? "" : "TYPE", t ? 0 : key->class);
+                 strempty(c), c ? "" : "CLASS", c ? 0 : key->class,
+                 strempty(t), t ? "" : "TYPE", t ? 0 : key->class);
 
         return ans;
 }
@@ -752,7 +766,7 @@ static int format_timestamp_dns(char *buf, size_t l, time_t sec) {
         struct tm tm;
 
         assert(buf);
-        assert(l > strlen("YYYYMMDDHHmmSS"));
+        assert(l > STRLEN("YYYYMMDDHHmmSS"));
 
         if (!gmtime_r(&sec, &tm))
                 return -EINVAL;
@@ -1021,7 +1035,7 @@ const char *dns_resource_record_to_string(DnsResourceRecord *rr) {
 
         case DNS_TYPE_RRSIG: {
                 _cleanup_free_ char *alg = NULL;
-                char expiration[strlen("YYYYMMDDHHmmSS") + 1], inception[strlen("YYYYMMDDHHmmSS") + 1];
+                char expiration[STRLEN("YYYYMMDDHHmmSS") + 1], inception[STRLEN("YYYYMMDDHHmmSS") + 1];
                 const char *type;
                 int n;
 
@@ -1570,7 +1584,7 @@ DnsResourceRecord *dns_resource_record_copy(DnsResourceRecord *rr) {
                         return NULL;
 
                 copy->hinfo.os = strdup(rr->hinfo.os);
-                if(!copy->hinfo.os)
+                if (!copy->hinfo.os)
                         return NULL;
                 break;
 
@@ -1805,6 +1819,22 @@ DnsTxtItem *dns_txt_item_copy(DnsTxtItem *first) {
         return copy;
 }
 
+int dns_txt_item_new_empty(DnsTxtItem **ret) {
+        DnsTxtItem *i;
+
+        /* RFC 6763, section 6.1 suggests to treat
+         * empty TXT RRs as equivalent to a TXT record
+         * with a single empty string. */
+
+        i = malloc0(offsetof(DnsTxtItem, data) + 1); /* for safety reasons we add an extra NUL byte */
+        if (!i)
+                return -ENOMEM;
+
+        *ret = i;
+
+        return 0;
+}
+
 static const char* const dnssec_algorithm_table[_DNSSEC_ALGORITHM_MAX_DEFINED] = {
         /* Mnemonics as listed on https://www.iana.org/assignments/dns-sec-alg-numbers/dns-sec-alg-numbers.xhtml */
         [DNSSEC_ALGORITHM_RSAMD5]             = "RSAMD5",
@@ -1819,6 +1849,8 @@ static const char* const dnssec_algorithm_table[_DNSSEC_ALGORITHM_MAX_DEFINED] =
         [DNSSEC_ALGORITHM_ECC_GOST]           = "ECC-GOST",
         [DNSSEC_ALGORITHM_ECDSAP256SHA256]    = "ECDSAP256SHA256",
         [DNSSEC_ALGORITHM_ECDSAP384SHA384]    = "ECDSAP384SHA384",
+        [DNSSEC_ALGORITHM_ED25519]            = "ED25519",
+        [DNSSEC_ALGORITHM_ED448]              = "ED448",
         [DNSSEC_ALGORITHM_INDIRECT]           = "INDIRECT",
         [DNSSEC_ALGORITHM_PRIVATEDNS]         = "PRIVATEDNS",
         [DNSSEC_ALGORITHM_PRIVATEOID]         = "PRIVATEOID",
index 42d39a1..8e1a6bb 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -56,6 +57,8 @@ enum {
         DNSSEC_ALGORITHM_ECC_GOST = 12,        /* RFC 5933 */
         DNSSEC_ALGORITHM_ECDSAP256SHA256 = 13, /* RFC 6605 */
         DNSSEC_ALGORITHM_ECDSAP384SHA384 = 14, /* RFC 6605 */
+        DNSSEC_ALGORITHM_ED25519 = 15,         /* RFC 8080 */
+        DNSSEC_ALGORITHM_ED448 = 16,           /* RFC 8080 */
         DNSSEC_ALGORITHM_INDIRECT = 252,
         DNSSEC_ALGORITHM_PRIVATEDNS,
         DNSSEC_ALGORITHM_PRIVATEOID,
@@ -297,6 +300,7 @@ DnsResourceKey* dns_resource_key_ref(DnsResourceKey *key);
 DnsResourceKey* dns_resource_key_unref(DnsResourceKey *key);
 const char* dns_resource_key_name(const DnsResourceKey *key);
 bool dns_resource_key_is_address(const DnsResourceKey *key);
+bool dns_resource_key_is_dnssd_ptr(const DnsResourceKey *key);
 int dns_resource_key_equal(const DnsResourceKey *a, const DnsResourceKey *b);
 int dns_resource_key_match_rr(const DnsResourceKey *key, DnsResourceRecord *rr, const char *search_domain);
 int dns_resource_key_match_cname_or_dname(const DnsResourceKey *key, const DnsResourceKey *cname, const char *search_domain);
@@ -340,6 +344,7 @@ int dns_resource_record_clamp_ttl(DnsResourceRecord **rr, uint32_t max_ttl);
 DnsTxtItem *dns_txt_item_free_all(DnsTxtItem *i);
 bool dns_txt_item_equal(DnsTxtItem *a, DnsTxtItem *b);
 DnsTxtItem *dns_txt_item_copy(DnsTxtItem *i);
+int dns_txt_item_new_empty(DnsTxtItem **ret);
 
 void dns_resource_record_hash_func(const void *i, struct siphash *state);
 
index ca54158..ea4459a 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -26,7 +27,9 @@
 #include "hostname-util.h"
 #include "missing.h"
 #include "random-util.h"
+#include "resolved-dnssd.h"
 #include "resolved-dns-scope.h"
+#include "resolved-dns-zone.h"
 #include "resolved-llmnr.h"
 #include "resolved-mdns.h"
 #include "socket-util.h"
@@ -102,8 +105,6 @@ static void dns_scope_abort_transactions(DnsScope *s) {
 }
 
 DnsScope* dns_scope_free(DnsScope *s) {
-        DnsResourceRecord *rr;
-
         if (!s)
                 return NULL;
 
@@ -118,10 +119,7 @@ DnsScope* dns_scope_free(DnsScope *s) {
 
         hashmap_free(s->transactions_by_key);
 
-        while ((rr = ordered_hashmap_steal_first(s->conflict_queue)))
-                dns_resource_record_unref(rr);
-
-        ordered_hashmap_free(s->conflict_queue);
+        ordered_hashmap_free_with_destructor(s->conflict_queue, dns_resource_record_unref);
         sd_event_source_unref(s->conflict_event_source);
 
         sd_event_source_unref(s->announce_event_source);
@@ -145,6 +143,26 @@ DnsServer *dns_scope_get_dns_server(DnsScope *s) {
                 return manager_get_dns_server(s->manager);
 }
 
+unsigned dns_scope_get_n_dns_servers(DnsScope *s) {
+        unsigned n = 0;
+        DnsServer *i;
+
+        assert(s);
+
+        if (s->protocol != DNS_PROTOCOL_DNS)
+                return 0;
+
+        if (s->link)
+                i = s->link->dns_servers;
+        else
+                i = s->manager->dns_servers;
+
+        for (; i; i = i->servers_next)
+                n++;
+
+        return n;
+}
+
 void dns_scope_next_dns_server(DnsScope *s) {
         assert(s);
 
@@ -407,7 +425,6 @@ int dns_scope_socket_tcp(DnsScope *s, int family, const union in_addr_union *add
 
 DnsScopeMatch dns_scope_good_domain(DnsScope *s, int ifindex, uint64_t flags, const char *domain) {
         DnsSearchDomain *d;
-        DnsServer *dns_server;
 
         assert(s);
         assert(domain);
@@ -440,24 +457,27 @@ DnsScopeMatch dns_scope_good_domain(DnsScope *s, int ifindex, uint64_t flags, co
         if (dns_name_endswith(domain, "invalid") > 0)
                 return DNS_SCOPE_NO;
 
-        /* Always honour search domains for routing queries. Note that
-         * we return DNS_SCOPE_YES here, rather than just
-         * DNS_SCOPE_MAYBE, which means wildcard scopes won't be
-         * considered anymore. */
-        LIST_FOREACH(domains, d, dns_scope_get_search_domains(s))
-                if (dns_name_endswith(domain, d->name) > 0)
-                        return DNS_SCOPE_YES;
-
-        /* If the DNS server has route-only domains, don't send other requests
-         * to it. This would be a privacy violation, will most probably fail
-         * anyway, and adds unnecessary load. */
-        dns_server = dns_scope_get_dns_server(s);
-        if (dns_server && dns_server_limited_domains(dns_server))
-                return DNS_SCOPE_NO;
-
         switch (s->protocol) {
 
-        case DNS_PROTOCOL_DNS:
+        case DNS_PROTOCOL_DNS: {
+                DnsServer *dns_server;
+
+                /* Never route things to scopes that lack DNS servers */
+                dns_server = dns_scope_get_dns_server(s);
+                if (!dns_server)
+                        return DNS_SCOPE_NO;
+
+                /* Always honour search domains for routing queries, except if this scope lacks DNS servers. Note that
+                 * we return DNS_SCOPE_YES here, rather than just DNS_SCOPE_MAYBE, which means other wildcard scopes
+                 * won't be considered anymore. */
+                LIST_FOREACH(domains, d, dns_scope_get_search_domains(s))
+                        if (dns_name_endswith(domain, d->name) > 0)
+                                return DNS_SCOPE_YES;
+
+                /* If the DNS server has route-only domains, don't send other requests to it. This would be a privacy
+                 * violation, will most probably fail anyway, and adds unnecessary load. */
+                if (dns_server_limited_domains(dns_server))
+                        return DNS_SCOPE_NO;
 
                 /* Exclude link-local IP ranges */
                 if (dns_name_endswith(domain, "254.169.in-addr.arpa") == 0 &&
@@ -472,6 +492,7 @@ DnsScopeMatch dns_scope_good_domain(DnsScope *s, int ifindex, uint64_t flags, co
                         return DNS_SCOPE_MAYBE;
 
                 return DNS_SCOPE_NO;
+        }
 
         case DNS_PROTOCOL_MDNS:
                 if ((s->family == AF_INET && dns_name_endswith(domain, "in-addr.arpa") > 0) ||
@@ -1068,7 +1089,12 @@ static int on_announcement_timeout(sd_event_source *s, usec_t usec, void *userda
 int dns_scope_announce(DnsScope *scope, bool goodbye) {
         _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
         _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
-        LinkAddress *a;
+        _cleanup_set_free_ Set *types = NULL;
+        DnsTransaction *t;
+        DnsZoneItem *z, *i;
+        unsigned size = 0;
+        Iterator iterator;
+        char *service_type;
         int r;
 
         if (!scope)
@@ -1077,18 +1103,85 @@ int dns_scope_announce(DnsScope *scope, bool goodbye) {
         if (scope->protocol != DNS_PROTOCOL_MDNS)
                 return 0;
 
-        answer = dns_answer_new(scope->link->n_addresses * 2);
+        /* Check if we're done with probing. */
+        LIST_FOREACH(transactions_by_scope, t, scope->transactions)
+                if (DNS_TRANSACTION_IS_LIVE(t->state))
+                        return 0;
+
+        /* Check if there're services pending conflict resolution. */
+        if (manager_next_dnssd_names(scope->manager))
+                return 0; /* we reach this point only if changing hostname didn't help */
+
+        /* Calculate answer's size. */
+        HASHMAP_FOREACH(z, scope->zone.by_key, iterator) {
+                if (z->state != DNS_ZONE_ITEM_ESTABLISHED)
+                        continue;
+
+                if (z->rr->key->type == DNS_TYPE_PTR &&
+                    !dns_zone_contains_name(&scope->zone, z->rr->ptr.name)) {
+                        char key_str[DNS_RESOURCE_KEY_STRING_MAX];
+
+                        log_debug("Skip PTR RR <%s> since its counterparts seem to be withdrawn", dns_resource_key_to_string(z->rr->key, key_str, sizeof key_str));
+                        z->state = DNS_ZONE_ITEM_WITHDRAWN;
+                        continue;
+                }
+
+                /* Collect service types for _services._dns-sd._udp.local RRs in a set */
+                if (!scope->announced &&
+                    dns_resource_key_is_dnssd_ptr(z->rr->key)) {
+                        if (!set_contains(types, dns_resource_key_name(z->rr->key))) {
+                                r = set_ensure_allocated(&types, &dns_name_hash_ops);
+                                if (r < 0)
+                                        return log_debug_errno(r, "Failed to allocate set: %m");
+
+                                r = set_put(types, dns_resource_key_name(z->rr->key));
+                                if (r < 0)
+                                        return log_debug_errno(r, "Failed to add item to set: %m");
+                        }
+                }
+
+                LIST_FOREACH(by_key, i, z)
+                        size++;
+        }
+
+        answer = dns_answer_new(size + set_size(types));
         if (!answer)
                 return log_oom();
 
-        LIST_FOREACH(addresses, a, scope->link->addresses) {
-                r = dns_answer_add(answer, a->mdns_address_rr, 0, goodbye ? DNS_ANSWER_GOODBYE : DNS_ANSWER_CACHE_FLUSH);
+        /* Second iteration, actually add RRs to the answer. */
+        HASHMAP_FOREACH(z, scope->zone.by_key, iterator)
+                LIST_FOREACH (by_key, i, z) {
+                        DnsAnswerFlags flags;
+
+                        if (i->state != DNS_ZONE_ITEM_ESTABLISHED)
+                                continue;
+
+                        if (dns_resource_key_is_dnssd_ptr(i->rr->key))
+                                flags = goodbye ? DNS_ANSWER_GOODBYE : 0;
+                        else
+                                flags = goodbye ? (DNS_ANSWER_GOODBYE|DNS_ANSWER_CACHE_FLUSH) : DNS_ANSWER_CACHE_FLUSH;
+
+                        r = dns_answer_add(answer, i->rr, 0 , flags);
+                        if (r < 0)
+                                return log_debug_errno(r, "Failed to add RR to announce: %m");
+                }
+
+        /* Since all the active services are in the zone make them discoverable now. */
+        SET_FOREACH(service_type, types, iterator) {
+                _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr;
+
+                rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_PTR,
+                                                  "_services._dns-sd._udp.local");
+                rr->ptr.name = strdup(service_type);
+                rr->ttl = MDNS_DEFAULT_TTL;
+
+                r = dns_zone_put(&scope->zone, scope, rr, false);
                 if (r < 0)
-                        return log_debug_errno(r, "Failed to add address RR to answer: %m");
+                        log_warning_errno(r, "Failed to add DNS-SD PTR record to MDNS zone: %m");
 
-                r = dns_answer_add(answer, a->mdns_ptr_rr, 0, goodbye ? DNS_ANSWER_GOODBYE : DNS_ANSWER_CACHE_FLUSH);
+                r = dns_answer_add(answer, rr, 0 , 0);
                 if (r < 0)
-                        return log_debug_errno(r, "Failed to add PTR RR to answer: %m");
+                        return log_debug_errno(r, "Failed to add RR to announce: %m");
         }
 
         if (dns_answer_isempty(answer))
@@ -1127,3 +1220,65 @@ int dns_scope_announce(DnsScope *scope, bool goodbye) {
 
         return 0;
 }
+
+int dns_scope_add_dnssd_services(DnsScope *scope) {
+        Iterator i;
+        DnssdService *service;
+        DnssdTxtData *txt_data;
+        int r;
+
+        assert(scope);
+
+        if (hashmap_size(scope->manager->dnssd_services) == 0)
+                return 0;
+
+        scope->announced = false;
+
+        HASHMAP_FOREACH(service, scope->manager->dnssd_services, i) {
+                service->withdrawn = false;
+
+                r = dns_zone_put(&scope->zone, scope, service->ptr_rr, false);
+                if (r < 0)
+                        log_warning_errno(r, "Failed to add PTR record to MDNS zone: %m");
+
+                r = dns_zone_put(&scope->zone, scope, service->srv_rr, true);
+                if (r < 0)
+                        log_warning_errno(r, "Failed to add SRV record to MDNS zone: %m");
+
+                LIST_FOREACH(items, txt_data, service->txt_data_items) {
+                        r = dns_zone_put(&scope->zone, scope, txt_data->rr, true);
+                        if (r < 0)
+                                log_warning_errno(r, "Failed to add TXT record to MDNS zone: %m");
+                }
+        }
+
+        return 0;
+}
+
+int dns_scope_remove_dnssd_services(DnsScope *scope) {
+        _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
+        Iterator i;
+        DnssdService *service;
+        DnssdTxtData *txt_data;
+        int r;
+
+        assert(scope);
+
+        key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_PTR,
+                                   "_services._dns-sd._udp.local");
+        if (!key)
+                return log_oom();
+
+        r = dns_zone_remove_rrs_by_key(&scope->zone, key);
+        if (r < 0)
+                return r;
+
+        HASHMAP_FOREACH(service, scope->manager->dnssd_services, i) {
+                dns_zone_remove_rr(&scope->zone, service->ptr_rr);
+                dns_zone_remove_rr(&scope->zone, service->srv_rr);
+                LIST_FOREACH(items, txt_data, service->txt_data_items)
+                        dns_zone_remove_rr(&scope->zone, txt_data->rr);
+        }
+
+        return 0;
+}
index 6f94b1f..6f58c3c 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -94,6 +95,7 @@ DnsScopeMatch dns_scope_good_domain(DnsScope *s, int ifindex, uint64_t flags, co
 bool dns_scope_good_key(DnsScope *s, const DnsResourceKey *key);
 
 DnsServer *dns_scope_get_dns_server(DnsScope *s);
+unsigned dns_scope_get_n_dns_servers(DnsScope *s);
 void dns_scope_next_dns_server(DnsScope *s);
 
 int dns_scope_llmnr_membership(DnsScope *s, bool b);
@@ -118,3 +120,7 @@ bool dns_scope_network_good(DnsScope *s);
 int dns_scope_ifindex(DnsScope *s);
 
 int dns_scope_announce(DnsScope *scope, bool goodbye);
+
+int dns_scope_add_dnssd_services(DnsScope *scope);
+
+int dns_scope_remove_dnssd_services(DnsScope *scope);
index 1386e6a..585c518 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index eaacef4..8442fbd 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 1b61dea..d470a64 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 00edd47..acc9281 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 5892534..52f23cd 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 4cdb4f6..e099158 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 5bc79a3..5ce8d24 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 12b86f6..197f2cc 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index e8592a6..e71fcbd 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -422,11 +423,11 @@ int dns_synthesize_answer(
 
                         v = synthesize_system_hostname_ptr(m, af, &address, ifindex, &answer);
                         if (v < 0)
-                                return log_error_errno(r, "Failed to synthesize system hostname PTR RR: %m");
+                                return log_error_errno(v, "Failed to synthesize system hostname PTR RR: %m");
 
                         w = synthesize_gateway_ptr(m, af, &address, ifindex, &answer);
                         if (w < 0)
-                                return log_error_errno(r, "Failed to synthesize gateway hostname PTR RR: %m");
+                                return log_error_errno(w, "Failed to synthesize gateway hostname PTR RR: %m");
 
                         if (v == 0 && w == 0) /* This IP address is neither a local one nor a gateway */
                                 continue;
index 5d829bb..3858637 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 3cda429..f4bbde0 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -364,7 +365,7 @@ void dns_transaction_complete(DnsTransaction *t, DnsTransactionState state) {
         SET_FOREACH_MOVE(z, t->notify_zone_items_done, t->notify_zone_items)
                 dns_zone_item_notify(z);
         SWAP_TWO(t->notify_zone_items, t->notify_zone_items_done);
-        if (t->probing)
+        if (t->probing && t->state == DNS_TRANSACTION_ATTEMPTS_MAX_REACHED)
                 (void) dns_scope_announce(t->scope, false);
 
         SET_FOREACH_MOVE(d, t->notify_transactions_done, t->notify_transactions)
@@ -407,6 +408,8 @@ static int dns_transaction_pick_server(DnsTransaction *t) {
         dns_server_unref(t->server);
         t->server = dns_server_ref(server);
 
+        t->n_picked_servers ++;
+
         log_debug("Using DNS server %s for transaction %u.", dns_server_string(t->server), t->id);
 
         return 1;
@@ -736,8 +739,17 @@ static void dns_transaction_process_dnssec(DnsTransaction *t) {
 
         if (t->answer_dnssec_result == DNSSEC_INCOMPATIBLE_SERVER &&
             t->scope->dnssec_mode == DNSSEC_YES) {
-                /*  We are not in automatic downgrade mode, and the
-                 *  server is bad, refuse operation. */
+
+                /*  We are not in automatic downgrade mode, and the server is bad. Let's try a different server, maybe
+                 *  that works. */
+
+                if (t->n_picked_servers < dns_scope_get_n_dns_servers(t->scope)) {
+                        /* We tried fewer servers on this transaction than we know, let's try another one then */
+                        dns_transaction_retry(t, true);
+                        return;
+                }
+
+                /* OK, let's give up, apparently all servers we tried didn't work. */
                 dns_transaction_complete(t, DNS_TRANSACTION_DNSSEC_FAILED);
                 return;
         }
@@ -912,12 +924,21 @@ void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p) {
                         /* Request failed, immediately try again with reduced features */
 
                         if (t->current_feature_level <= DNS_SERVER_FEATURE_LEVEL_UDP) {
+
                                 /* This was already at UDP feature level? If so, it doesn't make sense to downgrade
-                                 * this transaction anymore, hence let's process the response, and accept the
+                                 * this transaction anymore, but let's see if it might make sense to send the request
+                                 * to a different DNS server instead. If not let's process the response, and accept the
                                  * rcode. Note that we don't retry on TCP, since that's a suitable way to mitigate
                                  * packet loss, but is not going to give us better rcodes should we actually have
                                  * managed to get them already at UDP level. */
 
+                                if (t->n_picked_servers < dns_scope_get_n_dns_servers(t->scope)) {
+                                        /* We tried fewer servers on this transaction than we know, let's try another one then */
+                                        dns_transaction_retry(t, true);
+                                        return;
+                                }
+
+                                /* Give up, accept the rcode */
                                 log_debug("Server returned error: %s", dns_rcode_to_string(DNS_PACKET_RCODE(p)));
                                 break;
                         }
@@ -1350,7 +1371,7 @@ static int dns_transaction_prepare(DnsTransaction *t, usec_t ts) {
                 /* Before trying the cache, let's make sure we figured out a
                  * server to use. Should this cause a change of server this
                  * might flush the cache. */
-                dns_scope_get_dns_server(t->scope);
+                (void) dns_scope_get_dns_server(t->scope);
 
                 /* Let's then prune all outdated entries */
                 dns_cache_prune(&t->scope->cache);
@@ -1376,7 +1397,11 @@ static int dns_transaction_make_packet_mdns(DnsTransaction *t) {
         _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
         bool add_known_answers = false;
         DnsTransaction *other;
+        Iterator i;
+        DnsResourceKey *tkey;
+        _cleanup_set_free_ Set *keys = NULL;
         unsigned qdcount;
+        unsigned nscount = 0;
         usec_t ts;
         int r;
 
@@ -1399,6 +1424,16 @@ static int dns_transaction_make_packet_mdns(DnsTransaction *t) {
         if (dns_key_is_shared(t->key))
                 add_known_answers = true;
 
+        if (t->key->type == DNS_TYPE_ANY) {
+                r = set_ensure_allocated(&keys, &dns_resource_key_hash_ops);
+                if (r < 0)
+                        return r;
+
+                r = set_put(keys, t->key);
+                if (r < 0)
+                        return r;
+        }
+
         /*
          * For mDNS, we want to coalesce as many open queries in pending transactions into one single
          * query packet on the wire as possible. To achieve that, we iterate through all pending transactions
@@ -1458,6 +1493,16 @@ static int dns_transaction_make_packet_mdns(DnsTransaction *t) {
 
                 if (dns_key_is_shared(other->key))
                         add_known_answers = true;
+
+                if (other->key->type == DNS_TYPE_ANY) {
+                        r = set_ensure_allocated(&keys, &dns_resource_key_hash_ops);
+                        if (r < 0)
+                                return r;
+
+                        r = set_put(keys, other->key);
+                        if (r < 0)
+                                return r;
+                }
         }
 
         DNS_PACKET_HEADER(p)->qdcount = htobe16(qdcount);
@@ -1469,6 +1514,22 @@ static int dns_transaction_make_packet_mdns(DnsTransaction *t) {
                         return r;
         }
 
+        SET_FOREACH(tkey, keys, i) {
+                _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
+                bool tentative;
+
+                r = dns_zone_lookup(&t->scope->zone, tkey, t->scope->link->ifindex, &answer, NULL, &tentative);
+                if (r < 0)
+                        return r;
+
+                r = dns_packet_append_answer(p, answer);
+                if (r < 0)
+                        return r;
+
+                nscount += dns_answer_size(answer);
+        }
+        DNS_PACKET_HEADER(p)->nscount = htobe16(nscount);
+
         t->sent = p;
         p = NULL;
 
index a8d9773..31dcd76 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -108,6 +109,8 @@ struct DnsTransaction {
         sd_event_source *timeout_event_source;
         unsigned n_attempts;
 
+        unsigned n_picked_servers;
+
         /* UDP connection logic, if we need it */
         int dns_udp_fd;
         sd_event_source *dns_udp_event_source;
index e169c8f..c6e47ed 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -541,19 +542,10 @@ int dns_trust_anchor_load(DnsTrustAnchor *d) {
 }
 
 void dns_trust_anchor_flush(DnsTrustAnchor *d) {
-        DnsAnswer *a;
-        DnsResourceRecord *rr;
-
         assert(d);
 
-        while ((a = hashmap_steal_first(d->positive_by_key)))
-                dns_answer_unref(a);
-        d->positive_by_key = hashmap_free(d->positive_by_key);
-
-        while ((rr = set_steal_first(d->revoked_by_rr)))
-                dns_resource_record_unref(rr);
-        d->revoked_by_rr = set_free(d->revoked_by_rr);
-
+        d->positive_by_key = hashmap_free_with_destructor(d->positive_by_key, dns_answer_unref);
+        d->revoked_by_rr = set_free_with_destructor(d->revoked_by_rr, dns_resource_record_unref);
         d->negative_by_name = set_free_free(d->negative_by_name);
 }
 
index 635c75f..94d620e 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index ad024b5..dcb9702 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -22,6 +23,7 @@
 #include "list.h"
 #include "resolved-dns-packet.h"
 #include "resolved-dns-zone.h"
+#include "resolved-dnssd.h"
 #include "string-util.h"
 
 /* Never allow more than 1K entries */
@@ -94,7 +96,7 @@ void dns_zone_flush(DnsZone *z) {
         z->by_name = hashmap_free(z->by_name);
 }
 
-static DnsZoneItem* dns_zone_get(DnsZone *z, DnsResourceRecord *rr) {
+DnsZoneItem* dns_zone_get(DnsZone *z, DnsResourceRecord *rr) {
         DnsZoneItem *i;
 
         assert(z);
@@ -118,6 +120,22 @@ void dns_zone_remove_rr(DnsZone *z, DnsResourceRecord *rr) {
                 dns_zone_item_remove_and_free(z, i);
 }
 
+int dns_zone_remove_rrs_by_key(DnsZone *z, DnsResourceKey *key) {
+        _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL, *soa = NULL;
+        DnsResourceRecord *rr;
+        bool tentative;
+        int r;
+
+        r = dns_zone_lookup(z, key, 0, &answer, &soa, &tentative);
+        if (r < 0)
+                return r;
+
+        DNS_ANSWER_FOREACH(rr, answer)
+                dns_zone_remove_rr(z, rr);
+
+        return 0;
+}
+
 static int dns_zone_init(DnsZone *z) {
         int r;
 
@@ -288,6 +306,24 @@ int dns_zone_put(DnsZone *z, DnsScope *s, DnsResourceRecord *rr, bool probe) {
         return 0;
 }
 
+static int dns_zone_add_authenticated_answer(DnsAnswer *a, DnsZoneItem *i, int ifindex) {
+        DnsAnswerFlags flags;
+
+        /* From RFC 6762, Section 10.2
+         * "They (the rules about when to set the cache-flush bit) apply to
+         * startup announcements as described in Section 8.3, "Announcing",
+         * and to responses generated as a result of receiving query messages."
+         * So, set the cache-flush bit for mDNS answers except for DNS-SD
+         * service enumeration PTRs described in RFC 6763, Section 4.1. */
+        if (i->scope->protocol == DNS_PROTOCOL_MDNS &&
+            !dns_resource_key_is_dnssd_ptr(i->rr->key))
+                flags = DNS_ANSWER_AUTHENTICATED|DNS_ANSWER_CACHE_FLUSH;
+        else
+                flags = DNS_ANSWER_AUTHENTICATED;
+
+        return dns_answer_add(a, i->rr, ifindex, flags);
+}
+
 int dns_zone_lookup(DnsZone *z, DnsResourceKey *key, int ifindex, DnsAnswer **ret_answer, DnsAnswer **ret_soa, bool *ret_tentative) {
         _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL, *soa = NULL;
         unsigned n_answer = 0;
@@ -393,7 +429,7 @@ int dns_zone_lookup(DnsZone *z, DnsResourceKey *key, int ifindex, DnsAnswer **re
                         if (k < 0)
                                 return k;
                         if (k > 0) {
-                                r = dns_answer_add(answer, j->rr, ifindex, DNS_ANSWER_AUTHENTICATED);
+                                r = dns_zone_add_authenticated_answer(answer, j, ifindex);
                                 if (r < 0)
                                         return r;
 
@@ -419,7 +455,7 @@ int dns_zone_lookup(DnsZone *z, DnsResourceKey *key, int ifindex, DnsAnswer **re
                         if (j->state != DNS_ZONE_ITEM_PROBING)
                                 tentative = false;
 
-                        r = dns_answer_add(answer, j->rr, ifindex, DNS_ANSWER_AUTHENTICATED);
+                        r = dns_zone_add_authenticated_answer(answer, j, ifindex);
                         if (r < 0)
                                 return r;
                 }
@@ -490,6 +526,8 @@ void dns_zone_item_conflict(DnsZoneItem *i) {
         /* Withdraw the conflict item */
         i->state = DNS_ZONE_ITEM_WITHDRAWN;
 
+        dnssd_signal_conflict(i->scope->manager, dns_resource_key_name(i->rr->key));
+
         /* Maybe change the hostname */
         if (manager_is_own_hostname(i->scope->manager, dns_resource_key_name(i->rr->key)) > 0)
                 manager_next_hostname(i->scope->manager);
@@ -509,7 +547,9 @@ void dns_zone_item_notify(DnsZoneItem *i) {
                 bool we_lost = false;
 
                 /* The probe got a successful reply. If we so far
-                 * weren't established we just give up. If we already
+                 * weren't established we just give up.
+                 *
+                 * In LLMNR case if we already
                  * were established, and the peer has the
                  * lexicographically larger IP address we continue
                  * and defend it. */
@@ -517,7 +557,7 @@ void dns_zone_item_notify(DnsZoneItem *i) {
                 if (!IN_SET(i->state, DNS_ZONE_ITEM_ESTABLISHED, DNS_ZONE_ITEM_VERIFYING)) {
                         log_debug("Got a successful probe for not yet established RR, we lost.");
                         we_lost = true;
-                } else {
+                } else if (i->probe_transaction->scope->protocol == DNS_PROTOCOL_LLMNR) {
                         assert(i->probe_transaction->received);
                         we_lost = memcmp(&i->probe_transaction->received->sender, &i->probe_transaction->received->destination, FAMILY_ADDRESS_SIZE(i->probe_transaction->received->family)) < 0;
                         if (we_lost)
@@ -579,6 +619,10 @@ int dns_zone_check_conflicts(DnsZone *zone, DnsResourceRecord *rr) {
         if (dns_zone_get(zone, rr))
                 return 0;
 
+        /* No conflict if it is DNS-SD RR used for service enumeration. */
+        if (dns_resource_key_is_dnssd_ptr(rr->key))
+                return 0;
+
         /* OK, somebody else has RRs for the same name. Yuck! Let's
          * start probing again */
 
@@ -663,3 +707,20 @@ bool dns_zone_is_empty(DnsZone *zone) {
 
         return hashmap_isempty(zone->by_key);
 }
+
+bool dns_zone_contains_name(DnsZone *z, const char *name) {
+        DnsZoneItem *i, *first;
+
+        first = hashmap_get(z->by_name, name);
+        if (!first)
+                return false;
+
+        LIST_FOREACH(by_name, i, first) {
+                if (!IN_SET(i->state, DNS_ZONE_ITEM_PROBING, DNS_ZONE_ITEM_ESTABLISHED, DNS_ZONE_ITEM_VERIFYING))
+                        continue;
+
+                return true;
+        }
+
+        return false;
+}
index 545ec95..c9c7440 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -66,7 +67,9 @@ struct DnsZoneItem {
 void dns_zone_flush(DnsZone *z);
 
 int dns_zone_put(DnsZone *z, DnsScope *s, DnsResourceRecord *rr, bool probe);
+DnsZoneItem* dns_zone_get(DnsZone *z, DnsResourceRecord *rr);
 void dns_zone_remove_rr(DnsZone *z, DnsResourceRecord *rr);
+int dns_zone_remove_rrs_by_key(DnsZone *z, DnsResourceKey *key);
 
 int dns_zone_lookup(DnsZone *z, DnsResourceKey *key, int ifindex, DnsAnswer **answer, DnsAnswer **soa, bool *tentative);
 
@@ -82,3 +85,4 @@ void dns_zone_item_probe_stop(DnsZoneItem *i);
 
 void dns_zone_dump(DnsZone *zone, FILE *f);
 bool dns_zone_is_empty(DnsZone *zone);
+bool dns_zone_contains_name(DnsZone *z, const char *name);
diff --git a/src/resolve/resolved-dnssd-bus.c b/src/resolve/resolved-dnssd-bus.c
new file mode 100644 (file)
index 0000000..c914e8f
--- /dev/null
@@ -0,0 +1,146 @@
+/***
+  This file is part of systemd.
+
+  Copyright 2017 Dmitry Rozhkov
+
+  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.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "alloc-util.h"
+#include "bus-util.h"
+#include "resolved-dnssd.h"
+#include "resolved-dnssd-bus.h"
+#include "resolved-link.h"
+#include "strv.h"
+#include "user-util.h"
+
+int bus_dnssd_method_unregister(sd_bus_message *message, void *userdata, sd_bus_error *error) {
+        DnssdService *s = userdata;
+        DnssdTxtData *txt_data;
+        Manager *m;
+        Iterator i;
+        Link *l;
+        int r;
+
+        assert(message);
+        assert(s);
+
+        m = s->manager;
+
+        r = bus_verify_polkit_async(message, CAP_SYS_ADMIN,
+                                    "org.freedesktop.resolve1.unregister-service",
+                                    NULL, false, s->originator,
+                                    &m->polkit_registry, error);
+        if (r < 0)
+                return r;
+        if (r == 0)
+                return 1; /* Polkit will call us back */
+
+        HASHMAP_FOREACH(l, m->links, i) {
+                if (l->mdns_ipv4_scope) {
+                        r = dns_scope_announce(l->mdns_ipv4_scope, true);
+                        if (r < 0)
+                                log_warning_errno(r, "Failed to send goodbye messages in IPv4 scope: %m");
+
+                        dns_zone_remove_rr(&l->mdns_ipv4_scope->zone, s->ptr_rr);
+                        dns_zone_remove_rr(&l->mdns_ipv4_scope->zone, s->srv_rr);
+                        LIST_FOREACH(items, txt_data, s->txt_data_items)
+                                dns_zone_remove_rr(&l->mdns_ipv4_scope->zone, txt_data->rr);
+                }
+
+                if (l->mdns_ipv6_scope) {
+                        r = dns_scope_announce(l->mdns_ipv6_scope, true);
+                        if (r < 0)
+                                log_warning_errno(r, "Failed to send goodbye messages in IPv6 scope: %m");
+
+                        dns_zone_remove_rr(&l->mdns_ipv6_scope->zone, s->ptr_rr);
+                        dns_zone_remove_rr(&l->mdns_ipv6_scope->zone, s->srv_rr);
+                        LIST_FOREACH(items, txt_data, s->txt_data_items)
+                                dns_zone_remove_rr(&l->mdns_ipv6_scope->zone, txt_data->rr);
+                }
+        }
+
+        dnssd_service_free(s);
+
+        manager_refresh_rrs(m);
+
+        return sd_bus_reply_method_return(message, NULL);
+}
+
+const sd_bus_vtable dnssd_vtable[] = {
+        SD_BUS_VTABLE_START(0),
+
+        SD_BUS_METHOD("Unregister", NULL, NULL, bus_dnssd_method_unregister, SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_SIGNAL("Conflicted", NULL, 0),
+
+        SD_BUS_VTABLE_END
+};
+
+int dnssd_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
+        _cleanup_free_ char *name = NULL;
+        Manager *m = userdata;
+        DnssdService *service;
+        int r;
+
+        assert(bus);
+        assert(path);
+        assert(interface);
+        assert(found);
+        assert(m);
+
+        r = sd_bus_path_decode(path, "/org/freedesktop/resolve1/dnssd", &name);
+        if (r <= 0)
+                return 0;
+
+        service = hashmap_get(m->dnssd_services, name);
+        if (!service)
+                return 0;
+
+        *found = service;
+        return 1;
+}
+
+int dnssd_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
+        _cleanup_strv_free_ char **l = NULL;
+        Manager *m = userdata;
+        DnssdService *service;
+        Iterator i;
+        unsigned c = 0;
+        int r;
+
+        assert(bus);
+        assert(path);
+        assert(m);
+        assert(nodes);
+
+        l = new0(char*, hashmap_size(m->dnssd_services) + 1);
+        if (!l)
+                return -ENOMEM;
+
+        HASHMAP_FOREACH(service, m->dnssd_services, i) {
+                char *p;
+
+                r = sd_bus_path_encode("/org/freedesktop/resolve1/dnssd", service->name, &p);
+                if (r < 0)
+                        return r;
+
+                l[c++] = p;
+        }
+
+        l[c] = NULL;
+        *nodes = l;
+        l = NULL;
+
+        return 1;
+}
diff --git a/src/resolve/resolved-dnssd-bus.h b/src/resolve/resolved-dnssd-bus.h
new file mode 100644 (file)
index 0000000..ab915c8
--- /dev/null
@@ -0,0 +1,29 @@
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2017 Dmitry Rozhkov
+
+  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.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "sd-bus.h"
+
+extern const sd_bus_vtable dnssd_vtable[];
+
+int dnssd_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error);
+int dnssd_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error);
+
+int bus_dnssd_method_unregister(sd_bus_message *message, void *userdata, sd_bus_error *error);
diff --git a/src/resolve/resolved-dnssd-gperf.gperf b/src/resolve/resolved-dnssd-gperf.gperf
new file mode 100644 (file)
index 0000000..2780b85
--- /dev/null
@@ -0,0 +1,24 @@
+%{
+#include <stddef.h>
+#include "conf-parser.h"
+#include "resolved-conf.h"
+#include "resolved-dnssd.h"
+%}
+struct ConfigPerfItem;
+%null_strings
+%language=ANSI-C
+%define slot-name section_and_lvalue
+%define hash-function-name resolved_dnssd_gperf_hash
+%define lookup-function-name resolved_dnssd_gperf_lookup
+%readonly-tables
+%omit-struct-type
+%struct-type
+%includes
+%%
+Service.Name,     config_parse_dnssd_service_name, 0,                 0
+Service.Type,     config_parse_dnssd_service_type, 0,                 0
+Service.Port,     config_parse_ip_port,            0,                 offsetof(DnssdService, port)
+Service.Priority, config_parse_uint16,             0,                 offsetof(DnssdService, priority)
+Service.Weight,   config_parse_uint16,             0,                 offsetof(DnssdService, weight)
+Service.TxtText,  config_parse_dnssd_txt,          DNS_TXT_ITEM_TEXT, 0
+Service.TxtData,  config_parse_dnssd_txt,          DNS_TXT_ITEM_DATA, 0
diff --git a/src/resolve/resolved-dnssd.c b/src/resolve/resolved-dnssd.c
new file mode 100644 (file)
index 0000000..db589f4
--- /dev/null
@@ -0,0 +1,387 @@
+/***
+  This file is part of systemd.
+
+  Copyright 2017 Dmitry Rozhkov
+
+  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.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "conf-files.h"
+#include "conf-parser.h"
+#include "resolved-dnssd.h"
+#include "resolved-dns-rr.h"
+#include "resolved-manager.h"
+#include "specifier.h"
+#include "strv.h"
+
+const char* const dnssd_service_dirs[] = {
+        "/etc/systemd/dnssd",
+        "/run/systemd/dnssd",
+        "/usr/lib/systemd/dnssd",
+#ifdef HAVE_SPLIT_USR
+        "/lib/systemd/dnssd",
+#endif
+    NULL
+};
+
+DnssdTxtData *dnssd_txtdata_free(DnssdTxtData *txt_data) {
+        if (!txt_data)
+                return NULL;
+
+        dns_resource_record_unref(txt_data->rr);
+        dns_txt_item_free_all(txt_data->txt);
+
+        return mfree(txt_data);
+}
+
+DnssdTxtData *dnssd_txtdata_free_all(DnssdTxtData *txt_data) {
+        DnssdTxtData *next;
+
+        if (!txt_data)
+                return NULL;
+
+        next = txt_data->items_next;
+
+        dnssd_txtdata_free(txt_data);
+
+        return dnssd_txtdata_free_all(next);
+}
+
+DnssdService *dnssd_service_free(DnssdService *service) {
+        if (!service)
+                return NULL;
+
+        if (service->manager)
+                hashmap_remove(service->manager->dnssd_services, service->name);
+
+        dns_resource_record_unref(service->ptr_rr);
+        dns_resource_record_unref(service->srv_rr);
+
+        dnssd_txtdata_free_all(service->txt_data_items);
+
+        free(service->filename);
+        free(service->name);
+        free(service->type);
+        free(service->name_template);
+
+        return mfree(service);
+}
+
+static int dnssd_service_load(Manager *manager, const char *filename) {
+        _cleanup_(dnssd_service_freep) DnssdService *service = NULL;
+        _cleanup_(dnssd_txtdata_freep) DnssdTxtData *txt_data = NULL;
+        char *d;
+        const char *dropin_dirname;
+        int r;
+
+        assert(manager);
+        assert(filename);
+
+        service = new0(DnssdService, 1);
+        if (!service)
+                return log_oom();
+
+        service->filename = strdup(filename);
+        if (!service->filename)
+                return log_oom();
+
+        service->name = strdup(basename(filename));
+        if (!service->name)
+                return log_oom();
+
+        d = endswith(service->name, ".dnssd");
+        if (!d)
+                return -EINVAL;
+
+        assert(streq(d, ".dnssd"));
+
+        *d = '\0';
+
+        dropin_dirname = strjoina(service->name, ".dnssd.d");
+
+        r = config_parse_many(filename, dnssd_service_dirs, dropin_dirname,
+                              "Service\0",
+                              config_item_perf_lookup, resolved_dnssd_gperf_lookup,
+                              false, service);
+        if (r < 0)
+                return r;
+
+        if (!service->name_template) {
+                log_error("%s doesn't define service instance name", service->name);
+                return -EINVAL;
+        }
+
+        if (!service->type) {
+                log_error("%s doesn't define service type", service->name);
+                return -EINVAL;
+        }
+
+        if (LIST_IS_EMPTY(service->txt_data_items)) {
+                txt_data = new0(DnssdTxtData, 1);
+                if (!txt_data)
+                        return log_oom();
+
+                r = dns_txt_item_new_empty(&txt_data->txt);
+                if (r < 0)
+                        return r;
+
+                LIST_PREPEND(items, service->txt_data_items, txt_data);
+                txt_data = NULL;
+        }
+
+        r = hashmap_ensure_allocated(&manager->dnssd_services, &string_hash_ops);
+        if (r < 0)
+                return r;
+
+        r = hashmap_put(manager->dnssd_services, service->name, service);
+        if (r < 0)
+                return r;
+
+        service->manager = manager;
+
+        r = dnssd_update_rrs(service);
+        if (r < 0)
+                return r;
+
+        service = NULL;
+
+        return 0;
+}
+
+static int specifier_dnssd_host_name(char specifier, void *data, void *userdata, char **ret) {
+        DnssdService *s  = (DnssdService *) userdata;
+        char *n;
+
+        assert(s);
+        assert(s->manager);
+        assert(s->manager->llmnr_hostname);
+
+        n = strdup(s->manager->llmnr_hostname);
+        if (!n)
+                return -ENOMEM;
+
+        *ret = n;
+        return 0;
+}
+
+int dnssd_render_instance_name(DnssdService *s, char **ret_name) {
+        static const Specifier specifier_table[] = {
+                { 'b', specifier_boot_id,         NULL },
+                { 'H', specifier_dnssd_host_name, NULL },
+                { 'm', specifier_machine_id, NULL },
+                { 'v', specifier_kernel_release,  NULL },
+                {}
+        };
+        _cleanup_free_ char *name = NULL;
+        int r;
+
+        assert(s);
+        assert(s->name_template);
+
+        r = specifier_printf(s->name_template, specifier_table, s, &name);
+        if (r < 0)
+                return log_debug_errno(r, "Failed to replace specifiers: %m");
+
+        if (!dns_service_name_is_valid(name)) {
+                log_debug("Service instance name '%s' is invalid.", name);
+                return -EINVAL;
+        }
+
+        *ret_name = name;
+        name = NULL;
+
+        return 0;
+}
+
+int dnssd_load(Manager *manager) {
+        _cleanup_strv_free_ char **files = NULL;
+        char **f;
+        int r;
+
+        assert(manager);
+
+        if (manager->mdns_support != RESOLVE_SUPPORT_YES)
+                return 0;
+
+        r = conf_files_list_strv(&files, ".dnssd", NULL, 0, dnssd_service_dirs);
+        if (r < 0)
+                return log_error_errno(r, "Failed to enumerate .dnssd files: %m");
+
+        STRV_FOREACH_BACKWARDS(f, files) {
+                r = dnssd_service_load(manager, *f);
+                if (r < 0)
+                        log_warning_errno(r, "Failed to load '%s': %m", *f);;
+        }
+
+        return 0;
+}
+
+int dnssd_update_rrs(DnssdService *s) {
+        _cleanup_free_ char *n = NULL;
+        _cleanup_free_ char *service_name = NULL;
+        _cleanup_free_ char *full_name = NULL;
+        DnssdTxtData *txt_data;
+        int r;
+
+        assert(s);
+        assert(s->txt_data_items);
+        assert(s->manager);
+
+        s->ptr_rr = dns_resource_record_unref(s->ptr_rr);
+        s->srv_rr = dns_resource_record_unref(s->srv_rr);
+        LIST_FOREACH(items, txt_data, s->txt_data_items)
+                txt_data->rr = dns_resource_record_unref(txt_data->rr);
+
+        r = dnssd_render_instance_name(s, &n);
+        if (r < 0)
+                return r;
+
+        r = dns_name_concat(s->type, "local", &service_name);
+        if (r < 0)
+                return r;
+        r = dns_name_concat(n, service_name, &full_name);
+        if (r < 0)
+                return r;
+
+        LIST_FOREACH(items, txt_data, s->txt_data_items) {
+                txt_data->rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_TXT,
+                                                            full_name);
+                if (!txt_data->rr)
+                        goto oom;
+
+                txt_data->rr->ttl = MDNS_DEFAULT_TTL;
+                txt_data->rr->txt.items = dns_txt_item_copy(txt_data->txt);
+                if (!txt_data->rr->txt.items)
+                        goto oom;
+        }
+
+        s->ptr_rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_PTR,
+                                                 service_name);
+        if (!s->ptr_rr)
+                goto oom;
+
+        s->ptr_rr->ttl = MDNS_DEFAULT_TTL;
+        s->ptr_rr->ptr.name = strdup(full_name);
+        if (!s->ptr_rr->ptr.name)
+                goto oom;
+
+        s->srv_rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_SRV,
+                                                 full_name);
+        if (!s->srv_rr)
+                goto oom;
+
+        s->srv_rr->ttl = MDNS_DEFAULT_TTL;
+        s->srv_rr->srv.priority = s->priority;
+        s->srv_rr->srv.weight = s->weight;
+        s->srv_rr->srv.port = s->port;
+        s->srv_rr->srv.name = strdup(s->manager->mdns_hostname);
+        if (!s->srv_rr->srv.name)
+                goto oom;
+
+        return 0;
+
+oom:
+        LIST_FOREACH(items, txt_data, s->txt_data_items)
+                txt_data->rr = dns_resource_record_unref(txt_data->rr);
+        s->ptr_rr = dns_resource_record_unref(s->ptr_rr);
+        s->srv_rr = dns_resource_record_unref(s->srv_rr);
+        return -ENOMEM;
+}
+
+int dnssd_txt_item_new_from_string(const char *key, const char *value, DnsTxtItem **ret_item) {
+        size_t length;
+        DnsTxtItem *i;
+
+        length = strlen(key);
+
+        if (!isempty(value))
+                length += strlen(value) + 1; /* length of value plus '=' */
+
+        i = malloc0(offsetof(DnsTxtItem, data) + length + 1); /* for safety reasons we add an extra NUL byte */
+        if (!i)
+                return -ENOMEM;
+
+        memcpy(i->data, key, strlen(key));
+        if (!isempty(value)) {
+                memcpy(i->data + strlen(key), "=", 1);
+                memcpy(i->data + strlen(key) + 1, value, strlen(value));
+        }
+        i->length = length;
+
+        *ret_item = i;
+        i = NULL;
+
+        return 0;
+}
+
+int dnssd_txt_item_new_from_data(const char *key, const void *data, const size_t size, DnsTxtItem **ret_item) {
+        size_t length;
+        DnsTxtItem *i;
+
+        length = strlen(key);
+
+        if (size > 0)
+                length += size + 1; /* size of date plus '=' */
+
+        i = malloc0(offsetof(DnsTxtItem, data) + length + 1); /* for safety reasons we add an extra NUL byte */
+        if (!i)
+                return -ENOMEM;
+
+        memcpy(i->data, key, strlen(key));
+        if (size > 0) {
+                memcpy(i->data + strlen(key), "=", 1);
+                memcpy(i->data + strlen(key) + 1, data, size);
+        }
+        i->length = length;
+
+        *ret_item = i;
+        i = NULL;
+
+        return 0;
+}
+
+void dnssd_signal_conflict(Manager *manager, const char *name) {
+        Iterator i;
+        DnssdService *s;
+        int r;
+
+        HASHMAP_FOREACH(s, manager->dnssd_services, i) {
+                if (s->withdrawn)
+                        continue;
+
+                if (dns_name_equal(dns_resource_key_name(s->srv_rr->key), name)) {
+                        _cleanup_free_ char *path = NULL;
+
+                        s->withdrawn = true;
+
+                        r = sd_bus_path_encode("/org/freedesktop/resolve1/dnssd", s->name, &path);
+                        if (r < 0) {
+                                log_error_errno(r, "Can't get D-BUS object path: %m");
+                                return;
+                        }
+
+                        r = sd_bus_emit_signal(manager->bus,
+                                               path,
+                                               "org.freedesktop.resolve1.DnssdService",
+                                               "Conflicted",
+                                               NULL);
+                        if (r < 0) {
+                                log_error_errno(r, "Cannot emit signal: %m");
+                                return;
+                        }
+
+                        break;
+                }
+        }
+}
diff --git a/src/resolve/resolved-dnssd.h b/src/resolve/resolved-dnssd.h
new file mode 100644 (file)
index 0000000..fbc043d
--- /dev/null
@@ -0,0 +1,78 @@
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2017 Dmitry Rozhkov
+
+  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.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "list.h"
+
+typedef struct DnssdService DnssdService;
+typedef struct DnssdTxtData DnssdTxtData;
+
+typedef struct Manager Manager;
+typedef struct DnsResourceRecord DnsResourceRecord;
+typedef struct DnsTxtItem DnsTxtItem;
+
+enum {
+        DNS_TXT_ITEM_TEXT,
+        DNS_TXT_ITEM_DATA
+};
+
+struct DnssdTxtData {
+        DnsResourceRecord *rr;
+
+        LIST_HEAD(DnsTxtItem, txt);
+
+        LIST_FIELDS(DnssdTxtData, items);
+};
+
+struct DnssdService {
+        char *filename;
+        char *name;
+        char *name_template;
+        char *type;
+        uint16_t port;
+        uint16_t priority;
+        uint16_t weight;
+
+        DnsResourceRecord *ptr_rr;
+        DnsResourceRecord *srv_rr;
+
+        /* Section 6.8 of RFC 6763 allows having service
+         * instances with multiple TXT resource records. */
+        LIST_HEAD(DnssdTxtData, txt_data_items);
+
+        Manager *manager;
+
+        bool withdrawn:1;
+        uid_t originator;
+};
+
+DnssdService *dnssd_service_free(DnssdService *service);
+DnssdTxtData *dnssd_txtdata_free(DnssdTxtData *txt_data);
+DnssdTxtData *dnssd_txtdata_free_all(DnssdTxtData *txt_data);
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(DnssdService*, dnssd_service_free);
+DEFINE_TRIVIAL_CLEANUP_FUNC(DnssdTxtData*, dnssd_txtdata_free);
+
+int dnssd_render_instance_name(DnssdService *s, char **ret_name);
+int dnssd_load(Manager *manager);
+int dnssd_txt_item_new_from_string(const char *key, const char *value, DnsTxtItem **ret_item);
+int dnssd_txt_item_new_from_data(const char *key, const void *value, const size_t size, DnsTxtItem **ret_item);
+int dnssd_update_rrs(DnssdService *s);
+void dnssd_signal_conflict(Manager *manager, const char *name);
index 0a28482..769cfb7 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 9d5a175..6756f13 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 5153563..a5865ce 100644 (file)
@@ -1,4 +1,7 @@
 %{
+#if __GNUC__ >= 7
+_Pragma("GCC diagnostic ignored \"-Wimplicit-fallthrough\"")
+#endif
 #include <stddef.h>
 #include "conf-parser.h"
 #include "resolved-conf.h"
index 59cd6cf..711dff0 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 646031b..deed6fe 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 3d26831..e3e50ec 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -18,6 +19,7 @@
 ***/
 
 #include <net/if.h>
+#include <stdio_ext.h>
 
 #include "sd-network.h"
 
@@ -190,9 +192,41 @@ void link_allocate_scopes(Link *l) {
 
 void link_add_rrs(Link *l, bool force_remove) {
         LinkAddress *a;
+        int r;
 
         LIST_FOREACH(addresses, a, l->addresses)
                 link_address_add_rrs(a, force_remove);
+
+        if (!force_remove &&
+            l->mdns_support == RESOLVE_SUPPORT_YES &&
+            l->manager->mdns_support == RESOLVE_SUPPORT_YES) {
+
+                if (l->mdns_ipv4_scope) {
+                        r = dns_scope_add_dnssd_services(l->mdns_ipv4_scope);
+                        if (r < 0)
+                                log_warning_errno(r, "Failed to add IPv4 DNS-SD services: %m");
+                }
+
+                if (l->mdns_ipv6_scope) {
+                        r = dns_scope_add_dnssd_services(l->mdns_ipv6_scope);
+                        if (r < 0)
+                                log_warning_errno(r, "Failed to add IPv6 DNS-SD services: %m");
+                }
+
+        } else {
+
+                if (l->mdns_ipv4_scope) {
+                        r = dns_scope_remove_dnssd_services(l->mdns_ipv4_scope);
+                        if (r < 0)
+                                log_warning_errno(r, "Failed to remove IPv4 DNS-SD services: %m");
+                }
+
+                if (l->mdns_ipv6_scope) {
+                        r = dns_scope_remove_dnssd_services(l->mdns_ipv6_scope);
+                        if (r < 0)
+                                log_warning_errno(r, "Failed to remove IPv6 DNS-SD services: %m");
+                }
+        }
 }
 
 int link_process_rtnl(Link *l, sd_netlink_message *m) {
@@ -1067,7 +1101,10 @@ int link_save_user(Link *l) {
         if (r < 0)
                 goto fail;
 
-        fputs_unlocked("# This is private data. Do not parse.\n", f);
+        (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
+        (void) fchmod(fileno(f), 0644);
+
+        fputs("# This is private data. Do not parse.\n", f);
 
         v = resolve_support_to_string(l->llmnr_support);
         if (v)
@@ -1084,11 +1121,11 @@ int link_save_user(Link *l) {
         if (l->dns_servers) {
                 DnsServer *server;
 
-                fputs_unlocked("SERVERS=", f);
+                fputs("SERVERS=", f);
                 LIST_FOREACH(servers, server, l->dns_servers) {
 
                         if (server != l->dns_servers)
-                                fputc_unlocked(' ', f);
+                                fputc(' ', f);
 
                         v = dns_server_string(server);
                         if (!v) {
@@ -1096,26 +1133,26 @@ int link_save_user(Link *l) {
                                 goto fail;
                         }
 
-                        fputs_unlocked(v, f);
+                        fputs(v, f);
                 }
-                fputc_unlocked('\n', f);
+                fputc('\n', f);
         }
 
         if (l->search_domains) {
                 DnsSearchDomain *domain;
 
-                fputs_unlocked("DOMAINS=", f);
+                fputs("DOMAINS=", f);
                 LIST_FOREACH(domains, domain, l->search_domains) {
 
                         if (domain != l->search_domains)
-                                fputc_unlocked(' ', f);
+                                fputc(' ', f);
 
                         if (domain->route_only)
-                                fputc_unlocked('~', f);
+                                fputc('~', f);
 
-                        fputs_unlocked(DNS_SEARCH_DOMAIN_NAME(domain), f);
+                        fputs(DNS_SEARCH_DOMAIN_NAME(domain), f);
                 }
-                fputc_unlocked('\n', f);
+                fputc('\n', f);
         }
 
         if (!set_isempty(l->dnssec_negative_trust_anchors)) {
@@ -1123,16 +1160,16 @@ int link_save_user(Link *l) {
                 Iterator i;
                 char *nta;
 
-                fputs_unlocked("NTAS=", f);
+                fputs("NTAS=", f);
                 SET_FOREACH(nta, l->dnssec_negative_trust_anchors, i) {
 
                         if (space)
-                                fputc_unlocked(' ', f);
+                                fputc(' ', f);
 
-                        fputs_unlocked(nta, f);
+                        fputs(nta, f);
                         space = true;
                 }
-                fputc_unlocked('\n', f);
+                fputc('\n', f);
         }
 
         r = fflush_and_check(f);
index c20b8b6..261e34b 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 0cf4583..59499c9 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -99,10 +100,16 @@ static int on_llmnr_packet(sd_event_source *s, int fd, uint32_t revents, void *u
         if (r <= 0)
                 return r;
 
+        if (manager_our_packet(m, p))
+                return 0;
+
         scope = manager_find_scope(m, p);
-        if (!scope)
-                log_warning("Got LLMNR UDP packet on unknown scope. Ignoring.");
-        else if (dns_packet_validate_reply(p) > 0) {
+        if (!scope) {
+                log_debug("Got LLMNR UDP packet on unknown scope. Ignoring.");
+                return 0;
+        }
+
+        if (dns_packet_validate_reply(p) > 0) {
                 log_debug("Got LLMNR UDP reply packet for id %u", DNS_PACKET_ID(p));
 
                 dns_scope_check_conflicts(scope, p);
@@ -326,7 +333,7 @@ static int on_llmnr_stream_packet(DnsStream *s) {
 
         scope = manager_find_scope(s->manager, s->read_packet);
         if (!scope)
-                log_warning("Got LLMNR TCP packet on unknown scope. Ignoring.");
+                log_debug("Got LLMNR TCP packet on unknown scope. Ignoring.");
         else if (dns_packet_validate_query(s->read_packet) > 0) {
                 log_debug("Got LLMNR TCP query packet for id %u", DNS_PACKET_ID(s->read_packet));
 
index 8133582..7670380 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 23c6731..2dbf432 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -19,6 +20,7 @@
 
 #include <netinet/in.h>
 #include <poll.h>
+#include <stdio_ext.h>
 #include <sys/ioctl.h>
 
 #if HAVE_LIBIDN2
@@ -40,6 +42,7 @@
 #include "random-util.h"
 #include "resolved-bus.h"
 #include "resolved-conf.h"
+#include "resolved-dnssd.h"
 #include "resolved-dns-stub.h"
 #include "resolved-etc-hosts.h"
 #include "resolved-llmnr.h"
@@ -533,6 +536,8 @@ static int manager_sigusr1(sd_event_source *s, const struct signalfd_siginfo *si
         if (!f)
                 return log_oom();
 
+        (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
+
         LIST_FOREACH(scopes, scope, m->dns_scopes)
                 dns_scope_dump(scope, f);
 
@@ -620,6 +625,10 @@ int manager_new(Manager **ret) {
         if (r < 0)
                 return r;
 
+        r = dnssd_load(m);
+        if (r < 0)
+                log_warning_errno(r, "Failed to load DNS-SD configuration files: %m");
+
         r = dns_scope_new(m, &m->unicast_scope, NULL, DNS_PROTOCOL_DNS, AF_UNSPEC);
         if (r < 0)
                 return r;
@@ -662,6 +671,7 @@ int manager_start(Manager *m) {
 
 Manager *manager_free(Manager *m) {
         Link *l;
+        DnssdService *s;
 
         if (!m)
                 return NULL;
@@ -718,6 +728,10 @@ Manager *manager_free(Manager *m) {
         free(m->llmnr_hostname);
         free(m->mdns_hostname);
 
+        while ((s = hashmap_first(m->dnssd_services)))
+               dnssd_service_free(s);
+        hashmap_free(m->dnssd_services);
+
         dns_trust_anchor_flush(&m->trust_anchor);
         manager_etc_hosts_flush(m);
 
@@ -1093,6 +1107,7 @@ int manager_find_ifindex(Manager *m, int family, const union in_addr_union *in_a
 void manager_refresh_rrs(Manager *m) {
         Iterator i;
         Link *l;
+        DnssdService *s;
 
         assert(m);
 
@@ -1101,25 +1116,27 @@ void manager_refresh_rrs(Manager *m) {
         m->mdns_host_ipv4_key = dns_resource_key_unref(m->mdns_host_ipv4_key);
         m->mdns_host_ipv6_key = dns_resource_key_unref(m->mdns_host_ipv6_key);
 
+        if (m->mdns_support == RESOLVE_SUPPORT_YES)
+                HASHMAP_FOREACH(s, m->dnssd_services, i)
+                        if (dnssd_update_rrs(s) < 0)
+                                log_warning("Failed to refresh DNS-SD service '%s'", s->name);
+
         HASHMAP_FOREACH(l, m->links, i) {
                 link_add_rrs(l, true);
                 link_add_rrs(l, false);
         }
 }
 
-int manager_next_hostname(Manager *m) {
+static int manager_next_random_name(const char *old, char **ret_new) {
         const char *p;
         uint64_t u, a;
-        char *h, *k;
-        int r;
-
-        assert(m);
+        char *n;
 
-        p = strchr(m->llmnr_hostname, 0);
+        p = strchr(old, 0);
         assert(p);
 
-        while (p > m->llmnr_hostname) {
-                if (!strchr("0123456789", p[-1]))
+        while (p > old) {
+                if (!strchr(DIGITS, p[-1]))
                         break;
 
                 p--;
@@ -1138,22 +1155,32 @@ int manager_next_hostname(Manager *m) {
         random_bytes(&a, sizeof(a));
         u += 1 + a % 10;
 
-        if (asprintf(&h, "%.*s%" PRIu64, (int) (p - m->llmnr_hostname), m->llmnr_hostname, u) < 0)
+        if (asprintf(&n, "%.*s%" PRIu64, (int) (p - old), old, u) < 0)
                 return -ENOMEM;
 
+        *ret_new = n;
+
+        return 0;
+}
+
+int manager_next_hostname(Manager *m) {
+        _cleanup_free_ char *h = NULL, *k = NULL;
+        int r;
+
+        assert(m);
+
+        r = manager_next_random_name(m->llmnr_hostname, &h);
+        if (r < 0)
+                return r;
+
         r = dns_name_concat(h, "local", &k);
-        if (r < 0) {
-                free(h);
+        if (r < 0)
                 return r;
-        }
 
         log_info("Hostname conflict, changing published hostname from '%s' to '%s'.", m->llmnr_hostname, h);
 
-        free(m->llmnr_hostname);
-        m->llmnr_hostname = h;
-
-        free(m->mdns_hostname);
-        m->mdns_hostname = k;
+        free_and_replace(m->llmnr_hostname, h);
+        free_and_replace(m->mdns_hostname, k);
 
         manager_refresh_rrs(m);
 
@@ -1487,3 +1514,36 @@ void manager_cleanup_saved_user(Manager *m) {
                 (void) unlink(p);
         }
 }
+
+bool manager_next_dnssd_names(Manager *m) {
+        Iterator i;
+        DnssdService *s;
+        bool tried = false;
+        int r;
+
+        assert(m);
+
+        HASHMAP_FOREACH(s, m->dnssd_services, i) {
+                _cleanup_free_ char * new_name = NULL;
+
+                if (!s->withdrawn)
+                        continue;
+
+                r = manager_next_random_name(s->name_template, &new_name);
+                if (r < 0) {
+                        log_warning_errno(r, "Failed to get new name for service '%s': %m", s->name);
+                        continue;
+                }
+
+                free_and_replace(s->name_template, new_name);
+
+                s->withdrawn = false;
+
+                tried = true;
+        }
+
+        if (tried)
+                manager_refresh_rrs(m);
+
+        return tried;
+}
index 32a0e5f..5c1a667 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -101,6 +102,9 @@ struct Manager {
         int mdns_ipv4_fd;
         int mdns_ipv6_fd;
 
+        /* DNS-SD */
+        Hashmap *dnssd_services;
+
         sd_event_source *mdns_ipv4_event_source;
         sd_event_source *mdns_ipv6_event_source;
 
@@ -142,6 +146,8 @@ struct Manager {
 
         sd_event_source *dns_stub_udp_event_source;
         sd_event_source *dns_stub_tcp_event_source;
+
+        Hashmap *polkit_registry;
 };
 
 /* Manager */
@@ -188,3 +194,5 @@ void manager_flush_caches(Manager *m);
 void manager_reset_server_features(Manager *m);
 
 void manager_cleanup_saved_user(Manager *m);
+
+bool manager_next_dnssd_names(Manager *m);
index 6fbf755..38e2c54 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
 #include <netinet/in.h>
 #include <arpa/inet.h>
 
+#include "alloc-util.h"
 #include "fd-util.h"
 #include "resolved-manager.h"
 #include "resolved-mdns.h"
 
+#define CLEAR_CACHE_FLUSH(x) (~MDNS_RR_CACHE_FLUSH & (x))
+
 void manager_mdns_stop(Manager *m) {
         assert(m);
 
@@ -67,10 +71,145 @@ eaddrinuse:
         return 0;
 }
 
+static int mdns_rr_compare(const void *a, const void *b) {
+        DnsResourceRecord **x = (DnsResourceRecord**) a, **y = (DnsResourceRecord**) b;
+        size_t m;
+        int r;
+
+        assert(x);
+        assert(*x);
+        assert(y);
+        assert(*y);
+
+        if (CLEAR_CACHE_FLUSH((*x)->key->class) < CLEAR_CACHE_FLUSH((*y)->key->class))
+                return -1;
+        else if (CLEAR_CACHE_FLUSH((*x)->key->class) > CLEAR_CACHE_FLUSH((*y)->key->class))
+                return 1;
+
+        if ((*x)->key->type < (*y)->key->type)
+                return -1;
+        else if ((*x)->key->type > (*y)->key->type)
+                return 1;
+
+        r = dns_resource_record_to_wire_format(*x, false);
+        if (r < 0) {
+                log_warning_errno(r, "Can't wire-format RR: %m");
+                return 0;
+        }
+
+        r = dns_resource_record_to_wire_format(*y, false);
+        if (r < 0) {
+                log_warning_errno(r, "Can't wire-format RR: %m");
+                return 0;
+        }
+
+        m = MIN(DNS_RESOURCE_RECORD_RDATA_SIZE(*x), DNS_RESOURCE_RECORD_RDATA_SIZE(*y));
+
+        r = memcmp(DNS_RESOURCE_RECORD_RDATA(*x), DNS_RESOURCE_RECORD_RDATA(*y), m);
+        if (r != 0)
+                return r;
+
+        if (DNS_RESOURCE_RECORD_RDATA_SIZE(*x) < DNS_RESOURCE_RECORD_RDATA_SIZE(*y))
+                return -1;
+        else if (DNS_RESOURCE_RECORD_RDATA_SIZE(*x) > DNS_RESOURCE_RECORD_RDATA_SIZE(*y))
+                return 1;
+
+        return 0;
+}
+
+static int proposed_rrs_cmp(DnsResourceRecord **x, unsigned x_size, DnsResourceRecord **y, unsigned y_size) {
+        unsigned m;
+        int r;
+
+        m = MIN(x_size, y_size);
+        for (unsigned i = 0; i < m; i++) {
+                r = mdns_rr_compare(&x[i], &y[i]);
+                if (r != 0)
+                        return r;
+        }
+
+        if (x_size < y_size)
+                return -1;
+        if (x_size > y_size)
+                return 1;
+
+        return 0;
+}
+
+static int mdns_packet_extract_matching_rrs(DnsPacket *p, DnsResourceKey *key, DnsResourceRecord ***ret_rrs) {
+        _cleanup_free_ DnsResourceRecord **list = NULL;
+        unsigned n = 0, size = 0;
+        int r;
+
+        assert(p);
+        assert(key);
+        assert(ret_rrs);
+        assert_return(DNS_PACKET_NSCOUNT(p) > 0, -EINVAL);
+
+        for (unsigned i = DNS_PACKET_ANCOUNT(p); i < (DNS_PACKET_ANCOUNT(p) + DNS_PACKET_NSCOUNT(p)); i++) {
+                r = dns_resource_key_match_rr(key, p->answer->items[i].rr, NULL);
+                if (r < 0)
+                        return r;
+                if (r > 0)
+                        size++;
+        }
+
+        if (size == 0)
+                return 0;
+
+        list = new(DnsResourceRecord *, size);
+        if (!list)
+                return -ENOMEM;
+
+        for (unsigned i = DNS_PACKET_ANCOUNT(p); i < (DNS_PACKET_ANCOUNT(p) + DNS_PACKET_NSCOUNT(p)); i++) {
+                r = dns_resource_key_match_rr(key, p->answer->items[i].rr, NULL);
+                if (r < 0)
+                        return r;
+                if (r > 0)
+                        list[n++] = p->answer->items[i].rr;
+        }
+        assert(n == size);
+        qsort_safe(list, size, sizeof(DnsResourceRecord*), mdns_rr_compare);
+
+        *ret_rrs = list;
+        list = NULL;
+
+        return size;
+}
+
+static int mdns_do_tiebreak(DnsResourceKey *key, DnsAnswer *answer, DnsPacket *p) {
+        _cleanup_free_ DnsResourceRecord **our = NULL, **remote = NULL;
+        DnsResourceRecord *rr;
+        unsigned i = 0;
+        unsigned size;
+        int r;
+
+        size = dns_answer_size(answer);
+        our = new(DnsResourceRecord *, size);
+        if (!our)
+                return -ENOMEM;
+
+        DNS_ANSWER_FOREACH(rr, answer)
+                our[i++] = rr;
+        qsort_safe(our, size, sizeof(DnsResourceRecord*), mdns_rr_compare);
+
+        r = mdns_packet_extract_matching_rrs(p, key, &remote);
+        if (r < 0)
+                return r;
+
+        assert(r > 0);
+
+        if (proposed_rrs_cmp(remote, r, our, size) > 0)
+                return 1;
+
+        return 0;
+}
+
 static int mdns_scope_process_query(DnsScope *s, DnsPacket *p) {
-        _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL, *soa = NULL;
+        _cleanup_(dns_answer_unrefp) DnsAnswer *full_answer = NULL;
         _cleanup_(dns_packet_unrefp) DnsPacket *reply = NULL;
         DnsResourceKey *key = NULL;
+        DnsResourceRecord *rr;
         bool tentative = false;
         int r;
 
@@ -81,17 +220,49 @@ static int mdns_scope_process_query(DnsScope *s, DnsPacket *p) {
         if (r < 0)
                 return log_debug_errno(r, "Failed to extract resource records from incoming packet: %m");
 
-        /* TODO: there might be more than one question in mDNS queries. */
         assert_return((dns_question_size(p->question) > 0), -EINVAL);
-        key = p->question->keys[0];
 
-        r = dns_zone_lookup(&s->zone, key, 0, &answer, &soa, &tentative);
-        if (r < 0)
-                return log_debug_errno(r, "Failed to lookup key: %m");
-        if (r == 0)
+        DNS_QUESTION_FOREACH(key, p->question) {
+                _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL, *soa = NULL;
+
+                r = dns_zone_lookup(&s->zone, key, 0, &answer, &soa, &tentative);
+                if (r < 0)
+                        return log_debug_errno(r, "Failed to lookup key: %m");
+
+                if (tentative && DNS_PACKET_NSCOUNT(p) > 0) {
+                        /*
+                         * A race condition detected with the probe packet from
+                         * a remote host.
+                         * Do simultaneous probe tiebreaking as described in
+                         * RFC 6762, Section 8.2. In case we lost don't reply
+                         * the question and withdraw conflicting RRs.
+                         */
+                        r = mdns_do_tiebreak(key, answer, p);
+                        if (r < 0)
+                                return log_debug_errno(r, "Failed to do tiebreaking");
+
+                        if (r > 0) { /* we lost */
+                                DNS_ANSWER_FOREACH(rr, answer) {
+                                        DnsZoneItem *i;
+
+                                        i = dns_zone_get(&s->zone, rr);
+                                        if (i)
+                                                dns_zone_item_conflict(i);
+                                }
+
+                                continue;
+                        }
+                }
+
+                r = dns_answer_extend(&full_answer, answer);
+                if (r < 0)
+                        return log_debug_errno(r, "Failed to extend answer: %m");
+        }
+
+        if (dns_answer_isempty(full_answer))
                 return 0;
 
-        r = dns_scope_make_reply_packet(s, DNS_PACKET_ID(p), DNS_RCODE_SUCCESS, NULL, answer, NULL, false, &reply);
+        r = dns_scope_make_reply_packet(s, DNS_PACKET_ID(p), DNS_RCODE_SUCCESS, NULL, full_answer, NULL, false, &reply);
         if (r < 0)
                 return log_debug_errno(r, "Failed to build reply packet: %m");
 
@@ -120,7 +291,7 @@ static int on_mdns_packet(sd_event_source *s, int fd, uint32_t revents, void *us
 
         scope = manager_find_scope(m, p);
         if (!scope) {
-                log_warning("Got mDNS UDP packet on unknown scope. Ignoring.");
+                log_debug("Got mDNS UDP packet on unknown scope. Ignoring.");
                 return 0;
         }
 
index 06bd329..af9f7a9 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index e3d6a33..bad04d6 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -18,6 +19,7 @@
  ***/
 
 #include <resolv.h>
+#include <stdio_ext.h>
 
 #include "alloc-util.h"
 #include "dns-domain.h"
 #include "string-util.h"
 #include "strv.h"
 
+/* A resolv.conf file containing the DNS server and domain data we learnt from uplink, i.e. the full uplink data */
+#define PRIVATE_UPLINK_RESOLV_CONF "/run/systemd/resolve/resolv.conf"
+
+/* A resolv.conf file containing the domain data we learnt from uplink, but our own DNS server address. */
+#define PRIVATE_STUB_RESOLV_CONF "/run/systemd/resolve/stub-resolv.conf"
+
+/* A static resolv.conf file containing no domains, but only our own DNS sever address */
+#define PRIVATE_STATIC_RESOLV_CONF ROOTLIBEXECDIR "/resolv.conf"
+
+static bool file_is_our_own(const struct stat *st) {
+        const char *path;
+
+        assert(st);
+
+        FOREACH_STRING(path,
+                       PRIVATE_UPLINK_RESOLV_CONF,
+                       PRIVATE_STUB_RESOLV_CONF,
+                       PRIVATE_STATIC_RESOLV_CONF) {
+
+                struct stat own;
+
+                /* Is it symlinked to our own uplink file? */
+                if (stat(path, &own) >= 0 &&
+                    st->st_dev == own.st_dev &&
+                    st->st_ino == own.st_ino)
+                        return true;
+        }
+
+        return false;
+}
+
 int manager_read_resolv_conf(Manager *m) {
         _cleanup_fclose_ FILE *f = NULL;
-        struct stat st, own;
+        struct stat st;
         char line[LINE_MAX];
-        usec_t t;
         int r;
 
         assert(m);
@@ -56,14 +88,10 @@ int manager_read_resolv_conf(Manager *m) {
         }
 
         /* Have we already seen the file? */
-        t = timespec_load(&st.st_mtim);
-        if (t == m->resolv_conf_mtime)
+        if (timespec_load(&st.st_mtim) == m->resolv_conf_mtime)
                 return 0;
 
-        /* Is it symlinked to our own file? */
-        if (stat(PRIVATE_RESOLV_CONF, &own) >= 0 &&
-            st.st_dev == own.st_dev &&
-            st.st_ino == own.st_ino)
+        if (file_is_our_own(&st))
                 return 0;
 
         f = fopen("/etc/resolv.conf", "re");
@@ -80,6 +108,9 @@ int manager_read_resolv_conf(Manager *m) {
                 goto clear;
         }
 
+        if (file_is_our_own(&st))
+                return 0;
+
         dns_server_mark_all(m->dns_servers);
         dns_search_domain_mark_all(m->search_domains);
 
@@ -110,7 +141,7 @@ int manager_read_resolv_conf(Manager *m) {
                 }
         }
 
-        m->resolv_conf_mtime = t;
+        m->resolv_conf_mtime = timespec_load(&st.st_mtim);
 
         /* Flush out all servers and search domains that are still
          * marked. Those are then ones that didn't appear in the new
@@ -171,7 +202,7 @@ static void write_resolv_conf_server(DnsServer *s, FILE *f, unsigned *count) {
         }
 
         if (*count == MAXNS)
-                fputs_unlocked("# Too many DNS servers configured, the following entries may be ignored.\n", f);
+                fputs("# Too many DNS servers configured, the following entries may be ignored.\n", f);
         (*count)++;
 
         fprintf(f, "nameserver %s\n", dns_server_string(s));
@@ -187,39 +218,43 @@ static void write_resolv_conf_search(
         assert(domains);
         assert(f);
 
-        fputs_unlocked("search", f);
+        fputs("search", f);
 
         ORDERED_SET_FOREACH(domain, domains, i) {
                 if (++count > MAXDNSRCH) {
-                        fputs_unlocked("\n# Too many search domains configured, remaining ones ignored.", f);
+                        fputs("\n# Too many search domains configured, remaining ones ignored.", f);
                         break;
                 }
                 length += strlen(domain) + 1;
                 if (length > 256) {
-                        fputs_unlocked("\n# Total length of all search domains is too long, remaining ones ignored.", f);
+                        fputs("\n# Total length of all search domains is too long, remaining ones ignored.", f);
                         break;
                 }
-                fputc_unlocked(' ', f);
-                fputs_unlocked(domain, f);
+                fputc(' ', f);
+                fputs(domain, f);
         }
 
-        fputs_unlocked("\n", f);
+        fputs("\n", f);
 }
 
-static int write_resolv_conf_contents(FILE *f, OrderedSet *dns, OrderedSet *domains) {
+static int write_uplink_resolv_conf_contents(FILE *f, OrderedSet *dns, OrderedSet *domains) {
         Iterator i;
 
-        fputs_unlocked("# This file is managed by man:systemd-resolved(8). Do not edit.\n#\n"
-                       "# This is a dynamic resolv.conf file for connecting local clients directly to\n"
-                       "# all known DNS servers.\n#\n"
-                       "# Third party programs must not access this file directly, but only through the\n"
-                       "# symlink at /etc/resolv.conf. To manage man:resolv.conf(5) in a different way,\n"
-                       "# replace this symlink by a static file or a different symlink.\n#\n"
-                       "# See man:systemd-resolved.service(8) for details about the supported modes of\n"
-                       "# operation for /etc/resolv.conf.\n\n", f);
+        fputs("# This file is managed by man:systemd-resolved(8). Do not edit.\n"
+              "#\n"
+              "# This is a dynamic resolv.conf file for connecting local clients directly to\n"
+              "# all known uplink DNS servers. This file lists all configured search domains.\n"
+              "#\n"
+              "# Third party programs must not access this file directly, but only through the\n"
+              "# symlink at /etc/resolv.conf. To manage man:resolv.conf(5) in a different way,\n"
+              "# replace this symlink by a static file or a different symlink.\n"
+              "#\n"
+              "# See man:systemd-resolved.service(8) for details about the supported modes of\n"
+              "# operation for /etc/resolv.conf.\n"
+              "\n", f);
 
         if (ordered_set_isempty(dns))
-                fputs_unlocked("# No DNS servers known.\n", f);
+                fputs("# No DNS servers known.\n", f);
         else {
                 unsigned count = 0;
                 DnsServer *s;
@@ -234,11 +269,36 @@ static int write_resolv_conf_contents(FILE *f, OrderedSet *dns, OrderedSet *doma
         return fflush_and_check(f);
 }
 
+static int write_stub_resolv_conf_contents(FILE *f, OrderedSet *dns, OrderedSet *domains) {
+        fputs_unlocked("# This file is managed by man:systemd-resolved(8). Do not edit.\n"
+                       "#\n"
+                       "# This is a dynamic resolv.conf file for connecting local clients to the\n"
+                       "# internal DNS stub resolver of systemd-resolved. This file lists all\n"
+                       "# configured search domains.\n"
+                       "#\n"
+                       "# Run \"systemd-resolve --status\" to see details about the uplink DNS servers\n"
+                       "# currently in use.\n"
+                       "#\n"
+                       "# Third party programs must not access this file directly, but only through the\n"
+                       "# symlink at /etc/resolv.conf. To manage man:resolv.conf(5) in a different way,\n"
+                       "# replace this symlink by a static file or a different symlink.\n"
+                       "#\n"
+                       "# See man:systemd-resolved.service(8) for details about the supported modes of\n"
+                       "# operation for /etc/resolv.conf.\n"
+                       "\n"
+                       "nameserver 127.0.0.53\n", f);
+
+        if (!ordered_set_isempty(domains))
+                write_resolv_conf_search(domains, f);
+
+        return fflush_and_check(f);
+}
+
 int manager_write_resolv_conf(Manager *m) {
 
         _cleanup_ordered_set_free_ OrderedSet *dns = NULL, *domains = NULL;
-        _cleanup_free_ char *temp_path = NULL;
-        _cleanup_fclose_ FILE *f = NULL;
+        _cleanup_free_ char *temp_path_uplink = NULL, *temp_path_stub = NULL;
+        _cleanup_fclose_ FILE *f_uplink = NULL, *f_stub = NULL;
         int r;
 
         assert(m);
@@ -255,28 +315,49 @@ int manager_write_resolv_conf(Manager *m) {
         if (r < 0)
                 return log_warning_errno(r, "Failed to compile list of search domains: %m");
 
-        r = fopen_temporary_label(PRIVATE_RESOLV_CONF, PRIVATE_RESOLV_CONF, &f, &temp_path);
+        r = fopen_temporary_label(PRIVATE_UPLINK_RESOLV_CONF, PRIVATE_UPLINK_RESOLV_CONF, &f_uplink, &temp_path_uplink);
         if (r < 0)
                 return log_warning_errno(r, "Failed to open private resolv.conf file for writing: %m");
 
-        (void) fchmod(fileno(f), 0644);
+        (void) __fsetlocking(f_uplink, FSETLOCKING_BYCALLER);
+        (void) fchmod(fileno(f_uplink), 0644);
+
+        r = fopen_temporary_label(PRIVATE_STUB_RESOLV_CONF, PRIVATE_STUB_RESOLV_CONF, &f_stub, &temp_path_stub);
+        if (r < 0)
+                return log_warning_errno(r, "Failed to open private stub-resolv.conf file for writing: %m");
+
+        (void) __fsetlocking(f_stub, FSETLOCKING_BYCALLER);
+        (void) fchmod(fileno(f_stub), 0644);
 
-        r = write_resolv_conf_contents(f, dns, domains);
+        r = write_uplink_resolv_conf_contents(f_uplink, dns, domains);
         if (r < 0) {
                 log_error_errno(r, "Failed to write private resolv.conf contents: %m");
                 goto fail;
         }
 
-        if (rename(temp_path, PRIVATE_RESOLV_CONF) < 0) {
+        if (rename(temp_path_uplink, PRIVATE_UPLINK_RESOLV_CONF) < 0) {
                 r = log_error_errno(errno, "Failed to move private resolv.conf file into place: %m");
                 goto fail;
         }
 
+        r = write_stub_resolv_conf_contents(f_stub, dns, domains);
+        if (r < 0) {
+                log_error_errno(r, "Failed to write private stub-resolv.conf contents: %m");
+                goto fail;
+        }
+
+        if (rename(temp_path_stub, PRIVATE_STUB_RESOLV_CONF) < 0) {
+                r = log_error_errno(errno, "Failed to move private stub-resolv.conf file into place: %m");
+                goto fail;
+        }
+
         return 0;
 
 fail:
-        (void) unlink(PRIVATE_RESOLV_CONF);
-        (void) unlink(temp_path);
+        (void) unlink(PRIVATE_UPLINK_RESOLV_CONF);
+        (void) unlink(temp_path_uplink);
+        (void) unlink(PRIVATE_STUB_RESOLV_CONF);
+        (void) unlink(temp_path_stub);
 
         return r;
 }
index 75fa080..ef34f8e 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -21,7 +22,5 @@
 
 #include "resolved-manager.h"
 
-#define PRIVATE_RESOLV_CONF "/run/systemd/resolve/resolv.conf"
-
 int manager_read_resolv_conf(Manager *m);
 int manager_write_resolv_conf(Manager *m);
index 2eb7bfd..a4cda0b 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -61,7 +62,7 @@ int main(int argc, char *argv[]) {
         }
 
         /* Always create the directory where resolv.conf will live */
-        r = mkdir_safe_label("/run/systemd/resolve", 0755, uid, gid);
+        r = mkdir_safe_label("/run/systemd/resolve", 0755, uid, gid, false);
         if (r < 0) {
                 log_error_errno(r, "Could not create runtime directory: %m");
                 goto finish;
@@ -117,10 +118,6 @@ int main(int argc, char *argv[]) {
         sd_event_get_exit_code(m->event, &r);
 
 finish:
-        /* systemd-nspawn checks for private resolv.conf to decide whether
-           or not to mount it into the container. So just delete it. */
-        (void) unlink(PRIVATE_RESOLV_CONF);
-
         sd_notify(false,
                   "STOPPING=1\n"
                   "STATUS=Shutting down...");
index 00dde9b..458c908 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd
 
index 25ec6f4..e7b0779 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 8cb4b50..2d2b5e3 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -18,6 +19,7 @@
 ***/
 
 #include <arpa/inet.h>
+#include <gcrypt.h>
 #include <netinet/in.h>
 #include <sys/socket.h>
 
@@ -123,6 +125,189 @@ static void test_dnssec_verify_dns_key(void) {
         assert_se(dnssec_verify_dnskey_by_ds(dnskey, ds2, false) > 0);
 }
 
+static void test_dnssec_verify_rfc8080_ed25519_example1(void) {
+        static const uint8_t dnskey_blob[] = {
+                0x97, 0x4d, 0x96, 0xa2, 0x2d, 0x22, 0x4b, 0xc0, 0x1a, 0xdb, 0x91, 0x50, 0x91, 0x47, 0x7d,
+                0x44, 0xcc, 0xd9, 0x1c, 0x9a, 0x41, 0xa1, 0x14, 0x30, 0x01, 0x01, 0x17, 0xd5, 0x2c, 0x59,
+                0x24, 0xe
+        };
+        static const uint8_t ds_fprint[] = {
+                0xdd, 0xa6, 0xb9, 0x69, 0xbd, 0xfb, 0x79, 0xf7, 0x1e, 0xe7, 0xb7, 0xfb, 0xdf, 0xb7, 0xdc,
+                0xd7, 0xad, 0xbb, 0xd3, 0x5d, 0xdf, 0x79, 0xed, 0x3b, 0x6d, 0xd7, 0xf6, 0xe3, 0x56, 0xdd,
+                0xd7, 0x47, 0xf7, 0x6f, 0x5f, 0x7a, 0xe1, 0xa6, 0xf9, 0xe5, 0xce, 0xfc, 0x7b, 0xbf, 0x5a,
+                0xdf, 0x4e, 0x1b
+        };
+        static const uint8_t signature_blob[] = {
+                0xa0, 0xbf, 0x64, 0xac, 0x9b, 0xa7, 0xef, 0x17, 0xc1, 0x38, 0x85, 0x9c, 0x18, 0x78, 0xbb,
+                0x99, 0xa8, 0x39, 0xfe, 0x17, 0x59, 0xac, 0xa5, 0xb0, 0xd7, 0x98, 0xcf, 0x1a, 0xb1, 0xe9,
+                0x8d, 0x07, 0x91, 0x02, 0xf4, 0xdd, 0xb3, 0x36, 0x8f, 0x0f, 0xe4, 0x0b, 0xb3, 0x77, 0xf1,
+                0xf0, 0x0e, 0x0c, 0xdd, 0xed, 0xb7, 0x99, 0x16, 0x7d, 0x56, 0xb6, 0xe9, 0x32, 0x78, 0x30,
+                0x72, 0xba, 0x8d, 0x02
+        };
+
+        _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *dnskey = NULL, *ds = NULL, *mx = NULL,
+                *rrsig = NULL;
+        _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
+        DnssecResult result;
+
+        dnskey = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_DNSKEY, "example.com.");
+        assert_se(dnskey);
+
+        dnskey->dnskey.flags = 257;
+        dnskey->dnskey.protocol = 3;
+        dnskey->dnskey.algorithm = DNSSEC_ALGORITHM_ED25519;
+        dnskey->dnskey.key_size = sizeof(dnskey_blob);
+        dnskey->dnskey.key = memdup(dnskey_blob, sizeof(dnskey_blob));
+        assert_se(dnskey->dnskey.key);
+
+        log_info("DNSKEY: %s", strna(dns_resource_record_to_string(dnskey)));
+
+        ds = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_DS, "example.com.");
+        assert_se(ds);
+
+        ds->ds.key_tag = 3613;
+        ds->ds.algorithm = DNSSEC_ALGORITHM_ED25519;
+        ds->ds.digest_type = DNSSEC_DIGEST_SHA256;
+        ds->ds.digest_size = sizeof(ds_fprint);
+        ds->ds.digest = memdup(ds_fprint, ds->ds.digest_size);
+        assert_se(ds->ds.digest);
+
+        log_info("DS: %s", strna(dns_resource_record_to_string(ds)));
+
+        mx = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_MX, "example.com.");
+        assert_se(mx);
+
+        mx->mx.priority = 10;
+        mx->mx.exchange = strdup("mail.example.com.");
+        assert_se(mx->mx.exchange);
+
+        log_info("MX: %s", strna(dns_resource_record_to_string(mx)));
+
+        rrsig = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_RRSIG, "example.com.");
+        assert_se(rrsig);
+
+        rrsig->rrsig.type_covered = DNS_TYPE_MX;
+        rrsig->rrsig.algorithm = DNSSEC_ALGORITHM_ED25519;
+        rrsig->rrsig.labels = 2;
+        rrsig->rrsig.original_ttl = 3600;
+        rrsig->rrsig.expiration = 1440021600;
+        rrsig->rrsig.inception = 1438207200;
+        rrsig->rrsig.key_tag = 3613;
+        rrsig->rrsig.signer = strdup("example.com.");
+        assert_se(rrsig->rrsig.signer);
+        rrsig->rrsig.signature_size = sizeof(signature_blob);
+        rrsig->rrsig.signature = memdup(signature_blob, rrsig->rrsig.signature_size);
+        assert_se(rrsig->rrsig.signature);
+
+        log_info("RRSIG: %s", strna(dns_resource_record_to_string(rrsig)));
+
+        assert_se(dnssec_key_match_rrsig(mx->key, rrsig) > 0);
+        assert_se(dnssec_rrsig_match_dnskey(rrsig, dnskey, false) > 0);
+
+        answer = dns_answer_new(1);
+        assert_se(answer);
+        assert_se(dns_answer_add(answer, mx, 0, DNS_ANSWER_AUTHENTICATED) >= 0);
+
+        assert_se(dnssec_verify_rrset(answer, mx->key, rrsig, dnskey,
+                                rrsig->rrsig.inception * USEC_PER_SEC, &result) >= 0);
+#if GCRYPT_VERSION_NUMBER >= 0x010600
+        assert_se(result == DNSSEC_VALIDATED);
+#else
+        assert_se(result == DNSSEC_UNSUPPORTED_ALGORITHM);
+#endif
+}
+
+static void test_dnssec_verify_rfc8080_ed25519_example2(void) {
+        static const uint8_t dnskey_blob[] = {
+                0xcc, 0xf9, 0xd9, 0xfd, 0x0c, 0x04, 0x7b, 0xb4, 0xbc, 0x0b, 0x94, 0x8f, 0xcf, 0x63, 0x9f,
+                0x4b, 0x94, 0x51, 0xe3, 0x40, 0x13, 0x93, 0x6f, 0xeb, 0x62, 0x71, 0x3d, 0xc4, 0x72, 0x4,
+                0x8a, 0x3b
+        };
+        static const uint8_t ds_fprint[] = {
+                0xe3, 0x4d, 0x7b, 0xf3, 0x56, 0xfd, 0xdf, 0x87, 0xb7, 0xf7, 0x67, 0x5e, 0xe3, 0xdd, 0x9e,
+                0x73, 0xbe, 0xda, 0x7b, 0x67, 0xb5, 0xe5, 0xde, 0xf4, 0x7f, 0xae, 0x7b, 0xe5, 0xad, 0x5c,
+                0xd1, 0xb7, 0x39, 0xf5, 0xce, 0x76, 0xef, 0x97, 0x34, 0xe1, 0xe6, 0xde, 0xf3, 0x47, 0x3a,
+                0xeb, 0x5e, 0x1c
+        };
+        static const uint8_t signature_blob[] = {
+                0xcd, 0x74, 0x34, 0x6e, 0x46, 0x20, 0x41, 0x31, 0x05, 0xc9, 0xf2, 0xf2, 0x8b, 0xd4, 0x28,
+                0x89, 0x8e, 0x83, 0xf1, 0x97, 0x58, 0xa3, 0x8c, 0x32, 0x52, 0x15, 0x62, 0xa1, 0x86, 0x57,
+                0x15, 0xd4, 0xf8, 0xd7, 0x44, 0x0f, 0x44, 0x84, 0xd0, 0x4a, 0xa2, 0x52, 0x9f, 0x34, 0x28,
+                0x4a, 0x6e, 0x69, 0xa0, 0x9e, 0xe0, 0x0f, 0xb0, 0x10, 0x47, 0x43, 0xbb, 0x2a, 0xe2, 0x39,
+                0x93, 0x6a, 0x5c, 0x06
+        };
+
+        _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *dnskey = NULL, *ds = NULL, *mx = NULL,
+                *rrsig = NULL;
+        _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
+        DnssecResult result;
+
+        dnskey = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_DNSKEY, "example.com.");
+        assert_se(dnskey);
+
+        dnskey->dnskey.flags = 257;
+        dnskey->dnskey.protocol = 3;
+        dnskey->dnskey.algorithm = DNSSEC_ALGORITHM_ED25519;
+        dnskey->dnskey.key_size = sizeof(dnskey_blob);
+        dnskey->dnskey.key = memdup(dnskey_blob, sizeof(dnskey_blob));
+        assert_se(dnskey->dnskey.key);
+
+        log_info("DNSKEY: %s", strna(dns_resource_record_to_string(dnskey)));
+
+        ds = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_DS, "example.com.");
+        assert_se(ds);
+
+        ds->ds.key_tag = 35217;
+        ds->ds.algorithm = DNSSEC_ALGORITHM_ED25519;
+        ds->ds.digest_type = DNSSEC_DIGEST_SHA256;
+        ds->ds.digest_size = sizeof(ds_fprint);
+        ds->ds.digest = memdup(ds_fprint, ds->ds.digest_size);
+        assert_se(ds->ds.digest);
+
+        log_info("DS: %s", strna(dns_resource_record_to_string(ds)));
+
+        mx = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_MX, "example.com.");
+        assert_se(mx);
+
+        mx->mx.priority = 10;
+        mx->mx.exchange = strdup("mail.example.com.");
+        assert_se(mx->mx.exchange);
+
+        log_info("MX: %s", strna(dns_resource_record_to_string(mx)));
+
+        rrsig = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_RRSIG, "example.com.");
+        assert_se(rrsig);
+
+        rrsig->rrsig.type_covered = DNS_TYPE_MX;
+        rrsig->rrsig.algorithm = DNSSEC_ALGORITHM_ED25519;
+        rrsig->rrsig.labels = 2;
+        rrsig->rrsig.original_ttl = 3600;
+        rrsig->rrsig.expiration = 1440021600;
+        rrsig->rrsig.inception = 1438207200;
+        rrsig->rrsig.key_tag = 35217;
+        rrsig->rrsig.signer = strdup("example.com.");
+        assert_se(rrsig->rrsig.signer);
+        rrsig->rrsig.signature_size = sizeof(signature_blob);
+        rrsig->rrsig.signature = memdup(signature_blob, rrsig->rrsig.signature_size);
+        assert_se(rrsig->rrsig.signature);
+
+        log_info("RRSIG: %s", strna(dns_resource_record_to_string(rrsig)));
+
+        assert_se(dnssec_key_match_rrsig(mx->key, rrsig) > 0);
+        assert_se(dnssec_rrsig_match_dnskey(rrsig, dnskey, false) > 0);
+
+        answer = dns_answer_new(1);
+        assert_se(answer);
+        assert_se(dns_answer_add(answer, mx, 0, DNS_ANSWER_AUTHENTICATED) >= 0);
+
+        assert_se(dnssec_verify_rrset(answer, mx->key, rrsig, dnskey,
+                                rrsig->rrsig.inception * USEC_PER_SEC, &result) >= 0);
+#if GCRYPT_VERSION_NUMBER >= 0x010600
+        assert_se(result == DNSSEC_VALIDATED);
+#else
+        assert_se(result == DNSSEC_UNSUPPORTED_ALGORITHM);
+#endif
+}
 static void test_dnssec_verify_rrset(void) {
 
         static const uint8_t signature_blob[] = {
@@ -334,6 +519,8 @@ int main(int argc, char*argv[]) {
 
 #if HAVE_GCRYPT
         test_dnssec_verify_dns_key();
+        test_dnssec_verify_rfc8080_ed25519_example1();
+        test_dnssec_verify_rfc8080_ed25519_example2();
         test_dnssec_verify_rrset();
         test_dnssec_verify_rrset2();
         test_dnssec_nsec3_hash();
index 2d61513..808ec76 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd
 
index ab11fbc..af5bec1 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd
 
index 3aa468f..ff95145 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -88,7 +89,8 @@ static int find_device(
 
         device = udev_device_new_from_subsystem_sysname(udev, "rfkill", sysname);
         if (!device)
-                return log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_ERR, errno, "Failed to open device: %m");
+                return log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_ERR, errno,
+                                      "Failed to open device %s: %m", sysname);
 
         name = udev_device_get_sysattr_value(device, "name");
         if (!name) {
@@ -146,7 +148,8 @@ static int wait_for_initialized(
         /* Check again, maybe things changed */
         d = udev_device_new_from_subsystem_sysname(udev, "rfkill", sysname);
         if (!d)
-                return log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_ERR, errno, "Failed to open device: %m");
+                return log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_ERR, errno,
+                                      "Failed to open device %s: %m", sysname);
 
         if (udev_device_get_is_initialized(d) != 0) {
                 *ret = d;
index f9ca568..5d7441a 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -67,26 +68,10 @@ static enum {
         ARG_STDIO_DIRECT,    /* Directly pass our stdin/stdout/stderr to the activated service, useful for usage in shell pipelines, requested by --pipe */
         ARG_STDIO_AUTO,      /* If --pipe and --pty are used together we use --pty when invoked on a TTY, and --pipe otherwise */
 } arg_stdio = ARG_STDIO_NONE;
-static usec_t arg_on_active = 0;
-static usec_t arg_on_boot = 0;
-static usec_t arg_on_startup = 0;
-static usec_t arg_on_unit_active = 0;
-static usec_t arg_on_unit_inactive = 0;
-static const char *arg_on_calendar = NULL;
 static char **arg_timer_property = NULL;
+static bool with_timer = false;
 static bool arg_quiet = false;
-
-static void polkit_agent_open_if_enabled(void) {
-
-        /* Open the polkit agent as a child process if necessary */
-        if (!arg_ask_password)
-                return;
-
-        if (arg_transport != BUS_TRANSPORT_LOCAL)
-                return;
-
-        polkit_agent_open();
-}
+static bool arg_aggressive_gc = false;
 
 static void help(void) {
         printf("%s [OPTIONS...] {COMMAND} [ARGS...]\n\n"
@@ -114,7 +99,8 @@ static void help(void) {
                "  -t --pty                        Run service on pseudo TTY as STDIN/STDOUT/\n"
                "                                  STDERR\n"
                "  -P --pipe                       Pass STDIN/STDOUT/STDERR directly to service\n"
-               "  -q --quiet                      Suppress information messages during runtime\n\n"
+               "  -q --quiet                      Suppress information messages during runtime\n"
+               "  -G --collect                    Unload unit after it ran, even when failed\n\n"
                "Timer options:\n"
                "     --on-active=SECONDS          Run after SECONDS delay\n"
                "     --on-boot=SECONDS            Run SECONDS after machine was booted up\n"
@@ -126,8 +112,22 @@ static void help(void) {
                , program_invocation_short_name);
 }
 
-static bool with_timer(void) {
-        return arg_on_active || arg_on_boot || arg_on_startup || arg_on_unit_active || arg_on_unit_inactive || arg_on_calendar;
+static int add_timer_property(const char *name, const char *val) {
+        _cleanup_free_ char *p = NULL;
+
+        assert(name);
+        assert(val);
+
+        p = strjoin(name, "=", val);
+        if (!p)
+                return log_oom();
+
+        if (strv_consume(&arg_timer_property, p) < 0)
+                return log_oom();
+
+        p = NULL;
+
+        return 0;
 }
 
 static int parse_argv(int argc, char *argv[]) {
@@ -190,6 +190,7 @@ static int parse_argv(int argc, char *argv[]) {
                 { "timer-property",    required_argument, NULL, ARG_TIMER_PROPERTY   },
                 { "no-block",          no_argument,       NULL, ARG_NO_BLOCK         },
                 { "no-ask-password",   no_argument,       NULL, ARG_NO_ASK_PASSWORD  },
+                { "collect",           no_argument,       NULL, 'G'                  },
                 {},
         };
 
@@ -198,7 +199,7 @@ static int parse_argv(int argc, char *argv[]) {
         assert(argc >= 0);
         assert(argv);
 
-        while ((c = getopt_long(argc, argv, "+hrH:M:E:p:tPq", options, NULL)) >= 0)
+        while ((c = getopt_long(argc, argv, "+hrH:M:E:p:tPqG", options, NULL)) >= 0)
 
                 switch (c) {
 
@@ -306,74 +307,65 @@ static int parse_argv(int argc, char *argv[]) {
                         break;
 
                 case ARG_ON_ACTIVE:
-
-                        r = parse_sec(optarg, &arg_on_active);
-                        if (r < 0) {
-                                log_error("Failed to parse timer value: %s", optarg);
+                        r = add_timer_property("OnActiveSec", optarg);
+                        if (r < 0)
                                 return r;
-                        }
 
+                        with_timer = true;
                         break;
 
                 case ARG_ON_BOOT:
-
-                        r = parse_sec(optarg, &arg_on_boot);
-                        if (r < 0) {
-                                log_error("Failed to parse timer value: %s", optarg);
+                        r = add_timer_property("OnBootSec", optarg);
+                        if (r < 0)
                                 return r;
-                        }
 
+                        with_timer = true;
                         break;
 
                 case ARG_ON_STARTUP:
-
-                        r = parse_sec(optarg, &arg_on_startup);
-                        if (r < 0) {
-                                log_error("Failed to parse timer value: %s", optarg);
+                        r = add_timer_property("OnStartupSec", optarg);
+                        if (r < 0)
                                 return r;
-                        }
 
+                        with_timer = true;
                         break;
 
                 case ARG_ON_UNIT_ACTIVE:
-
-                        r = parse_sec(optarg, &arg_on_unit_active);
-                        if (r < 0) {
-                                log_error("Failed to parse timer value: %s", optarg);
+                        r = add_timer_property("OnUnitActiveSec", optarg);
+                        if (r < 0)
                                 return r;
-                        }
 
+                        with_timer = true;
                         break;
 
                 case ARG_ON_UNIT_INACTIVE:
-
-                        r = parse_sec(optarg, &arg_on_unit_inactive);
-                        if (r < 0) {
-                                log_error("Failed to parse timer value: %s", optarg);
+                        r = add_timer_property("OnUnitInactiveSec", optarg);
+                        if (r < 0)
                                 return r;
-                        }
 
+                        with_timer = true;
                         break;
 
-                case ARG_ON_CALENDAR: {
-                        CalendarSpec *spec = NULL;
-
-                        r = calendar_spec_from_string(optarg, &spec);
-                        if (r < 0) {
-                                log_error("Invalid calendar spec: %s", optarg);
+                case ARG_ON_CALENDAR:
+                        r = add_timer_property("OnCalendar", optarg);
+                        if (r < 0)
                                 return r;
-                        }
 
-                        calendar_spec_free(spec);
-                        arg_on_calendar = optarg;
+                        with_timer = true;
                         break;
-                }
 
                 case ARG_TIMER_PROPERTY:
 
                         if (strv_extend(&arg_timer_property, optarg) < 0)
                                 return log_oom();
 
+                        with_timer = with_timer ||
+                                !!startswith(optarg, "OnActiveSec=") ||
+                                !!startswith(optarg, "OnBootSec=") ||
+                                !!startswith(optarg, "OnStartupSec=") ||
+                                !!startswith(optarg, "OnUnitActiveSec=") ||
+                                !!startswith(optarg, "OnUnitInactiveSec=") ||
+                                !!startswith(optarg, "OnCalendar=");
                         break;
 
                 case ARG_NO_BLOCK:
@@ -384,6 +376,10 @@ static int parse_argv(int argc, char *argv[]) {
                         arg_wait = true;
                         break;
 
+                case 'G':
+                        arg_aggressive_gc = true;
+                        break;
+
                 case '?':
                         return -EINVAL;
 
@@ -401,7 +397,7 @@ static int parse_argv(int argc, char *argv[]) {
                         ARG_STDIO_DIRECT;
         }
 
-        if ((optind >= argc) && (!arg_unit || !with_timer())) {
+        if ((optind >= argc) && (!arg_unit || !with_timer)) {
                 log_error("Command line to execute required.");
                 return -EINVAL;
         }
@@ -421,7 +417,7 @@ static int parse_argv(int argc, char *argv[]) {
                 return -EINVAL;
         }
 
-        if (arg_stdio != ARG_STDIO_NONE && (with_timer() || arg_scope)) {
+        if (arg_stdio != ARG_STDIO_NONE && (with_timer || arg_scope)) {
                 log_error("--pty/--pipe is not compatible in timer or --scope mode.");
                 return -EINVAL;
         }
@@ -436,12 +432,12 @@ static int parse_argv(int argc, char *argv[]) {
                 return -EINVAL;
         }
 
-        if (arg_scope && with_timer()) {
+        if (arg_scope && with_timer) {
                 log_error("Timer options are not supported in --scope mode.");
                 return -EINVAL;
         }
 
-        if (arg_timer_property && !with_timer()) {
+        if (arg_timer_property && !with_timer) {
                 log_error("--timer-property= has no effect without any other timer options.");
                 return -EINVAL;
         }
@@ -452,7 +448,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
                 }
 
-                if (with_timer()) {
+                if (with_timer) {
                         log_error("--wait may not be combined with timer operations.");
                         return -EINVAL;
                 }
@@ -471,7 +467,13 @@ static int transient_unit_set_properties(sd_bus_message *m, char **properties) {
 
         r = sd_bus_message_append(m, "(sv)", "Description", "s", arg_description);
         if (r < 0)
-                return r;
+                return bus_log_create_error(r);
+
+        if (arg_aggressive_gc) {
+                r = sd_bus_message_append(m, "(sv)", "CollectMode", "s", "inactive-or-failed");
+                if (r < 0)
+                        return bus_log_create_error(r);
+        }
 
         r = bus_append_unit_property_assignment_many(m, properties);
         if (r < 0)
@@ -485,27 +487,32 @@ static int transient_cgroup_set_properties(sd_bus_message *m) {
         assert(m);
 
         if (!isempty(arg_slice)) {
-                _cleanup_free_ char *slice;
+                _cleanup_free_ char *slice = NULL;
 
                 r = unit_name_mangle_with_suffix(arg_slice, UNIT_NAME_NOGLOB, ".slice", &slice);
                 if (r < 0)
-                        return r;
+                        return log_error_errno(r, "Failed to mangle name '%s': %m", arg_slice);
 
                 r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice);
                 if (r < 0)
-                        return r;
+                        return bus_log_create_error(r);
         }
 
         return 0;
 }
 
 static int transient_kill_set_properties(sd_bus_message *m) {
+        int r;
+
         assert(m);
 
-        if (arg_send_sighup)
-                return sd_bus_message_append(m, "(sv)", "SendSIGHUP", "b", arg_send_sighup);
-        else
-                return 0;
+        if (arg_send_sighup) {
+                r = sd_bus_message_append(m, "(sv)", "SendSIGHUP", "b", arg_send_sighup);
+                if (r < 0)
+                        return bus_log_create_error(r);
+        }
+
+        return 0;
 }
 
 static int transient_service_set_properties(sd_bus_message *m, char **argv, const char *pty_path) {
@@ -529,37 +536,37 @@ static int transient_service_set_properties(sd_bus_message *m, char **argv, cons
         if (arg_wait || arg_stdio != ARG_STDIO_NONE) {
                 r = sd_bus_message_append(m, "(sv)", "AddRef", "b", 1);
                 if (r < 0)
-                        return r;
+                        return bus_log_create_error(r);
         }
 
         if (arg_remain_after_exit) {
                 r = sd_bus_message_append(m, "(sv)", "RemainAfterExit", "b", arg_remain_after_exit);
                 if (r < 0)
-                        return r;
+                        return bus_log_create_error(r);
         }
 
         if (arg_service_type) {
                 r = sd_bus_message_append(m, "(sv)", "Type", "s", arg_service_type);
                 if (r < 0)
-                        return r;
+                        return bus_log_create_error(r);
         }
 
         if (arg_exec_user) {
                 r = sd_bus_message_append(m, "(sv)", "User", "s", arg_exec_user);
                 if (r < 0)
-                        return r;
+                        return bus_log_create_error(r);
         }
 
         if (arg_exec_group) {
                 r = sd_bus_message_append(m, "(sv)", "Group", "s", arg_exec_group);
                 if (r < 0)
-                        return r;
+                        return bus_log_create_error(r);
         }
 
         if (arg_nice_set) {
                 r = sd_bus_message_append(m, "(sv)", "Nice", "i", arg_nice);
                 if (r < 0)
-                        return r;
+                        return bus_log_create_error(r);
         }
 
         if (pty_path) {
@@ -570,7 +577,7 @@ static int transient_service_set_properties(sd_bus_message *m, char **argv, cons
                                           "StandardError", "s", "tty",
                                           "TTYPath", "s", pty_path);
                 if (r < 0)
-                        return r;
+                        return bus_log_create_error(r);
 
                 send_term = true;
 
@@ -581,7 +588,7 @@ static int transient_service_set_properties(sd_bus_message *m, char **argv, cons
                                           "StandardOutputFileDescriptor", "h", STDOUT_FILENO,
                                           "StandardErrorFileDescriptor", "h", STDERR_FILENO);
                 if (r < 0)
-                        return r;
+                        return bus_log_create_error(r);
 
                 send_term = isatty(STDIN_FILENO) || isatty(STDOUT_FILENO) || isatty(STDERR_FILENO);
         }
@@ -598,85 +605,85 @@ static int transient_service_set_properties(sd_bus_message *m, char **argv, cons
                                                   "(sv)",
                                                   "Environment", "as", 1, n);
                         if (r < 0)
-                                return r;
+                                return bus_log_create_error(r);
                 }
         }
 
         if (!strv_isempty(arg_environment)) {
                 r = sd_bus_message_open_container(m, 'r', "sv");
                 if (r < 0)
-                        return r;
+                        return bus_log_create_error(r);
 
                 r = sd_bus_message_append(m, "s", "Environment");
                 if (r < 0)
-                        return r;
+                        return bus_log_create_error(r);
 
                 r = sd_bus_message_open_container(m, 'v', "as");
                 if (r < 0)
-                        return r;
+                        return bus_log_create_error(r);
 
                 r = sd_bus_message_append_strv(m, arg_environment);
                 if (r < 0)
-                        return r;
+                        return bus_log_create_error(r);
 
                 r = sd_bus_message_close_container(m);
                 if (r < 0)
-                        return r;
+                        return bus_log_create_error(r);
 
                 r = sd_bus_message_close_container(m);
                 if (r < 0)
-                        return r;
+                        return bus_log_create_error(r);
         }
 
         /* Exec container */
         {
                 r = sd_bus_message_open_container(m, 'r', "sv");
                 if (r < 0)
-                        return r;
+                        return bus_log_create_error(r);
 
                 r = sd_bus_message_append(m, "s", "ExecStart");
                 if (r < 0)
-                        return r;
+                        return bus_log_create_error(r);
 
                 r = sd_bus_message_open_container(m, 'v', "a(sasb)");
                 if (r < 0)
-                        return r;
+                        return bus_log_create_error(r);
 
                 r = sd_bus_message_open_container(m, 'a', "(sasb)");
                 if (r < 0)
-                        return r;
+                        return bus_log_create_error(r);
 
                 r = sd_bus_message_open_container(m, 'r', "sasb");
                 if (r < 0)
-                        return r;
+                        return bus_log_create_error(r);
 
                 r = sd_bus_message_append(m, "s", argv[0]);
                 if (r < 0)
-                        return r;
+                        return bus_log_create_error(r);
 
                 r = sd_bus_message_append_strv(m, argv);
                 if (r < 0)
-                        return r;
+                        return bus_log_create_error(r);
 
                 r = sd_bus_message_append(m, "b", false);
                 if (r < 0)
-                        return r;
+                        return bus_log_create_error(r);
 
                 r = sd_bus_message_close_container(m);
                 if (r < 0)
-                        return r;
+                        return bus_log_create_error(r);
 
                 r = sd_bus_message_close_container(m);
                 if (r < 0)
-                        return r;
+                        return bus_log_create_error(r);
 
                 r = sd_bus_message_close_container(m);
                 if (r < 0)
-                        return r;
+                        return bus_log_create_error(r);
 
                 r = sd_bus_message_close_container(m);
                 if (r < 0)
-                        return r;
+                        return bus_log_create_error(r);
         }
 
         return 0;
@@ -701,7 +708,7 @@ static int transient_scope_set_properties(sd_bus_message *m) {
 
         r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, (uint32_t) getpid_cached());
         if (r < 0)
-                return r;
+                return bus_log_create_error(r);
 
         return 0;
 }
@@ -718,43 +725,7 @@ static int transient_timer_set_properties(sd_bus_message *m) {
         /* Automatically clean up our transient timers */
         r = sd_bus_message_append(m, "(sv)", "RemainAfterElapse", "b", false);
         if (r < 0)
-                return r;
-
-        if (arg_on_active) {
-                r = sd_bus_message_append(m, "(sv)", "OnActiveSec", "t", arg_on_active);
-                if (r < 0)
-                        return r;
-        }
-
-        if (arg_on_boot) {
-                r = sd_bus_message_append(m, "(sv)", "OnBootSec", "t", arg_on_boot);
-                if (r < 0)
-                        return r;
-        }
-
-        if (arg_on_startup) {
-                r = sd_bus_message_append(m, "(sv)", "OnStartupSec", "t", arg_on_startup);
-                if (r < 0)
-                        return r;
-        }
-
-        if (arg_on_unit_active) {
-                r = sd_bus_message_append(m, "(sv)", "OnUnitActiveSec", "t", arg_on_unit_active);
-                if (r < 0)
-                        return r;
-        }
-
-        if (arg_on_unit_inactive) {
-                r = sd_bus_message_append(m, "(sv)", "OnUnitInactiveSec", "t", arg_on_unit_inactive);
-                if (r < 0)
-                        return r;
-        }
-
-        if (arg_on_calendar) {
-                r = sd_bus_message_append(m, "(sv)", "OnCalendar", "s", arg_on_calendar);
-                if (r < 0)
-                        return r;
-        }
+                return bus_log_create_error(r);
 
         return 0;
 }
@@ -1016,7 +987,7 @@ static int start_transient_service(
 
         r = transient_service_set_properties(m, argv, pty_path);
         if (r < 0)
-                return bus_log_create_error(r);
+                return r;
 
         r = sd_bus_message_close_container(m);
         if (r < 0)
@@ -1027,7 +998,7 @@ static int start_transient_service(
         if (r < 0)
                 return bus_log_create_error(r);
 
-        polkit_agent_open_if_enabled();
+        polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
 
         r = sd_bus_call(bus, m, 0, &error, &reply);
         if (r < 0)
@@ -1078,6 +1049,9 @@ static int start_transient_service(
                                 return log_error_errno(r, "Failed to create PTY forwarder: %m");
 
                         pty_forward_set_handler(c.forward, pty_forward_handler, &c);
+
+                        /* Make sure to process any TTY events before we process bus events */
+                        (void) pty_forward_set_priority(c.forward, SD_EVENT_PRIORITY_IMPORTANT);
                 }
 
                 path = unit_dbus_path_from_name(service);
@@ -1093,7 +1067,7 @@ static int start_transient_service(
                 if (r < 0)
                         return log_error_errno(r, "Failed to add properties changed signal.");
 
-                r = sd_bus_attach_event(bus, c.event, 0);
+                r = sd_bus_attach_event(bus, c.event, SD_EVENT_PRIORITY_NORMAL);
                 if (r < 0)
                         return log_error_errno(r, "Failed to attach bus to event loop.");
 
@@ -1215,7 +1189,7 @@ static int start_transient_scope(
 
         r = transient_scope_set_properties(m);
         if (r < 0)
-                return bus_log_create_error(r);
+                return r;
 
         r = sd_bus_message_close_container(m);
         if (r < 0)
@@ -1226,7 +1200,7 @@ static int start_transient_scope(
         if (r < 0)
                 return bus_log_create_error(r);
 
-        polkit_agent_open_if_enabled();
+        polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
 
         r = sd_bus_call(bus, m, 0, &error, &reply);
         if (r < 0) {
@@ -1396,7 +1370,7 @@ static int start_transient_timer(
 
         r = transient_timer_set_properties(m);
         if (r < 0)
-                return bus_log_create_error(r);
+                return r;
 
         r = sd_bus_message_close_container(m);
         if (r < 0)
@@ -1421,7 +1395,7 @@ static int start_transient_timer(
 
                 r = transient_service_set_properties(m, argv, NULL);
                 if (r < 0)
-                        return bus_log_create_error(r);
+                        return r;
 
                 r = sd_bus_message_close_container(m);
                 if (r < 0)
@@ -1436,7 +1410,7 @@ static int start_transient_timer(
         if (r < 0)
                 return bus_log_create_error(r);
 
-        polkit_agent_open_if_enabled();
+        polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
 
         r = sd_bus_call(bus, m, 0, &error, &reply);
         if (r < 0) {
@@ -1514,7 +1488,7 @@ int main(int argc, char* argv[]) {
 
         if (arg_scope)
                 r = start_transient_scope(bus, argv + optind);
-        else if (with_timer())
+        else if (with_timer)
                 r = start_transient_timer(bus, argv + optind);
         else
                 r = start_transient_service(bus, argv + optind, &retval);
index 79a3b95..889a971 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -225,7 +226,7 @@ int acl_search_groups(const char *path, char ***ret_groups) {
 }
 
 int parse_acl(const char *text, acl_t *acl_access, acl_t *acl_default, bool want_mask) {
-        _cleanup_free_ char **a = NULL, **d = NULL; /* strings are not be freed */
+        _cleanup_free_ char **a = NULL, **d = NULL; /* strings are not freed */
         _cleanup_strv_free_ char **split;
         char **entry;
         int r = -EINVAL;
index a0e31d8..6b581cb 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 6779691..1a640f4 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index fc28175..4521a1e 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index edd695f..e9c4081 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 524f740..33ebd4d 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index e33d8b1..17928a9 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -251,11 +252,13 @@ int ask_password_tty(
                 }
 
                 if (colors_enabled())
-                        loop_write(ttyfd, ANSI_HIGHLIGHT, strlen(ANSI_HIGHLIGHT), false);
+                        loop_write(ttyfd, ANSI_HIGHLIGHT,
+                                   STRLEN(ANSI_HIGHLIGHT), false);
                 loop_write(ttyfd, message, strlen(message), false);
                 loop_write(ttyfd, " ", 1, false);
                 if (colors_enabled())
-                        loop_write(ttyfd, ANSI_NORMAL, strlen(ANSI_NORMAL), false);
+                        loop_write(ttyfd, ANSI_NORMAL, STRLEN(ANSI_NORMAL),
+                                   false);
 
                 new_termios = old_termios;
                 new_termios.c_lflag &= ~(ICANON|ECHO);
index 9d7f651..f3ca674 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 903a187..3c25aa5 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 49599f0..5d134b4 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 7e01527..543e01a 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 6f69102..8c67d30 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
diff --git a/src/shared/bootspec.c b/src/shared/bootspec.c
new file mode 100644 (file)
index 0000000..c0a1041
--- /dev/null
@@ -0,0 +1,654 @@
+/***
+  This file is part of systemd.
+
+  Copyright 2017 Zbigniew Jędrzejewski-Szmek
+
+  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.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdio.h>
+#include <linux/magic.h>
+
+#include "alloc-util.h"
+#include "blkid-util.h"
+#include "bootspec.h"
+#include "conf-files.h"
+#include "def.h"
+#include "device-nodes.h"
+#include "efivars.h"
+#include "fd-util.h"
+#include "fileio.h"
+#include "parse-util.h"
+#include "stat-util.h"
+#include "string-util.h"
+#include "strv.h"
+#include "virt.h"
+
+void boot_entry_free(BootEntry *entry) {
+        assert(entry);
+
+        free(entry->filename);
+        free(entry->title);
+        free(entry->show_title);
+        free(entry->version);
+        free(entry->machine_id);
+        free(entry->architecture);
+        strv_free(entry->options);
+        free(entry->kernel);
+        free(entry->efi);
+        strv_free(entry->initrd);
+        free(entry->device_tree);
+}
+
+int boot_entry_load(const char *path, BootEntry *entry) {
+        _cleanup_fclose_ FILE *f = NULL;
+        unsigned line = 1;
+        _cleanup_(boot_entry_free) BootEntry tmp = {};
+        int r;
+
+        assert(path);
+        assert(entry);
+
+        f = fopen(path, "re");
+        if (!f)
+                return log_error_errno(errno, "Failed to open \"%s\": %m", path);
+
+        tmp.filename = strdup(basename(path));
+        if (!tmp.filename)
+                return log_oom();
+
+        for (;;) {
+                _cleanup_free_ char *buf = NULL;
+                char *p;
+
+                r = read_line(f, LONG_LINE_MAX, &buf);
+                if (r == 0)
+                        break;
+                if (r == -ENOBUFS)
+                        return log_error_errno(r, "%s:%u: Line too long", path, line);
+                if (r < 0)
+                        return log_error_errno(r, "%s:%u: Error while reading: %m", path, line);
+
+                line++;
+
+                if (IN_SET(*strstrip(buf), '#', '\0'))
+                        continue;
+
+                p = strchr(buf, ' ');
+                if (!p) {
+                        log_warning("%s:%u: Bad syntax", path, line);
+                        continue;
+                }
+                *p = '\0';
+                p = strstrip(p + 1);
+
+                if (streq(buf, "title"))
+                        r = free_and_strdup(&tmp.title, p);
+                else if (streq(buf, "version"))
+                        r = free_and_strdup(&tmp.version, p);
+                else if (streq(buf, "machine-id"))
+                        r = free_and_strdup(&tmp.machine_id, p);
+                else if (streq(buf, "architecture"))
+                        r = free_and_strdup(&tmp.architecture, p);
+                else if (streq(buf, "options"))
+                        r = strv_extend(&tmp.options, p);
+                else if (streq(buf, "linux"))
+                        r = free_and_strdup(&tmp.kernel, p);
+                else if (streq(buf, "efi"))
+                        r = free_and_strdup(&tmp.efi, p);
+                else if (streq(buf, "initrd"))
+                        r = strv_extend(&tmp.initrd, p);
+                else if (streq(buf, "devicetree"))
+                        r = free_and_strdup(&tmp.device_tree, p);
+                else {
+                        log_notice("%s:%u: Unknown line \"%s\"", path, line, buf);
+                        continue;
+                }
+                if (r < 0)
+                        return log_error_errno(r, "%s:%u: Error while reading: %m", path, line);
+        }
+
+        *entry = tmp;
+        tmp = (BootEntry) {};
+        return 0;
+}
+
+void boot_config_free(BootConfig *config) {
+        unsigned i;
+
+        assert(config);
+
+        free(config->default_pattern);
+        free(config->timeout);
+        free(config->editor);
+
+        free(config->entry_oneshot);
+        free(config->entry_default);
+
+        for (i = 0; i < config->n_entries; i++)
+                boot_entry_free(config->entries + i);
+        free(config->entries);
+}
+
+int boot_loader_read_conf(const char *path, BootConfig *config) {
+        _cleanup_fclose_ FILE *f = NULL;
+        unsigned line = 1;
+        int r;
+
+        assert(path);
+        assert(config);
+
+        f = fopen(path, "re");
+        if (!f)
+                return log_error_errno(errno, "Failed to open \"%s\": %m", path);
+
+        for (;;) {
+                _cleanup_free_ char *buf = NULL;
+                char *p;
+
+                r = read_line(f, LONG_LINE_MAX, &buf);
+                if (r == 0)
+                        break;
+                if (r == -ENOBUFS)
+                        return log_error_errno(r, "%s:%u: Line too long", path, line);
+                if (r < 0)
+                        return log_error_errno(r, "%s:%u: Error while reading: %m", path, line);
+
+                line++;
+
+                if (IN_SET(*strstrip(buf), '#', '\0'))
+                        continue;
+
+                p = strchr(buf, ' ');
+                if (!p) {
+                        log_warning("%s:%u: Bad syntax", path, line);
+                        continue;
+                }
+                *p = '\0';
+                p = strstrip(p + 1);
+
+                if (streq(buf, "default"))
+                        r = free_and_strdup(&config->default_pattern, p);
+                else if (streq(buf, "timeout"))
+                        r = free_and_strdup(&config->timeout, p);
+                else if (streq(buf, "editor"))
+                        r = free_and_strdup(&config->editor, p);
+                else {
+                        log_notice("%s:%u: Unknown line \"%s\"", path, line, buf);
+                        continue;
+                }
+                if (r < 0)
+                        return log_error_errno(r, "%s:%u: Error while reading: %m", path, line);
+        }
+
+        return 0;
+}
+
+/* This is a direct translation of str_verscmp from boot.c */
+static bool is_digit(int c) {
+        return c >= '0' && c <= '9';
+}
+
+static int c_order(int c) {
+        if (c == '\0')
+                return 0;
+        if (is_digit(c))
+                return 0;
+        else if ((c >= 'a') && (c <= 'z'))
+                return c;
+        else
+                return c + 0x10000;
+}
+
+static int str_verscmp(const char *s1, const char *s2) {
+        const char *os1 = s1;
+        const char *os2 = s2;
+
+        while (*s1 || *s2) {
+                int first;
+
+                while ((*s1 && !is_digit(*s1)) || (*s2 && !is_digit(*s2))) {
+                        int order;
+
+                        order = c_order(*s1) - c_order(*s2);
+                        if (order)
+                                return order;
+                        s1++;
+                        s2++;
+                }
+
+                while (*s1 == '0')
+                        s1++;
+                while (*s2 == '0')
+                        s2++;
+
+                first = 0;
+                while (is_digit(*s1) && is_digit(*s2)) {
+                        if (first == 0)
+                                first = *s1 - *s2;
+                        s1++;
+                        s2++;
+                }
+
+                if (is_digit(*s1))
+                        return 1;
+                if (is_digit(*s2))
+                        return -1;
+
+                if (first != 0)
+                        return first;
+        }
+
+        return strcmp(os1, os2);
+}
+
+static int boot_entry_compare(const void *a, const void *b) {
+        const BootEntry *aa = a;
+        const BootEntry *bb = b;
+
+        return str_verscmp(aa->filename, bb->filename);
+}
+
+int boot_entries_find(const char *dir, BootEntry **ret_entries, size_t *ret_n_entries) {
+        _cleanup_strv_free_ char **files = NULL;
+        char **f;
+        int r;
+        BootEntry *array = NULL;
+        size_t n_allocated = 0, n = 0;
+
+        assert(dir);
+        assert(ret_entries);
+        assert(ret_n_entries);
+
+        r = conf_files_list(&files, ".conf", NULL, 0, dir, NULL);
+        if (r < 0)
+                return log_error_errno(r, "Failed to list files in \"%s\": %m", dir);
+
+        STRV_FOREACH(f, files) {
+                if (!GREEDY_REALLOC0(array, n_allocated, n + 1))
+                        return log_oom();
+
+                r = boot_entry_load(*f, array + n);
+                if (r < 0)
+                        continue;
+
+                n++;
+        }
+
+        qsort_safe(array, n, sizeof(BootEntry), boot_entry_compare);
+
+        *ret_entries = array;
+        *ret_n_entries = n;
+
+        return 0;
+}
+
+static bool find_nonunique(BootEntry *entries, size_t n_entries, bool *arr) {
+        unsigned i, j;
+        bool non_unique = false;
+
+        assert(entries || n_entries == 0);
+        assert(arr || n_entries == 0);
+
+        for (i = 0; i < n_entries; i++)
+                arr[i] = false;
+
+        for (i = 0; i < n_entries; i++)
+                for (j = 0; j < n_entries; j++)
+                        if (i != j && streq(boot_entry_title(entries + i),
+                                            boot_entry_title(entries + j)))
+                                non_unique = arr[i] = arr[j] = true;
+
+        return non_unique;
+}
+
+static int boot_entries_uniquify(BootEntry *entries, size_t n_entries) {
+        char *s;
+        unsigned i;
+        int r;
+        bool arr[n_entries];
+
+        assert(entries || n_entries == 0);
+
+        /* Find _all_ non-unique titles */
+        if (!find_nonunique(entries, n_entries, arr))
+                return 0;
+
+        /* Add version to non-unique titles */
+        for (i = 0; i < n_entries; i++)
+                if (arr[i] && entries[i].version) {
+                        r = asprintf(&s, "%s (%s)", boot_entry_title(entries + i), entries[i].version);
+                        if (r < 0)
+                                return -ENOMEM;
+
+                        free_and_replace(entries[i].show_title, s);
+                }
+
+        if (!find_nonunique(entries, n_entries, arr))
+                return 0;
+
+        /* Add machine-id to non-unique titles */
+        for (i = 0; i < n_entries; i++)
+                if (arr[i] && entries[i].machine_id) {
+                        r = asprintf(&s, "%s (%s)", boot_entry_title(entries + i), entries[i].machine_id);
+                        if (r < 0)
+                                return -ENOMEM;
+
+                        free_and_replace(entries[i].show_title, s);
+                }
+
+        if (!find_nonunique(entries, n_entries, arr))
+                return 0;
+
+        /* Add file name to non-unique titles */
+        for (i = 0; i < n_entries; i++)
+                if (arr[i]) {
+                        r = asprintf(&s, "%s (%s)", boot_entry_title(entries + i), entries[i].filename);
+                        if (r < 0)
+                                return -ENOMEM;
+
+                        free_and_replace(entries[i].show_title, s);
+                }
+
+        return 0;
+}
+
+static int boot_entries_select_default(const BootConfig *config) {
+        int i;
+
+        assert(config);
+
+        if (config->entry_oneshot)
+                for (i = config->n_entries - 1; i >= 0; i--)
+                        if (streq(config->entry_oneshot, config->entries[i].filename)) {
+                                log_debug("Found default: filename \"%s\" is matched by LoaderEntryOneShot",
+                                          config->entries[i].filename);
+                                return i;
+                        }
+
+        if (config->entry_default)
+                for (i = config->n_entries - 1; i >= 0; i--)
+                        if (streq(config->entry_default, config->entries[i].filename)) {
+                                log_debug("Found default: filename \"%s\" is matched by LoaderEntryDefault",
+                                          config->entries[i].filename);
+                                return i;
+                        }
+
+        if (config->default_pattern)
+                for (i = config->n_entries - 1; i >= 0; i--)
+                        if (fnmatch(config->default_pattern, config->entries[i].filename, FNM_CASEFOLD) == 0) {
+                                log_debug("Found default: filename \"%s\" is matched by pattern \"%s\"",
+                                          config->entries[i].filename, config->default_pattern);
+                                return i;
+                        }
+
+        if (config->n_entries > 0)
+                log_debug("Found default: last entry \"%s\"", config->entries[config->n_entries - 1].filename);
+        else
+                log_debug("Found no default boot entry :(");
+
+        return config->n_entries - 1; /* -1 means "no default" */
+}
+
+int boot_entries_load_config(const char *esp_path, BootConfig *config) {
+        const char *p;
+        int r;
+
+        assert(esp_path);
+        assert(config);
+
+        p = strjoina(esp_path, "/loader/loader.conf");
+        r = boot_loader_read_conf(p, config);
+        if (r < 0)
+                return log_error_errno(r, "Failed to read boot config from \"%s\": %m", p);
+
+        p = strjoina(esp_path, "/loader/entries");
+        r = boot_entries_find(p, &config->entries, &config->n_entries);
+        if (r < 0)
+                return log_error_errno(r, "Failed to read boot entries from \"%s\": %m", p);
+
+        r = boot_entries_uniquify(config->entries, config->n_entries);
+        if (r < 0)
+                return log_error_errno(r, "Failed to uniquify boot entries: %m");
+
+        r = efi_get_variable_string(EFI_VENDOR_LOADER, "LoaderEntryOneShot", &config->entry_oneshot);
+        if (r < 0 && r != -ENOENT)
+                return log_error_errno(r, "Failed to read EFI var \"LoaderEntryOneShot\": %m");
+
+        r = efi_get_variable_string(EFI_VENDOR_LOADER, "LoaderEntryDefault", &config->entry_default);
+        if (r < 0 && r != -ENOENT)
+                return log_error_errno(r, "Failed to read EFI var \"LoaderEntryDefault\": %m");
+
+        config->default_entry = boot_entries_select_default(config);
+        return 0;
+}
+
+/********************************************************************************/
+
+static int verify_esp(
+                const char *p,
+                bool searching,
+                bool unprivileged_mode,
+                uint32_t *ret_part,
+                uint64_t *ret_pstart,
+                uint64_t *ret_psize,
+                sd_id128_t *ret_uuid) {
+#if HAVE_BLKID
+        _cleanup_blkid_free_probe_ blkid_probe b = NULL;
+        char t[DEV_NUM_PATH_MAX];
+        const char *v;
+#endif
+        uint64_t pstart = 0, psize = 0;
+        struct stat st, st2;
+        const char *t2;
+        struct statfs sfs;
+        sd_id128_t uuid = SD_ID128_NULL;
+        uint32_t part = 0;
+        int r;
+
+        assert(p);
+
+        /* Non-root user can only check the status, so if an error occured in the following, it does not cause any
+         * issues. Let's also, silence the error messages. */
+
+        if (statfs(p, &sfs) < 0) {
+                /* If we are searching for the mount point, don't generate a log message if we can't find the path */
+                if (errno == ENOENT && searching)
+                        return -ENOENT;
+
+                return log_full_errno(unprivileged_mode && errno == EACCES ? LOG_DEBUG : LOG_ERR, errno,
+                                      "Failed to check file system type of \"%s\": %m", p);
+        }
+
+        if (!F_TYPE_EQUAL(sfs.f_type, MSDOS_SUPER_MAGIC)) {
+                if (searching)
+                        return -EADDRNOTAVAIL;
+
+                log_error("File system \"%s\" is not a FAT EFI System Partition (ESP) file system.", p);
+                return -ENODEV;
+        }
+
+        if (stat(p, &st) < 0)
+                return log_full_errno(unprivileged_mode && errno == EACCES ? LOG_DEBUG : LOG_ERR, errno,
+                                      "Failed to determine block device node of \"%s\": %m", p);
+
+        if (major(st.st_dev) == 0) {
+                log_error("Block device node of %p is invalid.", p);
+                return -ENODEV;
+        }
+
+        t2 = strjoina(p, "/..");
+        r = stat(t2, &st2);
+        if (r < 0)
+                return log_full_errno(unprivileged_mode && errno == EACCES ? LOG_DEBUG : LOG_ERR, errno,
+                                      "Failed to determine block device node of parent of \"%s\": %m", p);
+
+        if (st.st_dev == st2.st_dev) {
+                log_error("Directory \"%s\" is not the root of the EFI System Partition (ESP) file system.", p);
+                return -ENODEV;
+        }
+
+        /* In a container we don't have access to block devices, skip this part of the verification, we trust the
+         * container manager set everything up correctly on its own. Also skip the following verification for non-root user. */
+        if (detect_container() > 0 || unprivileged_mode)
+                goto finish;
+
+#if HAVE_BLKID
+        xsprintf_dev_num_path(t, "block", st.st_dev);
+        errno = 0;
+        b = blkid_new_probe_from_filename(t);
+        if (!b)
+                return log_error_errno(errno ?: ENOMEM, "Failed to open file system \"%s\": %m", p);
+
+        blkid_probe_enable_superblocks(b, 1);
+        blkid_probe_set_superblocks_flags(b, BLKID_SUBLKS_TYPE);
+        blkid_probe_enable_partitions(b, 1);
+        blkid_probe_set_partitions_flags(b, BLKID_PARTS_ENTRY_DETAILS);
+
+        errno = 0;
+        r = blkid_do_safeprobe(b);
+        if (r == -2) {
+                log_error("File system \"%s\" is ambiguous.", p);
+                return -ENODEV;
+        } else if (r == 1) {
+                log_error("File system \"%s\" does not contain a label.", p);
+                return -ENODEV;
+        } else if (r != 0)
+                return log_error_errno(errno ?: EIO, "Failed to probe file system \"%s\": %m", p);
+
+        errno = 0;
+        r = blkid_probe_lookup_value(b, "TYPE", &v, NULL);
+        if (r != 0)
+                return log_error_errno(errno ?: EIO, "Failed to probe file system type \"%s\": %m", p);
+        if (!streq(v, "vfat")) {
+                log_error("File system \"%s\" is not FAT.", p);
+                return -ENODEV;
+        }
+
+        errno = 0;
+        r = blkid_probe_lookup_value(b, "PART_ENTRY_SCHEME", &v, NULL);
+        if (r != 0)
+                return log_error_errno(errno ?: EIO, "Failed to probe partition scheme \"%s\": %m", p);
+        if (!streq(v, "gpt")) {
+                log_error("File system \"%s\" is not on a GPT partition table.", p);
+                return -ENODEV;
+        }
+
+        errno = 0;
+        r = blkid_probe_lookup_value(b, "PART_ENTRY_TYPE", &v, NULL);
+        if (r != 0)
+                return log_error_errno(errno ?: EIO, "Failed to probe partition type UUID \"%s\": %m", p);
+        if (!streq(v, "c12a7328-f81f-11d2-ba4b-00a0c93ec93b")) {
+                log_error("File system \"%s\" has wrong type for an EFI System Partition (ESP).", p);
+                return -ENODEV;
+        }
+
+        errno = 0;
+        r = blkid_probe_lookup_value(b, "PART_ENTRY_UUID", &v, NULL);
+        if (r != 0)
+                return log_error_errno(errno ?: EIO, "Failed to probe partition entry UUID \"%s\": %m", p);
+        r = sd_id128_from_string(v, &uuid);
+        if (r < 0) {
+                log_error("Partition \"%s\" has invalid UUID \"%s\".", p, v);
+                return -EIO;
+        }
+
+        errno = 0;
+        r = blkid_probe_lookup_value(b, "PART_ENTRY_NUMBER", &v, NULL);
+        if (r != 0)
+                return log_error_errno(errno ?: EIO, "Failed to probe partition number \"%s\": m", p);
+        r = safe_atou32(v, &part);
+        if (r < 0)
+                return log_error_errno(r, "Failed to parse PART_ENTRY_NUMBER field.");
+
+        errno = 0;
+        r = blkid_probe_lookup_value(b, "PART_ENTRY_OFFSET", &v, NULL);
+        if (r != 0)
+                return log_error_errno(errno ?: EIO, "Failed to probe partition offset \"%s\": %m", p);
+        r = safe_atou64(v, &pstart);
+        if (r < 0)
+                return log_error_errno(r, "Failed to parse PART_ENTRY_OFFSET field.");
+
+        errno = 0;
+        r = blkid_probe_lookup_value(b, "PART_ENTRY_SIZE", &v, NULL);
+        if (r != 0)
+                return log_error_errno(errno ?: EIO, "Failed to probe partition size \"%s\": %m", p);
+        r = safe_atou64(v, &psize);
+        if (r < 0)
+                return log_error_errno(r, "Failed to parse PART_ENTRY_SIZE field.");
+#endif
+
+finish:
+        if (ret_part)
+                *ret_part = part;
+        if (ret_pstart)
+                *ret_pstart = pstart;
+        if (ret_psize)
+                *ret_psize = psize;
+        if (ret_uuid)
+                *ret_uuid = uuid;
+
+        return 0;
+}
+
+int find_esp_and_warn(
+                const char *path,
+                bool unprivileged_mode,
+                char **ret_path,
+                uint32_t *ret_part,
+                uint64_t *ret_pstart,
+                uint64_t *ret_psize,
+                sd_id128_t *ret_uuid) {
+
+        int r;
+
+        /* This logs about all errors except:
+         *
+         *    -ENOKEY → when we can't find the partition
+         *   -EACCESS → when unprivileged_mode is true, and we can't access something
+         */
+
+        if (path) {
+                r = verify_esp(path, false, unprivileged_mode, ret_part, ret_pstart, ret_psize, ret_uuid);
+                if (r < 0)
+                        return r;
+
+                goto found;
+        }
+
+        FOREACH_STRING(path, "/efi", "/boot", "/boot/efi") {
+
+                r = verify_esp(path, true, unprivileged_mode, ret_part, ret_pstart, ret_psize, ret_uuid);
+                if (r >= 0)
+                        goto found;
+                if (!IN_SET(r, -ENOENT, -EADDRNOTAVAIL)) /* This one is not it */
+                        return r;
+        }
+
+        /* No logging here */
+        return -ENOKEY;
+
+found:
+        if (ret_path) {
+                char *c;
+
+                c = strdup(path);
+                if (!c)
+                        return log_oom();
+
+                *ret_path = c;
+        }
+
+        return 0;
+}
diff --git a/src/shared/bootspec.h b/src/shared/bootspec.h
new file mode 100644 (file)
index 0000000..d9c641b
--- /dev/null
@@ -0,0 +1,64 @@
+/***
+  This file is part of systemd.
+
+  Copyright 2017 Zbigniew Jędrzejewski-Szmek
+
+  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.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#pragma once
+
+#include <stdlib.h>
+
+typedef struct BootEntry {
+        char *filename;
+
+        char *title;
+        char *show_title;
+        char *version;
+        char *machine_id;
+        char *architecture;
+        char **options;
+        char *kernel;        /* linux is #defined to 1, yikes! */
+        char *efi;
+        char **initrd;
+        char *device_tree;
+} BootEntry;
+
+typedef struct BootConfig {
+        char *default_pattern;
+        char *timeout;
+        char *editor;
+
+        char *entry_oneshot;
+        char *entry_default;
+
+        BootEntry *entries;
+        size_t n_entries;
+        ssize_t default_entry;
+} BootConfig;
+
+void boot_entry_free(BootEntry *entry);
+int boot_entry_load(const char *path, BootEntry *entry);
+int boot_entries_find(const char *dir, BootEntry **entries, size_t *n_entries);
+
+int boot_loader_read_conf(const char *path, BootConfig *config);
+void boot_config_free(BootConfig *config);
+int boot_entries_load_config(const char *esp_path, BootConfig *config);
+
+static inline const char* boot_entry_title(const BootEntry *entry) {
+        return entry->show_title ?: entry->title ?: entry->filename;
+}
+
+int find_esp_and_warn(const char *path, bool unprivileged_mode, char **ret_path, uint32_t *ret_part, uint64_t *ret_pstart, uint64_t *ret_psize, sd_id128_t *ret_uuid);
index e191f8c..b58abed 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -28,6 +29,7 @@
 #include "errno-list.h"
 #include "escape.h"
 #include "hashmap.h"
+#include "hexdecoct.h"
 #include "hostname-util.h"
 #include "in-addr-util.h"
 #include "list.h"
@@ -132,9 +134,12 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
 
         } else if (streq(field, "EnvironmentFile")) {
 
-                r = sd_bus_message_append(m, "sv", "EnvironmentFiles", "a(sb)", 1,
-                                          eq[0] == '-' ? eq + 1 : eq,
-                                          eq[0] == '-');
+                if (isempty(eq))
+                        r = sd_bus_message_append(m, "sv", "EnvironmentFiles", "a(sb)", 0);
+                else
+                        r = sd_bus_message_append(m, "sv", "EnvironmentFiles", "a(sb)", 1,
+                                                  eq[0] == '-' ? eq + 1 : eq,
+                                                  eq[0] == '-');
                 goto finish;
 
         } else if (STR_IN_SET(field, "AccuracySec", "RandomizedDelaySec", "RuntimeMaxSec")) {
@@ -156,7 +161,32 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
                 r = sd_bus_message_append(m, "sv", n, "t", t);
                 goto finish;
 
-        } else if (STR_IN_SET(field, "MemoryLow", "MemoryHigh", "MemoryMax", "MemoryLimit")) {
+        } else if (streq(field, "LogExtraFields")) {
+
+                r = sd_bus_message_append(m, "s", "LogExtraFields");
+                if (r < 0)
+                        goto finish;
+
+                r = sd_bus_message_open_container(m, 'v', "aay");
+                if (r < 0)
+                        goto finish;
+
+                r = sd_bus_message_open_container(m, 'a', "ay");
+                if (r < 0)
+                        goto finish;
+
+                r = sd_bus_message_append_array(m, 'y', eq, strlen(eq));
+                if (r < 0)
+                        goto finish;
+
+                r = sd_bus_message_close_container(m);
+                if (r < 0)
+                        goto finish;
+
+                r = sd_bus_message_close_container(m);
+                goto finish;
+
+        } else if (STR_IN_SET(field, "MemoryLow", "MemoryHigh", "MemoryMax", "MemorySwapMax", "MemoryLimit")) {
                 uint64_t bytes;
 
                 if (isempty(eq) || streq(eq, "infinity"))
@@ -183,6 +213,51 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
 
                 r = sd_bus_message_append(m, "sv", field, "t", bytes);
                 goto finish;
+
+        } else if (streq(field, "Delegate")) {
+
+                r = parse_boolean(eq);
+                if (r < 0) {
+                        const char *p = eq;
+
+                        r = sd_bus_message_append(m, "s", "DelegateControllers");
+                        if (r < 0)
+                                goto finish;
+
+                        r = sd_bus_message_open_container(m, 'v', "as");
+                        if (r < 0)
+                                goto finish;
+
+                        r = sd_bus_message_open_container(m, 'a', "s");
+                        if (r < 0)
+                                goto finish;
+
+                        for (;;) {
+                                _cleanup_free_ char *word = NULL;
+
+                                r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES);
+                                if (r == 0)
+                                        break;
+                                if (r == -ENOMEM)
+                                        return log_oom();
+                                if (r < 0)
+                                        return log_error_errno(r, "Invalid syntax: %s", eq);
+
+                                r = sd_bus_message_append(m, "s", word);
+                                if (r < 0)
+                                        goto finish;
+                        }
+
+                        r = sd_bus_message_close_container(m);
+                        if (r < 0)
+                                goto finish;
+
+                        r = sd_bus_message_close_container(m);
+                } else
+                        r = sd_bus_message_append(m, "sv", "Delegate", "b", r);
+
+                goto finish;
+
         } else if (streq(field, "TasksMax")) {
                 uint64_t t;
 
@@ -203,6 +278,50 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
 
                 r = sd_bus_message_append(m, "sv", "TasksMax", "t", t);
                 goto finish;
+
+        } else if (STR_IN_SET(field, "StandardInput", "StandardOutput", "StandardError")) {
+                const char *n, *appended;
+
+                n = startswith(eq, "fd:");
+                if (n) {
+                        appended = strjoina(field, "FileDescriptorName");
+                        r = sd_bus_message_append(m, "sv", appended, "s", n);
+
+                } else if ((n = startswith(eq, "file:"))) {
+                        appended = strjoina(field, "File");
+                        r = sd_bus_message_append(m, "sv", appended, "s", n);
+                } else
+                        r = sd_bus_message_append(m, "sv", field, "s", eq);
+
+                goto finish;
+
+        } else if (streq(field, "StandardInputText")) {
+                _cleanup_free_ char *unescaped = NULL;
+
+                r = cunescape(eq, 0, &unescaped);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to unescape text '%s': %m", eq);
+
+                if (!strextend(&unescaped, "\n", NULL))
+                        return log_oom();
+
+                /* Note that we don't expand specifiers here, but that should be OK, as this is a programmatic
+                 * interface anyway */
+
+                r = sd_bus_message_append(m, "s", "StandardInputData");
+                if (r < 0)
+                        return bus_log_create_error(r);
+
+                r = sd_bus_message_open_container(m, 'v', "ay");
+                if (r < 0)
+                        return bus_log_create_error(r);
+
+                r = sd_bus_message_append_array(m, 'y', unescaped, strlen(unescaped));
+                if (r < 0)
+                        return bus_log_create_error(r);
+
+                r = sd_bus_message_close_container(m);
+                goto finish;
         }
 
         r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field);
@@ -238,7 +357,7 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
                               "TasksAccounting", "IPAccounting", "SendSIGHUP", "SendSIGKILL", "WakeSystem",
                               "DefaultDependencies", "IgnoreSIGPIPE", "TTYVHangup", "TTYReset", "TTYVTDisallocate",
                               "RemainAfterExit", "PrivateTmp", "PrivateDevices", "PrivateNetwork", "PrivateUsers",
-                              "NoNewPrivileges", "SyslogLevelPrefix", "Delegate", "RemainAfterElapse",
+                              "NoNewPrivileges", "SyslogLevelPrefix", "RemainAfterElapse", "Persistent",
                               "MemoryDenyWriteExecute", "RestrictRealtime", "DynamicUser", "RemoveIPC",
                               "ProtectKernelTunables", "ProtectKernelModules", "ProtectControlGroups", "MountAPIVFS",
                               "CPUSchedulingResetOnFork", "LockPersonality")) {
@@ -253,10 +372,8 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
                 uint64_t u;
 
                 r = cg_weight_parse(eq, &u);
-                if (r < 0) {
-                        log_error("Failed to parse %s value %s.", field, eq);
-                        return -EINVAL;
-                }
+                if (r < 0)
+                        return log_error_errno(r, "Failed to parse %s value %s: %m", field, eq);
 
                 r = sd_bus_message_append(m, "v", "t", u);
 
@@ -264,10 +381,8 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
                 uint64_t u;
 
                 r = cg_cpu_shares_parse(eq, &u);
-                if (r < 0) {
-                        log_error("Failed to parse %s value %s.", field, eq);
-                        return -EINVAL;
-                }
+                if (r < 0)
+                        return log_error_errno(r, "Failed to parse %s value %s: %m", field, eq);
 
                 r = sd_bus_message_append(m, "v", "t", u);
 
@@ -275,10 +390,8 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
                 uint64_t u;
 
                 r = cg_weight_parse(eq, &u);
-                if (r < 0) {
-                        log_error("Failed to parse %s value %s.", field, eq);
-                        return -EINVAL;
-                }
+                if (r < 0)
+                        return log_error_errno(r, "Failed to parse %s value %s: %m", field, eq);
 
                 r = sd_bus_message_append(m, "v", "t", u);
 
@@ -286,25 +399,42 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
                 uint64_t u;
 
                 r = cg_blkio_weight_parse(eq, &u);
-                if (r < 0) {
-                        log_error("Failed to parse %s value %s.", field, eq);
-                        return -EINVAL;
-                }
+                if (r < 0)
+                        return log_error_errno(r, "Failed to parse %s value %s: %m", field, eq);
 
                 r = sd_bus_message_append(m, "v", "t", u);
 
         } else if (STR_IN_SET(field,
                               "User", "Group", "DevicePolicy", "KillMode",
                               "UtmpIdentifier", "UtmpMode", "PAMName", "TTYPath",
-                              "StandardInput", "StandardOutput", "StandardError",
                               "Description", "Slice", "Type", "WorkingDirectory",
                               "RootDirectory", "SyslogIdentifier", "ProtectSystem",
                               "ProtectHome", "SELinuxContext", "Restart", "RootImage",
                               "NotifyAccess", "RuntimeDirectoryPreserve", "Personality",
-                              "KeyringMode"))
+                              "KeyringMode", "CollectMode", "FailureAction", "SuccessAction",
+                              "OnCalendar"))
+
                 r = sd_bus_message_append(m, "v", "s", eq);
 
-        else if (STR_IN_SET(field, "AppArmorProfile", "SmackProcessLabel")) {
+        else if (streq(field, "StandardInputData")) {
+                _cleanup_free_ void *decoded = NULL;
+                size_t sz;
+
+                r = unbase64mem(eq, (size_t) -1, &decoded, &sz);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to decode base64 data '%s': %m", eq);
+
+                r = sd_bus_message_open_container(m, 'v', "ay");
+                if (r < 0)
+                        return bus_log_create_error(r);
+
+                r = sd_bus_message_append_array(m, 'y', decoded, sz);
+                if (r < 0)
+                        return bus_log_create_error(r);
+
+                r = sd_bus_message_close_container(m);
+
+        } else if (STR_IN_SET(field, "AppArmorProfile", "SmackProcessLabel")) {
                 bool ignore;
                 const char *s;
 
@@ -318,7 +448,7 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
 
                 r = sd_bus_message_append(m, "v", "(bs)", ignore, s);
 
-        } else if (streq(field, "SyslogLevel")) {
+        } else if (STR_IN_SET(field, "SyslogLevel", "LogLevelMax")) {
                 int level;
 
                 level = log_level_from_string(eq);
@@ -343,10 +473,8 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
         } else if (streq(field, "SecureBits")) {
 
                 r = secure_bits_from_string(eq);
-                if (r < 0) {
-                        log_error("Failed to parse %s value %s.", field, eq);
-                        return -EINVAL;
-                }
+                if (r < 0)
+                        return log_error_errno(r, "Failed to parse %s value %s: %m", field, eq);
 
                 r = sd_bus_message_append(m, "v", "i", r);
 
@@ -362,10 +490,8 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
                 }
 
                 r = capability_set_from_string(p, &sum);
-                if (r < 0) {
-                        log_error("Failed to parse %s value %s.", field, eq);
-                        return -EINVAL;
-                }
+                if (r < 0)
+                        return log_error_errno(r, "Failed to parse %s value %s: %m", field, eq);
 
                 sum = invert ? ~sum : sum;
 
@@ -421,10 +547,8 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
                                 bytes = CGROUP_LIMIT_MAX;
                         } else {
                                 r = parse_size(bandwidth, 1000, &bytes);
-                                if (r < 0) {
-                                        log_error("Failed to parse byte value %s.", bandwidth);
-                                        return -EINVAL;
-                                }
+                                if (r < 0)
+                                        return log_error_errno(r, "Failed to parse byte value %s: %m", bandwidth);
                         }
 
                         r = sd_bus_message_append(m, "v", "a(st)", 1, path, bytes);
@@ -453,10 +577,9 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
                         }
 
                         r = safe_atou64(weight, &u);
-                        if (r < 0) {
-                                log_error("Failed to parse %s value %s.", field, weight);
-                                return -EINVAL;
-                        }
+                        if (r < 0)
+                                return log_error_errno(r, "Failed to parse %s value %s: %m", field, weight);
+
                         r = sd_bus_message_append(m, "v", "a(st)", 1, path, u);
                 }
 
@@ -511,7 +634,7 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
                                         return bus_log_create_error(r);
 
                                 prefix.in6 = (struct in6_addr) {
-                                        .__in6_u.__u6_addr32[0] = htobe32(0xfe800000)
+                                        .s6_addr32[0] = htobe32(0xfe800000)
                                 };
                                 r = bus_append_ip_address_access(m, AF_INET6, &prefix, 64);
                                 if (r < 0)
@@ -527,7 +650,7 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
                                         return bus_log_create_error(r);
 
                                 prefix.in6 = (struct in6_addr) {
-                                        .__in6_u.__u6_addr32[0] = htobe32(0xff000000)
+                                        .s6_addr32[0] = htobe32(0xff000000)
                                 };
                                 r = bus_append_ip_address_access(m, AF_INET6, &prefix, 8);
                                 if (r < 0)
@@ -584,8 +707,9 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
                 if (r < 0)
                         return bus_log_create_error(r);
 
-                if (cpuset)
-                        sd_bus_message_append_array(m, 'y', cpuset, CPU_ALLOC_SIZE(ncpus));
+                r = sd_bus_message_append_array(m, 'y', cpuset, CPU_ALLOC_SIZE(ncpus));
+                if (r < 0)
+                        return bus_log_create_error(r);
 
                 r = sd_bus_message_close_container(m);
 
@@ -598,16 +722,11 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
 
                 r = sd_bus_message_append(m, "v", "i", (int32_t) n);
 
-#if HAVE_SECCOMP
-
         } else if (streq(field, "SystemCallFilter")) {
                 int whitelist;
+                _cleanup_strv_free_ char **l = NULL;
                 const char *p;
 
-                r = sd_bus_message_open_container(m, 'v', "bas");
-                if (r < 0)
-                        return bus_log_create_error(r);
-
                 p = eq;
                 if (*p == '~') {
                         whitelist = 0;
@@ -615,18 +734,10 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
                 } else
                         whitelist = 1;
 
-                r = sd_bus_message_append_basic(m, 'b', &whitelist);
-                if (r < 0)
-                        return bus_log_create_error(r);
-
-                r = sd_bus_message_open_container(m, 'a', "s");
-                if (r < 0)
-                        return bus_log_create_error(r);
-
                 if (whitelist != 0) {
-                        r = sd_bus_message_append_basic(m, 's', "@default");
+                        r = strv_extend(&l, "@default");
                         if (r < 0)
-                                return bus_log_create_error(r);
+                                return log_oom();
                 }
 
                 for (;;) {
@@ -638,16 +749,34 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
                         if (r == 0)
                                 break;
 
-                        r = sd_bus_message_append_basic(m, 's', word);
+                        r = strv_extend(&l, word);
                         if (r < 0)
-                                return bus_log_create_error(r);
+                                return log_oom();
                 }
 
+                r = sd_bus_message_open_container(m, 'v', "(bas)");
+                if (r < 0)
+                        return bus_log_create_error(r);
+
+                r = sd_bus_message_open_container(m, 'r', "bas");
+                if (r < 0)
+                        return bus_log_create_error(r);
+
+                r = sd_bus_message_append_basic(m, 'b', &whitelist);
+                if (r < 0)
+                        return bus_log_create_error(r);
+
+                r = sd_bus_message_append_strv(m, l);
+                if (r < 0)
+                        return bus_log_create_error(r);
+
                 r = sd_bus_message_close_container(m);
                 if (r < 0)
                         return bus_log_create_error(r);
 
                 r = sd_bus_message_close_container(m);
+                if (r < 0)
+                        return bus_log_create_error(r);
 
         } else if (streq(field, "SystemCallArchitectures")) {
                 const char *p;
@@ -683,35 +812,23 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
         } else if (streq(field, "SystemCallErrorNumber")) {
                 int n;
 
-                n = errno_from_name(eq);
-                if (n < 0)
+                n = parse_errno(eq);
+                if (n <= 0)
                         return log_error_errno(r, "Failed to parse %s value: %s", field, eq);
 
                 r = sd_bus_message_append(m, "v", "i", (int32_t) n);
 
         } else if (streq(field, "RestrictAddressFamilies")) {
                 int whitelist;
-                const char *p;
-
-                r = sd_bus_message_open_container(m, 'v', "bas");
-                if (r < 0)
-                        return bus_log_create_error(r);
+                _cleanup_strv_free_ char **l = NULL;
+                const char *p = eq;
 
-                p = eq;
                 if (*p == '~') {
                         whitelist = 0;
                         p++;
                 } else
                         whitelist = 1;
 
-                r = sd_bus_message_append_basic(m, 'b', &whitelist);
-                if (r < 0)
-                        return bus_log_create_error(r);
-
-                r = sd_bus_message_open_container(m, 'a', "s");
-                if (r < 0)
-                        return bus_log_create_error(r);
-
                 for (;;) {
                         _cleanup_free_ char *word = NULL;
 
@@ -721,18 +838,34 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
                         if (r == 0)
                                 break;
 
-                        r = sd_bus_message_append_basic(m, 's', word);
+                        r = strv_extend(&l, word);
                         if (r < 0)
-                                return bus_log_create_error(r);
+                                return log_oom();
                 }
 
-                r = sd_bus_message_close_container(m);
+                r = sd_bus_message_open_container(m, 'v', "(bas)");
+                if (r < 0)
+                        return bus_log_create_error(r);
+
+                r = sd_bus_message_open_container(m, 'r', "bas");
+                if (r < 0)
+                        return bus_log_create_error(r);
+
+                r = sd_bus_message_append_basic(m, 'b', &whitelist);
+                if (r < 0)
+                        return bus_log_create_error(r);
+
+                r = sd_bus_message_append_strv(m, l);
                 if (r < 0)
                         return bus_log_create_error(r);
 
                 r = sd_bus_message_close_container(m);
+                if (r < 0)
+                        return bus_log_create_error(r);
 
-#endif
+                r = sd_bus_message_close_container(m);
+                if (r < 0)
+                        return bus_log_create_error(r);
 
         } else if (streq(field, "FileDescriptorStoreMax")) {
                 unsigned u;
@@ -776,10 +909,8 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
                         _cleanup_free_ char *word = NULL;
 
                         r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE);
-                        if (r < 0) {
-                                log_error("Failed to parse Environment value %s", eq);
-                                return -EINVAL;
-                        }
+                        if (r < 0)
+                                return log_error_errno(r, "Failed to parse Environment value %s: %m", eq);
                         if (r == 0)
                                 break;
 
@@ -826,20 +957,16 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
                 nsec_t n;
 
                 r = parse_nsec(eq, &n);
-                if (r < 0) {
-                        log_error("Failed to parse %s value %s", field, eq);
-                        return -EINVAL;
-                }
+                if (r < 0)
+                        return log_error_errno(r, "Failed to parse %s value %s: %m", field, eq);
 
                 r = sd_bus_message_append(m, "v", "t", n);
         } else if (streq(field, "OOMScoreAdjust")) {
                 int oa;
 
                 r = safe_atoi(eq, &oa);
-                if (r < 0) {
-                        log_error("Failed to parse %s value %s", field, eq);
-                        return -EINVAL;
-                }
+                if (r < 0)
+                        return log_error_errno(r, "Failed to parse %s value %s: %m", field, eq);
 
                 if (!oom_score_adjust_is_valid(oa)) {
                         log_error("OOM score adjust value out of range");
@@ -864,10 +991,8 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
                         size_t offset;
 
                         r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES);
-                        if (r < 0) {
-                                log_error("Failed to parse %s value %s", field, eq);
-                                return -EINVAL;
-                        }
+                        if (r < 0)
+                                return log_error_errno(r, "Failed to parse %s value %s: %m", field, eq);
                         if (r == 0)
                                 break;
 
@@ -912,10 +1037,8 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
                         _cleanup_free_ char *word = NULL;
 
                         r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES);
-                        if (r < 0) {
-                                log_error("Failed to parse %s value %s", field, eq);
-                                return -EINVAL;
-                        }
+                        if (r < 0)
+                                return log_error_errno(r, "Failed to parse %s value %s: %m", field, eq);
                         if (r == 0)
                                 break;
 
@@ -1081,8 +1204,107 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
                         return r;
 
                 r = sd_bus_message_close_container(m);
+
+        } else if (STR_IN_SET(field, "ExecStartPre", "ExecStart", "ExecStartPost",
+                              "ExecReload", "ExecStop", "ExecStopPost")) {
+
+                bool ignore_failure = false, explicit_path = false, done = false;
+                _cleanup_strv_free_ char **l = NULL;
+                _cleanup_free_ char *path = NULL;
+
+                do {
+                        switch (*eq) {
+
+                        case '-':
+                                if (ignore_failure)
+                                        done = true;
+                                else {
+                                        ignore_failure = true;
+                                        eq++;
+                                }
+                                break;
+
+                        case '@':
+                                if (explicit_path)
+                                        done = true;
+                                else {
+                                        explicit_path = true;
+                                        eq++;
+                                }
+                                break;
+
+                        case '+':
+                        case '!':
+                                /* The bus API doesn't support +, ! and !! currently, unfortunately. :-( */
+                                log_error("Sorry, but +, ! and !! are currently not supported for transient services.");
+                                return -EOPNOTSUPP;
+
+                        default:
+                                done = true;
+                                break;
+                        }
+                } while (!done);
+
+                if (explicit_path) {
+                        r = extract_first_word(&eq, &path, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE);
+                        if (r < 0)
+                                return log_error_errno(r, "Failed to parse path: %m");
+                }
+
+                r = strv_split_extract(&l, eq, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to parse command line: %m");
+
+                r = sd_bus_message_open_container(m, 'v', "a(sasb)");
+                if (r < 0)
+                        return r;
+
+                r = sd_bus_message_open_container(m, 'a', "(sasb)");
+                if (r < 0)
+                        return r;
+
+                if (strv_length(l) > 0) {
+
+                        r = sd_bus_message_open_container(m, 'r', "sasb");
+                        if (r < 0)
+                                return r;
+
+                        r = sd_bus_message_append(m, "s", path ?: l[0]);
+                        if (r < 0)
+                                return r;
+
+                        r = sd_bus_message_append_strv(m, l);
+                        if (r < 0)
+                                return r;
+
+                        r = sd_bus_message_append(m, "b", ignore_failure);
+                        if (r < 0)
+                                return r;
+
+                        r = sd_bus_message_close_container(m);
+                        if (r < 0)
+                                return r;
+                }
+
+                r = sd_bus_message_close_container(m);
+                if (r < 0)
+                        return r;
+
+                r = sd_bus_message_close_container(m);
+
+        } else if (STR_IN_SET(field,
+                              "OnActiveSec", "OnBootSec", "OnStartupSec",
+                              "OnUnitActiveSec","OnUnitInactiveSec")) {
+                usec_t t;
+
+                r = parse_sec(eq, &t);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to parse %s= parameter: %s", field, eq);
+
+                r = sd_bus_message_append(m, "v", "t", t);
+
         } else {
-                log_error("Unknown assignment %s.", assignment);
+                log_error("Unknown assignment: %s", assignment);
                 return -EINVAL;
         }
 
@@ -1290,7 +1512,7 @@ static void log_job_error_with_service_result(const char* service, const char *r
 
         service_shell_quoted = shell_maybe_quote(service, ESCAPE_BACKSLASH);
 
-        if (extra_args) {
+        if (!strv_isempty((char**) extra_args)) {
                 _cleanup_free_ char *t;
 
                 t = strv_join((char**) extra_args, " ");
@@ -1471,7 +1693,7 @@ int bus_deserialize_and_dump_unit_file_changes(sd_bus_message *m, bool quiet, Un
         if (r < 0)
                 return bus_log_parse_error(r);
 
-        unit_file_dump_changes(0, NULL, *changes, *n_changes, false);
+        unit_file_dump_changes(0, NULL, *changes, *n_changes, quiet);
         return 0;
 }
 
index d102ea1..1a137e8 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 7609d9c..7a18546 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -553,12 +554,7 @@ int bus_verify_polkit_async(
 
 void bus_verify_polkit_async_registry_free(Hashmap *registry) {
 #if ENABLE_POLKIT
-        AsyncPolkitQuery *q;
-
-        while ((q = hashmap_steal_first(registry)))
-                async_polkit_query_free(q);
-
-        hashmap_free(registry);
+        hashmap_free_with_destructor(registry, async_polkit_query_free);
 #endif
 }
 
@@ -664,7 +660,7 @@ int bus_connect_user_systemd(sd_bus **_bus) {
                         printf(fmt "\n", __VA_ARGS__);                  \
                 else                                                    \
                         printf("%s=" fmt "\n", name, __VA_ARGS__);      \
-        } while(0)
+        } while (0)
 
 int bus_print_property(const char *name, sd_bus_message *property, bool value, bool all) {
         char type;
index d9ce426..a9f4969 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 436130e..0ddae95 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 1764f76..efa597a 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 64f81bb..7e2ef4a 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index c04ed35..0ade561 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 74d5e85..3f32dfb 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -54,6 +55,7 @@
 #include "stat-util.h"
 #include "string-table.h"
 #include "string-util.h"
+#include "tomoyo-util.h"
 #include "user-util.h"
 #include "util.h"
 #include "virt.h"
@@ -76,8 +78,7 @@ Condition* condition_new(ConditionType type, const char *parameter, bool trigger
 
         r = free_and_strdup(&c->parameter, parameter);
         if (r < 0) {
-                free(c);
-                return NULL;
+                return mfree(c);
         }
 
         return c;
@@ -156,7 +157,7 @@ static int condition_test_user(Condition *c) {
                 return id == getuid() || id == geteuid();
 
         if (streq("@system", c->parameter))
-                return getuid() <= SYSTEM_UID_MAX || geteuid() <= SYSTEM_UID_MAX;
+                return uid_is_system(getuid()) || uid_is_system(geteuid());
 
         username = getusername_malloc();
         if (!username)
@@ -301,6 +302,8 @@ static int condition_test_security(Condition *c) {
                 return use_audit();
         if (streq(c->parameter, "ima"))
                 return use_ima();
+        if (streq(c->parameter, "tomoyo"))
+                return mac_tomoyo_use();
 
         return false;
 }
index d0b592b..534906b 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index c304ae3..daddb7c 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -121,17 +122,18 @@ int config_item_perf_lookup(
 }
 
 /* Run the user supplied parser for an assignment */
-static int next_assignment(const char *unit,
-                           const char *filename,
-                           unsigned line,
-                           ConfigItemLookup lookup,
-                           const void *table,
-                           const char *section,
-                           unsigned section_line,
-                           const char *lvalue,
-                           const char *rvalue,
-                           bool relaxed,
-                           void *userdata) {
+static int next_assignment(
+                const char *unit,
+                const char *filename,
+                unsigned line,
+                ConfigItemLookup lookup,
+                const void *table,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                const char *rvalue,
+                ConfigParseFlags flags,
+                void *userdata) {
 
         ConfigParserCallback func = NULL;
         int ltype = 0;
@@ -157,26 +159,26 @@ static int next_assignment(const char *unit,
         }
 
         /* Warn about unknown non-extension fields. */
-        if (!relaxed && !startswith(lvalue, "X-"))
+        if (!(flags & CONFIG_PARSE_RELAXED) && !startswith(lvalue, "X-"))
                 log_syntax(unit, LOG_WARNING, filename, line, 0, "Unknown lvalue '%s' in section '%s'", lvalue, section);
 
         return 0;
 }
 
 /* Parse a variable assignment line */
-static int parse_line(const char* unit,
-                      const char *filename,
-                      unsigned line,
-                      const char *sections,
-                      ConfigItemLookup lookup,
-                      const void *table,
-                      bool relaxed,
-                      bool allow_include,
-                      char **section,
-                      unsigned *section_line,
-                      bool *section_ignored,
-                      char *l,
-                      void *userdata) {
+static int parse_line(
+                const char* unit,
+                const char *filename,
+                unsigned line,
+                const char *sections,
+                ConfigItemLookup lookup,
+                const void *table,
+                ConfigParseFlags flags,
+                char **section,
+                unsigned *section_line,
+                bool *section_ignored,
+                char *l,
+                void *userdata) {
 
         char *e;
 
@@ -186,7 +188,6 @@ static int parse_line(const char* unit,
         assert(l);
 
         l = strstrip(l);
-
         if (!*l)
                 return 0;
 
@@ -205,7 +206,7 @@ static int parse_line(const char* unit,
                  *
                  * Support for them should be eventually removed. */
 
-                if (!allow_include) {
+                if (!(flags & CONFIG_PARSE_ALLOW_INCLUDE)) {
                         log_syntax(unit, LOG_ERR, filename, line, 0, ".include not allowed here. Ignoring.");
                         return 0;
                 }
@@ -214,7 +215,7 @@ static int parse_line(const char* unit,
                 if (!fn)
                         return -ENOMEM;
 
-                return config_parse(unit, fn, NULL, sections, lookup, table, relaxed, false, false, userdata);
+                return config_parse(unit, fn, NULL, sections, lookup, table, flags, userdata);
         }
 
         if (*l == '[') {
@@ -235,7 +236,7 @@ static int parse_line(const char* unit,
 
                 if (sections && !nulstr_contains(sections, n)) {
 
-                        if (!relaxed && !startswith(n, "X-"))
+                        if (!(flags & CONFIG_PARSE_RELAXED) && !startswith(n, "X-"))
                                 log_syntax(unit, LOG_WARNING, filename, line, 0, "Unknown section '%s'. Ignoring.", n);
 
                         free(n);
@@ -254,7 +255,7 @@ static int parse_line(const char* unit,
 
         if (sections && !*section) {
 
-                if (!relaxed && !*section_ignored)
+                if (!(flags & CONFIG_PARSE_RELAXED) && !*section_ignored)
                         log_syntax(unit, LOG_WARNING, filename, line, 0, "Assignment outside of section. Ignoring.");
 
                 return 0;
@@ -278,7 +279,7 @@ static int parse_line(const char* unit,
                                *section_line,
                                strstrip(l),
                                strstrip(e),
-                               relaxed,
+                               flags,
                                userdata);
 }
 
@@ -289,15 +290,13 @@ int config_parse(const char *unit,
                  const char *sections,
                  ConfigItemLookup lookup,
                  const void *table,
-                 bool relaxed,
-                 bool allow_include,
-                 bool warn,
+                 ConfigParseFlags flags,
                  void *userdata) {
 
         _cleanup_free_ char *section = NULL, *continuation = NULL;
         _cleanup_fclose_ FILE *ours = NULL;
         unsigned line = 0, section_line = 0;
-        bool section_ignored = false, allow_bom = true;
+        bool section_ignored = false;
         int r;
 
         assert(filename);
@@ -308,7 +307,7 @@ int config_parse(const char *unit,
                 if (!f) {
                         /* Only log on request, except for ENOENT,
                          * since we return 0 to the caller. */
-                        if (warn || errno == ENOENT)
+                        if ((flags & CONFIG_PARSE_WARN) || errno == ENOENT)
                                 log_full(errno == ENOENT ? LOG_DEBUG : LOG_ERR,
                                          "Failed to open configuration file '%s': %m", filename);
                         return errno == ENOENT ? 0 : -errno;
@@ -319,52 +318,50 @@ int config_parse(const char *unit,
 
         for (;;) {
                 _cleanup_free_ char *buf = NULL;
-                char *l, *p, *c = NULL, *e;
                 bool escaped = false;
+                char *l, *p, *e;
 
                 r = read_line(f, LONG_LINE_MAX, &buf);
                 if (r == 0)
                         break;
                 if (r == -ENOBUFS) {
-                        if (warn)
+                        if (flags & CONFIG_PARSE_WARN)
                                 log_error_errno(r, "%s:%u: Line too long", filename, line);
 
                         return r;
                 }
                 if (r < 0) {
-                        if (warn)
+                        if (CONFIG_PARSE_WARN)
                                 log_error_errno(r, "%s:%u: Error while reading configuration file: %m", filename, line);
 
                         return r;
                 }
 
                 l = buf;
-                if (allow_bom) {
+                if (!(flags & CONFIG_PARSE_REFUSE_BOM)) {
                         char *q;
 
                         q = startswith(buf, UTF8_BYTE_ORDER_MARK);
                         if (q) {
                                 l = q;
-                                allow_bom = false;
+                                flags |= CONFIG_PARSE_REFUSE_BOM;
                         }
                 }
 
                 if (continuation) {
                         if (strlen(continuation) + strlen(l) > LONG_LINE_MAX) {
-                                if (warn)
+                                if (flags & CONFIG_PARSE_WARN)
                                         log_error("%s:%u: Continuation line too long", filename, line);
                                 return -ENOBUFS;
                         }
 
-                        c = strappend(continuation, l);
-                        if (!c) {
-                                if (warn)
+                        if (!strextend(&continuation, l, NULL)) {
+                                if (flags & CONFIG_PARSE_WARN)
                                         log_oom();
                                 return -ENOMEM;
                         }
 
-                        continuation = mfree(continuation);
-                        p = c;
+                        p = continuation;
                 } else
                         p = l;
 
@@ -378,12 +375,10 @@ int config_parse(const char *unit,
                 if (escaped) {
                         *(e-1) = ' ';
 
-                        if (c)
-                                continuation = c;
-                        else {
+                        if (!continuation) {
                                 continuation = strdup(l);
                                 if (!continuation) {
-                                        if (warn)
+                                        if (flags & CONFIG_PARSE_WARN)
                                                 log_oom();
                                         return -ENOMEM;
                                 }
@@ -398,20 +393,20 @@ int config_parse(const char *unit,
                                sections,
                                lookup,
                                table,
-                               relaxed,
-                               allow_include,
+                               flags,
                                &section,
                                &section_line,
                                &section_ignored,
                                p,
                                userdata);
-                free(c);
-
                 if (r < 0) {
-                        if (warn)
+                        if (flags & CONFIG_PARSE_WARN)
                                 log_warning_errno(r, "%s:%u: Failed to parse file: %m", filename, line);
                         return r;
+
                 }
+
+                continuation = mfree(continuation);
         }
 
         return 0;
@@ -423,20 +418,20 @@ static int config_parse_many_files(
                 const char *sections,
                 ConfigItemLookup lookup,
                 const void *table,
-                bool relaxed,
+                ConfigParseFlags flags,
                 void *userdata) {
 
         char **fn;
         int r;
 
         if (conf_file) {
-                r = config_parse(NULL, conf_file, NULL, sections, lookup, table, relaxed, false, true, userdata);
+                r = config_parse(NULL, conf_file, NULL, sections, lookup, table, flags, userdata);
                 if (r < 0)
                         return r;
         }
 
         STRV_FOREACH(fn, files) {
-                r = config_parse(NULL, *fn, NULL, sections, lookup, table, relaxed, false, true, userdata);
+                r = config_parse(NULL, *fn, NULL, sections, lookup, table, flags, userdata);
                 if (r < 0)
                         return r;
         }
@@ -451,7 +446,7 @@ int config_parse_many_nulstr(
                 const char *sections,
                 ConfigItemLookup lookup,
                 const void *table,
-                bool relaxed,
+                ConfigParseFlags flags,
                 void *userdata) {
 
         _cleanup_strv_free_ char **files = NULL;
@@ -461,8 +456,7 @@ int config_parse_many_nulstr(
         if (r < 0)
                 return r;
 
-        return config_parse_many_files(conf_file, files,
-                                       sections, lookup, table, relaxed, userdata);
+        return config_parse_many_files(conf_file, files, sections, lookup, table, flags, userdata);
 }
 
 /* Parse each config file in the directories specified as strv. */
@@ -473,7 +467,7 @@ int config_parse_many(
                 const char *sections,
                 ConfigItemLookup lookup,
                 const void *table,
-                bool relaxed,
+                ConfigParseFlags flags,
                 void *userdata) {
 
         _cleanup_strv_free_ char **dropin_dirs = NULL;
@@ -490,8 +484,7 @@ int config_parse_many(
         if (r < 0)
                 return r;
 
-        return config_parse_many_files(conf_file, files,
-                                       sections, lookup, table, relaxed, userdata);
+        return config_parse_many_files(conf_file, files, sections, lookup, table, flags, userdata);
 }
 
 #define DEFINE_PARSER(type, vartype, conv_func)                         \
@@ -567,16 +560,17 @@ int config_parse_iec_size(const char* unit,
         return 0;
 }
 
-int config_parse_si_size(const char* unit,
-                            const char *filename,
-                            unsigned line,
-                            const char *section,
-                            unsigned section_line,
-                            const char *lvalue,
-                            int ltype,
-                            const char *rvalue,
-                            void *data,
-                            void *userdata) {
+int config_parse_si_size(
+                const char* unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
 
         size_t *sz = data;
         uint64_t v;
@@ -597,16 +591,17 @@ int config_parse_si_size(const char* unit,
         return 0;
 }
 
-int config_parse_iec_uint64(const char* unit,
-                           const char *filename,
-                           unsigned line,
-                           const char *section,
-                           unsigned section_line,
-                           const char *lvalue,
-                           int ltype,
-                           const char *rvalue,
-                           void *data,
-                           void *userdata) {
+int config_parse_iec_uint64(
+                const char* unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
 
         uint64_t *bytes = data;
         int r;
@@ -840,7 +835,6 @@ int config_parse_log_facility(
                 void *data,
                 void *userdata) {
 
-
         int *o = data, x;
 
         assert(filename);
@@ -871,7 +865,6 @@ int config_parse_log_level(
                 void *data,
                 void *userdata) {
 
-
         int *o = data, x;
 
         assert(filename);
@@ -885,7 +878,11 @@ int config_parse_log_level(
                 return 0;
         }
 
-        *o = (*o & LOG_FACMASK) | x;
+        if (*o < 0) /* if it wasn't initialized so far, assume zero facility */
+                *o = x;
+        else
+                *o = (*o & LOG_FACMASK) | x;
+
         return 0;
 }
 
index ce11134..2fd135b 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
 #include "log.h"
 #include "macro.h"
 
-/* An abstract parser for simple, line based, shallow configuration
- * files consisting of variable assignments only. */
+/* An abstract parser for simple, line based, shallow configuration files consisting of variable assignments only. */
+
+typedef enum ConfigParseFlags {
+        CONFIG_PARSE_RELAXED       = 1U << 0,
+        CONFIG_PARSE_ALLOW_INCLUDE = 1U << 1,
+        CONFIG_PARSE_WARN          = 1U << 2,
+        CONFIG_PARSE_REFUSE_BOM    = 1U << 3,
+} ConfigParseFlags;
 
 /* Prototype for a parser for a specific configuration setting */
 typedef int (*ConfigParserCallback)(const char *unit,
@@ -91,9 +98,7 @@ int config_parse(
                 const char *sections,  /* nulstr */
                 ConfigItemLookup lookup,
                 const void *table,
-                bool relaxed,
-                bool allow_include,
-                bool warn,
+                ConfigParseFlags flags,
                 void *userdata);
 
 int config_parse_many_nulstr(
@@ -102,7 +107,7 @@ int config_parse_many_nulstr(
                 const char *sections,       /* nulstr */
                 ConfigItemLookup lookup,
                 const void *table,
-                bool relaxed,
+                ConfigParseFlags flags,
                 void *userdata);
 
 int config_parse_many(
@@ -112,7 +117,7 @@ int config_parse_many(
                 const char *sections,       /* nulstr */
                 ConfigItemLookup lookup,
                 const void *table,
-                bool relaxed,
+                ConfigParseFlags flags,
                 void *userdata);
 
 /* Generic parsers */
index b2d464c..6d2cc68 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 5766a62..4dd591d 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 4b59f2c..e8d7db8 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
-#if HAVE_LIBCRYPTSETUP
-#include <libcryptsetup.h>
-#endif
 #include <sys/mount.h>
+#include <sys/prctl.h>
+#include <sys/wait.h>
 
 #include "architecture.h"
 #include "ask-password-api.h"
 #include "blkid-util.h"
+#include "copy.h"
+#include "crypt-util.h"
+#include "def.h"
+#include "device-nodes.h"
 #include "dissect-image.h"
 #include "fd-util.h"
 #include "fileio.h"
 #include "fs-util.h"
 #include "gpt.h"
 #include "hexdecoct.h"
+#include "hostname-util.h"
+#include "id128-util.h"
 #include "linux-3.13/dm-ioctl.h"
 #include "mount-util.h"
 #include "path-util.h"
+#include "process-util.h"
+#include "raw-clone.h"
+#include "signal-util.h"
 #include "stat-util.h"
 #include "stdio-util.h"
 #include "string-table.h"
 #include "string-util.h"
 #include "strv.h"
 #include "udev-util.h"
+#include "user-util.h"
 #include "xattr-util.h"
 
-_unused_ static int probe_filesystem(const char *node, char **ret_fstype) {
+int probe_filesystem(const char *node, char **ret_fstype) {
+        /* Try to find device content type and return it in *ret_fstype. If nothing is found,
+         * 0/NULL will be returned. -EUCLEAN will be returned for ambigous results, and an
+         * different error otherwise. */
+
 #if HAVE_BLKID
         _cleanup_blkid_free_probe_ blkid_probe b = NULL;
         const char *fstype;
         int r;
 
+        errno = 0;
         b = blkid_new_probe_from_filename(node);
         if (!b)
-                return -ENOMEM;
+                return -errno ?: -ENOMEM;
 
         blkid_probe_enable_superblocks(b, 1);
         blkid_probe_set_superblocks_flags(b, BLKID_SUBLKS_TYPE);
 
         errno = 0;
         r = blkid_do_safeprobe(b);
-        if (IN_SET(r, -2, 1)) {
-                log_debug("Failed to identify any partition type on partition %s", node);
+        if (r == 1) {
+                log_debug("No type detected on partition %s", node);
                 goto not_found;
         }
+        if (r == -2) {
+                log_debug("Results ambiguous for partition %s", node);
+                return -EUCLEAN;
+        }
         if (r != 0)
                 return -errno ?: -EIO;
 
@@ -266,18 +285,34 @@ int dissect_image(int fd, const void *root_hash, size_t root_hash_size, DissectI
                         return -EIO;
                 }
                 if (n < z + 1) {
-                        unsigned j;
+                        unsigned j = 0;
 
                         /* The kernel has probed fewer partitions than blkid? Maybe the kernel prober is still running
                          * or it got EBUSY because udev already opened the device. Let's reprobe the device, which is a
                          * synchronous call that waits until probing is complete. */
 
-                        for (j = 0; j < 20; j++) {
+                        for (;;) {
+                                if (j++ > 20)
+                                        return -EBUSY;
 
-                                r = ioctl(fd, BLKRRPART, 0);
-                                if (r < 0)
+                                if (ioctl(fd, BLKRRPART, 0) < 0) {
                                         r = -errno;
-                                if (r >= 0 || r != -EBUSY)
+
+                                        if (r == -EINVAL) {
+                                                struct loop_info64 info;
+
+                                                /* If we are running on a loop device that has partition scanning off,
+                                                 * return an explicit recognizable error about this, so that callers
+                                                 * can generate a proper message explaining the situation. */
+
+                                                if (ioctl(fd, LOOP_GET_STATUS64, &info) >= 0 && (info.lo_flags & LO_FLAGS_PARTSCAN) == 0) {
+                                                        log_debug("Device is loop device and partition scanning is off!");
+                                                        return -EPROTONOSUPPORT;
+                                                }
+                                        }
+                                        if (r != -EBUSY)
+                                                return r;
+                                } else
                                         break;
 
                                 /* If something else has the device open, such as an udev rule, the ioctl will return
@@ -286,11 +321,8 @@ int dissect_image(int fd, const void *root_hash, size_t root_hash_size, DissectI
                                  *
                                  * This is really something they should fix in the kernel! */
 
-                                usleep(50 * USEC_PER_MSEC);
+                                (void) usleep(50 * USEC_PER_MSEC);
                         }
-
-                        if (r < 0)
-                                return r;
                 }
 
                 e = udev_enumerate_unref(e);
@@ -585,7 +617,7 @@ int dissect_image(int fd, const void *root_hash, size_t root_hash_size, DissectI
 
                 if (!p->fstype && p->node) {
                         r = probe_filesystem(p->node, &p->fstype);
-                        if (r < 0)
+                        if (r < 0 && r != -EUCLEAN)
                                 return r;
                 }
 
@@ -618,12 +650,15 @@ DissectedImage* dissected_image_unref(DissectedImage *m) {
                 free(m->partitions[i].decrypted_node);
         }
 
-        free(m);
-        return NULL;
+        free(m->hostname);
+        strv_free(m->machine_info);
+        strv_free(m->os_release);
+
+        return mfree(m);
 }
 
 static int is_loop_device(const char *path) {
-        char s[strlen("/sys/dev/block/") + DECIMAL_STR_MAX(dev_t) + 1 + DECIMAL_STR_MAX(dev_t) + strlen("/../loop/")];
+        char s[SYS_BLOCK_PATH_MAX("/../loop/")];
         struct stat st;
 
         assert(path);
@@ -634,13 +669,13 @@ static int is_loop_device(const char *path) {
         if (!S_ISBLK(st.st_mode))
                 return -ENOTBLK;
 
-        xsprintf(s, "/sys/dev/block/%u:%u/loop/", major(st.st_rdev), minor(st.st_rdev));
+        xsprintf_sys_block_path(s, "/loop/", st.st_dev);
         if (access(s, F_OK) < 0) {
                 if (errno != ENOENT)
                         return -errno;
 
                 /* The device itself isn't a loop device, but maybe it's a partition and its parent is? */
-                xsprintf(s, "/sys/dev/block/%u:%u/../loop/", major(st.st_rdev), minor(st.st_rdev));
+                xsprintf_sys_block_path(s, "/../loop/", st.st_dev);
                 if (access(s, F_OK) < 0)
                         return errno == ENOENT ? false : -errno;
         }
@@ -652,10 +687,11 @@ static int mount_partition(
                 DissectedPartition *m,
                 const char *where,
                 const char *directory,
+                uid_t uid_shift,
                 DissectImageFlags flags) {
 
-        const char *p, *options = NULL, *node, *fstype;
-        _cleanup_free_ char *chased = NULL;
+        _cleanup_free_ char *chased = NULL, *options = NULL;
+        const char *p, *node, *fstype;
         bool rw;
         int r;
 
@@ -686,13 +722,26 @@ static int mount_partition(
         /* If requested, turn on discard support. */
         if (fstype_can_discard(fstype) &&
             ((flags & DISSECT_IMAGE_DISCARD) ||
-             ((flags & DISSECT_IMAGE_DISCARD_ON_LOOP) && is_loop_device(m->node))))
-                options = "discard";
+             ((flags & DISSECT_IMAGE_DISCARD_ON_LOOP) && is_loop_device(m->node)))) {
+                options = strdup("discard");
+                if (!options)
+                        return -ENOMEM;
+        }
+
+        if (uid_is_valid(uid_shift) && uid_shift != 0 && fstype_can_uid_gid(fstype)) {
+                _cleanup_free_ char *uid_option = NULL;
+
+                if (asprintf(&uid_option, "uid=" UID_FMT ",gid=" GID_FMT, uid_shift, (gid_t) uid_shift) < 0)
+                        return -ENOMEM;
+
+                if (!strextend_with_separator(&options, ",", uid_option, NULL))
+                        return -ENOMEM;
+        }
 
         return mount_verbose(LOG_DEBUG, node, p, fstype, MS_NODEV|(rw ? 0 : MS_RDONLY), options);
 }
 
-int dissected_image_mount(DissectedImage *m, const char *where, DissectImageFlags flags) {
+int dissected_image_mount(DissectedImage *m, const char *where, uid_t uid_shift, DissectImageFlags flags) {
         int r;
 
         assert(m);
@@ -701,15 +750,20 @@ int dissected_image_mount(DissectedImage *m, const char *where, DissectImageFlag
         if (!m->partitions[PARTITION_ROOT].found)
                 return -ENXIO;
 
-        r = mount_partition(m->partitions + PARTITION_ROOT, where, NULL, flags);
-        if (r < 0)
-                return r;
+        if ((flags & DISSECT_IMAGE_MOUNT_NON_ROOT_ONLY) == 0) {
+                r = mount_partition(m->partitions + PARTITION_ROOT, where, NULL, uid_shift, flags);
+                if (r < 0)
+                        return r;
+        }
+
+        if ((flags & DISSECT_IMAGE_MOUNT_ROOT_ONLY))
+                return 0;
 
-        r = mount_partition(m->partitions + PARTITION_HOME, where, "/home", flags);
+        r = mount_partition(m->partitions + PARTITION_HOME, where, "/home", uid_shift, flags);
         if (r < 0)
                 return r;
 
-        r = mount_partition(m->partitions + PARTITION_SRV, where, "/srv", flags);
+        r = mount_partition(m->partitions + PARTITION_SRV, where, "/srv", uid_shift, flags);
         if (r < 0)
                 return r;
 
@@ -727,7 +781,7 @@ int dissected_image_mount(DissectedImage *m, const char *where, DissectImageFlag
 
                         r = dir_is_empty(p);
                         if (r > 0) {
-                                r = mount_partition(m->partitions + PARTITION_ESP, where, mp, flags);
+                                r = mount_partition(m->partitions + PARTITION_ESP, where, mp, uid_shift, flags);
                                 if (r < 0)
                                         return r;
                         }
@@ -820,7 +874,7 @@ static int decrypt_partition(
                 DecryptedImage *d) {
 
         _cleanup_free_ char *node = NULL, *name = NULL;
-        struct crypt_device *cd;
+        _cleanup_(crypt_freep) struct crypt_device *cd = NULL;
         int r;
 
         assert(m);
@@ -832,6 +886,9 @@ static int decrypt_partition(
         if (!streq(m->fstype, "crypto_LUKS"))
                 return 0;
 
+        if (!passphrase)
+                return -ENOKEY;
+
         r = make_dm_name_and_node(m->node, "-decrypted", &name, &node);
         if (r < 0)
                 return r;
@@ -843,38 +900,29 @@ static int decrypt_partition(
         if (r < 0)
                 return log_debug_errno(r, "Failed to initialize dm-crypt: %m");
 
-        r = crypt_load(cd, CRYPT_LUKS1, NULL);
-        if (r < 0) {
-                log_debug_errno(r, "Failed to load LUKS metadata: %m");
-                goto fail;
-        }
+        r = crypt_load(cd, CRYPT_LUKS, NULL);
+        if (r < 0)
+                return log_debug_errno(r, "Failed to load LUKS metadata: %m");
 
         r = crypt_activate_by_passphrase(cd, name, CRYPT_ANY_SLOT, passphrase, strlen(passphrase),
                                          ((flags & DISSECT_IMAGE_READ_ONLY) ? CRYPT_ACTIVATE_READONLY : 0) |
                                          ((flags & DISSECT_IMAGE_DISCARD_ON_CRYPTO) ? CRYPT_ACTIVATE_ALLOW_DISCARDS : 0));
-        if (r < 0)
+        if (r < 0) {
                 log_debug_errno(r, "Failed to activate LUKS device: %m");
-        if (r == -EPERM) {
-                r = -EKEYREJECTED;
-                goto fail;
+                return r == -EPERM ? -EKEYREJECTED : r;
         }
-        if (r < 0)
-                goto fail;
 
         d->decrypted[d->n_decrypted].name = name;
         name = NULL;
 
         d->decrypted[d->n_decrypted].device = cd;
+        cd = NULL;
         d->n_decrypted++;
 
         m->decrypted_node = node;
         node = NULL;
 
         return 0;
-
-fail:
-        crypt_free(cd);
-        return r;
 }
 
 static int verity_partition(
@@ -886,7 +934,7 @@ static int verity_partition(
                 DecryptedImage *d) {
 
         _cleanup_free_ char *node = NULL, *name = NULL;
-        struct crypt_device *cd;
+        _cleanup_(crypt_freep) struct crypt_device *cd = NULL;
         int r;
 
         assert(m);
@@ -916,30 +964,27 @@ static int verity_partition(
 
         r = crypt_load(cd, CRYPT_VERITY, NULL);
         if (r < 0)
-                goto fail;
+                return r;
 
         r = crypt_set_data_device(cd, m->node);
         if (r < 0)
-                goto fail;
+                return r;
 
         r = crypt_activate_by_volume_key(cd, name, root_hash, root_hash_size, CRYPT_ACTIVATE_READONLY);
         if (r < 0)
-                goto fail;
+                return r;
 
         d->decrypted[d->n_decrypted].name = name;
         name = NULL;
 
         d->decrypted[d->n_decrypted].device = cd;
+        cd = NULL;
         d->n_decrypted++;
 
         m->decrypted_node = node;
         node = NULL;
 
         return 0;
-
-fail:
-        crypt_free(cd);
-        return r;
 }
 #endif
 
@@ -951,8 +996,8 @@ int dissected_image_decrypt(
                 DissectImageFlags flags,
                 DecryptedImage **ret) {
 
-        _cleanup_(decrypted_image_unrefp) DecryptedImage *d = NULL;
 #if HAVE_LIBCRYPTSETUP
+        _cleanup_(decrypted_image_unrefp) DecryptedImage *d = NULL;
         unsigned i;
         int r;
 #endif
@@ -977,9 +1022,6 @@ int dissected_image_decrypt(
         }
 
 #if HAVE_LIBCRYPTSETUP
-        if (m->encrypted && !passphrase)
-                return -ENOKEY;
-
         d = new0(DecryptedImage, 1);
         if (!d)
                 return -ENOMEM;
@@ -1004,7 +1046,7 @@ int dissected_image_decrypt(
 
                 if (!p->decrypted_fstype && p->decrypted_node) {
                         r = probe_filesystem(p->decrypted_node, &p->decrypted_fstype);
-                        if (r < 0)
+                        if (r < 0 && r != -EUCLEAN)
                                 return r;
                 }
         }
@@ -1144,7 +1186,7 @@ int root_hash_load(const char *image, void **ret, size_t *ret_size) {
                 if (!IN_SET(r, -ENODATA, -EOPNOTSUPP, -ENOENT))
                         return r;
 
-                fn = newa(char, strlen(image) + strlen(".roothash") + 1);
+                fn = newa(char, strlen(image) + STRLEN(".roothash") + 1);
                 n = stpcpy(fn, image);
                 e = endswith(fn, ".raw");
                 if (e)
@@ -1176,6 +1218,174 @@ int root_hash_load(const char *image, void **ret, size_t *ret_size) {
         return 1;
 }
 
+int dissected_image_acquire_metadata(DissectedImage *m) {
+
+        enum {
+                META_HOSTNAME,
+                META_MACHINE_ID,
+                META_MACHINE_INFO,
+                META_OS_RELEASE,
+                _META_MAX,
+        };
+
+        static const char *const paths[_META_MAX] = {
+                [META_HOSTNAME]     = "/etc/hostname\0",
+                [META_MACHINE_ID]   = "/etc/machine-id\0",
+                [META_MACHINE_INFO] = "/etc/machine-info\0",
+                [META_OS_RELEASE]   = "/etc/os-release\0/usr/lib/os-release\0",
+        };
+
+        _cleanup_strv_free_ char **machine_info = NULL, **os_release = NULL;
+        _cleanup_(rmdir_and_freep) char *t = NULL;
+        _cleanup_(sigkill_waitp) pid_t child = 0;
+        sd_id128_t machine_id = SD_ID128_NULL;
+        _cleanup_free_ char *hostname = NULL;
+        unsigned n_meta_initialized = 0, k;
+        int fds[2 * _META_MAX], r;
+        siginfo_t si;
+
+        BLOCK_SIGNALS(SIGCHLD);
+
+        assert(m);
+
+        for (; n_meta_initialized < _META_MAX; n_meta_initialized ++)
+                if (pipe2(fds + 2*n_meta_initialized, O_CLOEXEC) < 0) {
+                        r = -errno;
+                        goto finish;
+                }
+
+        r = mkdtemp_malloc("/tmp/dissect-XXXXXX", &t);
+        if (r < 0)
+                goto finish;
+
+        child = raw_clone(SIGCHLD|CLONE_NEWNS);
+        if (child < 0) {
+                r = -errno;
+                goto finish;
+        }
+
+        if (child == 0) {
+
+                (void) reset_all_signal_handlers();
+                (void) reset_signal_mask();
+                assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
+
+                /* Make sure we never propagate to the host */
+                if (mount(NULL, "/", NULL, MS_SLAVE | MS_REC, NULL) < 0)
+                        _exit(EXIT_FAILURE);
+
+                r = dissected_image_mount(m, t, UID_INVALID, DISSECT_IMAGE_READ_ONLY);
+                if (r < 0)
+                        _exit(EXIT_FAILURE);
+
+                for (k = 0; k < _META_MAX; k++) {
+                        _cleanup_close_ int fd = -1;
+                        const char *p;
+
+                        fds[2*k] = safe_close(fds[2*k]);
+
+                        NULSTR_FOREACH(p, paths[k]) {
+                                _cleanup_free_ char *q = NULL;
+
+                                r = chase_symlinks(p, t, CHASE_PREFIX_ROOT, &q);
+                                if (r < 0)
+                                        continue;
+
+                                fd = open(q, O_RDONLY|O_CLOEXEC|O_NOCTTY);
+                                if (fd >= 0)
+                                        break;
+                        }
+                        if (fd < 0)
+                                continue;
+
+                        r = copy_bytes(fd, fds[2*k+1], (uint64_t) -1, 0);
+                        if (r < 0)
+                                _exit(EXIT_FAILURE);
+
+                        fds[2*k+1] = safe_close(fds[2*k+1]);
+                }
+
+                _exit(EXIT_SUCCESS);
+        }
+
+        for (k = 0; k < _META_MAX; k++) {
+                _cleanup_fclose_ FILE *f = NULL;
+
+                fds[2*k+1] = safe_close(fds[2*k+1]);
+
+                f = fdopen(fds[2*k], "re");
+                if (!f) {
+                        r = -errno;
+                        goto finish;
+                }
+
+                fds[2*k] = -1;
+
+                switch (k) {
+
+                case META_HOSTNAME:
+                        r = read_etc_hostname_stream(f, &hostname);
+                        if (r < 0)
+                                log_debug_errno(r, "Failed to read /etc/hostname: %m");
+
+                        break;
+
+                case META_MACHINE_ID: {
+                        _cleanup_free_ char *line = NULL;
+
+                        r = read_line(f, LONG_LINE_MAX, &line);
+                        if (r < 0)
+                                log_debug_errno(r, "Failed to read /etc/machine-id: %m");
+                        else if (r == 33) {
+                                r = sd_id128_from_string(line, &machine_id);
+                                if (r < 0)
+                                        log_debug_errno(r, "Image contains invalid /etc/machine-id: %s", line);
+                        } else if (r == 0)
+                                log_debug("/etc/machine-id file is empty.");
+                        else
+                                log_debug("/etc/machine-id has unexpected length %i.", r);
+
+                        break;
+                }
+
+                case META_MACHINE_INFO:
+                        r = load_env_file_pairs(f, "machine-info", NULL, &machine_info);
+                        if (r < 0)
+                                log_debug_errno(r, "Failed to read /etc/machine-info: %m");
+
+                        break;
+
+                case META_OS_RELEASE:
+                        r = load_env_file_pairs(f, "os-release", NULL, &os_release);
+                        if (r < 0)
+                                log_debug_errno(r, "Failed to read OS release file: %m");
+
+                        break;
+                }
+        }
+
+        r = wait_for_terminate(child, &si);
+        if (r < 0)
+                goto finish;
+        child = 0;
+
+        if (si.si_code != CLD_EXITED || si.si_status != EXIT_SUCCESS) {
+                r = -EPROTO;
+                goto finish;
+        }
+
+        free_and_replace(m->hostname, hostname);
+        m->machine_id = machine_id;
+        strv_free_and_replace(m->machine_info, machine_info);
+        strv_free_and_replace(m->os_release, os_release);
+
+finish:
+        for (k = 0; k < n_meta_initialized; k++)
+                safe_close_pair(fds + 2*k);
+
+        return r;
+}
+
 static const char *const partition_designator_table[] = {
         [PARTITION_ROOT] = "root",
         [PARTITION_ROOT_SECONDARY] = "root-secondary",
index cdb083b..53a1554 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -61,24 +62,33 @@ static inline int PARTITION_VERITY_OF(int p) {
 }
 
 typedef enum DissectImageFlags {
-        DISSECT_IMAGE_READ_ONLY = 1,
-        DISSECT_IMAGE_DISCARD_ON_LOOP = 2,   /* Turn on "discard" if on a loop device and file system supports it */
-        DISSECT_IMAGE_DISCARD = 4,           /* Turn on "discard" if file system supports it, on all block devices */
-        DISSECT_IMAGE_DISCARD_ON_CRYPTO = 8, /* Turn on "discard" also on crypto devices */
+        DISSECT_IMAGE_READ_ONLY           = 1 << 0,
+        DISSECT_IMAGE_DISCARD_ON_LOOP     = 1 << 1,  /* Turn on "discard" if on a loop device and file system supports it */
+        DISSECT_IMAGE_DISCARD             = 1 << 2,  /* Turn on "discard" if file system supports it, on all block devices */
+        DISSECT_IMAGE_DISCARD_ON_CRYPTO   = 1 << 3,  /* Turn on "discard" also on crypto devices */
         DISSECT_IMAGE_DISCARD_ANY = DISSECT_IMAGE_DISCARD_ON_LOOP |
                                     DISSECT_IMAGE_DISCARD |
                                     DISSECT_IMAGE_DISCARD_ON_CRYPTO,
-        DISSECT_IMAGE_GPT_ONLY = 16,         /* Only recognize images with GPT partition tables */
-        DISSECT_IMAGE_REQUIRE_ROOT = 32,     /* Don't accept disks without root partition */
+        DISSECT_IMAGE_GPT_ONLY            = 1 << 4,  /* Only recognize images with GPT partition tables */
+        DISSECT_IMAGE_REQUIRE_ROOT        = 1 << 5,  /* Don't accept disks without root partition */
+        DISSECT_IMAGE_MOUNT_ROOT_ONLY     = 1 << 6,  /* Mount only the root partition */
+        DISSECT_IMAGE_MOUNT_NON_ROOT_ONLY = 1 << 7,  /* Mount only non-root partitions */
 } DissectImageFlags;
 
 struct DissectedImage {
         bool encrypted:1;
         bool verity:1;     /* verity available and usable */
         bool can_verity:1; /* verity available, but not necessarily used */
+
         DissectedPartition partitions[_PARTITION_DESIGNATOR_MAX];
+
+        char *hostname;
+        sd_id128_t machine_id;
+        char **machine_info;
+        char **os_release;
 };
 
+int probe_filesystem(const char *node, char **ret_fstype);
 int dissect_image(int fd, const void *root_hash, size_t root_hash_size, DissectImageFlags flags, DissectedImage **ret);
 
 DissectedImage* dissected_image_unref(DissectedImage *m);
@@ -86,7 +96,9 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(DissectedImage*, dissected_image_unref);
 
 int dissected_image_decrypt(DissectedImage *m, const char *passphrase, const void *root_hash, size_t root_hash_size, DissectImageFlags flags, DecryptedImage **ret);
 int dissected_image_decrypt_interactively(DissectedImage *m, const char *passphrase, const void *root_hash, size_t root_hash_size, DissectImageFlags flags, DecryptedImage **ret);
-int dissected_image_mount(DissectedImage *m, const char *dest, DissectImageFlags flags);
+int dissected_image_mount(DissectedImage *m, const char *dest, uid_t uid_shift, DissectImageFlags flags);
+
+int dissected_image_acquire_metadata(DissectedImage *m);
 
 DecryptedImage* decrypted_image_unref(DecryptedImage *p);
 DEFINE_TRIVIAL_CLEANUP_FUNC(DecryptedImage*, decrypted_image_unref);
index 4739cc8..8c807e0 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -692,23 +693,26 @@ int dns_name_change_suffix(const char *name, const char *old_suffix, const char
 }
 
 int dns_name_between(const char *a, const char *b, const char *c) {
-        int n;
-
         /* Determine if b is strictly greater than a and strictly smaller than c.
            We consider the order of names to be circular, so that if a is
            strictly greater than c, we consider b to be between them if it is
            either greater than a or smaller than c. This is how the canonical
            DNS name order used in NSEC records work. */
 
-        n = dns_name_compare_func(a, c);
-        if (n == 0)
-                return -EINVAL;
-        else if (n < 0)
-                /*       a<---b--->c       */
+        if (dns_name_compare_func(a, c) < 0)
+                /*
+                   a and c are properly ordered:
+                   a<---b--->c
+                */
                 return dns_name_compare_func(a, b) < 0 &&
                        dns_name_compare_func(b, c) < 0;
         else
-                /* <--b--c         a--b--> */
+                /*
+                   a and c are equal or 'reversed':
+                   <--b--c         a----->
+                   or:
+                   <-----c         a--b-->
+                */
                 return dns_name_compare_func(b, c) < 0 ||
                        dns_name_compare_func(a, b) < 0;
 }
@@ -958,6 +962,12 @@ bool dns_srv_type_is_valid(const char *name) {
         return c == 2; /* exactly two labels */
 }
 
+bool dnssd_srv_type_is_valid(const char *name) {
+        return dns_srv_type_is_valid(name) &&
+                ((dns_name_endswith(name, "_tcp") > 0) ||
+                 (dns_name_endswith(name, "_udp") > 0)); /* Specific to DNS-SD. RFC 6763, Section 7 */
+}
+
 bool dns_service_name_is_valid(const char *name) {
         size_t l;
 
index a44d9d4..cd3dbb7 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -95,6 +96,7 @@ bool dns_name_is_single_label(const char *name);
 int dns_name_to_wire_format(const char *domain, uint8_t *buffer, size_t len, bool canonical);
 
 bool dns_srv_type_is_valid(const char *name);
+bool dnssd_srv_type_is_valid(const char *name);
 bool dns_service_name_is_valid(const char *name);
 
 int dns_service_join(const char *name, const char *type, const char *domain, char **ret);
index 059b50d..f096687 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -127,7 +128,11 @@ static int unit_file_find_dir(
         assert(path);
 
         r = chase_symlinks(path, original_root, 0, &chased);
-        if (r == -ENOENT) /* Ignore -ENOENT, after all most units won't have a drop-in dir */
+        /* Ignore -ENOENT, after all most units won't have a drop-in dir.
+         * Also ignore -ENAMETOOLONG, users are not even able to create
+         * the drop-in dir in such case. This mostly happens for device units with long /sys path.
+         * */
+        if (IN_SET(r, -ENOENT, -ENAMETOOLONG))
                 return 0;
         if (r < 0)
                 return log_full_errno(LOG_WARNING, r, "Failed to canonicalize path %s: %m", path);
index a2b8cdc..102fc94 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index a3850be..9ca51cf 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -84,10 +85,10 @@ bool is_efi_boot(void) {
 }
 
 static int read_flag(const char *varname) {
-        int r;
         _cleanup_free_ void *v = NULL;
-        size_t s;
         uint8_t b;
+        size_t s;
+        int r;
 
         r = efi_get_variable(EFI_VENDOR_GLOBAL, varname, NULL, &v, &s);
         if (r < 0)
@@ -97,8 +98,7 @@ static int read_flag(const char *varname) {
                 return -EINVAL;
 
         b = *(uint8_t *)v;
-        r = b > 0;
-        return r;
+        return b > 0;
 }
 
 bool is_efi_secure_boot(void) {
@@ -110,29 +110,33 @@ bool is_efi_secure_boot_setup_mode(void) {
 }
 
 int efi_reboot_to_firmware_supported(void) {
-        int r;
-        size_t s;
-        uint64_t b;
         _cleanup_free_ void *v = NULL;
+        uint64_t b;
+        size_t s;
+        int r;
 
         if (!is_efi_boot() || detect_container() > 0)
                 return -EOPNOTSUPP;
 
         r = efi_get_variable(EFI_VENDOR_GLOBAL, "OsIndicationsSupported", NULL, &v, &s);
+        if (r == -ENOENT) /* variable doesn't exist? it's not supported then */
+                return -EOPNOTSUPP;
         if (r < 0)
                 return r;
-        else if (s != sizeof(uint64_t))
+        if (s != sizeof(uint64_t))
                 return -EINVAL;
 
-        b = *(uint64_t *)v;
-        b &= EFI_OS_INDICATIONS_BOOT_TO_FW_UI;
-        return b > 0 ? 0 : -EOPNOTSUPP;
+        b = *(uint64_t*) v;
+        if (!(b & EFI_OS_INDICATIONS_BOOT_TO_FW_UI))
+                return -EOPNOTSUPP; /* bit unset? it's not supported then */
+
+        return 0;
 }
 
 static int get_os_indications(uint64_t *os_indication) {
-        int r;
-        size_t s;
         _cleanup_free_ void *v = NULL;
+        size_t s;
+        int r;
 
         r = efi_reboot_to_firmware_supported();
         if (r < 0)
index 72bace0..9a4880d 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 090f3fd..9ce1295 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 16efe5b..864ab67 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 6d295ea..a685946 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -77,7 +78,8 @@ static int entry_fill_basics(
 
         if (out_interface) {
                 size_t l = strlen(out_interface);
-                assert(l < sizeof entry->ip.outiface && l < sizeof entry->ip.outiface_mask);
+                assert(l < sizeof entry->ip.outiface);
+                assert(l < sizeof entry->ip.outiface_mask);
 
                 strcpy(entry->ip.outiface, out_interface);
                 memset(entry->ip.outiface_mask, 0xFF, l + 1);
index 5915266..fd7e3b4 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index ec2e868..bcd7b43 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index bbf0441..87f82dc 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index e10a38d..1bfb776 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
 
 /***
index f08ed60..69faf08 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
 
 /***
index 18fc469..3495a7e 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -32,6 +33,7 @@
 #include "mkdir.h"
 #include "path-util.h"
 #include "special.h"
+#include "specifier.h"
 #include "string-util.h"
 #include "time-util.h"
 #include "unit-name.h"
@@ -54,15 +56,19 @@ int generator_add_symlink(const char *root, const char *dst, const char *dep_typ
 }
 
 static int write_fsck_sysroot_service(const char *dir, const char *what) {
-        _cleanup_free_ char *device = NULL, *escaped = NULL;
+        _cleanup_free_ char *device = NULL, *escaped = NULL, *escaped2 = NULL;
         _cleanup_fclose_ FILE *f = NULL;
         const char *unit;
         int r;
 
-        escaped = cescape(what);
+        escaped = specifier_escape(what);
         if (!escaped)
                 return log_oom();
 
+        escaped2 = cescape(escaped);
+        if (!escaped2)
+                return log_oom();
+
         unit = strjoina(dir, "/systemd-fsck-root.service");
         log_debug("Creating %s", unit);
 
@@ -77,8 +83,8 @@ static int write_fsck_sysroot_service(const char *dir, const char *what) {
         fprintf(f,
                 "# Automatically generated by %1$s\n\n"
                 "[Unit]\n"
-                "Documentation=man:systemd-fsck-root.service(8)\n"
                 "Description=File System Check on %2$s\n"
+                "Documentation=man:systemd-fsck-root.service(8)\n"
                 "DefaultDependencies=no\n"
                 "BindsTo=%3$s\n"
                 "After=initrd-root-device.target local-fs-pre.target %3$s\n"
@@ -90,9 +96,9 @@ static int write_fsck_sysroot_service(const char *dir, const char *what) {
                 "ExecStart=" SYSTEMD_FSCK_PATH " %4$s\n"
                 "TimeoutSec=0\n",
                 program_invocation_short_name,
-                what,
+                escaped,
                 device,
-                escaped);
+                escaped2);
 
         r = fflush_and_check(f);
         if (r < 0)
@@ -242,7 +248,8 @@ int generator_write_device_deps(
 
         r = unit_name_from_path(node, ".device", &unit);
         if (r < 0)
-                return log_error_errno(r, "Failed to make unit name from path: %m");
+                return log_error_errno(r, "Failed to make unit name from path \"%s\": %m",
+                                       node);
 
         /* See mount_add_default_dependencies for explanation why we create such
          * dependencies. */
@@ -260,7 +267,8 @@ int generator_write_initrd_root_device_deps(const char *dir, const char *what) {
 
         r = unit_name_from_path(what, ".device", &unit);
         if (r < 0)
-                return log_error_errno(r, "Failed to make unit name from path: %m");
+                return log_error_errno(r, "Failed to make unit name from path \"%s\": %m",
+                                       what);
 
         return write_drop_in_format(dir, SPECIAL_INITRD_ROOT_DEVICE_TARGET, 50, "root-device",
                                     "# Automatically generated by %s\n\n"
@@ -271,3 +279,206 @@ int generator_write_initrd_root_device_deps(const char *dir, const char *what) {
                                     unit,
                                     unit);
 }
+
+int generator_hook_up_mkswap(
+                const char *dir,
+                const char *what) {
+
+        _cleanup_free_ char *node = NULL, *unit = NULL, *escaped = NULL, *where_unit = NULL;
+        _cleanup_fclose_ FILE *f = NULL;
+        const char *unit_file;
+        int r;
+
+        node = fstab_node_to_udev_node(what);
+        if (!node)
+                return log_oom();
+
+        /* Nothing to work on. */
+        if (!is_device_path(node)) {
+                log_error("Cannot format something that is not a device node: %s", node);
+                return -EINVAL;
+        }
+
+        r = unit_name_from_path_instance("systemd-mkswap", node, ".service", &unit);
+        if (r < 0)
+                return log_error_errno(r, "Failed to make unit instance name from path \"%s\": %m",
+                                       node);
+
+        unit_file = strjoina(dir, "/", unit);
+        log_debug("Creating %s", unit_file);
+
+        escaped = cescape(node);
+        if (!escaped)
+                return log_oom();
+
+        r = unit_name_from_path(what, ".swap", &where_unit);
+        if (r < 0)
+                return log_error_errno(r, "Failed to make unit name from path \"%s\": %m",
+                                       what);
+
+        f = fopen(unit_file, "wxe");
+        if (!f)
+                return log_error_errno(errno, "Failed to create unit file %s: %m",
+                                       unit_file);
+
+        fprintf(f,
+                "# Automatically generated by %s\n\n"
+                "[Unit]\n"
+                "Description=Make Swap on %%f\n"
+                "Documentation=man:systemd-mkswap@.service(8)\n"
+                "DefaultDependencies=no\n"
+                "BindsTo=%%i.device\n"
+                "After=%%i.device\n"
+                "Before=%s\n"
+                "Before=shutdown.target\n"
+                "\n"
+                "[Service]\n"
+                "Type=oneshot\n"
+                "RemainAfterExit=yes\n"
+                "ExecStart="SYSTEMD_MAKEFS_PATH " swap %s\n"
+                "TimeoutSec=0\n",
+                program_invocation_short_name,
+                where_unit,
+                escaped);
+
+        r = fflush_and_check(f);
+        if (r < 0)
+                return log_error_errno(r, "Failed to write unit file %s: %m", unit_file);
+
+        return generator_add_symlink(dir, where_unit, "requires", unit);
+}
+
+int generator_hook_up_mkfs(
+                const char *dir,
+                const char *what,
+                const char *where,
+                const char *type) {
+
+        _cleanup_free_ char *node = NULL, *unit = NULL, *escaped = NULL, *where_unit = NULL;
+        _cleanup_fclose_ FILE *f = NULL;
+        const char *unit_file;
+        int r;
+
+        node = fstab_node_to_udev_node(what);
+        if (!node)
+                return log_oom();
+
+        /* Nothing to work on. */
+        if (!is_device_path(node)) {
+                log_error("Cannot format something that is not a device node: %s", node);
+                return -EINVAL;
+        }
+
+        if (!type || streq(type, "auto")) {
+                log_error("Cannot format partition %s, filesystem type is not specified", node);
+                return -EINVAL;
+        }
+
+        r = unit_name_from_path_instance("systemd-mkfs", node, ".service", &unit);
+        if (r < 0)
+                return log_error_errno(r, "Failed to make unit instance name from path \"%s\": %m",
+                                       node);
+
+        unit_file = strjoina(dir, "/", unit);
+        log_debug("Creating %s", unit_file);
+
+        escaped = cescape(node);
+        if (!escaped)
+                return log_oom();
+
+        r = unit_name_from_path(where, ".mount", &where_unit);
+        if (r < 0)
+                return log_error_errno(r, "Failed to make unit name from path \"%s\": %m",
+                                       where);
+
+        f = fopen(unit_file, "wxe");
+        if (!f)
+                return log_error_errno(errno, "Failed to create unit file %s: %m",
+                                       unit_file);
+
+        fprintf(f,
+                "# Automatically generated by %s\n\n"
+                "[Unit]\n"
+                "Description=Make File System on %%f\n"
+                "Documentation=man:systemd-mkfs@.service(8)\n"
+                "DefaultDependencies=no\n"
+                "BindsTo=%%i.device\n"
+                "After=%%i.device\n"
+                /* fsck might or might not be used, so let's be safe and order
+                 * ourselves before both systemd-fsck@.service and the mount unit. */
+                "Before=systemd-fsck@%%i.service\n"
+                "Before=%s\n"
+                "Before=shutdown.target\n"
+                "\n"
+                "[Service]\n"
+                "Type=oneshot\n"
+                "RemainAfterExit=yes\n"
+                "ExecStart="SYSTEMD_MAKEFS_PATH " %s %s\n"
+                "TimeoutSec=0\n",
+                program_invocation_short_name,
+                where_unit,
+                type,
+                escaped);
+        // XXX: what about local-fs-pre.target?
+
+        r = fflush_and_check(f);
+        if (r < 0)
+                return log_error_errno(r, "Failed to write unit file %s: %m", unit_file);
+
+        return generator_add_symlink(dir, where_unit, "requires", unit);
+}
+
+int generator_hook_up_growfs(
+                const char *dir,
+                const char *where,
+                const char *target) {
+
+        _cleanup_free_ char *unit = NULL, *escaped = NULL, *where_unit = NULL;
+        _cleanup_fclose_ FILE *f = NULL;
+        const char *unit_file;
+        int r;
+
+        escaped = cescape(where);
+        if (!escaped)
+                return log_oom();
+
+        r = unit_name_from_path_instance("systemd-growfs", where, ".service", &unit);
+        if (r < 0)
+                return log_error_errno(r, "Failed to make unit instance name from path \"%s\": %m",
+                                       where);
+
+        r = unit_name_from_path(where, ".mount", &where_unit);
+        if (r < 0)
+                return log_error_errno(r, "Failed to make unit name from path \"%s\": %m",
+                                       where);
+
+        unit_file = strjoina(dir, "/", unit);
+        log_debug("Creating %s", unit_file);
+
+        f = fopen(unit_file, "wxe");
+        if (!f)
+                return log_error_errno(errno, "Failed to create unit file %s: %m",
+                                       unit_file);
+
+        fprintf(f,
+                "# Automatically generated by %s\n\n"
+                "[Unit]\n"
+                "Description=Grow File System on %%f\n"
+                "Documentation=man:systemd-growfs@.service(8)\n"
+                "DefaultDependencies=no\n"
+                "BindsTo=%%i.mount\n"
+                "After=%%i.mount\n"
+                "Before=shutdown.target\n"
+                "Before=%s\n"
+                "\n"
+                "[Service]\n"
+                "Type=oneshot\n"
+                "RemainAfterExit=yes\n"
+                "ExecStart="SYSTEMD_GROWFS_PATH " %s\n"
+                "TimeoutSec=0\n",
+                program_invocation_short_name,
+                target,
+                escaped);
+
+        return generator_add_symlink(dir, where_unit, "wants", unit);
+}
index e700168..32d1ad0 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -38,11 +39,24 @@ int generator_write_timeouts(
         char **filtered);
 
 int generator_write_device_deps(
-                const char *dir,
-                const char *what,
-                const char *where,
-                const char *opts);
+        const char *dir,
+        const char *what,
+        const char *where,
+        const char *opts);
 
 int generator_write_initrd_root_device_deps(
         const char *dir,
         const char *what);
+
+int generator_hook_up_mkswap(
+        const char *dir,
+        const char *what);
+int generator_hook_up_mkfs(
+        const char *dir,
+        const char *what,
+        const char *where,
+        const char *type);
+int generator_hook_up_growfs(
+        const char *dir,
+        const char *where,
+        const char *target);
index cc75200..7589f6f 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 789064d..064f38b 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 5be9476..5633c78 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index ab701ad..07ba216 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 77b17d9..583845b 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index c10ed3d..aaab2e6 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -93,7 +94,7 @@ static int specifier_instance(char specifier, void *data, void *userdata, char *
                 return r;
 
         if (isempty(instance)) {
-                r = free_and_strdup(&instance, i->default_instance ?: "");
+                r = free_and_strdup(&instance, strempty(i->default_instance));
                 if (r < 0)
                         return r;
         }
@@ -102,34 +103,6 @@ static int specifier_instance(char specifier, void *data, void *userdata, char *
         return 0;
 }
 
-static int specifier_user_name(char specifier, void *data, void *userdata, char **ret) {
-        char *t;
-
-        /* If we are UID 0 (root), this will not result in NSS,
-         * otherwise it might. This is good, as we want to be able to
-         * run this in PID 1, where our user ID is 0, but where NSS
-         * lookups are not allowed.
-
-         * We don't user getusername_malloc() here, because we don't want to look
-         * at $USER, to remain consistent with specifer_user_id() below.
-         */
-
-        t = uid_to_name(getuid());
-        if (!t)
-                return -ENOMEM;
-
-        *ret = t;
-        return 0;
-}
-
-static int specifier_user_id(char specifier, void *data, void *userdata, char **ret) {
-
-        if (asprintf(ret, UID_FMT, getuid()) < 0)
-                return -ENOMEM;
-
-        return 0;
-}
-
 int install_full_printf(UnitFileInstallInfo *i, const char *format, char **ret) {
 
         /* This is similar to unit_full_printf() but does not support
index 8a570fc..d868f65 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 7598bf6..05ccc58 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -991,23 +992,11 @@ static void install_info_free(UnitFileInstallInfo *i) {
         free(i);
 }
 
-static OrderedHashmap* install_info_hashmap_free(OrderedHashmap *m) {
-        UnitFileInstallInfo *i;
-
-        if (!m)
-                return NULL;
-
-        while ((i = ordered_hashmap_steal_first(m)))
-                install_info_free(i);
-
-        return ordered_hashmap_free(m);
-}
-
 static void install_context_done(InstallContext *c) {
         assert(c);
 
-        c->will_process = install_info_hashmap_free(c->will_process);
-        c->have_processed = install_info_hashmap_free(c->have_processed);
+        c->will_process = ordered_hashmap_free_with_destructor(c->will_process, install_info_free);
+        c->have_processed = ordered_hashmap_free_with_destructor(c->have_processed, install_info_free);
 }
 
 static UnitFileInstallInfo *install_info_find(InstallContext *c, const char *name) {
@@ -1128,15 +1117,14 @@ static int config_parse_alias(
                 void *data,
                 void *userdata) {
 
-        const char *name;
         UnitType type;
 
+        assert(unit);
         assert(filename);
         assert(lvalue);
         assert(rvalue);
 
-        name = basename(filename);
-        type = unit_name_to_type(name);
+        type = unit_name_to_type(unit);
         if (!unit_type_may_alias(type))
                 return log_syntax(unit, LOG_WARNING, filename, line, 0,
                                   "Alias= is not allowed for %s units, ignoring.",
@@ -1162,6 +1150,7 @@ static int config_parse_also(
         InstallContext *c = data;
         int r;
 
+        assert(unit);
         assert(filename);
         assert(lvalue);
         assert(rvalue);
@@ -1209,20 +1198,19 @@ static int config_parse_default_instance(
                 void *userdata) {
 
         UnitFileInstallInfo *i = data;
-        const char *name;
         _cleanup_free_ char *printed = NULL;
         int r;
 
+        assert(unit);
         assert(filename);
         assert(lvalue);
         assert(rvalue);
 
-        name = basename(filename);
-        if (unit_name_is_valid(name, UNIT_NAME_INSTANCE))
+        if (unit_name_is_valid(unit, UNIT_NAME_INSTANCE))
                 /* When enabling an instance, we might be using a template unit file,
                  * but we should ignore DefaultInstance silently. */
                 return 0;
-        if (!unit_name_is_valid(name, UNIT_NAME_TEMPLATE))
+        if (!unit_name_is_valid(unit, UNIT_NAME_TEMPLATE))
                 return log_syntax(unit, LOG_WARNING, filename, line, 0,
                                   "DefaultInstance= only makes sense for template units, ignoring.");
 
@@ -1251,7 +1239,6 @@ static int unit_file_load(
                 {}
         };
 
-        const char *name;
         UnitType type;
         _cleanup_fclose_ FILE *f = NULL;
         _cleanup_close_ int fd = -1;
@@ -1261,9 +1248,8 @@ static int unit_file_load(
         assert(info);
         assert(path);
 
-        name = basename(path);
-        type = unit_name_to_type(name);
-        if (unit_name_is_valid(name, UNIT_NAME_TEMPLATE|UNIT_NAME_INSTANCE) &&
+        type = unit_name_to_type(info->name);
+        if (unit_name_is_valid(info->name, UNIT_NAME_TEMPLATE|UNIT_NAME_INSTANCE) &&
             !unit_type_may_template(type))
                 return log_error_errno(EINVAL, "Unit type %s cannot be templated.", unit_type_to_string(type));
 
@@ -1308,10 +1294,10 @@ static int unit_file_load(
                 return -errno;
         fd = -1;
 
-        r = config_parse(NULL, path, f,
+        r = config_parse(info->name, path, f,
                          NULL,
                          config_item_table_lookup, items,
-                         true, true, false, info);
+                         CONFIG_PARSE_RELAXED|CONFIG_PARSE_ALLOW_INCLUDE, info);
         if (r < 0)
                 return log_debug_errno(r, "Failed to parse %s: %m", info->name);
 
@@ -1398,8 +1384,15 @@ static int unit_file_search(
                 SearchFlags flags) {
 
         _cleanup_free_ char *template = NULL;
+        _cleanup_strv_free_ char **dirs = NULL;
+        _cleanup_strv_free_ char **files = NULL;
+        const char *dropin_dir_name = NULL;
+        const char *dropin_template_dir_name = NULL;
+
         char **p;
         int r;
+        int result;
+        bool found_unit = false;
 
         assert(info);
         assert(paths);
@@ -1413,6 +1406,12 @@ static int unit_file_search(
 
         assert(info->name);
 
+        if (unit_name_is_valid(info->name, UNIT_NAME_INSTANCE)) {
+                r = unit_name_template(info->name, &template);
+                if (r < 0)
+                        return r;
+        }
+
         STRV_FOREACH(p, paths->search_path) {
                 _cleanup_free_ char *path = NULL;
 
@@ -1421,23 +1420,23 @@ static int unit_file_search(
                         return -ENOMEM;
 
                 r = unit_file_load_or_readlink(c, info, path, paths->root_dir, flags);
+
                 if (r >= 0) {
                         info->path = path;
                         path = NULL;
-                        return r;
+                        result = r;
+                        found_unit = true;
+                        break;
                 } else if (!IN_SET(r, -ENOENT, -ENOTDIR, -EACCES))
                         return r;
         }
 
-        if (unit_name_is_valid(info->name, UNIT_NAME_INSTANCE)) {
+        if (!found_unit && template) {
+
                 /* Unit file doesn't exist, however instance
                  * enablement was requested.  We will check if it is
                  * possible to load template unit file. */
 
-                r = unit_name_template(info->name, &template);
-                if (r < 0)
-                        return r;
-
                 STRV_FOREACH(p, paths->search_path) {
                         _cleanup_free_ char *path = NULL;
 
@@ -1449,14 +1448,62 @@ static int unit_file_search(
                         if (r >= 0) {
                                 info->path = path;
                                 path = NULL;
-                                return r;
+                                result = r;
+                                found_unit = true;
+                                break;
                         } else if (!IN_SET(r, -ENOENT, -ENOTDIR, -EACCES))
                                 return r;
                 }
         }
 
-        log_debug("Cannot find unit %s%s%s.", info->name, template ? " or " : "", strempty(template));
-        return -ENOENT;
+        if (!found_unit) {
+                log_debug("Cannot find unit %s%s%s.", info->name, template ? " or " : "", strempty(template));
+                return -ENOENT;
+        }
+
+        /* Search for drop-in directories */
+
+        dropin_dir_name = strjoina(info->name, ".d");
+        STRV_FOREACH(p, paths->search_path) {
+                char *path;
+
+                path = path_join(NULL, *p, dropin_dir_name);
+                if (!path)
+                        return -ENOMEM;
+
+                r = strv_consume(&dirs, path);
+                if (r < 0)
+                        return r;
+        }
+
+        if (template) {
+                dropin_template_dir_name = strjoina(template, ".d");
+                STRV_FOREACH(p, paths->search_path) {
+                        char *path;
+
+                        path = path_join(NULL, *p, dropin_template_dir_name);
+                        if (!path)
+                                return -ENOMEM;
+
+                        r = strv_consume(&dirs, path);
+                        if (r < 0)
+                                return r;
+                }
+        }
+
+        /* Load drop-in conf files */
+
+        r = conf_files_list_strv(&files, ".conf", NULL, 0, (const char**) dirs);
+        if (r < 0)
+                return log_debug_errno(r, "Failed to get list of conf files: %m");
+
+        STRV_FOREACH(p, files) {
+                r = unit_file_load_or_readlink(c, info, *p, paths->root_dir, flags);
+                if (r < 0)
+                        return log_debug_errno(r, "Failed to load conf file %s: %m", *p);
+        }
+
+        return result;
 }
 
 static int install_info_follow(
@@ -2937,7 +2984,7 @@ static int preset_prepare_one(
         if (r < 0)
                 return r;
         if (!streq(name, i->name)) {
-                log_debug("Skipping %s because is an alias for %s", name, i->name);
+                log_debug("Skipping %s because it is an alias for %s.", name, i->name);
                 return 0;
         }
 
@@ -3063,6 +3110,8 @@ int unit_file_preset_all(
                         else if (r == -ENOLINK)
                                 r = unit_file_changes_add(changes, n_changes,
                                                           UNIT_FILE_IS_DANGLING, de->d_name, NULL);
+                        else if (r == -EADDRNOTAVAIL) /* Ignore generated/transient units when applying preset */
+                                continue;
                         if (r < 0)
                                 return r;
                 }
@@ -3080,12 +3129,7 @@ static void unit_file_list_free_one(UnitFileList *f) {
 }
 
 Hashmap* unit_file_list_free(Hashmap *h) {
-        UnitFileList *i;
-
-        while ((i = hashmap_steal_first(h)))
-                unit_file_list_free_one(i);
-
-        return hashmap_free(h);
+        return hashmap_free_with_destructor(h, unit_file_list_free_one);
 }
 
 DEFINE_TRIVIAL_CLEANUP_FUNC(UnitFileList*, unit_file_list_free_one);
index c1fcbe9..6d7518d 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index fff3dfc..eb7a752 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -149,3 +150,41 @@ int journal_access_check_and_warn(sd_journal *j, bool quiet) {
 
         return r;
 }
+
+bool journal_field_valid(const char *p, size_t l, bool allow_protected) {
+        const char *a;
+
+        /* We kinda enforce POSIX syntax recommendations for
+           environment variables here, but make a couple of additional
+           requirements.
+
+           http://pubs.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap08.html */
+
+        if (l == (size_t) -1)
+                l = strlen(p);
+
+        /* No empty field names */
+        if (l <= 0)
+                return false;
+
+        /* Don't allow names longer than 64 chars */
+        if (l > 64)
+                return false;
+
+        /* Variables starting with an underscore are protected */
+        if (!allow_protected && p[0] == '_')
+                return false;
+
+        /* Don't allow digits as first character */
+        if (p[0] >= '0' && p[0] <= '9')
+                return false;
+
+        /* Only allow A-Z0-9 and '_' */
+        for (a = p; a < p + l; a++)
+                if ((*a < 'A' || *a > 'Z') &&
+                    (*a < '0' || *a > '9') &&
+                    *a != '_')
+                        return false;
+
+        return true;
+}
index 499e6c6..ef5e314 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
 ***/
 
 #include <stdbool.h>
+#include <sys/types.h>
 
 #include "sd-journal.h"
 
+bool journal_field_valid(const char *p, size_t l, bool allow_protected);
+
 int journal_access_check_and_warn(sd_journal *j, bool quiet);
index aeaeb3e..b3555fb 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * Copyright 2008 Red Hat, Inc. All rights reserved.
  * Copyright 2008 Ian Kent <raven@themaw.net>
index 0626d80..afc3dcd 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -48,6 +49,7 @@
 #include "stdio-util.h"
 #include "string-table.h"
 #include "string-util.h"
+#include "strv.h"
 #include "terminal-util.h"
 #include "time-util.h"
 #include "utf8.h"
@@ -79,37 +81,76 @@ static int print_catalog(FILE *f, sd_journal *j) {
         return 0;
 }
 
-static int parse_field(const void *data, size_t length, const char *field, char **target, size_t *target_size) {
-        size_t fl, nl;
+static int parse_field(const void *data, size_t length, const char *field, size_t field_len, char **target, size_t *target_len) {
+        size_t nl;
         char *buf;
 
         assert(data);
         assert(field);
         assert(target);
 
-        fl = strlen(field);
-        if (length < fl)
+        if (length < field_len)
                 return 0;
 
-        if (memcmp(data, field, fl))
+        if (memcmp(data, field, field_len))
                 return 0;
 
-        nl = length - fl;
+        nl = length - field_len;
 
 
-        buf = newdup_suffix0(char, (const char*) data + fl, nl);
+        buf = newdup_suffix0(char, (const char*) data + field_len, nl);
         if (!buf)
                 return log_oom();
 
         free(*target);
         *target = buf;
 
-        if (target_size)
-                *target_size = nl;
+        if (target_len)
+                *target_len = nl;
 
         return 1;
 }
 
+typedef struct ParseFieldVec {
+        const char *field;
+        size_t field_len;
+        char **target;
+        size_t *target_len;
+} ParseFieldVec;
+
+#define PARSE_FIELD_VEC_ENTRY(_field, _target, _target_len) \
+        { .field = _field, .field_len = strlen(_field), .target = _target, .target_len = _target_len }
+
+static int parse_fieldv(const void *data, size_t length, const ParseFieldVec *fields, unsigned n_fields) {
+        unsigned i;
+
+        for (i = 0; i < n_fields; i++) {
+                const ParseFieldVec *f = &fields[i];
+                int r;
+
+                r = parse_field(data, length, f->field, f->field_len, f->target, f->target_len);
+                if (r < 0)
+                        return r;
+                else if (r > 0)
+                        break;
+        }
+
+        return 0;
+}
+
+static int field_set_test(Set *fields, const char *name, size_t n) {
+        char *s = NULL;
+
+        if (!fields)
+                return 1;
+
+        s = strndupa(name, n);
+        if (!s)
+                return log_oom();
+
+        return set_get(fields, s) ? 1 : 0;
+}
+
 static bool shall_print(const char *p, size_t l, OutputFlags flags) {
         assert(p);
 
@@ -327,7 +368,8 @@ static int output_short(
                 sd_journal *j,
                 OutputMode mode,
                 unsigned n_columns,
-                OutputFlags flags) {
+                OutputFlags flags,
+                Set *output_fields) {
 
         int r;
         const void *data;
@@ -337,6 +379,17 @@ static int output_short(
         size_t hostname_len = 0, identifier_len = 0, comm_len = 0, pid_len = 0, fake_pid_len = 0, message_len = 0, realtime_len = 0, monotonic_len = 0, priority_len = 0;
         int p = LOG_INFO;
         bool ellipsized = false;
+        const ParseFieldVec fields[] = {
+                PARSE_FIELD_VEC_ENTRY("_PID=", &pid, &pid_len),
+                PARSE_FIELD_VEC_ENTRY("_COMM=", &comm, &comm_len),
+                PARSE_FIELD_VEC_ENTRY("MESSAGE=", &message, &message_len),
+                PARSE_FIELD_VEC_ENTRY("PRIORITY=", &priority, &priority_len),
+                PARSE_FIELD_VEC_ENTRY("_HOSTNAME=", &hostname, &hostname_len),
+                PARSE_FIELD_VEC_ENTRY("SYSLOG_PID=", &fake_pid, &fake_pid_len),
+                PARSE_FIELD_VEC_ENTRY("SYSLOG_IDENTIFIER=", &identifier, &identifier_len),
+                PARSE_FIELD_VEC_ENTRY("_SOURCE_REALTIME_TIMESTAMP=", &realtime, &realtime_len),
+                PARSE_FIELD_VEC_ENTRY("_SOURCE_MONOTONIC_TIMESTAMP=", &monotonic, &monotonic_len),
+        };
 
         assert(f);
         assert(j);
@@ -351,55 +404,7 @@ static int output_short(
 
         JOURNAL_FOREACH_DATA_RETVAL(j, data, length, r) {
 
-                r = parse_field(data, length, "PRIORITY=", &priority, &priority_len);
-                if (r < 0)
-                        return r;
-                else if (r > 0)
-                        continue;
-
-                r = parse_field(data, length, "_HOSTNAME=", &hostname, &hostname_len);
-                if (r < 0)
-                        return r;
-                else if (r > 0)
-                        continue;
-
-                r = parse_field(data, length, "SYSLOG_IDENTIFIER=", &identifier, &identifier_len);
-                if (r < 0)
-                        return r;
-                else if (r > 0)
-                        continue;
-
-                r = parse_field(data, length, "_COMM=", &comm, &comm_len);
-                if (r < 0)
-                        return r;
-                else if (r > 0)
-                        continue;
-
-                r = parse_field(data, length, "_PID=", &pid, &pid_len);
-                if (r < 0)
-                        return r;
-                else if (r > 0)
-                        continue;
-
-                r = parse_field(data, length, "SYSLOG_PID=", &fake_pid, &fake_pid_len);
-                if (r < 0)
-                        return r;
-                else if (r > 0)
-                        continue;
-
-                r = parse_field(data, length, "_SOURCE_REALTIME_TIMESTAMP=", &realtime, &realtime_len);
-                if (r < 0)
-                        return r;
-                else if (r > 0)
-                        continue;
-
-                r = parse_field(data, length, "_SOURCE_MONOTONIC_TIMESTAMP=", &monotonic, &monotonic_len);
-                if (r < 0)
-                        return r;
-                else if (r > 0)
-                        continue;
-
-                r = parse_field(data, length, "MESSAGE=", &message, &message_len);
+                r = parse_fieldv(data, length, fields, ELEMENTSOF(fields));
                 if (r < 0)
                         return r;
         }
@@ -477,7 +482,8 @@ static int output_verbose(
                 sd_journal *j,
                 OutputMode mode,
                 unsigned n_columns,
-                OutputFlags flags) {
+                OutputFlags flags,
+                Set *output_fields) {
 
         const void *data;
         size_t length;
@@ -500,7 +506,9 @@ static int output_verbose(
         else {
                 _cleanup_free_ char *value = NULL;
 
-                r = parse_field(data, length, "_SOURCE_REALTIME_TIMESTAMP=", &value, NULL);
+                r = parse_field(data, length, "_SOURCE_REALTIME_TIMESTAMP=",
+                                STRLEN("_SOURCE_REALTIME_TIMESTAMP="), &value,
+                                NULL);
                 if (r < 0)
                         return r;
                 assert(r > 0);
@@ -538,6 +546,12 @@ static int output_verbose(
                 }
                 fieldlen = c - (const char*) data;
 
+                r = field_set_test(output_fields, data, fieldlen);
+                if (r < 0)
+                        return r;
+                if (!r)
+                        continue;
+
                 if (flags & OUTPUT_COLOR && startswith(data, "MESSAGE=")) {
                         on = ANSI_HIGHLIGHT;
                         off = ANSI_NORMAL;
@@ -575,7 +589,8 @@ static int output_export(
                 sd_journal *j,
                 OutputMode mode,
                 unsigned n_columns,
-                OutputFlags flags) {
+                OutputFlags flags,
+                Set *output_fields) {
 
         sd_id128_t boot_id;
         char sid[33];
@@ -612,6 +627,7 @@ static int output_export(
                 sd_id128_to_string(boot_id, sid));
 
         JOURNAL_FOREACH_DATA_RETVAL(j, data, length, r) {
+                const char *c;
 
                 /* We already printed the boot id, from the data in
                  * the header, hence let's suppress it here */
@@ -619,18 +635,23 @@ static int output_export(
                     startswith(data, "_BOOT_ID="))
                         continue;
 
+                c = memchr(data, '=', length);
+                if (!c) {
+                        log_error("Invalid field.");
+                        return -EINVAL;
+                }
+
+                r = field_set_test(output_fields, data, c - (const char *) data);
+                if (r < 0)
+                        return r;
+                if (!r)
+                        continue;
+
                 if (utf8_is_printable_newline(data, length, false))
                         fwrite(data, length, 1, f);
                 else {
-                        const char *c;
                         uint64_t le64;
 
-                        c = memchr(data, '=', length);
-                        if (!c) {
-                                log_error("Invalid field.");
-                                return -EINVAL;
-                        }
-
                         fwrite(data, c - (const char*) data, 1, f);
                         fputc('\n', f);
                         le64 = htole64(length - (c - (const char*) data) - 1);
@@ -706,7 +727,8 @@ static int output_json(
                 sd_journal *j,
                 OutputMode mode,
                 unsigned n_columns,
-                OutputFlags flags) {
+                OutputFlags flags,
+                Set *output_fields) {
 
         uint64_t realtime, monotonic;
         _cleanup_free_ char *cursor = NULL;
@@ -825,13 +847,6 @@ static int output_json(
                         if (!eq)
                                 continue;
 
-                        if (separator) {
-                                if (mode == OUTPUT_JSON_PRETTY)
-                                        fputs(",\n\t", f);
-                                else
-                                        fputs(", ", f);
-                        }
-
                         m = eq - (const char*) data;
 
                         n = strndup(data, m);
@@ -840,6 +855,18 @@ static int output_json(
                                 goto finish;
                         }
 
+                        if (output_fields && !set_get(output_fields, n)) {
+                                free(n);
+                                continue;
+                        }
+
+                        if (separator) {
+                                if (mode == OUTPUT_JSON_PRETTY)
+                                        fputs(",\n\t", f);
+                                else
+                                        fputs(", ", f);
+                        }
+
                         u = PTR_TO_UINT(hashmap_get2(h, n, (void**) &kk));
                         if (u == 0) {
                                 /* We already printed this, let's jump to the next */
@@ -924,7 +951,8 @@ static int output_cat(
                 sd_journal *j,
                 OutputMode mode,
                 unsigned n_columns,
-                OutputFlags flags) {
+                OutputFlags flags,
+                Set *output_fields) {
 
         const void *data;
         size_t l;
@@ -957,7 +985,8 @@ static int (*output_funcs[_OUTPUT_MODE_MAX])(
                 sd_journal*j,
                 OutputMode mode,
                 unsigned n_columns,
-                OutputFlags flags) = {
+                OutputFlags flags,
+                Set *output_fields) = {
 
         [OUTPUT_SHORT] = output_short,
         [OUTPUT_SHORT_ISO] = output_short,
@@ -980,16 +1009,28 @@ int output_journal(
                 OutputMode mode,
                 unsigned n_columns,
                 OutputFlags flags,
+                char **output_fields,
                 bool *ellipsized) {
 
         int ret;
+        _cleanup_set_free_free_ Set *fields = NULL;
         assert(mode >= 0);
         assert(mode < _OUTPUT_MODE_MAX);
 
         if (n_columns <= 0)
                 n_columns = columns();
 
-        ret = output_funcs[mode](f, j, mode, n_columns, flags);
+        if (output_fields) {
+                fields = set_new(&string_hash_ops);
+                if (!fields)
+                        return log_oom();
+
+                ret = set_put_strdupv(fields, output_fields);
+                if (ret < 0)
+                        return ret;
+        }
+
+        ret = output_funcs[mode](f, j, mode, n_columns, flags, fields);
 
         if (ellipsized && ret > 0)
                 *ellipsized = true;
@@ -1071,7 +1112,7 @@ static int show_journal(FILE *f,
                         line++;
                         maybe_print_begin_newline(f, &flags);
 
-                        r = output_journal(f, j, mode, n_columns, flags, ellipsized);
+                        r = output_journal(f, j, mode, n_columns, flags, NULL, ellipsized);
                         if (r < 0)
                                 return r;
                 }
index 6643440..eaa69b6 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -37,6 +38,7 @@ int output_journal(
                 OutputMode mode,
                 unsigned n_columns,
                 OutputFlags flags,
+                char **output_fields,
                 bool *ellipsized);
 
 int add_match_this_boot(sd_journal *j, const char *machine);
index 047e213..097de69 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -151,9 +152,7 @@ LoopDevice* loop_device_unref(LoopDevice *d) {
         }
 
         free(d->node);
-        free(d);
-
-        return NULL;
+        return mfree(d);
 }
 
 void loop_device_relinquish(LoopDevice *d) {
index 45fead5..7e18e57 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 859e5ff..66eefb3 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
 #include "chattr-util.h"
 #include "copy.h"
 #include "dirent-util.h"
+#include "dissect-image.h"
 #include "env-util.h"
 #include "fd-util.h"
+#include "fileio.h"
 #include "fs-util.h"
 #include "hashmap.h"
+#include "hostname-util.h"
+#include "id128-util.h"
 #include "lockfile-util.h"
 #include "log.h"
+#include "loop-util.h"
 #include "machine-image.h"
 #include "macro.h"
 #include "mkdir.h"
@@ -64,6 +70,11 @@ Image *image_unref(Image *i) {
 
         free(i->name);
         free(i->path);
+
+        free(i->hostname);
+        strv_free(i->machine_info);
+        strv_free(i->os_release);
+
         return mfree(i);
 }
 
@@ -171,9 +182,8 @@ static int image_make(
 
         assert(filename);
 
-        /* We explicitly *do* follow symlinks here, since we want to
-         * allow symlinking trees into /var/lib/machines/, and treat
-         * them normally. */
+        /* We explicitly *do* follow symlinks here, since we want to allow symlinking trees, raw files and block
+         * devices into /var/lib/machines/, and treat them normally. */
 
         if (fstatat(dfd, filename, &st, 0) < 0)
                 return -errno;
@@ -286,6 +296,58 @@ static int image_make(
                 (*ret)->limit = (*ret)->limit_exclusive = st.st_size;
 
                 return 1;
+
+        } else if (S_ISBLK(st.st_mode)) {
+                _cleanup_close_ int block_fd = -1;
+                uint64_t size = UINT64_MAX;
+
+                /* A block device */
+
+                if (!ret)
+                        return 1;
+
+                if (!pretty)
+                        pretty = filename;
+
+                block_fd = openat(dfd, filename, O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_NOCTTY);
+                if (block_fd < 0)
+                        log_debug_errno(errno, "Failed to open block device %s/%s, ignoring: %m", path, filename);
+                else {
+                        if (fstat(block_fd, &st) < 0)
+                                return -errno;
+                        if (!S_ISBLK(st.st_mode)) /* Verify that what we opened is actually what we think it is */
+                                return -ENOTTY;
+
+                        if (!read_only) {
+                                int state = 0;
+
+                                if (ioctl(block_fd, BLKROGET, &state) < 0)
+                                        log_debug_errno(errno, "Failed to issue BLKROGET on device %s/%s, ignoring: %m", path, filename);
+                                else if (state)
+                                        read_only = true;
+                        }
+
+                        if (ioctl(block_fd, BLKGETSIZE64, &size) < 0)
+                                log_debug_errno(errno, "Failed to issue BLKFLSBUF on device %s/%s, ignoring: %m", path, filename);
+
+                        block_fd = safe_close(block_fd);
+                }
+
+                r = image_new(IMAGE_BLOCK,
+                              pretty,
+                              path,
+                              filename,
+                              !(st.st_mode & 0222) || read_only,
+                              0,
+                              0,
+                              ret);
+                if (r < 0)
+                        return r;
+
+                if (size != 0 && size != UINT64_MAX)
+                        (*ret)->usage = (*ret)->usage_exclusive = (*ret)->limit = (*ret)->limit_exclusive = size;
+
+                return 1;
         }
 
         return 0;
@@ -395,15 +457,6 @@ int image_discover(Hashmap *h) {
         return 0;
 }
 
-void image_hashmap_free(Hashmap *map) {
-        Image *i;
-
-        while ((i = hashmap_steal_first(map)))
-                image_unref(i);
-
-        hashmap_free(map);
-}
-
 int image_remove(Image *i) {
         _cleanup_release_lock_file_ LockFile global_lock = LOCK_FILE_INIT, local_lock = LOCK_FILE_INIT;
         _cleanup_strv_free_ char **settings = NULL;
@@ -432,9 +485,15 @@ int image_remove(Image *i) {
         switch (i->type) {
 
         case IMAGE_SUBVOLUME:
-                r = btrfs_subvol_remove(i->path, BTRFS_REMOVE_RECURSIVE|BTRFS_REMOVE_QUOTA);
-                if (r < 0)
-                        return r;
+
+                /* Let's unlink first, maybe it is a symlink? If that works we are happy. Otherwise, let's get out the
+                 * big guns */
+                if (unlink(i->path) < 0) {
+                        r = btrfs_subvol_remove(i->path, BTRFS_REMOVE_RECURSIVE|BTRFS_REMOVE_QUOTA);
+                        if (r < 0)
+                                return r;
+                }
+
                 break;
 
         case IMAGE_DIRECTORY:
@@ -446,6 +505,16 @@ int image_remove(Image *i) {
 
                 break;
 
+        case IMAGE_BLOCK:
+
+                /* If this is inside of /dev, then it's a real block device, hence let's not touch the device node
+                 * itself (but let's remove the stuff stored alongside it). If it's anywhere else, let's try to unlink
+                 * the thing (it's most likely a symlink after all). */
+
+                if (path_startswith(i->path, "/dev"))
+                        break;
+
+                _fallthrough_;
         case IMAGE_RAW:
                 if (unlink(i->path) < 0)
                         return -errno;
@@ -530,12 +599,20 @@ int image_rename(Image *i, const char *new_name) {
                 if (file_attr & FS_IMMUTABLE_FL)
                         (void) chattr_path(i->path, 0, FS_IMMUTABLE_FL);
 
-                /* fall through */
-
+                _fallthrough_;
         case IMAGE_SUBVOLUME:
                 new_path = file_in_same_dir(i->path, new_name);
                 break;
 
+        case IMAGE_BLOCK:
+
+                /* Refuse renaming raw block devices in /dev, the names are picked by udev after all. */
+                if (path_startswith(i->path, "/dev"))
+                        return -EROFS;
+
+                new_path = file_in_same_dir(i->path, new_name);
+                break;
+
         case IMAGE_RAW: {
                 const char *fn;
 
@@ -563,13 +640,8 @@ int image_rename(Image *i, const char *new_name) {
         if (file_attr & FS_IMMUTABLE_FL)
                 (void) chattr_path(new_path, FS_IMMUTABLE_FL, FS_IMMUTABLE_FL);
 
-        free(i->path);
-        i->path = new_path;
-        new_path = NULL;
-
-        free(i->name);
-        i->name = nn;
-        nn = NULL;
+        free_and_replace(i->path, new_path);
+        free_and_replace(i->name, nn);
 
         STRV_FOREACH(j, settings) {
                 r = rename_auxiliary_file(*j, new_name, ".nspawn");
@@ -659,6 +731,7 @@ int image_clone(Image *i, const char *new_name, bool read_only) {
                 r = copy_file_atomic(i->path, new_path, read_only ? 0444 : 0644, FS_NOCOW_FL, COPY_REFLINK);
                 break;
 
+        case IMAGE_BLOCK:
         default:
                 return -EOPNOTSUPP;
         }
@@ -682,6 +755,7 @@ int image_clone(Image *i, const char *new_name, bool read_only) {
 int image_read_only(Image *i, bool b) {
         _cleanup_release_lock_file_ LockFile global_lock = LOCK_FILE_INIT, local_lock = LOCK_FILE_INIT;
         int r;
+
         assert(i);
 
         if (IMAGE_IS_VENDOR(i) || IMAGE_IS_HOST(i))
@@ -737,6 +811,26 @@ int image_read_only(Image *i, bool b) {
                 break;
         }
 
+        case IMAGE_BLOCK: {
+                _cleanup_close_ int fd = -1;
+                struct stat st;
+                int state = b;
+
+                fd = open(i->path, O_CLOEXEC|O_RDONLY|O_NONBLOCK|O_NOCTTY);
+                if (fd < 0)
+                        return -errno;
+
+                if (fstat(fd, &st) < 0)
+                        return -errno;
+                if (!S_ISBLK(st.st_mode))
+                        return -ENOTTY;
+
+                if (ioctl(fd, BLKROSET, &state) < 0)
+                        return -errno;
+
+                break;
+        }
+
         default:
                 return -EOPNOTSUPP;
         }
@@ -772,13 +866,24 @@ int image_path_lock(const char *path, int operation, LockFile *global, LockFile
                 return -EBUSY;
 
         if (stat(path, &st) >= 0) {
-                if (asprintf(&p, "/run/systemd/nspawn/locks/inode-%lu:%lu", (unsigned long) st.st_dev, (unsigned long) st.st_ino) < 0)
+                if (S_ISBLK(st.st_mode))
+                        r = asprintf(&p, "/run/systemd/nspawn/locks/block-%u:%u", major(st.st_rdev), minor(st.st_rdev));
+                else if (S_ISDIR(st.st_mode) || S_ISREG(st.st_mode))
+                        r = asprintf(&p, "/run/systemd/nspawn/locks/inode-%lu:%lu", (unsigned long) st.st_dev, (unsigned long) st.st_ino);
+                else
+                        return -ENOTTY;
+
+                if (r < 0)
                         return -ENOMEM;
         }
 
-        r = make_lock_file_for(path, operation, &t);
-        if (r < 0)
-                return r;
+        /* For block devices we don't need the "local" lock, as the major/minor lock above should be sufficient, since
+         * block devices are device local anyway. */
+        if (!path_startswith(path, "/dev")) {
+                r = make_lock_file_for(path, operation, &t);
+                if (r < 0)
+                        return r;
+        }
 
         if (p) {
                 mkdir_p("/run/systemd/nspawn/locks", 0700);
@@ -814,6 +919,118 @@ int image_set_limit(Image *i, uint64_t referenced_max) {
         return btrfs_subvol_set_subtree_quota_limit(i->path, 0, referenced_max);
 }
 
+int image_read_metadata(Image *i) {
+        _cleanup_release_lock_file_ LockFile global_lock = LOCK_FILE_INIT, local_lock = LOCK_FILE_INIT;
+        int r;
+
+        assert(i);
+
+        r = image_path_lock(i->path, LOCK_SH|LOCK_NB, &global_lock, &local_lock);
+        if (r < 0)
+                return r;
+
+        switch (i->type) {
+
+        case IMAGE_SUBVOLUME:
+        case IMAGE_DIRECTORY: {
+                _cleanup_strv_free_ char **machine_info = NULL, **os_release = NULL;
+                sd_id128_t machine_id = SD_ID128_NULL;
+                _cleanup_free_ char *hostname = NULL;
+                _cleanup_free_ char *path = NULL;
+
+                r = chase_symlinks("/etc/hostname", i->path, CHASE_PREFIX_ROOT, &path);
+                if (r < 0 && r != -ENOENT)
+                        log_debug_errno(r, "Failed to chase /etc/hostname in image %s: %m", i->name);
+                else if (r >= 0) {
+                        r = read_etc_hostname(path, &hostname);
+                        if (r < 0)
+                                log_debug_errno(errno, "Failed to read /etc/hostname of image %s: %m", i->name);
+                }
+
+                path = mfree(path);
+
+                r = chase_symlinks("/etc/machine-id", i->path, CHASE_PREFIX_ROOT, &path);
+                if (r < 0 && r != -ENOENT)
+                        log_debug_errno(r, "Failed to chase /etc/machine-id in image %s: %m", i->name);
+                else if (r >= 0) {
+                        _cleanup_close_ int fd = -1;
+
+                        fd = open(path, O_RDONLY|O_CLOEXEC|O_NOCTTY);
+                        if (fd < 0)
+                                log_debug_errno(errno, "Failed to open %s: %m", path);
+                        else {
+                                r = id128_read_fd(fd, ID128_PLAIN, &machine_id);
+                                if (r < 0)
+                                        log_debug_errno(r, "Image %s contains invalid machine ID.", i->name);
+                        }
+                }
+
+                path = mfree(path);
+
+                r = chase_symlinks("/etc/machine-info", i->path, CHASE_PREFIX_ROOT, &path);
+                if (r < 0 && r != -ENOENT)
+                        log_debug_errno(r, "Failed to chase /etc/machine-info in image %s: %m", i->name);
+                else if (r >= 0) {
+                        r = load_env_file_pairs(NULL, path, NULL, &machine_info);
+                        if (r < 0)
+                                log_debug_errno(r, "Failed to parse machine-info data of %s: %m", i->name);
+                }
+
+                path = mfree(path);
+
+                r = chase_symlinks("/etc/os-release", i->path, CHASE_PREFIX_ROOT, &path);
+                if (r == -ENOENT)
+                        r = chase_symlinks("/usr/lib/os-release", i->path, CHASE_PREFIX_ROOT, &path);
+                if (r < 0 && r != -ENOENT)
+                        log_debug_errno(r, "Failed to chase os-release in image: %m");
+                else if (r >= 0) {
+                        r = load_env_file_pairs(NULL, path, NULL, &os_release);
+                        if (r < 0)
+                                log_debug_errno(r, "Failed to parse os-release data of %s: %m", i->name);
+                }
+
+                free_and_replace(i->hostname, hostname);
+                i->machine_id = machine_id;
+                strv_free_and_replace(i->machine_info, machine_info);
+                strv_free_and_replace(i->os_release, os_release);
+
+                break;
+        }
+
+        case IMAGE_RAW:
+        case IMAGE_BLOCK: {
+                _cleanup_(loop_device_unrefp) LoopDevice *d = NULL;
+                _cleanup_(dissected_image_unrefp) DissectedImage *m = NULL;
+
+                r = loop_device_make_by_path(i->path, O_RDONLY, &d);
+                if (r < 0)
+                        return r;
+
+                r = dissect_image(d->fd, NULL, 0, DISSECT_IMAGE_REQUIRE_ROOT, &m);
+                if (r < 0)
+                        return r;
+
+                r = dissected_image_acquire_metadata(m);
+                if (r < 0)
+                        return r;
+
+                free_and_replace(i->hostname, m->hostname);
+                i->machine_id = m->machine_id;
+                strv_free_and_replace(i->machine_info, m->machine_info);
+                strv_free_and_replace(i->os_release, m->os_release);
+
+                break;
+        }
+
+        default:
+                return -EOPNOTSUPP;
+        }
+
+        i->metadata_valid = true;
+
+        return 0;
+}
+
 int image_name_lock(const char *name, int operation, LockFile *ret) {
         const char *p;
 
@@ -860,6 +1077,7 @@ static const char* const image_type_table[_IMAGE_TYPE_MAX] = {
         [IMAGE_DIRECTORY] = "directory",
         [IMAGE_SUBVOLUME] = "subvolume",
         [IMAGE_RAW] = "raw",
+        [IMAGE_BLOCK] = "block",
 };
 
 DEFINE_STRING_TABLE_LOOKUP(image_type, ImageType);
index 7410168..3df9a29 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -33,6 +34,7 @@ typedef enum ImageType {
         IMAGE_DIRECTORY,
         IMAGE_SUBVOLUME,
         IMAGE_RAW,
+        IMAGE_BLOCK,
         _IMAGE_TYPE_MAX,
         _IMAGE_TYPE_INVALID = -1
 } ImageType;
@@ -51,11 +53,20 @@ typedef struct Image {
         uint64_t limit;
         uint64_t limit_exclusive;
 
+        char *hostname;
+        sd_id128_t machine_id;
+        char **machine_info;
+        char **os_release;
+
+        bool metadata_valid;
+
         void *userdata;
 } Image;
 
 Image *image_unref(Image *i);
-void image_hashmap_free(Hashmap *map);
+static inline Hashmap* image_hashmap_free(Hashmap *map) {
+        return hashmap_free_with_destructor(map, image_unref);
+}
 
 DEFINE_TRIVIAL_CLEANUP_FUNC(Image*, image_unref);
 DEFINE_TRIVIAL_CLEANUP_FUNC(Hashmap*, image_hashmap_free);
@@ -78,6 +89,8 @@ int image_name_lock(const char *name, int operation, LockFile *ret);
 
 int image_set_limit(Image *i, uint64_t referenced_max);
 
+int image_read_metadata(Image *i);
+
 static inline bool IMAGE_IS_HIDDEN(const struct Image *i) {
         assert(i);
 
index c581bde..167bcfa 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 40fe5ec..6e39052 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 8838213..06a944c 100644 (file)
@@ -1,3 +1,20 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
+# Copyright 2017 Zbigniew Jędrzejewski-Szmek
+#
+# 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.
+#
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
 shared_sources = '''
         acl-util.h
         acpi-fpdt.c
@@ -10,6 +27,8 @@ shared_sources = '''
         base-filesystem.h
         boot-timestamps.c
         boot-timestamps.h
+        bootspec.c
+        bootspec.h
         bus-unit-util.c
         bus-unit-util.h
         bus-util.c
@@ -88,6 +107,8 @@ shared_sources = '''
         sysctl-util.h
         tests.c
         tests.h
+        tomoyo-util.c
+        tomoyo-util.h
         udev-util.h
         udev-util.c
         uid-range.c
index aeb79b1..05ec9fe 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 152ab8b..dcac6cd 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 29dcba9..5256e91 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 2a1bfd9..747f7eb 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 0661ff0..3999727 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -80,9 +81,10 @@ int pager_open(bool no_pager, bool jump_to_end) {
         if (pager && STR_IN_SET(pager, "", "cat"))
                 return 0;
 
-        /* Determine and cache number of columns before we spawn the
-         * pager so that we get the value from the actual tty */
+        /* Determine and cache number of columns/lines before we spawn the pager so that we get the value from the
+         * actual tty */
         (void) columns();
+        (void) lines();
 
         if (pipe2(fd, O_CLOEXEC) < 0)
                 return log_error_errno(errno, "Failed to create pager pipe: %m");
index 893e1d2..99716f8 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 802e4b9..d57c78a 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -38,7 +39,7 @@
 #include "user-util.h"
 #include "util.h"
 
-static int user_runtime_dir(char **ret, const char *suffix) {
+int xdg_user_runtime_dir(char **ret, const char *suffix) {
         const char *e;
         char *j;
 
@@ -57,7 +58,7 @@ static int user_runtime_dir(char **ret, const char *suffix) {
         return 0;
 }
 
-static int user_config_dir(char **ret, const char *suffix) {
+int xdg_user_config_dir(char **ret, const char *suffix) {
         const char *e;
         char *j;
         int r;
@@ -84,7 +85,7 @@ static int user_config_dir(char **ret, const char *suffix) {
         return 0;
 }
 
-static int user_data_dir(char **ret, const char *suffix) {
+int xdg_user_data_dir(char **ret, const char *suffix) {
         const char *e;
         char *j;
         int r;
@@ -130,23 +131,7 @@ static const char* const user_config_unit_paths[] = {
         NULL
 };
 
-static char** user_dirs(
-                const char *persistent_config,
-                const char *runtime_config,
-                const char *generator,
-                const char *generator_early,
-                const char *generator_late,
-                const char *transient,
-                const char *persistent_control,
-                const char *runtime_control) {
-
-        _cleanup_strv_free_ char **config_dirs = NULL, **data_dirs = NULL;
-        _cleanup_free_ char *data_home = NULL;
-        _cleanup_strv_free_ char **res = NULL;
-        const char *e;
-        char **tmp;
-        int r;
-
+int xdg_user_dirs(char ***ret_config_dirs, char ***ret_data_dirs) {
         /* Implement the mechanisms defined in
          *
          * http://standards.freedesktop.org/basedir-spec/basedir-spec-0.6.html
@@ -155,18 +140,16 @@ static char** user_dirs(
          * want to encourage that distributors ship their unit files
          * as data, and allow overriding as configuration.
          */
+        const char *e;
+        _cleanup_strv_free_ char **config_dirs = NULL, **data_dirs = NULL;
 
         e = getenv("XDG_CONFIG_DIRS");
         if (e) {
                 config_dirs = strv_split(e, ":");
                 if (!config_dirs)
-                        return NULL;
+                        return -ENOMEM;
         }
 
-        r = user_data_dir(&data_home, "/systemd/user");
-        if (r < 0 && r != -ENXIO)
-                return NULL;
-
         e = getenv("XDG_DATA_DIRS");
         if (e)
                 data_dirs = strv_split(e, ":");
@@ -175,6 +158,36 @@ static char** user_dirs(
                                      "/usr/share",
                                      NULL);
         if (!data_dirs)
+                return -ENOMEM;
+
+        *ret_config_dirs = config_dirs;
+        *ret_data_dirs = data_dirs;
+        config_dirs = data_dirs = NULL;
+        return 0;
+}
+
+static char** user_dirs(
+                const char *persistent_config,
+                const char *runtime_config,
+                const char *generator,
+                const char *generator_early,
+                const char *generator_late,
+                const char *transient,
+                const char *persistent_control,
+                const char *runtime_control) {
+
+        _cleanup_strv_free_ char **config_dirs = NULL, **data_dirs = NULL;
+        _cleanup_free_ char *data_home = NULL;
+        _cleanup_strv_free_ char **res = NULL;
+        char **tmp;
+        int r;
+
+        r = xdg_user_dirs(&config_dirs, &data_dirs);
+        if (r < 0)
+                return NULL;
+
+        r = xdg_user_data_dir(&data_home, "/systemd/user");
+        if (r < 0 && r != -ENXIO)
                 return NULL;
 
         /* Now merge everything we found. */
@@ -245,7 +258,6 @@ static int acquire_generator_dirs(
                 char **generator_early,
                 char **generator_late) {
 
-        _cleanup_(rmdir_and_freep) char *t = NULL;
         _cleanup_free_ char *x = NULL, *y = NULL, *z = NULL;
         const char *prefix;
 
@@ -311,7 +323,7 @@ static int acquire_transient_dir(
         else if (scope == UNIT_FILE_SYSTEM)
                 transient = strdup("/run/systemd/transient");
         else
-                return user_runtime_dir(ret, "/systemd/transient");
+                return xdg_user_runtime_dir(ret, "/systemd/transient");
 
         if (!transient)
                 return -ENOMEM;
@@ -339,11 +351,11 @@ static int acquire_config_dirs(UnitFileScope scope, char **persistent, char **ru
                 break;
 
         case UNIT_FILE_USER:
-                r = user_config_dir(&a, "/systemd/user");
+                r = xdg_user_config_dir(&a, "/systemd/user");
                 if (r < 0 && r != -ENXIO)
                         return r;
 
-                r = user_runtime_dir(runtime, "/systemd/user");
+                r = xdg_user_runtime_dir(runtime, "/systemd/user");
                 if (r < 0) {
                         if (r != -ENXIO)
                                 return r;
@@ -399,11 +411,11 @@ static int acquire_control_dirs(UnitFileScope scope, char **persistent, char **r
         }
 
         case UNIT_FILE_USER:
-                r = user_config_dir(&a, "/systemd/system.control");
+                r = xdg_user_config_dir(&a, "/systemd/system.control");
                 if (r < 0 && r != -ENXIO)
                         return r;
 
-                r = user_runtime_dir(runtime, "/systemd/system.control");
+                r = xdg_user_runtime_dir(runtime, "/systemd/system.control");
                 if (r < 0) {
                         if (r != -ENXIO)
                                 return r;
@@ -736,6 +748,14 @@ int lookup_paths_reduce(LookupPaths *p) {
                 struct stat st;
                 unsigned k;
 
+                /* Never strip the transient and control directories from the path */
+                if (path_equal_ptr(p->search_path[c], p->transient) ||
+                    path_equal_ptr(p->search_path[c], p->persistent_control) ||
+                    path_equal_ptr(p->search_path[c], p->runtime_control)) {
+                        c++;
+                        continue;
+                }
+
                 if (p->root_dir)
                         r = lstat(p->search_path[c], &st);
                 else
index fc8b8ed..42a870a 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -27,8 +28,8 @@ typedef struct LookupPaths LookupPaths;
 #include "macro.h"
 
 typedef enum LookupPathsFlags {
-        LOOKUP_PATHS_EXCLUDE_GENERATED = 1,
-        LOOKUP_PATHS_TEMPORARY_GENERATED,
+        LOOKUP_PATHS_EXCLUDE_GENERATED   = 1 << 0,
+        LOOKUP_PATHS_TEMPORARY_GENERATED = 1 << 1,
 } LookupPathsFlags;
 
 struct LookupPaths {
@@ -67,6 +68,10 @@ struct LookupPaths {
 };
 
 int lookup_paths_init(LookupPaths *p, UnitFileScope scope, LookupPathsFlags flags, const char *root_dir);
+int xdg_user_dirs(char ***ret_config_dirs, char ***ret_data_dirs);
+int xdg_user_runtime_dir(char **ret, const char *suffix);
+int xdg_user_config_dir(char **ret, const char *suffix);
+int xdg_user_data_dir(char **ret, const char *suffix);
 bool path_is_user_data_dir(const char *path);
 bool path_is_user_config_dir(const char *path);
 
index 0c92184..94a4dd5 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -170,6 +171,30 @@ static bool ignore_vhangup(PTYForward *f) {
         return false;
 }
 
+static bool drained(PTYForward *f) {
+        int q = 0;
+
+        assert(f);
+
+        if (f->out_buffer_full > 0)
+                return false;
+
+        if (f->master_readable)
+                return false;
+
+        if (ioctl(f->master, TIOCINQ, &q) < 0)
+                log_debug_errno(errno, "TIOCINQ failed on master: %m");
+        else if (q > 0)
+                return false;
+
+        if (ioctl(f->master, TIOCOUTQ, &q) < 0)
+                log_debug_errno(errno, "TIOCOUTQ failed on master: %m");
+        else if (q > 0)
+                return false;
+
+        return true;
+}
+
 static int shovel(PTYForward *f) {
         ssize_t k;
 
@@ -305,7 +330,7 @@ static int shovel(PTYForward *f) {
 
         /* If we were asked to drain, and there's nothing more to handle from the master, then call the callback
          * too. */
-        if (f->drain && f->out_buffer_full == 0 && !f->master_readable)
+        if (f->drain && drained(f))
                 return pty_forward_done(f, 0);
 
         return 0;
@@ -546,6 +571,28 @@ bool pty_forward_drain(PTYForward *f) {
          */
 
         f->drain = true;
+        return drained(f);
+}
+
+int pty_forward_set_priority(PTYForward *f, int64_t priority) {
+        int r;
+        assert(f);
 
-        return f->out_buffer_full == 0 && !f->master_readable;
+        r = sd_event_source_set_priority(f->stdin_event_source, priority);
+        if (r < 0)
+                return r;
+
+        r = sd_event_source_set_priority(f->stdout_event_source, priority);
+        if (r < 0)
+                return r;
+
+        r = sd_event_source_set_priority(f->master_event_source, priority);
+        if (r < 0)
+                return r;
+
+        r = sd_event_source_set_priority(f->sigwinch_event_source, priority);
+        if (r < 0)
+                return r;
+
+        return 0;
 }
index 3fad1d3..6a0e0c6 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -53,4 +54,6 @@ void pty_forward_set_handler(PTYForward *f, PTYForwardHandler handler, void *use
 
 bool pty_forward_drain(PTYForward *f);
 
+int pty_forward_set_priority(PTYForward *f, int64_t priority);
+
 DEFINE_TRIVIAL_CLEANUP_FUNC(PTYForward*, pty_forward_free);
index e2da81b..edcb8e0 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 8636a6c..975156c 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 14a75bf..6274285 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -313,6 +314,7 @@ const SyscallFilterSet syscall_filter_sets[_SYSCALL_FILTER_SET_MAX] = {
                 "set_robust_list\0"
                 "set_thread_area\0"
                 "set_tid_address\0"
+                "set_tls\0"
                 "sigreturn\0"
                 "time\0"
                 "ugetrlimit\0"
@@ -465,7 +467,7 @@ const SyscallFilterSet syscall_filter_sets[_SYSCALL_FILTER_SET_MAX] = {
                 "stat64\0"
                 "statfs\0"
                 "statfs64\0"
-#ifdef __PNR_statx
+#ifdef __NR_statx
                 "statx\0"
 #endif
                 "symlink\0"
@@ -900,20 +902,20 @@ int seccomp_load_syscall_filter_set(uint32_t default_action, const SyscallFilter
         return 0;
 }
 
-int seccomp_load_syscall_filter_set_raw(uint32_t default_action, Set* set, uint32_t action) {
+int seccomp_load_syscall_filter_set_raw(uint32_t default_action, Hashmap* set, uint32_t action) {
         uint32_t arch;
         int r;
 
         /* Similar to seccomp_load_syscall_filter_set(), but takes a raw Set* of syscalls, instead of a
          * SyscallFilterSet* table. */
 
-        if (set_isempty(set) && default_action == SCMP_ACT_ALLOW)
+        if (hashmap_isempty(set) && default_action == SCMP_ACT_ALLOW)
                 return 0;
 
         SECCOMP_FOREACH_LOCAL_ARCH(arch) {
                 _cleanup_(seccomp_releasep) scmp_filter_ctx seccomp = NULL;
                 Iterator i;
-                void *id;
+                void *id, *val;
 
                 log_debug("Operating on architecture: %s", seccomp_arch_to_string(arch));
 
@@ -921,8 +923,14 @@ int seccomp_load_syscall_filter_set_raw(uint32_t default_action, Set* set, uint3
                 if (r < 0)
                         return r;
 
-                SET_FOREACH(id, set, i) {
-                        r = seccomp_rule_add_exact(seccomp, action, PTR_TO_INT(id) - 1, 0);
+                HASHMAP_FOREACH_KEY(val, id, set, i) {
+                        uint32_t a = action;
+                        int e = PTR_TO_INT(val);
+
+                        if (action != SCMP_ACT_ALLOW && e >= 0)
+                                a = SCMP_ACT_ERRNO(e);
+
+                        r = seccomp_rule_add_exact(seccomp, a, PTR_TO_INT(id) - 1, 0);
                         if (r < 0) {
                                 /* If the system call is not known on this architecture, then that's fine, let's ignore it */
                                 _cleanup_free_ char *n = NULL;
@@ -1433,6 +1441,14 @@ int seccomp_memory_deny_write_execute(void) {
                 if (r < 0)
                         continue;
 
+#ifdef __NR_pkey_mprotect
+                r = add_seccomp_syscall_filter(seccomp, arch, SCMP_SYS(pkey_mprotect),
+                                               1,
+                                               SCMP_A2(SCMP_CMP_MASKED_EQ, PROT_EXEC, PROT_EXEC));
+                if (r < 0)
+                        continue;
+#endif
+
                 if (shmat_syscall != 0) {
                         r = add_seccomp_syscall_filter(seccomp, arch, SCMP_SYS(shmat),
                                                        1,
@@ -1515,7 +1531,7 @@ int parse_syscall_archs(char **l, Set **archs) {
         return 0;
 }
 
-int seccomp_filter_set_add(Set *filter, bool add, const SyscallFilterSet *set) {
+int seccomp_filter_set_add(Hashmap *filter, bool add, const SyscallFilterSet *set) {
         const char *i;
         int r;
 
@@ -1543,11 +1559,11 @@ int seccomp_filter_set_add(Set *filter, bool add, const SyscallFilterSet *set) {
                         }
 
                         if (add) {
-                                r = set_put(filter, INT_TO_PTR(id + 1));
+                                r = hashmap_put(filter, INT_TO_PTR(id + 1), INT_TO_PTR(-1));
                                 if (r < 0)
                                         return r;
                         } else
-                                (void) set_remove(filter, INT_TO_PTR(id + 1));
+                                (void) hashmap_remove(filter, INT_TO_PTR(id + 1));
                 }
         }
 
index 6dfa465..ad2ab7f 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -73,12 +74,12 @@ extern const SyscallFilterSet syscall_filter_sets[];
 
 const SyscallFilterSet *syscall_filter_set_find(const char *name);
 
-int seccomp_filter_set_add(Set *s, bool b, const SyscallFilterSet *set);
+int seccomp_filter_set_add(Hashmap *s, bool b, const SyscallFilterSet *set);
 
 int seccomp_add_syscall_filter_item(scmp_filter_ctx *ctx, const char *name, uint32_t action, char **exclude);
 
 int seccomp_load_syscall_filter_set(uint32_t default_action, const SyscallFilterSet *set, uint32_t action);
-int seccomp_load_syscall_filter_set_raw(uint32_t default_action, Set* set, uint32_t action);
+int seccomp_load_syscall_filter_set_raw(uint32_t default_action, Hashmap* set, uint32_t action);
 
 int seccomp_restrict_archs(Set *archs);
 int seccomp_restrict_namespaces(unsigned long retain);
index 8c1624f..ecac98e 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -58,10 +59,10 @@ int parse_sleep_config(const char *verb, char ***_modes, char ***_states) {
                 {}
         };
 
-        config_parse_many_nulstr(PKGSYSCONFDIR "/sleep.conf",
-                                 CONF_PATHS_NULSTR("systemd/sleep.conf.d"),
-                                 "Sleep\0", config_item_table_lookup, items,
-                                 false, NULL);
+        (void) config_parse_many_nulstr(PKGSYSCONFDIR "/sleep.conf",
+                                        CONF_PATHS_NULSTR("systemd/sleep.conf.d"),
+                                        "Sleep\0", config_item_table_lookup, items,
+                                        CONFIG_PARSE_WARN, NULL);
 
         if (streq(verb, "suspend")) {
                 /* empty by default */
index ad10039..fc5a81d 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index a46b752..9af5faa 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index fb0749b..158f883 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 9a40147..423069f 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 42b2989..9f26fa1 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
+#include "bus-util.h"
+
 int polkit_agent_open(void);
 void polkit_agent_close(void);
+
+static inline void polkit_agent_open_if_enabled(
+                BusTransport transport,
+                bool ask_password) {
+
+        /* Open the polkit agent as a child process if necessary */
+
+        if (transport != BUS_TRANSPORT_LOCAL)
+                return;
+
+        if (!ask_password)
+                return;
+
+        polkit_agent_open();
+}
index 8137904..23aaa88 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -31,6 +32,8 @@
 #include "macro.h"
 #include "specifier.h"
 #include "string-util.h"
+#include "strv.h"
+#include "user-util.h"
 
 /*
  * Generic infrastructure for replacing %x style specifiers in
  *
  */
 
+/* Any ASCII character or digit: our pool of potential specifiers,
+ * and "%" used for escaping. */
+#define POSSIBLE_SPECIFIERS ALPHANUMERICAL "%"
+
 int specifier_printf(const char *text, const Specifier table[], void *userdata, char **_ret) {
-        char *ret, *t;
+        size_t l;
+        _cleanup_free_ char *ret = NULL;
+        char *t;
         const char *f;
         bool percent = false;
-        size_t l;
         int r;
 
         assert(text);
@@ -73,28 +81,25 @@ int specifier_printf(const char *text, const Specifier table[], void *userdata,
                                         size_t k, j;
 
                                         r = i->lookup(i->specifier, i->data, userdata, &w);
-                                        if (r < 0) {
-                                                free(ret);
+                                        if (r < 0)
                                                 return r;
-                                        }
 
                                         j = t - ret;
                                         k = strlen(w);
 
                                         n = new(char, j + k + l + 1);
-                                        if (!n) {
-                                                free(ret);
+                                        if (!n)
                                                 return -ENOMEM;
-                                        }
 
                                         memcpy(n, ret, j);
                                         memcpy(n + j, w, k);
 
-                                        free(ret);
-
-                                        ret = n;
-                                        t = n + j + k;
-                                } else {
+                                        free_and_replace(ret, n);
+                                        t = ret + j + k;
+                                } else if (strchr(POSSIBLE_SPECIFIERS, *f))
+                                        /* Oops, an unknown specifier. */
+                                        return -EBADSLT;
+                                else {
                                         *(t++) = '%';
                                         *(t++) = *f;
                                 }
@@ -113,6 +118,7 @@ int specifier_printf(const char *text, const Specifier table[], void *userdata,
 
         *t = 0;
         *_ret = ret;
+        ret = NULL;
         return 0;
 }
 
@@ -190,3 +196,74 @@ int specifier_kernel_release(char specifier, void *data, void *userdata, char **
         *ret = n;
         return 0;
 }
+
+int specifier_user_name(char specifier, void *data, void *userdata, char **ret) {
+        char *t;
+
+        /* If we are UID 0 (root), this will not result in NSS, otherwise it might. This is good, as we want to be able
+         * to run this in PID 1, where our user ID is 0, but where NSS lookups are not allowed.
+
+         * We don't use getusername_malloc() here, because we don't want to look at $USER, to remain consistent with
+         * specifer_user_id() below.
+         */
+
+        t = uid_to_name(getuid());
+        if (!t)
+                return -ENOMEM;
+
+        *ret = t;
+        return 0;
+}
+
+int specifier_user_id(char specifier, void *data, void *userdata, char **ret) {
+
+        if (asprintf(ret, UID_FMT, getuid()) < 0)
+                return -ENOMEM;
+
+        return 0;
+}
+
+int specifier_user_home(char specifier, void *data, void *userdata, char **ret) {
+
+        /* On PID 1 (which runs as root) this will not result in NSS,
+         * which is good. See above */
+
+        return get_home_dir(ret);
+}
+
+int specifier_user_shell(char specifier, void *data, void *userdata, char **ret) {
+
+        /* On PID 1 (which runs as root) this will not result in NSS,
+         * which is good. See above */
+
+        return get_shell(ret);
+}
+
+int specifier_escape_strv(char **l, char ***ret) {
+        char **z, **p, **q;
+
+        assert(ret);
+
+        if (strv_isempty(l)) {
+                *ret = NULL;
+                return 0;
+        }
+
+        z = new(char*, strv_length(l)+1);
+        if (!z)
+                return -ENOMEM;
+
+        for (p = l, q = z; *p; p++, q++) {
+
+                *q = specifier_escape(*p);
+                if (!*q) {
+                        strv_free(z);
+                        return -ENOMEM;
+                }
+        }
+
+        *q = NULL;
+        *ret = z;
+
+        return 0;
+}
index 6b1623e..bd6bc55 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -19,6 +20,8 @@
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
+#include "string-util.h"
+
 typedef int (*SpecifierCallback)(char specifier, void *data, void *userdata, char **ret);
 
 typedef struct Specifier {
@@ -35,3 +38,14 @@ int specifier_machine_id(char specifier, void *data, void *userdata, char **ret)
 int specifier_boot_id(char specifier, void *data, void *userdata, char **ret);
 int specifier_host_name(char specifier, void *data, void *userdata, char **ret);
 int specifier_kernel_release(char specifier, void *data, void *userdata, char **ret);
+
+int specifier_user_name(char specifier, void *data, void *userdata, char **ret);
+int specifier_user_id(char specifier, void *data, void *userdata, char **ret);
+int specifier_user_home(char specifier, void *data, void *userdata, char **ret);
+int specifier_user_shell(char specifier, void *data, void *userdata, char **ret);
+
+static inline char* specifier_escape(const char *string) {
+        return strreplace(string, "%", "%%");
+}
+
+int specifier_escape_strv(char **l, char ***ret);
index afdf1ab..3c51fa3 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index a7a080b..abcdc1c 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 #include <stdbool.h>
index e1ccb32..189580e 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -59,7 +60,7 @@ int sysctl_write(const char *property, const char *value) {
         log_debug("Setting '%s' to '%s'", property, value);
 
         p = strjoina("/proc/sys/", property);
-        return write_string_file(p, value, 0);
+        return write_string_file(p, value, WRITE_STRING_FILE_DISABLE_BUFFER);
 }
 
 int sysctl_read(const char *property, char **content) {
index 2decb39..446aa6f 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 228e510..6b223b1 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd
 
index f300bbc..d78ab7b 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 7055124..b070f38 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
diff --git a/src/shared/tomoyo-util.c b/src/shared/tomoyo-util.c
new file mode 100644 (file)
index 0000000..390fff6
--- /dev/null
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+/***
+  This file is part of systemd.
+
+  Copyright 2017 Shawn Landden
+
+  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.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <unistd.h>
+
+#include "tomoyo-util.h"
+
+bool mac_tomoyo_use(void) {
+        static int cached_use = -1;
+
+        if (cached_use < 0)
+                cached_use = (access("/sys/kernel/security/tomoyo/version",
+                                     F_OK) == 0);
+
+        return cached_use;
+}
diff --git a/src/shared/tomoyo-util.h b/src/shared/tomoyo-util.h
new file mode 100644 (file)
index 0000000..4fb309f
--- /dev/null
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2017 Shawn Landden
+
+  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.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdbool.h>
+
+bool mac_tomoyo_use(void);
index f708dcf..65a09e9 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index a415be2..c5e4197 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index b6ec474..c38b7cc 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 4044eb4..882f662 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index fc8548c..1715c0f 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -424,7 +425,7 @@ int utmp_wall(
                 if (u->ut_type != USER_PROCESS || u->ut_user[0] == 0)
                         continue;
 
-                /* this access is fine, because strlen("/dev/") << 32 (UT_LINESIZE) */
+                /* this access is fine, because STRLEN("/dev/") << 32 (UT_LINESIZE) */
                 if (path_startswith(u->ut_line, "/dev/"))
                         path = u->ut_line;
                 else {
index 8f4fbcd..2c75d40 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 1edd96f..fa27016 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 365ed14..6d287fd 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index e7e9721..85512d0 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 17930ba..3ad037a 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 4f3e012..b0a422d 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
 
 #include "fd-util.h"
 #include "log.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 int update_timeout(void) {
@@ -83,7 +86,8 @@ static int open_watchdog(void) {
         if (watchdog_fd >= 0)
                 return 0;
 
-        watchdog_fd = open("/dev/watchdog", O_WRONLY|O_CLOEXEC);
+        watchdog_fd = open(watchdog_device ?: "/dev/watchdog",
+                           O_WRONLY|O_CLOEXEC);
         if (watchdog_fd < 0)
                 return -errno;
 
@@ -95,6 +99,10 @@ static int open_watchdog(void) {
         return update_timeout();
 }
 
+int watchdog_set_device(char *path) {
+        return free_and_strdup(&watchdog_device, path);
+}
+
 int watchdog_set_timeout(usec_t *usec) {
         int r;
 
index f6ec178..5694338 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
 #include "time-util.h"
 #include "util.h"
 
+int watchdog_set_device(char *path);
 int watchdog_set_timeout(usec_t *usec);
 int watchdog_ping(void);
 void watchdog_close(bool disarm);
+
+static inline void watchdog_free_device(void) {
+        (void) watchdog_set_device(NULL);
+}
index 4d774c9..518032e 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 34c9384..d4f401d 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -91,19 +92,10 @@ static void connection_free(Connection *c) {
 }
 
 static void context_free(Context *context) {
-        sd_event_source *es;
-        Connection *c;
-
         assert(context);
 
-        while ((es = set_steal_first(context->listen)))
-                sd_event_source_unref(es);
-
-        while ((c = set_first(context->connections)))
-                connection_free(c);
-
-        set_free(context->listen);
-        set_free(context->connections);
+        set_free_with_destructor(context->listen, sd_event_source_unref);
+        set_free_with_destructor(context->connections, connection_free);
 
         sd_event_unref(context->event);
         sd_resolve_unref(context->resolve);
index 097f8c1..4c09999 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -43,7 +44,7 @@ static int help(void) {
                "STDIO or socket-activatable proxy to a given DBus endpoint.\n\n"
                "  -h --help              Show this help\n"
                "     --version           Show package version\n"
-               "     --bus-path=PATH     Path to the kernel bus (default: %s)\n",
+               "  -p --bus-path=PATH     Path to the kernel bus (default: %s)\n",
                program_invocation_short_name, DEFAULT_BUS_PATH);
 
         return 0;
@@ -56,9 +57,10 @@ static int parse_argv(int argc, char *argv[]) {
         };
 
         static const struct option options[] = {
-                { "help",            no_argument,       NULL, 'h'     },
-                { "bus-path",        required_argument, NULL, 'p'     },
-                { NULL,              0,                 NULL, 0       }
+                { "help",            no_argument,       NULL, 'h'         },
+                { "version",         no_argument,       NULL, ARG_VERSION },
+                { "bus-path",        required_argument, NULL, 'p'         },
+                {},
         };
 
         int c;
diff --git a/src/sulogin-shell/meson.build b/src/sulogin-shell/meson.build
deleted file mode 100644 (file)
index 90e6f3e..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-executable('systemd-sulogin-shell',
-           ['sulogin-shell.c'],
-           include_directories : includes,
-           link_with : [libshared],
-           dependencies : [],
-           install_rpath : rootlibexecdir,
-           install : true,
-           install_dir : rootlibexecdir)
index 7933ddc..70659df 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
 
 #include "bus-util.h"
 #include "bus-error.h"
+#include "def.h"
 #include "log.h"
 #include "process-util.h"
 #include "sd-bus.h"
 #include "signal-util.h"
 
-static int start_default_target(void) {
+static int reload_manager(sd_bus *bus) {
         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
-        _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
+        _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
         int r;
 
-        r = bus_connect_system_systemd(&bus);
-        if (r < 0) {
-                log_error_errno(r, "Failed to get D-Bus connection: %m");
-                return false;
-        }
+        log_info("Reloading system manager configuration");
+
+        r = sd_bus_message_new_method_call(
+                        bus,
+                        &m,
+                        "org.freedesktop.systemd1",
+                        "/org/freedesktop/systemd1",
+                        "org.freedesktop.systemd1.Manager",
+                        "Reload");
+        if (r < 0)
+                return bus_log_create_error(r);
+
+        /* Note we use an extra-long timeout here. This is because a reload or reexec means generators are rerun which
+         * are timed out after DEFAULT_TIMEOUT_USEC. Let's use twice that time here, so that the generators can have
+         * their timeout, and for everything else there's the same time budget in place. */
+
+        r = sd_bus_call(bus, m, DEFAULT_TIMEOUT_USEC * 2, &error, NULL);
+        if (r < 0)
+                return log_error_errno(r, "Failed to reload daemon: %s", bus_error_message(&error, r));
+
+        return 0;
+}
+
+static int start_default_target(sd_bus *bus) {
+        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+        int r;
 
         log_info("Starting default target");
 
@@ -56,14 +79,12 @@ static int start_default_target(void) {
         return r;
 }
 
-static void fork_wait(const char* const cmdline[]) {
+static int fork_wait(const char* const cmdline[]) {
         pid_t pid;
 
         pid = fork();
-        if (pid < 0) {
-                log_error_errno(errno, "fork(): %m");
-                return;
-        }
+        if (pid < 0)
+                return log_error_errno(errno, "fork(): %m");
         if (pid == 0) {
 
                 /* Child */
@@ -77,18 +98,19 @@ static void fork_wait(const char* const cmdline[]) {
                 _exit(EXIT_FAILURE); /* Operational error */
         }
 
-        wait_for_terminate_and_warn(cmdline[0], pid, false);
+        return wait_for_terminate_and_warn(cmdline[0], pid, false);
 }
 
 static void print_mode(const char* mode) {
         printf("You are in %s mode. After logging in, type \"journalctl -xb\" to view\n"
-                "system logs, \"systemctl reboot\" to reboot, \"systemctl default\" or ^D to boot\n"
-                "into default mode.\n", mode);
+                "system logs, \"systemctl reboot\" to reboot, \"systemctl default\" or \"exit\"\n"
+                "to boot into default mode.\n", mode);
         fflush(stdout);
 }
 
 int main(int argc, char *argv[]) {
         static const char* const sulogin_cmdline[] = {SULOGIN, NULL};
+        _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
         int r;
 
         log_set_target(LOG_TARGET_AUTO);
@@ -97,9 +119,17 @@ int main(int argc, char *argv[]) {
 
         print_mode(argc > 1 ? argv[1] : "");
 
-        fork_wait(sulogin_cmdline);
+        (void) fork_wait(sulogin_cmdline);
 
-        r = start_default_target();
+        r = bus_connect_system_systemd(&bus);
+        if (r < 0) {
+                log_warning_errno(r, "Failed to get D-Bus connection: %m");
+                r = 0;
+        } else {
+                (void) reload_manager(bus);
+
+                r = start_default_target(bus);
+        }
 
         return r >= 0 ? EXIT_SUCCESS : EXIT_FAILURE;
 }
index a3ee605..b5922db 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -105,16 +106,16 @@ static int parse_file(OrderedHashmap *sysctl_options, const char *path, bool ign
 
         log_debug("Parsing %s", path);
         for (;;) {
-                char l[LINE_MAX], *p, *value, *new_value, *property, *existing;
+                char *p, *value, *new_value, *property, *existing;
+                _cleanup_free_ char *l = NULL;
                 void *v;
                 int k;
+                k = read_line(f, LONG_LINE_MAX, &l);
+                if (k == 0)
+                        break;
 
-                if (!fgets(l, sizeof(l), f)) {
-                        if (feof(f))
-                                break;
-
-                        return log_error_errno(errno, "Failed to read file '%s', ignoring: %m", path);
-                }
+                if (k < 0)
+                        return log_error_errno(k, "Failed to read file '%s', ignoring: %m", path);
 
                 c++;
 
index 933cb92..51cd0ae 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -27,6 +28,7 @@
 #include <stddef.h>
 #include <stdio.h>
 #include <string.h>
+#include <sys/prctl.h>
 #include <sys/reboot.h>
 #include <sys/socket.h>
 #include <unistd.h>
@@ -36,6 +38,7 @@
 #include "sd-login.h"
 
 #include "alloc-util.h"
+#include "bootspec.h"
 #include "bus-common-errors.h"
 #include "bus-error.h"
 #include "bus-message.h"
@@ -55,6 +58,7 @@
 #include "fs-util.h"
 #include "glob-util.h"
 #include "hostname-util.h"
+#include "hexdecoct.h"
 #include "initreq.h"
 #include "install.h"
 #include "io-util.h"
@@ -130,7 +134,7 @@ static bool arg_no_reload = false;
 static bool arg_value = false;
 static bool arg_show_types = false;
 static bool arg_ignore_inhibitors = false;
-static bool arg_dry = false;
+static bool arg_dry_run = false;
 static bool arg_quiet = false;
 static bool arg_full = false;
 static bool arg_recursive = false;
@@ -143,6 +147,7 @@ static const char *arg_kill_who = NULL;
 static int arg_signal = SIGTERM;
 static char *arg_root = NULL;
 static usec_t arg_when = 0;
+static char *arg_esp_path = NULL;
 static char *argv_cmdline = NULL;
 static enum action {
         ACTION_SYSTEMCTL,
@@ -216,6 +221,12 @@ static int acquire_bus(BusFocus focus, sd_bus **ret) {
 
                 user = arg_scope != UNIT_FILE_SYSTEM;
 
+                if (!user && sd_booted() <= 0) {
+                        /* Print a friendly message when the local system is actually not running systemd as PID 1. */
+                        log_error("System has not been booted with systemd as init system (PID 1). Can't operate.");
+                        return -EHOSTDOWN;
+                }
+
                 if (focus == BUS_MANAGER)
                         r = bus_connect_transport_systemd(arg_transport, arg_host, user, &busses[focus]);
                 else
@@ -256,6 +267,9 @@ static void ask_password_agent_open_if_enabled(void) {
 
         /* Open the password agent as a child process if necessary */
 
+        if (arg_dry_run)
+                return;
+
         if (!arg_ask_password)
                 return;
 
@@ -268,27 +282,19 @@ static void ask_password_agent_open_if_enabled(void) {
         ask_password_agent_open();
 }
 
-static void polkit_agent_open_if_enabled(void) {
-
+static void polkit_agent_open_maybe(void) {
         /* Open the polkit agent as a child process if necessary */
 
-        if (!arg_ask_password)
-                return;
-
         if (arg_scope != UNIT_FILE_SYSTEM)
                 return;
 
-        if (arg_transport != BUS_TRANSPORT_LOCAL)
-                return;
-
-        polkit_agent_open();
+        polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
 }
 
 static OutputFlags get_output_flags(void) {
         return
                 arg_all * OUTPUT_SHOW_ALL |
-                arg_full * OUTPUT_FULL_WIDTH |
-                (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
+                (arg_full || !on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
                 colors_enabled() * OUTPUT_COLOR |
                 !arg_quiet * OUTPUT_WARN_CUTOFF;
 }
@@ -422,12 +428,12 @@ static int output_units_list(const UnitInfo *unit_infos, unsigned c) {
         unsigned n_shown = 0;
         int job_count = 0;
 
-        max_id_len = strlen("UNIT");
-        load_len = strlen("LOAD");
-        active_len = strlen("ACTIVE");
-        sub_len = strlen("SUB");
-        job_len = strlen("JOB");
-        max_desc_len = strlen("DESCRIPTION");
+        max_id_len = STRLEN("UNIT");
+        load_len = STRLEN("LOAD");
+        active_len = STRLEN("ACTIVE");
+        sub_len = STRLEN("SUB");
+        job_len = STRLEN("JOB");
+        max_desc_len = STRLEN("DESCRIPTION");
 
         for (u = unit_infos; u < unit_infos + c; u++) {
                 max_id_len = MAX(max_id_len, strlen(u->id) + (u->machine ? strlen(u->machine)+1 : 0));
@@ -693,12 +699,7 @@ static int get_unit_list(
 }
 
 static void message_set_freep(Set **set) {
-        sd_bus_message *m;
-
-        while ((m = set_steal_first(*set)))
-                sd_bus_message_unref(m);
-
-        set_free(*set);
+        set_free_with_destructor(*set, sd_bus_message_unref);
 }
 
 static int get_unit_list_recursive(
@@ -913,10 +914,10 @@ static int socket_info_compare(const struct socket_info *a, const struct socket_
 
 static int output_sockets_list(struct socket_info *socket_infos, unsigned cs) {
         struct socket_info *s;
-        unsigned pathlen = strlen("LISTEN"),
-                typelen = strlen("TYPE") * arg_show_types,
-                socklen = strlen("UNIT"),
-                servlen = strlen("ACTIVATES");
+        unsigned pathlen = STRLEN("LISTEN"),
+                typelen = STRLEN("TYPE") * arg_show_types,
+                socklen = STRLEN("UNIT"),
+                servlen = STRLEN("ACTIVATES");
         const char *on, *off;
 
         for (s = socket_infos; s < socket_infos + cs; s++) {
@@ -1084,7 +1085,7 @@ static int get_next_elapse(
                         't',
                         &t.monotonic);
         if (r < 0)
-                return log_error_errno(r, "Failed to get next elapsation time: %s", bus_error_message(&error, r));
+                return log_error_errno(r, "Failed to get next elapse time: %s", bus_error_message(&error, r));
 
         r = sd_bus_get_property_trivial(
                         bus,
@@ -1096,7 +1097,7 @@ static int get_next_elapse(
                         't',
                         &t.realtime);
         if (r < 0)
-                return log_error_errno(r, "Failed to get next elapsation time: %s", bus_error_message(&error, r));
+                return log_error_errno(r, "Failed to get next elapse time: %s", bus_error_message(&error, r));
 
         *next = t;
         return 0;
@@ -1164,12 +1165,12 @@ static int timer_info_compare(const struct timer_info *a, const struct timer_inf
 static int output_timers_list(struct timer_info *timer_infos, unsigned n) {
         struct timer_info *t;
         unsigned
-                nextlen = strlen("NEXT"),
-                leftlen = strlen("LEFT"),
-                lastlen = strlen("LAST"),
-                passedlen = strlen("PASSED"),
-                unitlen = strlen("UNIT"),
-                activatelen = strlen("ACTIVATES");
+                nextlen = STRLEN("NEXT"),
+                leftlen = STRLEN("LEFT"),
+                lastlen = STRLEN("LAST"),
+                passedlen = STRLEN("PASSED"),
+                unitlen = STRLEN("UNIT"),
+                activatelen = STRLEN("ACTIVATES");
 
         const char *on, *off;
 
@@ -1409,8 +1410,8 @@ static void output_unit_file_list(const UnitFileList *units, unsigned c) {
         unsigned max_id_len, id_cols, state_cols;
         const UnitFileList *u;
 
-        max_id_len = strlen("UNIT FILE");
-        state_cols = strlen("STATE");
+        max_id_len = STRLEN("UNIT FILE");
+        state_cols = STRLEN("STATE");
 
         for (u = units; u < units + c; u++) {
                 max_id_len = MAX(max_id_len, strlen(basename(u->path)));
@@ -1998,15 +1999,16 @@ static void output_machines_list(struct machine_info *machine_infos, unsigned n)
         struct machine_info *m;
         unsigned
                 circle_len = 0,
-                namelen = sizeof("NAME") - 1,
-                statelen = sizeof("STATE") - 1,
-                failedlen = sizeof("FAILED") - 1,
-                jobslen = sizeof("JOBS") - 1;
+                namelen = STRLEN("NAME"),
+                statelen = STRLEN("STATE"),
+                failedlen = STRLEN("FAILED"),
+                jobslen = STRLEN("JOBS");
 
         assert(machine_infos || n == 0);
 
         for (m = machine_infos; m < machine_infos + n; m++) {
-                namelen = MAX(namelen, strlen(m->name) + (m->is_host ? sizeof(" (host)") - 1 : 0));
+                namelen = MAX(namelen,
+                              strlen(m->name) + (m->is_host ? STRLEN(" (host)") : 0));
                 statelen = MAX(statelen, strlen_ptr(m->state));
                 failedlen = MAX(failedlen, DECIMAL_STR_WIDTH(m->n_failed_units));
                 jobslen = MAX(jobslen, DECIMAL_STR_WIDTH(m->n_jobs));
@@ -2052,7 +2054,8 @@ static void output_machines_list(struct machine_info *machine_infos, unsigned n)
 
                 if (m->is_host)
                         printf("%-*s (host) %s%-*s%s %s%*" PRIu32 "%s %*" PRIu32 "\n",
-                               (int) (namelen - (sizeof(" (host)")-1)), strna(m->name),
+                               (int) (namelen - (STRLEN(" (host)"))),
+                               strna(m->name),
                                on_state, statelen, strna(m->state), off_state,
                                on_failed, failedlen, m->n_failed_units, off_failed,
                                jobslen, m->n_jobs);
@@ -2073,11 +2076,6 @@ static int list_machines(int argc, char *argv[], void *userdata) {
         sd_bus *bus;
         int r;
 
-        if (geteuid() != 0) {
-                log_error("Must be root.");
-                return -EPERM;
-        }
-
         r = acquire_bus(BUS_MANAGER, &bus);
         if (r < 0)
                 return r;
@@ -2163,7 +2161,7 @@ static int set_default(int argc, char *argv[], void *userdata) {
                 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
                 sd_bus *bus;
 
-                polkit_agent_open_if_enabled();
+                polkit_agent_open_maybe();
 
                 r = acquire_bus(BUS_MANAGER, &bus);
                 if (r < 0)
@@ -2260,10 +2258,10 @@ static void output_jobs_list(sd_bus *bus, const struct job_info* jobs, unsigned
 
         pager_open(arg_no_pager, false);
 
-        id_len = strlen("JOB");
-        unit_len = strlen("UNIT");
-        type_len = strlen("TYPE");
-        state_len = strlen("STATE");
+        id_len = STRLEN("JOB");
+        unit_len = STRLEN("UNIT");
+        type_len = STRLEN("TYPE");
+        state_len = STRLEN("STATE");
 
         for (j = jobs; j < jobs + n; j++) {
                 uint32_t id = j->id;
@@ -2391,7 +2389,7 @@ static int cancel_job(int argc, char *argv[], void *userdata) {
         if (r < 0)
                 return r;
 
-        polkit_agent_open_if_enabled();
+        polkit_agent_open_maybe();
 
         STRV_FOREACH(name, strv_skip(argv, 1)) {
                 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
@@ -2465,7 +2463,7 @@ static int need_daemon_reload(sd_bus *bus, const char *unit) {
 static void warn_unit_file_changed(const char *name) {
         assert(name);
 
-        log_warning("%sWarning:%s %s changed on disk. Run 'systemctl%s daemon-reload' to reload units.",
+        log_warning("%sWarning:%s The unit file, source configuration file or drop-ins of %s changed on disk. Run 'systemctl%s daemon-reload' to reload units.",
                     ansi_highlight_red(),
                     ansi_normal(),
                     name,
@@ -2938,7 +2936,11 @@ static int start_unit_one(
                         return log_error_errno(r, "Failed to add match for PropertiesChanged signal: %m");
         }
 
-        log_debug("Calling manager for %s on %s, %s", method, name, mode);
+        log_debug("%s manager for %s on %s, %s",
+                  arg_dry_run ? "Would call" : "Calling",
+                  method, name, mode);
+        if (arg_dry_run)
+                return 0;
 
         r = sd_bus_call_method(
                         bus,
@@ -3099,7 +3101,7 @@ static int start_unit(int argc, char *argv[], void *userdata) {
                 return r;
 
         ask_password_agent_open_if_enabled();
-        polkit_agent_open_if_enabled();
+        polkit_agent_open_maybe();
 
         if (arg_action == ACTION_SYSTEMCTL) {
                 enum action action;
@@ -3301,7 +3303,7 @@ static int logind_reboot(enum action a) {
                 return -EINVAL;
         }
 
-        polkit_agent_open_if_enabled();
+        polkit_agent_open_maybe();
         (void) logind_set_wall_message();
 
         r = sd_bus_call_method(
@@ -3419,7 +3421,7 @@ static int logind_check_inhibitors(enum action a) {
                 if (sd_session_get_class(*s, &class) < 0 || !streq(class, "user"))
                         continue;
 
-                if (sd_session_get_type(*s, &type) < 0 || !STR_IN_SET(type, "x11", "tty"))
+                if (sd_session_get_type(*s, &type) < 0 || !STR_IN_SET(type, "x11", "wayland", "tty", "mir"))
                         continue;
 
                 sd_session_get_tty(*s, &tty);
@@ -3490,6 +3492,76 @@ static int prepare_firmware_setup(void) {
         return logind_prepare_firmware_setup();
 }
 
+static int load_kexec_kernel(void) {
+        _cleanup_(boot_config_free) BootConfig config = {};
+        _cleanup_free_ char *where = NULL, *kernel = NULL, *initrd = NULL, *options = NULL;
+        const BootEntry *e;
+        pid_t pid;
+        int r;
+
+        if (kexec_loaded()) {
+                log_debug("Kexec kernel already loaded.");
+                return 0;
+        }
+
+        r = find_esp_and_warn(arg_esp_path, false, &where, NULL, NULL, NULL, NULL);
+        if (r == -ENOKEY) /* find_esp_and_warn() doesn't warn about this case */
+                return log_error_errno(r, "Cannot find the ESP partition mount point.");
+        if (r < 0) /* But it logs about all these cases, hence don't log here again */
+                return r;
+
+        r = boot_entries_load_config(where, &config);
+        if (r < 0)
+                return log_error_errno(r, "Failed to load bootspec config from \"%s/loader\": %m", where);
+
+        if (config.default_entry < 0) {
+                log_error("No entry suitable as default, refusing to guess.");
+                return -ENOENT;
+        }
+        e = &config.entries[config.default_entry];
+
+        if (strv_length(e->initrd) > 1) {
+                log_error("Boot entry specifies multiple initrds, which is not supported currently.");
+                return -EINVAL;
+        }
+
+        kernel = path_join(NULL, where, e->kernel);
+        if (!strv_isempty(e->initrd))
+                initrd = path_join(NULL, where, *e->initrd);
+        options = strv_join(e->options, " ");
+        if (!options)
+                return log_oom();
+
+        log_debug("%s kexec kernel %s initrd %s options \"%s\".",
+                  arg_dry_run ? "Would load" : "loading",
+                  kernel, initrd, options);
+        if (arg_dry_run)
+                return 0;
+
+        pid = fork();
+        if (pid < 0)
+                return log_error_errno(errno, "Failed to fork: %m");
+        else if (pid == 0) {
+
+                const char* const args[] = {
+                        KEXEC,
+                        "--load", kernel,
+                        "--append", options,
+                        initrd ? "--initrd" : NULL, initrd,
+                        NULL };
+
+                /* Child */
+
+                (void) reset_all_signal_handlers();
+                (void) reset_signal_mask();
+                assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
+
+                execv(args[0], (char * const *) args);
+                _exit(EXIT_FAILURE);
+        } else
+                return wait_for_terminate_and_warn("kexec", pid, true);
+}
+
 static int set_exit_code(uint8_t code) {
         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
         sd_bus *bus;
@@ -3528,9 +3600,10 @@ static int start_special(int argc, char *argv[], void *userdata) {
         if (r < 0)
                 return r;
 
-        if (arg_force >= 2 && geteuid() != 0) {
-                log_error("Must be root.");
-                return -EPERM;
+        if (arg_force >= 2) {
+                r = must_be_root();
+                if (r < 0)
+                        return r;
         }
 
         r = prepare_firmware_setup();
@@ -3542,6 +3615,11 @@ static int start_special(int argc, char *argv[], void *userdata) {
                 if (r < 0)
                         return r;
 
+        } else if (a == ACTION_KEXEC) {
+                r = load_kexec_kernel();
+                if (r < 0)
+                        return r;
+
         } else if (a == ACTION_EXIT && argc > 1) {
                 uint8_t code;
 
@@ -3673,7 +3751,7 @@ static int kill_unit(int argc, char *argv[], void *userdata) {
         if (r < 0)
                 return r;
 
-        polkit_agent_open_if_enabled();
+        polkit_agent_open_maybe();
 
         if (!arg_kill_who)
                 arg_kill_who = "all";
@@ -4166,10 +4244,15 @@ static void print_status_info(
                         printf(" Main PID: "PID_FMT, i->main_pid);
 
                         if (i->running) {
-                                _cleanup_free_ char *comm = NULL;
-                                (void) get_process_comm(i->main_pid, &comm);
-                                if (comm)
-                                        printf(" (%s)", comm);
+
+                                if (arg_transport == BUS_TRANSPORT_LOCAL) {
+                                        _cleanup_free_ char *comm = NULL;
+
+                                        (void) get_process_comm(i->main_pid, &comm);
+                                        if (comm)
+                                                printf(" (%s)", comm);
+                                }
+
                         } else if (i->exit_code > 0) {
                                 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
 
@@ -4198,9 +4281,11 @@ static void print_status_info(
 
                         printf(PID_FMT, i->control_pid);
 
-                        (void) get_process_comm(i->control_pid, &c);
-                        if (c)
-                                printf(" (%s)", c);
+                        if (arg_transport == BUS_TRANSPORT_LOCAL) {
+                                (void) get_process_comm(i->control_pid, &c);
+                                if (c)
+                                        printf(" (%s)", c);
+                        }
                 }
 
                 printf("\n");
@@ -4693,7 +4778,7 @@ skip:
                         printf(fmt "\n", __VA_ARGS__);                  \
                 else                                                    \
                         printf("%s=" fmt "\n", name, __VA_ARGS__);      \
-        } while(0)
+        } while (0)
 
 static int print_property(const char *name, sd_bus_message *m, const char *contents) {
         int r;
@@ -4979,6 +5064,24 @@ static int print_property(const char *name, sd_bus_message *m, const char *conte
                                 return bus_log_parse_error(r);
 
                         return 0;
+
+                } else if (contents[1] == SD_BUS_TYPE_BYTE && streq(name, "StandardInputData")) {
+                        _cleanup_free_ char *h = NULL;
+                        const void *p;
+                        size_t sz;
+                        ssize_t n;
+
+                        r = sd_bus_message_read_array(m, 'y', &p, &sz);
+                        if (r < 0)
+                                return bus_log_parse_error(r);
+
+                        n = base64mem(p, sz, &h);
+                        if (n < 0)
+                                return log_oom();
+
+                        print_prop(name, "%s", h);
+
+                        return 0;
                 }
 
                 break;
@@ -5239,11 +5342,13 @@ static int show_system_status(sd_bus *bus) {
         if (streq_ptr(mi.state, "degraded")) {
                 on = ansi_highlight_red();
                 off = ansi_normal();
-        } else if (!streq_ptr(mi.state, "running")) {
+        } else if (streq_ptr(mi.state, "running")) {
+                on = ansi_highlight_green();
+                off = ansi_normal();
+        } else {
                 on = ansi_highlight_yellow();
                 off = ansi_normal();
-        } else
-                on = off = "";
+        }
 
         printf("%s%s%s %s\n", on, special_glyph(BLACK_CIRCLE), off, arg_host ? arg_host : hn);
 
@@ -5484,7 +5589,7 @@ static int set_property(int argc, char *argv[], void *userdata) {
         if (r < 0)
                 return r;
 
-        polkit_agent_open_if_enabled();
+        polkit_agent_open_maybe();
 
         r = sd_bus_message_new_method_call(
                         bus,
@@ -5534,7 +5639,7 @@ static int daemon_reload(int argc, char *argv[], void *userdata) {
         if (r < 0)
                 return r;
 
-        polkit_agent_open_if_enabled();
+        polkit_agent_open_maybe();
 
         switch (arg_action) {
 
@@ -5590,11 +5695,14 @@ static int trivial_method(int argc, char *argv[], void *userdata) {
         sd_bus *bus;
         int r;
 
+        if (arg_dry_run)
+                return 0;
+
         r = acquire_bus(BUS_MANAGER, &bus);
         if (r < 0)
                 return r;
 
-        polkit_agent_open_if_enabled();
+        polkit_agent_open_maybe();
 
         method =
                 streq(argv[0], "clear-jobs")    ||
@@ -5637,7 +5745,7 @@ static int reset_failed(int argc, char *argv[], void *userdata) {
         if (r < 0)
                 return r;
 
-        polkit_agent_open_if_enabled();
+        polkit_agent_open_maybe();
 
         r = expand_names(bus, strv_skip(argv, 1), NULL, &names);
         if (r < 0)
@@ -5822,7 +5930,7 @@ static int set_environment(int argc, char *argv[], void *userdata) {
         if (r < 0)
                 return r;
 
-        polkit_agent_open_if_enabled();
+        polkit_agent_open_maybe();
 
         method = streq(argv[0], "set-environment")
                 ? "SetEnvironment"
@@ -5859,7 +5967,7 @@ static int import_environment(int argc, char *argv[], void *userdata) {
         if (r < 0)
                 return r;
 
-        polkit_agent_open_if_enabled();
+        polkit_agent_open_maybe();
 
         r = sd_bus_message_new_method_call(
                         bus,
@@ -5980,7 +6088,7 @@ static int enable_sysv_units(const char *verb, char **args) {
                 if (!p)
                         return log_oom();
 
-                p[strlen(p) - strlen(".service")] = 0;
+                p[strlen(p) - STRLEN(".service")] = 0;
                 found_sysv = access(p, F_OK) >= 0;
                 if (!found_sysv)
                         continue;
@@ -6305,7 +6413,7 @@ static int enable_unit(int argc, char *argv[], void *userdata) {
                 if (r < 0)
                         return r;
 
-                polkit_agent_open_if_enabled();
+                polkit_agent_open_maybe();
 
                 if (streq(verb, "enable")) {
                         method = "EnableUnitFiles";
@@ -6475,7 +6583,7 @@ static int add_dependency(int argc, char *argv[], void *userdata) {
                 if (r < 0)
                         return r;
 
-                polkit_agent_open_if_enabled();
+                polkit_agent_open_maybe();
 
                 r = sd_bus_message_new_method_call(
                                 bus,
@@ -6537,7 +6645,7 @@ static int preset_all(int argc, char *argv[], void *userdata) {
                 if (r < 0)
                         return r;
 
-                polkit_agent_open_if_enabled();
+                polkit_agent_open_maybe();
 
                 r = sd_bus_call_method(
                                 bus,
@@ -7165,6 +7273,7 @@ static void systemctl_help(void) {
                "     --kill-who=WHO   Who to send signal to\n"
                "  -s --signal=SIGNAL  Which signal to send\n"
                "     --now            Start or stop unit in addition to enabling or disabling it\n"
+               "     --dry-run        Only print what would be done\n"
                "  -q --quiet          Suppress output\n"
                "     --wait           For (re)start, wait until service stopped again\n"
                "     --no-block       Do not wait until operation finished\n"
@@ -7174,12 +7283,14 @@ static void systemctl_help(void) {
                "     --no-pager       Do not pipe output into a pager\n"
                "     --no-ask-password\n"
                "                      Do not ask for system passwords\n"
-               "     --global         Enable/disable unit files globally\n"
-               "     --runtime        Enable unit files only temporarily until next reboot\n"
+               "     --global         Enable/disable/mask unit files globally\n"
+               "     --runtime        Enable/disable/mask unit files temporarily until next\n"
+               "                      reboot\n"
                "  -f --force          When enabling unit files, override existing symlinks\n"
                "                      When shutting down, execute action immediately\n"
                "     --preset-mode=   Apply only enable, only disable, or all presets\n"
-               "     --root=PATH      Enable unit files in the specified root directory\n"
+               "     --root=PATH      Enable/disable/mask unit files in the specified root\n"
+               "                      directory\n"
                "  -n --lines=INTEGER  Number of journal entries to show\n"
                "  -o --output=STRING  Change journal output mode (short, short-precise,\n"
                "                             short-iso, short-iso-precise, short-full,\n"
@@ -7409,6 +7520,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
                 ARG_REVERSE,
                 ARG_AFTER,
                 ARG_BEFORE,
+                ARG_DRY_RUN,
                 ARG_SHOW_TYPES,
                 ARG_IRREVERSIBLE,
                 ARG_IGNORE_DEPENDENCIES,
@@ -7464,6 +7576,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
                 { "no-legend",           no_argument,       NULL, ARG_NO_LEGEND           },
                 { "no-pager",            no_argument,       NULL, ARG_NO_PAGER            },
                 { "no-wall",             no_argument,       NULL, ARG_NO_WALL             },
+                { "dry-run",             no_argument,       NULL, ARG_DRY_RUN             },
                 { "quiet",               no_argument,       NULL, 'q'                     },
                 { "root",                required_argument, NULL, ARG_ROOT                },
                 { "force",               no_argument,       NULL, ARG_FORCE               },
@@ -7673,6 +7786,10 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
 
                         break;
 
+                case ARG_DRY_RUN:
+                        arg_dry_run = true;
+                        break;
+
                 case 'q':
                         arg_quiet = true;
                         break;
@@ -7878,7 +7995,7 @@ static int halt_parse_argv(int argc, char *argv[]) {
                         break;
 
                 case 'w':
-                        arg_dry = true;
+                        arg_dry_run = true;
                         break;
 
                 case 'd':
@@ -7998,7 +8115,7 @@ static int shutdown_parse_argv(int argc, char *argv[]) {
         assert(argc >= 0);
         assert(argv);
 
-        while ((c = getopt_long(argc, argv, "HPrhkKtafFc", options, NULL)) >= 0)
+        while ((c = getopt_long(argc, argv, "HPrhkKat:fFc", options, NULL)) >= 0)
                 switch (c) {
 
                 case ARG_HELP:
@@ -8030,15 +8147,15 @@ static int shutdown_parse_argv(int argc, char *argv[]) {
                         break;
 
                 case 'k':
-                        arg_dry = true;
+                        arg_dry_run = true;
                         break;
 
                 case ARG_NO_WALL:
                         arg_no_wall = true;
                         break;
 
-                case 't':
                 case 'a':
+                case 't': /* Note that we also ignore any passed argument to -t, not just the -t itself */
                 case 'f':
                 case 'F':
                         /* Compatibility nops */
@@ -8319,7 +8436,7 @@ static int systemctl_main(int argc, char *argv[]) {
                 { "list-sockets",          VERB_ANY, VERB_ANY, VERB_NOCHROOT, list_sockets         },
                 { "list-timers",           VERB_ANY, VERB_ANY, VERB_NOCHROOT, list_timers          },
                 { "list-jobs",             VERB_ANY, VERB_ANY, VERB_NOCHROOT, list_jobs            },
-                { "list-machines",         VERB_ANY, VERB_ANY, VERB_NOCHROOT, list_machines        },
+                { "list-machines",         VERB_ANY, VERB_ANY, VERB_NOCHROOT|VERB_MUSTBEROOT, list_machines },
                 { "clear-jobs",            VERB_ANY, 1,        VERB_NOCHROOT, trivial_method       },
                 { "cancel",                VERB_ANY, VERB_ANY, VERB_NOCHROOT, cancel_job           },
                 { "start",                 2,        VERB_ANY, VERB_NOCHROOT, start_unit           },
@@ -8421,24 +8538,28 @@ static int halt_now(enum action a) {
         /* The kernel will automaticall flush ATA disks and suchlike
          * on reboot(), but the file systems need to be synce'd
          * explicitly in advance. */
-        if (!arg_no_sync)
+        if (!arg_no_sync && !arg_dry_run)
                 (void) sync();
 
-        /* Make sure C-A-D is handled by the kernel from this point
-         * on... */
-        (void) reboot(RB_ENABLE_CAD);
+        /* Make sure C-A-D is handled by the kernel from this point on... */
+        if (!arg_dry_run)
+                (void) reboot(RB_ENABLE_CAD);
 
         switch (a) {
 
         case ACTION_HALT:
                 if (!arg_quiet)
                         log_info("Halting.");
+                if (arg_dry_run)
+                        return 0;
                 (void) reboot(RB_HALT_SYSTEM);
                 return -errno;
 
         case ACTION_POWEROFF:
                 if (!arg_quiet)
                         log_info("Powering off.");
+                if (arg_dry_run)
+                        return 0;
                 (void) reboot(RB_POWER_OFF);
                 return -errno;
 
@@ -8453,12 +8574,17 @@ static int halt_now(enum action a) {
                 if (!isempty(param)) {
                         if (!arg_quiet)
                                 log_info("Rebooting with argument '%s'.", param);
-                        (void) syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_RESTART2, param);
-                        log_warning_errno(errno, "Failed to reboot with parameter, retrying without: %m");
+                        if (!arg_dry_run) {
+                                (void) syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
+                                               LINUX_REBOOT_CMD_RESTART2, param);
+                                log_warning_errno(errno, "Failed to reboot with parameter, retrying without: %m");
+                        }
                 }
 
                 if (!arg_quiet)
                         log_info("Rebooting.");
+                if (arg_dry_run)
+                        return 0;
                 (void) reboot(RB_AUTOBOOT);
                 return -errno;
         }
@@ -8500,7 +8626,7 @@ static int logind_schedule_shutdown(void) {
                 break;
         }
 
-        if (arg_dry)
+        if (arg_dry_run)
                 action = strjoina("dry-", action);
 
         (void) logind_set_wall_message();
@@ -8539,8 +8665,8 @@ static int halt_main(void) {
                 return logind_schedule_shutdown();
 
         if (geteuid() != 0) {
-                if (arg_dry || arg_force > 0) {
-                        log_error("Must be root.");
+                if (arg_dry_run || arg_force > 0) {
+                        (void) must_be_root();
                         return -EPERM;
                 }
 
@@ -8560,7 +8686,7 @@ static int halt_main(void) {
                 }
         }
 
-        if (!arg_dry && !arg_force)
+        if (!arg_dry_run && !arg_force)
                 return start_with_fallback();
 
         assert(geteuid() == 0);
@@ -8575,7 +8701,7 @@ static int halt_main(void) {
                 }
         }
 
-        if (arg_dry)
+        if (arg_dry_run)
                 return 0;
 
         r = halt_now(arg_action);
@@ -8723,6 +8849,7 @@ finish:
 
         strv_free(arg_wall);
         free(arg_root);
+        free(arg_esp_path);
 
         /* Note that we return r here, not EXIT_SUCCESS, so that we can implement the LSB-like return codes */
         return r < 0 ? EXIT_FAILURE : r;
index 97c3943..b4400e7 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #ifndef foosdcommonhfoo
 #define foosdcommonhfoo
 
index debbd46..16e4b35 100644 (file)
@@ -1,3 +1,20 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
+# Copyright 2017 Zbigniew Jędrzejewski-Szmek
+#
+# 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.
+#
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
 _systemd_headers = '''
         sd-bus.h
         sd-bus-protocol.h
index 623cee0..63e3702 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #ifndef foosdbusprotocolhfoo
 #define foosdbusprotocolhfoo
 
index 1e82cae..f6fb40f 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #ifndef foosdbusvtablehfoo
 #define foosdbusvtablehfoo
 
index 2b6aeb7..c5c7096 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #ifndef foosdbushfoo
 #define foosdbushfoo
 
@@ -216,6 +217,7 @@ void *sd_bus_slot_get_current_userdata(sd_bus_slot *slot);
 
 /* Message object */
 
+int sd_bus_message_new(sd_bus *bus, sd_bus_message **m, uint8_t type);
 int sd_bus_message_new_signal(sd_bus *bus, sd_bus_message **m, const char *path, const char *interface, const char *member);
 int sd_bus_message_new_method_call(sd_bus *bus, sd_bus_message **m, const char *destination, const char *path, const char *interface, const char *member);
 int sd_bus_message_new_method_return(sd_bus_message *call, sd_bus_message **m);
@@ -227,6 +229,8 @@ int sd_bus_message_new_method_errnof(sd_bus_message *call, sd_bus_message **m, i
 sd_bus_message* sd_bus_message_ref(sd_bus_message *m);
 sd_bus_message* sd_bus_message_unref(sd_bus_message *m);
 
+int sd_bus_message_seal(sd_bus_message *m, uint64_t cookie, uint64_t timeout_usec);
+
 int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type);
 int sd_bus_message_get_cookie(sd_bus_message *m, uint64_t *cookie);
 int sd_bus_message_get_reply_cookie(sd_bus_message *m, uint64_t *cookie);
index 8c096f6..9772a05 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #ifndef foosddaemonhfoo
 #define foosddaemonhfoo
 
@@ -174,12 +175,22 @@ int sd_is_mq(int fd, const char *path);
   newline separated environment-style variable assignments in a
   string. The following variables are known:
 
-     READY=1      Tells systemd that daemon startup is finished (only
-                  relevant for services of Type=notify). The passed
-                  argument is a boolean "1" or "0". Since there is
-                  little value in signaling non-readiness the only
+     MAINPID=...  The main PID of a daemon, in case systemd did not
+                  fork off the process itself. Example: "MAINPID=4711"
+
+     READY=1      Tells systemd that daemon startup or daemon reload
+                  is finished (only relevant for services of Type=notify).
+                  The passed argument is a boolean "1" or "0". Since there
+                  is little value in signaling non-readiness the only
                   value daemons should send is "READY=1".
 
+     RELOADING=1  Tell systemd that the daemon began reloading its
+                  configuration. When the configuration has been
+                  reloaded completely, READY=1 should be sent to inform
+                  systemd about this.
+
+     STOPPING=1   Tells systemd that the daemon is about to go down.
+
      STATUS=...   Passes a single-line status string back to systemd
                   that describes the daemon state. This is free-form
                   and can be used for various purposes: general state
@@ -194,25 +205,31 @@ int sd_is_mq(int fd, const char *path);
      BUSERROR=... If a daemon fails, the D-Bus error-style error
                   code. Example: "BUSERROR=org.freedesktop.DBus.Error.TimedOut"
 
-     MAINPID=...  The main pid of a daemon, in case systemd did not
-                  fork off the process itself. Example: "MAINPID=4711"
-
      WATCHDOG=1   Tells systemd to update the watchdog timestamp.
                   Services using this feature should do this in
                   regular intervals. A watchdog framework can use the
                   timestamps to detect failed services. Also see
                   sd_watchdog_enabled() below.
 
+     WATCHDOG_USEC=...
+                  Reset watchdog_usec value during runtime.
+                  To reset watchdog_usec value, start the service again.
+                  Example: "WATCHDOG_USEC=20000000"
+
      FDSTORE=1    Store the file descriptors passed along with the
                   message in the per-service file descriptor store,
                   and pass them to the main process again on next
                   invocation. This variable is only supported with
                   sd_pid_notify_with_fds().
 
-     WATCHDOG_USEC=...
-                  Reset watchdog_usec value during runtime.
-                  To reset watchdog_usec value, start the service again.
-                  Example: "WATCHDOG_USEC=20000000"
+     FDSTOREREMOVE=1
+                  Remove one or more file descriptors from the file
+                  descriptor store, identified by the name specified
+                  in FDNAME=, see below.
+
+     FDNAME=      A name to assign to new file descriptors stored in the
+                  file descriptor store, or the name of the file descriptors
+                  to remove in case of FDSTOREREMOVE=1.
 
   Daemons can choose to send additional variables. However, it is
   recommended to prefix variable names not listed above with X_.
index c1d0756..6ac0b13 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #ifndef foosddevicehfoo
 #define foosddevicehfoo
 
index 5e46d8d..6eb9eb6 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #ifndef foosddhcpclienthfoo
 #define foosddhcpclienthfoo
 
index 7ab99cc..3cc7fca 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #ifndef foosddhcpleasehfoo
 #define foosddhcpleasehfoo
 
index d4517a2..9d39e43 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #ifndef foosddhcpserverhfoo
 #define foosddhcpserverhfoo
 
index 7819f0d..37803c7 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #ifndef foosddhcp6clienthfoo
 #define foosddhcp6clienthfoo
 
@@ -68,6 +69,8 @@ enum {
 
         /* option code 35 is unassigned */
 
+        SD_DHCP6_OPTION_FQDN                       = 39,  /* RFC 4704 */
+
         SD_DHCP6_OPTION_NTP_SERVER                 = 56,  /* RFC 5908 */
 
         /* option codes 89-142 are unassigned */
@@ -101,6 +104,9 @@ int sd_dhcp6_client_set_duid(
 int sd_dhcp6_client_set_iaid(
                 sd_dhcp6_client *client,
                 uint32_t iaid);
+int sd_dhcp6_client_set_fqdn(
+                sd_dhcp6_client *client,
+                const char *fqdn);
 int sd_dhcp6_client_set_information_request(
                 sd_dhcp6_client *client,
                 int enabled);
index 184fbb8..5807b18 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #ifndef foosddhcp6leasehfoo
 #define foosddhcp6leasehfoo
 
index f8cb895..9083d5f 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #ifndef foosdeventhfoo
 #define foosdeventhfoo
 
index 7105920..fd69aaf 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #ifndef foosdhwdbhfoo
 #define foosdhwdbhfoo
 
index 9b38969..67fc595 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #ifndef foosdid128hfoo
 #define foosdid128hfoo
 
index 16d9998..677ae3b 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #ifndef foosdipv4acdfoo
 #define foosdipv4acdfoo
 
index 5ba9208..c330b0a 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #ifndef foosdipv4llfoo
 #define foosdipv4llfoo
 
index 9c36b27..2a70d5e 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #ifndef foosdjournalhfoo
 #define foosdjournalhfoo
 
index 3f35eeb..0a76fa6 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #ifndef foosdlldphfoo
 #define foosdlldphfoo
 
index e3ecbd8..d8e2c68 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #ifndef foosdloginhfoo
 #define foosdloginhfoo
 
index 8c23486..5a3f78b 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #ifndef foosdmessageshfoo
 #define foosdmessageshfoo
 
@@ -69,6 +70,8 @@ _SD_BEGIN_DECLARATIONS;
 #define SD_MESSAGE_TIMEZONE_CHANGE        SD_ID128_MAKE(45,f8,2f,4a,ef,7a,4b,bf,94,2c,e8,61,d1,f2,09,90)
 #define SD_MESSAGE_TIMEZONE_CHANGE_STR    SD_ID128_MAKE_STR(45,f8,2f,4a,ef,7a,4b,bf,94,2c,e8,61,d1,f2,09,90)
 
+#define SD_MESSAGE_TAINTED                SD_ID128_MAKE(50,87,6a,9d,b0,0f,4c,40,bd,e1,a2,ad,38,1c,3a,1b)
+#define SD_MESSAGE_TAINTED_STR            SD_ID128_MAKE_STR(50,87,6a,9d,b0,0f,4c,40,bd,e1,a2,ad,38,1c,3a,1b)
 #define SD_MESSAGE_STARTUP_FINISHED       SD_ID128_MAKE(b0,7a,24,9c,d0,24,41,4a,82,dd,00,cd,18,13,78,ff)
 #define SD_MESSAGE_STARTUP_FINISHED_STR   SD_ID128_MAKE_STR(b0,7a,24,9c,d0,24,41,4a,82,dd,00,cd,18,13,78,ff)
 #define SD_MESSAGE_USER_STARTUP_FINISHED \
index 9f7d4ef..1521145 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #ifndef foosdndiscfoo
 #define foosdndiscfoo
 
index b28fc0d..d6e3816 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #ifndef foosdnetlinkhfoo
 #define foosdnetlinkhfoo
 
index 0f13e2b..2d48946 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #ifndef foosdnetworkhfoo
 #define foosdnetworkhfoo
 
@@ -94,6 +95,14 @@ int sd_network_link_get_setup_state(int ifindex, char **state);
  */
 int sd_network_link_get_operational_state(int ifindex, char **state);
 
+/* Indicates whether the network is relevant to being online.
+ * Possible return codes:
+ *   0: the connection is not required
+ *   1: the connection is required to consider the system online
+ *   <0: networkd is not aware of the link
+ */
+int sd_network_link_get_required_for_online(int ifindex);
+
 /* Get path to .network file applied to link */
 int sd_network_link_get_network_file(int ifindex, char **filename);
 
index be6abdc..2dfc896 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #ifndef foosdpathhfoo
 #define foosdpathhfoo
 
index 0cc1d67..94d5e71 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #ifndef foosdradvfoo
 #define foosdradvfoo
 
 
 _SD_BEGIN_DECLARATIONS;
 
+#define SD_RADV_DEFAULT_MIN_TIMEOUT_USEC        (200*USEC_PER_SEC)
+#define SD_RADV_DEFAULT_MAX_TIMEOUT_USEC        (600*USEC_PER_SEC)
+
+#define SD_RADV_DEFAULT_DNS_LIFETIME_USEC       (3*SD_RADV_DEFAULT_MAX_TIMEOUT_USEC)
+
 typedef struct sd_radv sd_radv;
 typedef struct sd_radv_prefix sd_radv_prefix;
 
index 1c792da..14d0cbd 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #ifndef foosdresolvehfoo
 #define foosdresolvehfoo
 
index 6781983..cd02c6a 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #ifndef foosdutf8hfoo
 #define foosdutf8hfoo
 
index 6ef00d8..d800945 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -1863,20 +1864,15 @@ int main(int argc, char *argv[]) {
                 log_error_errno(r, "Failed to write files: %m");
 
 finish:
-        while ((i = hashmap_steal_first(groups)))
-                item_free(i);
-
-        while ((i = hashmap_steal_first(users)))
-                item_free(i);
+        hashmap_free_with_destructor(groups, item_free);
+        hashmap_free_with_destructor(users, item_free);
 
         while ((n = hashmap_first_key(members))) {
                 strv_free(hashmap_steal_first(members));
                 free(n);
         }
-
-        hashmap_free(groups);
-        hashmap_free(users);
         hashmap_free(members);
+
         hashmap_free(todo_uids);
         hashmap_free(todo_gids);
 
index 195f7a0..51306b5 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -38,6 +39,7 @@
 #include "path-util.h"
 #include "set.h"
 #include "special.h"
+#include "specifier.h"
 #include "stat-util.h"
 #include "string-util.h"
 #include "strv.h"
@@ -94,12 +96,7 @@ static void free_sysvstub(SysvStub *s) {
 DEFINE_TRIVIAL_CLEANUP_FUNC(SysvStub*, free_sysvstub);
 
 static void free_sysvstub_hashmapp(Hashmap **h) {
-        SysvStub *stub;
-
-        while ((stub = hashmap_steal_first(*h)))
-                free_sysvstub(stub);
-
-        hashmap_free(*h);
+        hashmap_free_with_destructor(*h, free_sysvstub);
 }
 
 static int add_alias(const char *service, const char *alias) {
@@ -123,6 +120,7 @@ static int add_alias(const char *service, const char *alias) {
 }
 
 static int generate_unit_file(SysvStub *s) {
+        _cleanup_free_ char *path_escaped = NULL;
         _cleanup_fclose_ FILE *f = NULL;
         const char *unit;
         char **p;
@@ -133,6 +131,10 @@ static int generate_unit_file(SysvStub *s) {
         if (!s->loaded)
                 return 0;
 
+        path_escaped = specifier_escape(s->path);
+        if (!path_escaped)
+                return log_oom();
+
         unit = strjoina(arg_dest, "/", s->name);
 
         /* We might already have a symlink with the same name from a Provides:,
@@ -152,10 +154,17 @@ static int generate_unit_file(SysvStub *s) {
                 "[Unit]\n"
                 "Documentation=man:systemd-sysv-generator(8)\n"
                 "SourcePath=%s\n",
-                s->path);
+                path_escaped);
+
+        if (s->description) {
+                _cleanup_free_ char *t;
+
+                t = specifier_escape(s->description);
+                if (!t)
+                        return log_oom();
 
-        if (s->description)
-                fprintf(f, "Description=%s\n", s->description);
+                fprintf(f, "Description=%s\n", t);
+        }
 
         STRV_FOREACH(p, s->before)
                 fprintf(f, "Before=%s\n", *p);
@@ -175,8 +184,15 @@ static int generate_unit_file(SysvStub *s) {
                 "RemainAfterExit=%s\n",
                 yes_no(!s->pid_file));
 
-        if (s->pid_file)
-                fprintf(f, "PIDFile=%s\n", s->pid_file);
+        if (s->pid_file) {
+                _cleanup_free_ char *t;
+
+                t = specifier_escape(s->pid_file);
+                if (!t)
+                        return log_oom();
+
+                fprintf(f, "PIDFile=%s\n", t);
+        }
 
         /* Consider two special LSB exit codes a clean exit */
         if (s->has_lsb)
@@ -188,10 +204,10 @@ static int generate_unit_file(SysvStub *s) {
         fprintf(f,
                 "ExecStart=%s start\n"
                 "ExecStop=%s stop\n",
-                s->path, s->path);
+                path_escaped, path_escaped);
 
         if (s->reload)
-                fprintf(f, "ExecReload=%s reload\n", s->path);
+                fprintf(f, "ExecReload=%s reload\n", path_escaped);
 
         r = fflush_and_check(f);
         if (r < 0)
index 1f3db65..6bb5bd6 100644 (file)
@@ -1,3 +1,20 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
+# Copyright 2017 Zbigniew Jędrzejewski-Szmek
+#
+# 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.
+#
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
 awkscript = 'test-hashmap-ordered.awk'
 test_hashmap_ordered_c = custom_target(
         'test-hashmap-ordered.c',
@@ -37,6 +54,10 @@ test_dlopen_c = files('test-dlopen.c')
 
 ############################################################
 
+test_systemd_tmpfiles_py = find_program('test-systemd-tmpfiles.py')
+
+############################################################
+
 tests += [
         [['src/test/test-device-nodes.c'],
          [],
@@ -138,7 +159,8 @@ tests += [
 
         [['src/test/test-async.c'],
          [],
-         []],
+         [],
+         '', 'timeout=120'],
 
         [['src/test/test-locale-util.c'],
          [],
@@ -232,6 +254,10 @@ tests += [
          [],
          []],
 
+        [['src/test/test-specifier.c'],
+         [],
+         []],
+
         [['src/test/test-string-util.c'],
          [],
          []],
@@ -403,7 +429,7 @@ tests += [
          [],
          []],
 
-        [['src/test/test-time.c'],
+        [['src/test/test-time-util.c'],
          [],
          []],
 
@@ -647,7 +673,8 @@ tests += [
           libshared],
          [threads,
           libxz,
-          liblz4]],
+          liblz4],
+         '', 'timeout=360'],
 
         [['src/journal/test-journal-stream.c'],
          [libjournal_core,
index 5b572bb..70ffdbc 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -48,7 +49,7 @@ static void test_add_acls_for_user(void) {
         assert_se(system(cmd) == 0);
 
         if (getuid() == 0) {
-                const char *nobody = "nobody";
+                const char *nobody = NOBODY_USER_NAME;
                 r = get_user_creds(&nobody, &uid, NULL, NULL, NULL);
                 if (r < 0)
                         uid = 0;
index bbaf18b..2d42dc2 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd
 
@@ -45,6 +46,7 @@ int main(int argc, const char *argv[]) {
         assert_se(af_to_name(af_max()) == NULL);
         assert_se(af_to_name(-1) == NULL);
         assert_se(af_from_name("huddlduddl") == AF_UNSPEC);
+        assert_se(af_from_name("") == AF_UNSPEC);
 
         return 0;
 }
index cc4821e..ed598e1 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -17,6 +18,8 @@
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
+#include <stdint.h>
+
 #include "alloc-util.h"
 #include "macro.h"
 #include "util.h"
@@ -34,22 +37,42 @@ static void test_alloca(void) {
         assert_se(!memcmp(t, zero, 997));
 }
 
-static void test_memdup_multiply(void) {
+static void test_memdup_multiply_and_greedy_realloc(void) {
         int org[] = {1, 2, 3};
-        int *dup;
-
-        dup = (int*)memdup_multiply(org, sizeof(int), 3);
+        _cleanup_free_ int *dup;
+        int *p;
+        size_t i, allocated = 3;
 
+        dup = (int*) memdup_suffix0_multiply(org, sizeof(int), 3);
         assert_se(dup);
         assert_se(dup[0] == 1);
         assert_se(dup[1] == 2);
         assert_se(dup[2] == 3);
+        assert_se(*(uint8_t*) (dup + 3) == (uint8_t) 0);
         free(dup);
+
+        dup = (int*) memdup_multiply(org, sizeof(int), 3);
+        assert_se(dup);
+        assert_se(dup[0] == 1);
+        assert_se(dup[1] == 2);
+        assert_se(dup[2] == 3);
+
+        p = dup;
+        assert_se(greedy_realloc0((void**) &dup, &allocated, 2, sizeof(int)) == p);
+
+        p = (int *) greedy_realloc0((void**) &dup, &allocated, 10, sizeof(int));
+        assert_se(p == dup);
+        assert_se(allocated >= 10);
+        assert_se(p[0] == 1);
+        assert_se(p[1] == 2);
+        assert_se(p[2] == 3);
+        for (i = 3; i < allocated; i++)
+                assert_se(p[i] == 0);
 }
 
 int main(int argc, char *argv[]) {
         test_alloca();
-        test_memdup_multiply();
+        test_memdup_multiply_and_greedy_realloc();
 
         return 0;
 }
index 68975b7..586d54b 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
 
 int main(int argc, char *argv[]) {
         int a, v;
+        const char *p;
+
+        assert_se(architecture_from_string("") < 0);
+        assert_se(architecture_from_string(NULL) < 0);
+        assert_se(architecture_from_string("hoge") < 0);
+        assert_se(architecture_to_string(-1) == NULL);
+        assert_se(architecture_from_string(architecture_to_string(0)) == 0);
+        assert_se(architecture_from_string(architecture_to_string(1)) == 1);
 
         v = detect_virtualization();
         if (IN_SET(v, -EPERM, -EACCES))
@@ -39,12 +48,18 @@ int main(int argc, char *argv[]) {
         a = uname_architecture();
         assert_se(a >= 0);
 
-        log_info("uname architecture=%s", architecture_to_string(a));
+        p = architecture_to_string(a);
+        assert_se(p);
+        log_info("uname architecture=%s", p);
+        assert_se(architecture_from_string(p) == a);
 
         a = native_architecture();
         assert_se(a >= 0);
 
-        log_info("native architecture=%s", architecture_to_string(a));
+        p = architecture_to_string(a);
+        assert_se(p);
+        log_info("native architecture=%s", p);
+        assert_se(architecture_from_string(p) == a);
 
         log_info("primary library architecture=" LIB_ARCH_TUPLE);
 
index bb51518..e503582 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd
 
@@ -45,6 +46,7 @@ int main(int argc, const char *argv[]) {
         assert_se(arphrd_to_name(arphrd_max()) == NULL);
         assert_se(arphrd_to_name(0) == NULL);
         assert_se(arphrd_from_name("huddlduddl") == 0);
+        assert_se(arphrd_from_name("") == 0);
 
         return 0;
 }
index 8666659..da44465 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 4ebc27f..2055ce2 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd
 
index e6aa3b5..1001cc2 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index ff22117..fa38056 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd
 
@@ -96,8 +97,19 @@ int main(int argc, const char *argv[]) {
 
         assert_se(i == (unsigned) -1);
 
+        b2 = bitmap_copy(b);
+        assert_se(b2);
+        assert_se(bitmap_equal(b, b2) == true);
+        assert_se(bitmap_equal(b, b) == true);
+        assert_se(bitmap_equal(b, NULL) == false);
+        assert_se(bitmap_equal(NULL, b) == false);
+        assert_se(bitmap_equal(NULL, NULL) == true);
+
         bitmap_clear(b);
         assert_se(bitmap_isclear(b) == true);
+        assert_se(bitmap_equal(b, b2) == false);
+        bitmap_free(b2);
+        b2 = NULL;
 
         assert_se(bitmap_set(b, (unsigned) -1) == -ERANGE);
 
index 8e68d65..37e799d 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 74e9d50..361cf10 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -49,7 +50,12 @@ int main(int argc, char *argv[]) {
         log_parse_environment();
         log_open();
 
-        enter_cgroup_subroot();
+        r = enter_cgroup_subroot();
+        if (r == -ENOMEDIUM) {
+                log_notice("cgroupfs not available, skipping tests");
+                return EXIT_TEST_SKIP;
+        }
+
         assert_se(set_unit_path(get_testdata_dir("")) >= 0);
         assert_se(runtime_dir = setup_fake_runtime_dir());
 
@@ -104,8 +110,8 @@ int main(int argc, char *argv[]) {
         assert(cc->ip_address_deny->items_next);
         assert(!cc->ip_address_deny->items_next->items_next);
 
-        assert_se(config_parse_exec(u->id, "filename", 1, "Service", 1, "ExecStart", SERVICE_EXEC_START, "/usr/bin/ping -c 1 127.0.0.2 -W 5", SERVICE(u)->exec_command, u) == 0);
-        assert_se(config_parse_exec(u->id, "filename", 1, "Service", 1, "ExecStart", SERVICE_EXEC_START, "/usr/bin/ping -c 1 127.0.0.3 -W 5", SERVICE(u)->exec_command, u) == 0);
+        assert_se(config_parse_exec(u->id, "filename", 1, "Service", 1, "ExecStart", SERVICE_EXEC_START, "/bin/ping -c 1 127.0.0.2 -W 5", SERVICE(u)->exec_command, u) == 0);
+        assert_se(config_parse_exec(u->id, "filename", 1, "Service", 1, "ExecStart", SERVICE_EXEC_START, "/bin/ping -c 1 127.0.0.3 -W 5", SERVICE(u)->exec_command, u) == 0);
 
         assert_se(SERVICE(u)->exec_command[SERVICE_EXEC_START]);
         assert_se(SERVICE(u)->exec_command[SERVICE_EXEC_START]->command_next);
@@ -145,7 +151,7 @@ int main(int argc, char *argv[]) {
 
         assert(r >= 0);
 
-        assert(unit_start(u) >= 0);
+        assert_se(unit_start(u) >= 0);
 
         while (!IN_SET(SERVICE(u)->state, SERVICE_DEAD, SERVICE_FAILED))
                 assert_se(sd_event_run(m->event, UINT64_MAX) >= 0);
index ce29d88..645594c 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index bd5bebe..1a95b60 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index c1af277..935567c 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -22,7 +23,6 @@
 #include "alloc-util.h"
 #include "cap-list.h"
 #include "capability-util.h"
-#include "fileio.h"
 #include "parse-util.h"
 #include "string-util.h"
 #include "util.h"
@@ -70,57 +70,72 @@ static void test_cap_list(void) {
         }
 }
 
-/* verify cap_last_cap() against /proc/sys/kernel/cap_last_cap */
-static void test_last_cap_file(void) {
-        _cleanup_free_ char *content = NULL;
-        unsigned long val = 0;
-        int r;
+static void test_capability_set_one(uint64_t c, const char *t) {
+        _cleanup_free_ char *t1 = NULL;
+        uint64_t c1, c_masked = c & ((UINT64_C(1) << capability_list_length()) - 1);
 
-        r = read_one_line_file("/proc/sys/kernel/cap_last_cap", &content);
-        assert_se(r >= 0);
+        assert_se(capability_set_to_string_alloc(c, &t1) == 0);
+        assert_se(streq(t1, t));
 
-        r = safe_atolu(content, &val);
-        assert_se(r >= 0);
-        assert_se(val != 0);
-        assert_se(val == cap_last_cap());
-}
-
-/* verify cap_last_cap() against syscall probing */
-static void test_last_cap_probe(void) {
-        unsigned long p = (unsigned long)CAP_LAST_CAP;
-
-        if (prctl(PR_CAPBSET_READ, p) < 0) {
-                for (p--; p > 0; p --)
-                        if (prctl(PR_CAPBSET_READ, p) >= 0)
-                                break;
-        } else {
-                for (;; p++)
-                        if (prctl(PR_CAPBSET_READ, p+1) < 0)
-                                break;
-        }
+        assert_se(capability_set_from_string(t1, &c1) == 0);
+        assert_se(c1 == c_masked);
 
-        assert_se(p != 0);
-        assert_se(p == cap_last_cap());
+        free(t1);
+        assert_se(t1 = strjoin("'cap_chown cap_dac_override' \"cap_setgid cap_setuid\"", t,
+                               " hogehoge foobar 12345 3.14 -3 ", t));
+        assert_se(capability_set_from_string(t1, &c1) == 0);
+        assert_se(c1 == c_masked);
 }
 
-static void test_capability_set_to_string_alloc(void) {
-        _cleanup_free_ char *t1 = NULL, *t2 = NULL, *t3 = NULL;
-
-        assert_se(capability_set_to_string_alloc(0u, &t1) == 0);
-        assert_se(streq(t1, ""));
-
-        assert_se(capability_set_to_string_alloc(1u<<CAP_DAC_OVERRIDE, &t2) == 0);
-        assert_se(streq(t2, "cap_dac_override"));
-
-        assert_se(capability_set_to_string_alloc(UINT64_C(1)<<CAP_CHOWN | UINT64_C(1)<<CAP_DAC_OVERRIDE | UINT64_C(1)<<CAP_DAC_READ_SEARCH | UINT64_C(1)<<CAP_FOWNER | UINT64_C(1)<<CAP_SETGID | UINT64_C(1)<<CAP_SETUID | UINT64_C(1)<<CAP_SYS_PTRACE | UINT64_C(1)<<CAP_SYS_ADMIN | UINT64_C(1)<<CAP_AUDIT_CONTROL | UINT64_C(1)<<CAP_MAC_OVERRIDE | UINT64_C(1)<<CAP_SYSLOG, &t3) == 0);
-        assert_se(streq(t3, "cap_chown cap_dac_override cap_dac_read_search cap_fowner cap_setgid cap_setuid cap_sys_ptrace cap_sys_admin cap_audit_control cap_mac_override cap_syslog"));
+static void test_capability_set(void) {
+        uint64_t c;
+
+        assert_se(capability_set_from_string(NULL, &c) == 0);
+        assert_se(c == 0);
+
+        assert_se(capability_set_from_string("", &c) == 0);
+        assert_se(c == 0);
+
+        assert_se(capability_set_from_string("0", &c) == 0);
+        assert_se(c == UINT64_C(1));
+
+        assert_se(capability_set_from_string("1", &c) == 0);
+        assert_se(c == UINT64_C(1) << 1);
+
+        assert_se(capability_set_from_string("0 1 2 3", &c) == 0);
+        assert_se(c == (UINT64_C(1) << 4) - 1);
+
+        test_capability_set_one(0, "");
+        test_capability_set_one(
+                UINT64_C(1) << CAP_DAC_OVERRIDE,
+                "cap_dac_override");
+        test_capability_set_one(
+                UINT64_C(1) << CAP_DAC_OVERRIDE |
+                UINT64_C(1) << capability_list_length(),
+                "cap_dac_override");
+        test_capability_set_one(
+                UINT64_C(1) << capability_list_length(), "");
+        test_capability_set_one(
+                UINT64_C(1) << CAP_CHOWN |
+                UINT64_C(1) << CAP_DAC_OVERRIDE |
+                UINT64_C(1) << CAP_DAC_READ_SEARCH |
+                UINT64_C(1) << CAP_FOWNER |
+                UINT64_C(1) << CAP_SETGID |
+                UINT64_C(1) << CAP_SETUID |
+                UINT64_C(1) << CAP_SYS_PTRACE |
+                UINT64_C(1) << CAP_SYS_ADMIN |
+                UINT64_C(1) << CAP_AUDIT_CONTROL |
+                UINT64_C(1) << CAP_MAC_OVERRIDE |
+                UINT64_C(1) << CAP_SYSLOG |
+                UINT64_C(1) << (capability_list_length() + 1),
+                "cap_chown cap_dac_override cap_dac_read_search cap_fowner "
+                "cap_setgid cap_setuid cap_sys_ptrace cap_sys_admin "
+                "cap_audit_control cap_mac_override cap_syslog");
 }
 
 int main(int argc, char *argv[]) {
         test_cap_list();
-        test_last_cap_file();
-        test_last_cap_probe();
-        test_capability_set_to_string_alloc();
+        test_capability_set();
 
         return 0;
 }
index 8276c75..e5db52d 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd
 
 #include <sys/wait.h>
 #include <unistd.h>
 
+#include "alloc-util.h"
 #include "capability-util.h"
 #include "fd-util.h"
+#include "fileio.h"
 #include "macro.h"
+#include "parse-util.h"
 #include "util.h"
 
 static uid_t test_uid = -1;
@@ -36,6 +40,39 @@ static gid_t test_gid = -1;
 /* We keep CAP_DAC_OVERRIDE to avoid errors with gcov when doing test coverage */
 static uint64_t test_flags = 1ULL << CAP_DAC_OVERRIDE;
 
+/* verify cap_last_cap() against /proc/sys/kernel/cap_last_cap */
+static void test_last_cap_file(void) {
+        _cleanup_free_ char *content = NULL;
+        unsigned long val = 0;
+        int r;
+
+        r = read_one_line_file("/proc/sys/kernel/cap_last_cap", &content);
+        assert_se(r >= 0);
+
+        r = safe_atolu(content, &val);
+        assert_se(r >= 0);
+        assert_se(val != 0);
+        assert_se(val == cap_last_cap());
+}
+
+/* verify cap_last_cap() against syscall probing */
+static void test_last_cap_probe(void) {
+        unsigned long p = (unsigned long)CAP_LAST_CAP;
+
+        if (prctl(PR_CAPBSET_READ, p) < 0) {
+                for (p--; p > 0; p --)
+                        if (prctl(PR_CAPBSET_READ, p) >= 0)
+                                break;
+        } else {
+                for (;; p++)
+                        if (prctl(PR_CAPBSET_READ, p+1) < 0)
+                                break;
+        }
+
+        assert_se(p != 0);
+        assert_se(p == cap_last_cap());
+}
+
 static void fork_test(void (*test_func)(void)) {
         pid_t pid = 0;
 
@@ -71,7 +108,7 @@ static int setup_tests(bool *run_ambient) {
         struct passwd *nobody;
         int r;
 
-        nobody = getpwnam("nobody");
+        nobody = getpwnam(NOBODY_USER_NAME);
         if (!nobody) {
                 log_error_errno(errno, "Could not find nobody user: %m");
                 return -EXIT_TEST_SKIP;
@@ -202,6 +239,9 @@ int main(int argc, char *argv[]) {
         int r;
         bool run_ambient;
 
+        test_last_cap_file();
+        test_last_cap_probe();
+
         log_parse_environment();
         log_open();
 
index 02aae84..10ae523 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -22,6 +23,7 @@
 #include "macro.h"
 #include "manager.h"
 #include "rm-rf.h"
+#include "string-util.h"
 #include "test-helper.h"
 #include "tests.h"
 #include "unit.h"
@@ -34,7 +36,11 @@ static int test_cgroup_mask(void) {
         FDSet *fdset = NULL;
         int r;
 
-        enter_cgroup_subroot();
+        r = enter_cgroup_subroot();
+        if (r == -ENOMEDIUM) {
+                puts("Skipping test: cgroupfs not available");
+                return EXIT_TEST_SKIP;
+        }
 
         /* Prepare the manager. */
         assert_se(set_unit_path(get_testdata_dir("")) >= 0);
@@ -113,10 +119,38 @@ static int test_cgroup_mask(void) {
         return 0;
 }
 
+static void test_cg_mask_to_string_one(CGroupMask mask, const char *t) {
+        _cleanup_free_ char *b = NULL;
+
+        assert_se(cg_mask_to_string(mask, &b) >= 0);
+        assert_se(streq_ptr(b, t));
+}
+
+static void test_cg_mask_to_string(void) {
+        test_cg_mask_to_string_one(0, NULL);
+        test_cg_mask_to_string_one(_CGROUP_MASK_ALL, "cpu cpuacct io blkio memory devices pids");
+        test_cg_mask_to_string_one(CGROUP_MASK_CPU, "cpu");
+        test_cg_mask_to_string_one(CGROUP_MASK_CPUACCT, "cpuacct");
+        test_cg_mask_to_string_one(CGROUP_MASK_IO, "io");
+        test_cg_mask_to_string_one(CGROUP_MASK_BLKIO, "blkio");
+        test_cg_mask_to_string_one(CGROUP_MASK_MEMORY, "memory");
+        test_cg_mask_to_string_one(CGROUP_MASK_DEVICES, "devices");
+        test_cg_mask_to_string_one(CGROUP_MASK_PIDS, "pids");
+        test_cg_mask_to_string_one(CGROUP_MASK_CPU|CGROUP_MASK_CPUACCT, "cpu cpuacct");
+        test_cg_mask_to_string_one(CGROUP_MASK_CPU|CGROUP_MASK_PIDS, "cpu pids");
+        test_cg_mask_to_string_one(CGROUP_MASK_CPUACCT|CGROUP_MASK_PIDS, "cpuacct pids");
+        test_cg_mask_to_string_one(CGROUP_MASK_DEVICES|CGROUP_MASK_PIDS, "devices pids");
+        test_cg_mask_to_string_one(CGROUP_MASK_IO|CGROUP_MASK_BLKIO, "io blkio");
+}
+
 int main(int argc, char* argv[]) {
         int rc = 0;
 
+        log_parse_environment();
+        log_open();
+
         TEST_REQ_RUNNING_SYSTEMD(rc = test_cgroup_mask());
+        test_cg_mask_to_string();
 
         return rc;
 }
index d5bc73f..45eb3ef 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -371,6 +372,37 @@ static void test_is_wanted(void) {
         test_is_wanted_print(false);
 }
 
+static void test_cg_tests(void) {
+        int all, hybrid, systemd, r;
+
+        r = cg_unified_flush();
+        if (r == -ENOMEDIUM) {
+                log_notice_errno(r, "Skipping cg hierarchy tests: %m");
+                return;
+        }
+        assert_se(r == 0);
+
+        all = cg_all_unified();
+        assert_se(IN_SET(all, 0, 1));
+
+        hybrid = cg_hybrid_unified();
+        assert_se(IN_SET(hybrid, 0, 1));
+
+        systemd = cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER);
+        assert_se(IN_SET(systemd, 0, 1));
+
+        if (all) {
+                assert_se(systemd);
+                assert_se(!hybrid);
+
+        } else if (hybrid) {
+                assert_se(systemd);
+                assert_se(!all);
+
+        } else
+                assert_se(!systemd);
+}
+
 int main(void) {
         log_set_max_level(LOG_DEBUG);
         log_parse_environment();
@@ -395,6 +427,7 @@ int main(void) {
         test_is_wanted_print(true);
         test_is_wanted_print(false); /* run twice to test caching */
         test_is_wanted();
+        test_cg_tests();
 
         return 0;
 }
index 71e318a..2ae95db 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 94f8b50..11773cc 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 278ac2a..d43db3a 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd
 
@@ -390,7 +391,7 @@ static void test_condition_test_user(void) {
         assert_se(condition);
         r = condition_test(condition);
         log_info("ConditionUser=@system → %i", r);
-        if (getuid() < SYSTEM_UID_MAX || geteuid() < SYSTEM_UID_MAX)
+        if (uid_is_system(getuid()) || uid_is_system(geteuid()))
                 assert_se(r > 0);
         else
                 assert_se(r == 0);
index 777b5ca..de91efa 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 7a7de98..770bb96 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -311,7 +312,7 @@ static void test_config_parse(unsigned i, const char *s) {
         r = config_parse(NULL, name, f,
                          "Section\0",
                          config_item_table_lookup, items,
-                         false, false, true, NULL);
+                         CONFIG_PARSE_WARN, NULL);
 
         switch (i) {
         case 0 ... 3:
index 187baa2..d277b78 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd
 
index e510633..1a7220d 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -32,7 +33,7 @@ static void test_parse_cpu_set(void) {
         assert_se(CPU_ISSET_S(1, CPU_ALLOC_SIZE(ncpus), c));
         assert_se(CPU_ISSET_S(2, CPU_ALLOC_SIZE(ncpus), c));
         assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 2);
-        c = mfree(c);
+        c = cpu_set_mfree(c);
 
         /* A more interesting range */
         ncpus = parse_cpu_set_and_warn("0 1 2 3 8 9 10 11", &c, NULL, "fake", 1, "CPUAffinity");
@@ -42,7 +43,7 @@ static void test_parse_cpu_set(void) {
                 assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
         for (cpu = 8; cpu < 12; cpu++)
                 assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
-        c = mfree(c);
+        c = cpu_set_mfree(c);
 
         /* Quoted strings */
         ncpus = parse_cpu_set_and_warn("8 '9' 10 \"11\"", &c, NULL, "fake", 1, "CPUAffinity");
@@ -50,7 +51,7 @@ static void test_parse_cpu_set(void) {
         assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 4);
         for (cpu = 8; cpu < 12; cpu++)
                 assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
-        c = mfree(c);
+        c = cpu_set_mfree(c);
 
         /* Use commas as separators */
         ncpus = parse_cpu_set_and_warn("0,1,2,3 8,9,10,11", &c, NULL, "fake", 1, "CPUAffinity");
@@ -60,7 +61,7 @@ static void test_parse_cpu_set(void) {
                 assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
         for (cpu = 8; cpu < 12; cpu++)
                 assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
-        c = mfree(c);
+        c = cpu_set_mfree(c);
 
         /* Commas with spaces (and trailing comma, space) */
         ncpus = parse_cpu_set_and_warn("0, 1, 2, 3, 4, 5, 6, 7, ", &c, NULL, "fake", 1, "CPUAffinity");
@@ -68,7 +69,7 @@ static void test_parse_cpu_set(void) {
         assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 8);
         for (cpu = 0; cpu < 8; cpu++)
                 assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
-        c = mfree(c);
+        c = cpu_set_mfree(c);
 
         /* Ranges */
         ncpus = parse_cpu_set_and_warn("0-3,8-11", &c, NULL, "fake", 1, "CPUAffinity");
@@ -78,7 +79,7 @@ static void test_parse_cpu_set(void) {
                 assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
         for (cpu = 8; cpu < 12; cpu++)
                 assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
-        c = mfree(c);
+        c = cpu_set_mfree(c);
 
         /* Ranges with trailing comma, space */
         ncpus = parse_cpu_set_and_warn("0-3  8-11, ", &c, NULL, "fake", 1, "CPUAffinity");
@@ -88,13 +89,13 @@ static void test_parse_cpu_set(void) {
                 assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
         for (cpu = 8; cpu < 12; cpu++)
                 assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
-        c = mfree(c);
+        c = cpu_set_mfree(c);
 
         /* Negative range (returns empty cpu_set) */
         ncpus = parse_cpu_set_and_warn("3-0", &c, NULL, "fake", 1, "CPUAffinity");
         assert_se(ncpus >= 1024);
         assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 0);
-        c = mfree(c);
+        c = cpu_set_mfree(c);
 
         /* Overlapping ranges */
         ncpus = parse_cpu_set_and_warn("0-7 4-11", &c, NULL, "fake", 1, "CPUAffinity");
@@ -102,7 +103,7 @@ static void test_parse_cpu_set(void) {
         assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 12);
         for (cpu = 0; cpu < 12; cpu++)
                 assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
-        c = mfree(c);
+        c = cpu_set_mfree(c);
 
         /* Mix ranges and individual CPUs */
         ncpus = parse_cpu_set_and_warn("0,1 4-11", &c, NULL, "fake", 1, "CPUAffinity");
@@ -112,7 +113,7 @@ static void test_parse_cpu_set(void) {
         assert_se(CPU_ISSET_S(1, CPU_ALLOC_SIZE(ncpus), c));
         for (cpu = 4; cpu < 12; cpu++)
                 assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
-        c = mfree(c);
+        c = cpu_set_mfree(c);
 
         /* Garbage */
         ncpus = parse_cpu_set_and_warn("0 1 2 3 garbage", &c, NULL, "fake", 1, "CPUAffinity");
index e5887cc..0e82ba6 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index c09d615..85867db 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index af75b38..042907c 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 2bb68be..c594047 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 9f5343a..dd43da5 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 75bc5e4..0ad7d08 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -229,7 +230,7 @@ static void test_dns_name_between_one(const char *a, const char *b, const char *
 
         r = dns_name_between(c, b, a);
         if (ret >= 0)
-                assert_se(r == 0);
+                assert_se(r == 0 || dns_name_equal(a, c) > 0);
         else
                 assert_se(r == ret);
 }
@@ -248,7 +249,8 @@ static void test_dns_name_between(void) {
         test_dns_name_between_one("*.z.example", "\\200.z.example", "example", true);
         test_dns_name_between_one("\\200.z.example", "example", "a.example", true);
 
-        test_dns_name_between_one("example", "a.example", "example", -EINVAL);
+        test_dns_name_between_one("example", "a.example", "example", true);
+        test_dns_name_between_one("example", "example", "example", false);
         test_dns_name_between_one("example", "example", "yljkjljk.a.example", false);
         test_dns_name_between_one("example", "yljkjljk.a.example", "yljkjljk.a.example", false);
 }
@@ -426,6 +428,30 @@ static void test_dns_srv_type_is_valid(void) {
         assert_se(!dns_srv_type_is_valid("_piep._foo._udp"));
 }
 
+static void test_dnssd_srv_type_is_valid(void) {
+
+        assert_se(dnssd_srv_type_is_valid("_http._tcp"));
+        assert_se(dnssd_srv_type_is_valid("_foo-bar._tcp"));
+        assert_se(dnssd_srv_type_is_valid("_w._udp"));
+        assert_se(dnssd_srv_type_is_valid("_a800._tcp"));
+        assert_se(dnssd_srv_type_is_valid("_a-800._tcp"));
+
+        assert_se(!dnssd_srv_type_is_valid(NULL));
+        assert_se(!dnssd_srv_type_is_valid(""));
+        assert_se(!dnssd_srv_type_is_valid("x"));
+        assert_se(!dnssd_srv_type_is_valid("_foo"));
+        assert_se(!dnssd_srv_type_is_valid("_tcp"));
+        assert_se(!dnssd_srv_type_is_valid("_"));
+        assert_se(!dnssd_srv_type_is_valid("_foo."));
+        assert_se(!dnssd_srv_type_is_valid("_föo._tcp"));
+        assert_se(!dnssd_srv_type_is_valid("_f\no._tcp"));
+        assert_se(!dnssd_srv_type_is_valid("_800._tcp"));
+        assert_se(!dnssd_srv_type_is_valid("_-800._tcp"));
+        assert_se(!dnssd_srv_type_is_valid("_-foo._tcp"));
+        assert_se(!dnssd_srv_type_is_valid("_piep._foo._udp"));
+        assert_se(!dnssd_srv_type_is_valid("_foo._unknown"));
+}
+
 static void test_dns_service_join_one(const char *a, const char *b, const char *c, int r, const char *d) {
         _cleanup_free_ char *x = NULL, *y = NULL, *z = NULL, *t = NULL;
 
@@ -698,6 +724,7 @@ int main(int argc, char *argv[]) {
         test_dns_name_to_wire_format();
         test_dns_service_name_is_valid();
         test_dns_srv_type_is_valid();
+        test_dnssd_srv_type_is_valid();
         test_dns_service_join();
         test_dns_service_split();
         test_dns_name_change_suffix();
index d4f09b0..421774c 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 6916f83..a7cdbb6 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -37,7 +38,11 @@ int main(int argc, char *argv[]) {
         Job *j;
         int r;
 
-        enter_cgroup_subroot();
+        r = enter_cgroup_subroot();
+        if (r == -ENOMEDIUM) {
+                log_notice_errno(r, "Skipping test: cgroupfs not available");
+                return EXIT_TEST_SKIP;
+        }
 
         /* prepare the test */
         assert_se(set_unit_path(get_testdata_dir("")) >= 0);
@@ -111,6 +116,33 @@ int main(int argc, char *argv[]) {
         assert_se(manager_add_job(m, JOB_START, h, JOB_FAIL, NULL, &j) == 0);
         manager_dump_jobs(m, stdout, "\t");
 
+        assert_se(!hashmap_get(a->dependencies[UNIT_PROPAGATES_RELOAD_TO], b));
+        assert_se(!hashmap_get(b->dependencies[UNIT_RELOAD_PROPAGATED_FROM], a));
+        assert_se(!hashmap_get(a->dependencies[UNIT_PROPAGATES_RELOAD_TO], c));
+        assert_se(!hashmap_get(c->dependencies[UNIT_RELOAD_PROPAGATED_FROM], a));
+
+        assert_se(unit_add_dependency(a, UNIT_PROPAGATES_RELOAD_TO, b, true, UNIT_DEPENDENCY_UDEV) == 0);
+        assert_se(unit_add_dependency(a, UNIT_PROPAGATES_RELOAD_TO, c, true, UNIT_DEPENDENCY_PROC_SWAP) == 0);
+
+        assert_se(hashmap_get(a->dependencies[UNIT_PROPAGATES_RELOAD_TO], b));
+        assert_se(hashmap_get(b->dependencies[UNIT_RELOAD_PROPAGATED_FROM], a));
+        assert_se(hashmap_get(a->dependencies[UNIT_PROPAGATES_RELOAD_TO], c));
+        assert_se(hashmap_get(c->dependencies[UNIT_RELOAD_PROPAGATED_FROM], a));
+
+        unit_remove_dependencies(a, UNIT_DEPENDENCY_UDEV);
+
+        assert_se(!hashmap_get(a->dependencies[UNIT_PROPAGATES_RELOAD_TO], b));
+        assert_se(!hashmap_get(b->dependencies[UNIT_RELOAD_PROPAGATED_FROM], a));
+        assert_se(hashmap_get(a->dependencies[UNIT_PROPAGATES_RELOAD_TO], c));
+        assert_se(hashmap_get(c->dependencies[UNIT_RELOAD_PROPAGATED_FROM], a));
+
+        unit_remove_dependencies(a, UNIT_DEPENDENCY_PROC_SWAP);
+
+        assert_se(!hashmap_get(a->dependencies[UNIT_PROPAGATES_RELOAD_TO], b));
+        assert_se(!hashmap_get(b->dependencies[UNIT_RELOAD_PROPAGATED_FROM], a));
+        assert_se(!hashmap_get(a->dependencies[UNIT_PROPAGATES_RELOAD_TO], c));
+        assert_se(!hashmap_get(c->dependencies[UNIT_RELOAD_PROPAGATED_FROM], a));
+
         manager_free(m);
 
         return 0;
index 3a2492d..b1e69d4 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -319,10 +320,13 @@ static void test_env_assignment_is_valid(void) {
 static void test_deserialize_environment(void) {
         _cleanup_strv_free_ char **env = strv_new("A=1", NULL);
 
-        assert_se(deserialize_environment(&env, "env=test") < 0);
         assert_se(deserialize_environment(&env, "env=B=2") >= 0);
+        assert_se(deserialize_environment(&env, "env=FOO%%=a\\177b\\nc\\td e") >= 0);
 
-        assert_se(strv_equal(env, STRV_MAKE("A=1", "B=2")));
+        assert_se(strv_equal(env, STRV_MAKE("A=1", "B=2", "FOO%%=a\177b\nc\td e")));
+
+        assert_se(deserialize_environment(&env, "env=foo\\") < 0);
+        assert_se(deserialize_environment(&env, "env=bar\\_baz") < 0);
 }
 
 static void test_serialize_environment(void) {
@@ -334,6 +338,7 @@ static void test_serialize_environment(void) {
                                                   "B=2",
                                                   "C=ąęółń",
                                                   "D=D=a\\x0Ab",
+                                                  "FOO%%=a\177b\nc\td e",
                                                   NULL);
         _cleanup_strv_free_ char **env2 = NULL;
 
index d060afa..aa05520 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index c192d35..bd9c809 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 6786d56..fba798e 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -23,6 +24,8 @@
 #include <sys/prctl.h>
 #include <sys/types.h>
 
+#include "cpu-set-util.h"
+#include "errno-list.h"
 #include "fileio.h"
 #include "fs-util.h"
 #include "macro.h"
@@ -100,6 +103,40 @@ static void test(Manager *m, const char *unit_name, int status_expected, int cod
         check(m, unit, status_expected, code_expected);
 }
 
+static void test_exec_bindpaths(Manager *m) {
+        assert_se(mkdir_p("/tmp/test-exec-bindpaths", 0755) >= 0);
+        assert_se(mkdir_p("/tmp/test-exec-bindreadonlypaths", 0755) >= 0);
+
+        test(m, "exec-bindpaths.service", 0, CLD_EXITED);
+
+        (void) rm_rf("/tmp/test-exec-bindpaths", REMOVE_ROOT|REMOVE_PHYSICAL);
+        (void) rm_rf("/tmp/test-exec-bindreadonlypaths", REMOVE_ROOT|REMOVE_PHYSICAL);
+}
+
+static void test_exec_cpuaffinity(Manager *m) {
+        _cleanup_cpu_free_ cpu_set_t *c = NULL;
+        unsigned n;
+
+        assert_se(c = cpu_set_malloc(&n));
+        assert_se(sched_getaffinity(0, CPU_ALLOC_SIZE(n), c) >= 0);
+
+        if (CPU_ISSET_S(0, CPU_ALLOC_SIZE(n), c) == 0) {
+                log_notice("Cannot use CPU 0, skipping %s", __func__);
+                return;
+        }
+
+        test(m, "exec-cpuaffinity1.service", 0, CLD_EXITED);
+        test(m, "exec-cpuaffinity2.service", 0, CLD_EXITED);
+
+        if (CPU_ISSET_S(1, CPU_ALLOC_SIZE(n), c) == 0 ||
+            CPU_ISSET_S(2, CPU_ALLOC_SIZE(n), c) == 0) {
+                log_notice("Cannot use CPU 1 or 2, skipping remaining tests in %s", __func__);
+                return;
+        }
+
+        test(m, "exec-cpuaffinity3.service", 0, CLD_EXITED);
+}
+
 static void test_exec_workingdirectory(Manager *m) {
         assert_se(mkdir_p("/tmp/test-exec_workingdirectory", 0755) >= 0);
 
@@ -127,6 +164,8 @@ static void test_exec_personality(Manager *m) {
 
 #elif defined(__i386__)
         test(m, "exec-personality-x86.service", 0, CLD_EXITED);
+#else
+        log_notice("Unknown personality, skipping %s", __func__);
 #endif
 }
 
@@ -145,36 +184,25 @@ static void test_exec_privatetmp(Manager *m) {
 }
 
 static void test_exec_privatedevices(Manager *m) {
+        int r;
+
         if (detect_container() > 0) {
-                log_notice("testing in container, skipping %s", __func__);
+                log_notice("Testing in container, skipping %s", __func__);
                 return;
         }
         if (!is_inaccessible_available()) {
-                log_notice("testing without inaccessible, skipping %s", __func__);
+                log_notice("Testing without inaccessible, skipping %s", __func__);
                 return;
         }
 
         test(m, "exec-privatedevices-yes.service", 0, CLD_EXITED);
         test(m, "exec-privatedevices-no.service", 0, CLD_EXITED);
-}
-
-static void test_exec_privatedevices_capabilities(Manager *m) {
-        int r;
-
-        if (detect_container() > 0) {
-                log_notice("testing in container, skipping %s", __func__);
-                return;
-        }
-        if (!is_inaccessible_available()) {
-                log_notice("testing without inaccessible, skipping %s", __func__);
-                return;
-        }
 
         /* We use capsh to test if the capabilities are
          * properly set, so be sure that it exists */
         r = find_binary("capsh", NULL);
         if (r < 0) {
-                log_error_errno(r, "Skipping %s, could not find capsh binary: %m", __func__);
+                log_error_errno(r, "Could not find capsh binary, skipping remaining tests in %s: %m", __func__);
                 return;
         }
 
@@ -188,11 +216,11 @@ static void test_exec_protectkernelmodules(Manager *m) {
         int r;
 
         if (detect_container() > 0) {
-                log_notice("testing in container, skipping %s", __func__);
+                log_notice("Testing in container, skipping %s", __func__);
                 return;
         }
         if (!is_inaccessible_available()) {
-                log_notice("testing without inaccessible, skipping %s", __func__);
+                log_notice("Testing without inaccessible, skipping %s", __func__);
                 return;
         }
 
@@ -202,7 +230,6 @@ static void test_exec_protectkernelmodules(Manager *m) {
                 return;
         }
 
-
         test(m, "exec-protectkernelmodules-no-capabilities.service", 0, CLD_EXITED);
         test(m, "exec-protectkernelmodules-yes-capabilities.service", 0, CLD_EXITED);
         test(m, "exec-protectkernelmodules-yes-mount-propagation.service", 0, CLD_EXITED);
@@ -210,73 +237,93 @@ static void test_exec_protectkernelmodules(Manager *m) {
 
 static void test_exec_readonlypaths(Manager *m) {
 
-        if (path_is_read_only_fs("/var") > 0)
+        test(m, "exec-readonlypaths-simple.service", 0, CLD_EXITED);
+
+        if (path_is_read_only_fs("/var") > 0) {
+                log_notice("Directory /var is readonly, skipping remaining tests in %s", __func__);
                 return;
+        }
 
         test(m, "exec-readonlypaths.service", 0, CLD_EXITED);
         test(m, "exec-readonlypaths-mount-propagation.service", 0, CLD_EXITED);
+        test(m, "exec-readonlypaths-with-bindpaths.service", 0, CLD_EXITED);
 }
 
 static void test_exec_readwritepaths(Manager *m) {
 
-        if (path_is_read_only_fs("/") > 0)
+        if (path_is_read_only_fs("/") > 0) {
+                log_notice("Root directory is readonly, skipping %s", __func__);
                 return;
+        }
 
         test(m, "exec-readwritepaths-mount-propagation.service", 0, CLD_EXITED);
 }
 
 static void test_exec_inaccessiblepaths(Manager *m) {
 
-        if (path_is_read_only_fs("/") > 0)
+        if (!is_inaccessible_available()) {
+                log_notice("Testing without inaccessible, skipping %s", __func__);
                 return;
+        }
 
-        test(m, "exec-inaccessiblepaths-mount-propagation.service", 0, CLD_EXITED);
-}
+        test(m, "exec-inaccessiblepaths-proc.service", 0, CLD_EXITED);
 
-static void test_exec_inaccessiblepaths_proc(Manager *m) {
-        if (!is_inaccessible_available()) {
-                log_notice("testing without inaccessible, skipping %s", __func__);
+        if (path_is_read_only_fs("/") > 0) {
+                log_notice("Root directory is readonly, skipping remaining tests in %s", __func__);
                 return;
         }
 
-        test(m, "exec-inaccessiblepaths-proc.service", 0, CLD_EXITED);
+        test(m, "exec-inaccessiblepaths-mount-propagation.service", 0, CLD_EXITED);
 }
 
 static void test_exec_systemcallfilter(Manager *m) {
 #if HAVE_SECCOMP
-        if (!is_seccomp_available())
+        if (!is_seccomp_available()) {
+                log_notice("Seccomp not available, skipping %s", __func__);
                 return;
+        }
+
         test(m, "exec-systemcallfilter-not-failing.service", 0, CLD_EXITED);
         test(m, "exec-systemcallfilter-not-failing2.service", 0, CLD_EXITED);
         test(m, "exec-systemcallfilter-failing.service", SIGSYS, CLD_KILLED);
         test(m, "exec-systemcallfilter-failing2.service", SIGSYS, CLD_KILLED);
-
+        test(m, "exec-systemcallfilter-with-errno-name.service", errno_from_name("EILSEQ"), CLD_EXITED);
+        test(m, "exec-systemcallfilter-with-errno-number.service", 255, CLD_EXITED);
 #endif
 }
 
 static void test_exec_systemcallerrornumber(Manager *m) {
 #if HAVE_SECCOMP
-        if (is_seccomp_available())
-                test(m, "exec-systemcallerrornumber.service", 1, CLD_EXITED);
+        if (!is_seccomp_available()) {
+                log_notice("Seccomp not available, skipping %s", __func__);
+                return;
+        }
+
+        test(m, "exec-systemcallerrornumber-name.service", errno_from_name("EACCES"), CLD_EXITED);
+        test(m, "exec-systemcallerrornumber-number.service", 255, CLD_EXITED);
 #endif
 }
 
-static void test_exec_restrict_namespaces(Manager *m) {
+static void test_exec_restrictnamespaces(Manager *m) {
 #if HAVE_SECCOMP
-        if (!is_seccomp_available())
+        if (!is_seccomp_available()) {
+                log_notice("Seccomp not available, skipping %s", __func__);
                 return;
+        }
 
-        test(m, "exec-restrict-namespaces-no.service", 0, CLD_EXITED);
-        test(m, "exec-restrict-namespaces-yes.service", 1, CLD_EXITED);
-        test(m, "exec-restrict-namespaces-mnt.service", 0, CLD_EXITED);
-        test(m, "exec-restrict-namespaces-mnt-blacklist.service", 1, CLD_EXITED);
+        test(m, "exec-restrictnamespaces-no.service", 0, CLD_EXITED);
+        test(m, "exec-restrictnamespaces-yes.service", 1, CLD_EXITED);
+        test(m, "exec-restrictnamespaces-mnt.service", 0, CLD_EXITED);
+        test(m, "exec-restrictnamespaces-mnt-blacklist.service", 1, CLD_EXITED);
 #endif
 }
 
-static void test_exec_systemcall_system_mode_with_user(Manager *m) {
+static void test_exec_systemcallfilter_system(Manager *m) {
 #if HAVE_SECCOMP
-        if (!is_seccomp_available())
+        if (!is_seccomp_available()) {
+                log_notice("Seccomp not available, skipping %s", __func__);
                 return;
+        }
         if (getpwnam("nobody"))
                 test(m, "exec-systemcallfilter-system-user.service", 0, CLD_EXITED);
         else if (getpwnam("nfsnobody"))
@@ -300,11 +347,13 @@ static void test_exec_group(Manager *m) {
                 test(m, "exec-group.service", 0, CLD_EXITED);
         else if (getgrnam("nfsnobody"))
                 test(m, "exec-group-nfsnobody.service", 0, CLD_EXITED);
+        else if (getgrnam("nogroup"))
+                test(m, "exec-group-nogroup.service", 0, CLD_EXITED);
         else
-                log_error_errno(errno, "Skipping %s, could not find nobody/nfsnobody group: %m", __func__);
+                log_error_errno(errno, "Skipping %s, could not find nobody/nfsnobody/nogroup group: %m", __func__);
 }
 
-static void test_exec_supplementary_groups(Manager *m) {
+static void test_exec_supplementarygroups(Manager *m) {
         test(m, "exec-supplementarygroups.service", 0, CLD_EXITED);
         test(m, "exec-supplementarygroups-single-group.service", 0, CLD_EXITED);
         test(m, "exec-supplementarygroups-single-group-user.service", 0, CLD_EXITED);
@@ -313,11 +362,18 @@ static void test_exec_supplementary_groups(Manager *m) {
         test(m, "exec-supplementarygroups-multiple-groups-withuid.service", 0, CLD_EXITED);
 }
 
-static void test_exec_dynamic_user(Manager *m) {
+static void test_exec_dynamicuser(Manager *m) {
         test(m, "exec-dynamicuser-fixeduser.service", 0, CLD_EXITED);
         test(m, "exec-dynamicuser-fixeduser-one-supplementarygroup.service", 0, CLD_EXITED);
         test(m, "exec-dynamicuser-supplementarygroups.service", 0, CLD_EXITED);
-        test(m, "exec-dynamicuser-state-dir.service", 0, CLD_EXITED);
+        test(m, "exec-dynamicuser-statedir.service", 0, CLD_EXITED);
+
+        test(m, "exec-dynamicuser-statedir-migrate-step1.service", 0, CLD_EXITED);
+        test(m, "exec-dynamicuser-statedir-migrate-step2.service", 0, CLD_EXITED);
+        (void) rm_rf("/var/lib/test-dynamicuser-migrate", REMOVE_ROOT|REMOVE_PHYSICAL);
+        (void) rm_rf("/var/lib/test-dynamicuser-migrate2", REMOVE_ROOT|REMOVE_PHYSICAL);
+        (void) rm_rf("/var/lib/private/test-dynamicuser-migrate", REMOVE_ROOT|REMOVE_PHYSICAL);
+        (void) rm_rf("/var/lib/private/test-dynamicuser-migrate2", REMOVE_ROOT|REMOVE_PHYSICAL);
 }
 
 static void test_exec_environment(Manager *m) {
@@ -343,7 +399,7 @@ static void test_exec_environmentfile(Manager *m) {
 
         test(m, "exec-environmentfile.service", 0, CLD_EXITED);
 
-        unlink("/tmp/test-exec_environmentfile.conf");
+        (void) unlink("/tmp/test-exec_environmentfile.conf");
 }
 
 static void test_exec_passenvironment(Manager *m) {
@@ -409,17 +465,19 @@ static void test_exec_capabilityambientset(Manager *m) {
          * capabilities is fine, since we are expecting them to be unset
          * in the first place for the tests. */
         r = prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_CLEAR_ALL, 0, 0, 0);
-        if (r >= 0 || errno != EINVAL) {
-                if (getpwnam("nobody")) {
-                        test(m, "exec-capabilityambientset.service", 0, CLD_EXITED);
-                        test(m, "exec-capabilityambientset-merge.service", 0, CLD_EXITED);
-                } else if (getpwnam("nfsnobody")) {
-                        test(m, "exec-capabilityambientset-nfsnobody.service", 0, CLD_EXITED);
-                        test(m, "exec-capabilityambientset-merge-nfsnobody.service", 0, CLD_EXITED);
-                } else
-                        log_error_errno(errno, "Skipping %s, could not find nobody/nfsnobody user: %m", __func__);
+        if (r < 0 && IN_SET(errno, EINVAL, EOPNOTSUPP, ENOSYS)) {
+                log_error("Skipping %s, the kernel does not support ambient capabilities", __func__);
+                return;
+        }
+
+        if (getpwnam("nobody")) {
+                test(m, "exec-capabilityambientset.service", 0, CLD_EXITED);
+                test(m, "exec-capabilityambientset-merge.service", 0, CLD_EXITED);
+        } else if (getpwnam("nfsnobody")) {
+                test(m, "exec-capabilityambientset-nfsnobody.service", 0, CLD_EXITED);
+                test(m, "exec-capabilityambientset-merge-nfsnobody.service", 0, CLD_EXITED);
         } else
-                log_error_errno(errno, "Skipping %s, the kernel does not support ambient capabilities: %m", __func__);
+                log_error_errno(errno, "Skipping %s, could not find nobody/nfsnobody user: %m", __func__);
 }
 
 static void test_exec_privatenetwork(Manager *m) {
@@ -446,16 +504,19 @@ static void test_exec_ioschedulingclass(Manager *m) {
         test(m, "exec-ioschedulingclass-best-effort.service", 0, CLD_EXITED);
 }
 
-static void test_exec_spec_interpolation(Manager *m) {
-        test(m, "exec-spec-interpolation.service", 0, CLD_EXITED);
+static void test_exec_unsetenvironment(Manager *m) {
+        test(m, "exec-unsetenvironment.service", 0, CLD_EXITED);
 }
 
-static void test_exec_read_only_path_suceed(Manager *m) {
-        test(m, "exec-read-only-path-succeed.service", 0, CLD_EXITED);
+static void test_exec_specifier(Manager *m) {
+        test(m, "exec-specifier.service", 0, CLD_EXITED);
+        test(m, "exec-specifier@foo-bar.service", 0, CLD_EXITED);
+        test(m, "exec-specifier-interpolation.service", 0, CLD_EXITED);
 }
 
-static void test_exec_unset_environment(Manager *m) {
-        test(m, "exec-unset-environment.service", 0, CLD_EXITED);
+static void test_exec_standardinput(Manager *m) {
+        test(m, "exec-standardinput-data.service", 0, CLD_EXITED);
+        test(m, "exec-standardinput-file.service", 0, CLD_EXITED);
 }
 
 static int run_tests(UnitFileScope scope, const test_function_t *tests) {
@@ -483,41 +544,41 @@ static int run_tests(UnitFileScope scope, const test_function_t *tests) {
 
 int main(int argc, char *argv[]) {
         static const test_function_t user_tests[] = {
-                test_exec_workingdirectory,
-                test_exec_personality,
+                test_exec_bindpaths,
+                test_exec_capabilityambientset,
+                test_exec_capabilityboundingset,
+                test_exec_cpuaffinity,
+                test_exec_environment,
+                test_exec_environmentfile,
+                test_exec_group,
                 test_exec_ignoresigpipe,
-                test_exec_privatetmp,
+                test_exec_inaccessiblepaths,
+                test_exec_ioschedulingclass,
+                test_exec_oomscoreadjust,
+                test_exec_passenvironment,
+                test_exec_personality,
                 test_exec_privatedevices,
-                test_exec_privatedevices_capabilities,
+                test_exec_privatenetwork,
+                test_exec_privatetmp,
                 test_exec_protectkernelmodules,
                 test_exec_readonlypaths,
                 test_exec_readwritepaths,
-                test_exec_inaccessiblepaths,
-                test_exec_inaccessiblepaths_proc,
-                test_exec_privatenetwork,
-                test_exec_systemcallfilter,
+                test_exec_restrictnamespaces,
+                test_exec_runtimedirectory,
+                test_exec_standardinput,
+                test_exec_supplementarygroups,
                 test_exec_systemcallerrornumber,
-                test_exec_restrict_namespaces,
-                test_exec_user,
-                test_exec_group,
-                test_exec_supplementary_groups,
-                test_exec_environment,
-                test_exec_environmentfile,
-                test_exec_passenvironment,
+                test_exec_systemcallfilter,
                 test_exec_umask,
-                test_exec_runtimedirectory,
-                test_exec_capabilityboundingset,
-                test_exec_capabilityambientset,
-                test_exec_oomscoreadjust,
-                test_exec_ioschedulingclass,
-                test_exec_spec_interpolation,
-                test_exec_read_only_path_suceed,
-                test_exec_unset_environment,
+                test_exec_unsetenvironment,
+                test_exec_user,
+                test_exec_workingdirectory,
                 NULL,
         };
         static const test_function_t system_tests[] = {
-                test_exec_systemcall_system_mode_with_user,
-                test_exec_dynamic_user,
+                test_exec_dynamicuser,
+                test_exec_specifier,
+                test_exec_systemcallfilter_system,
                 NULL,
         };
         int r;
@@ -526,13 +587,20 @@ int main(int argc, char *argv[]) {
         log_parse_environment();
         log_open();
 
+        (void) unsetenv("USER");
+        (void) unsetenv("LOGNAME");
+
         /* It is needed otherwise cgroup creation fails */
         if (getuid() != 0) {
-                printf("Skipping test: not root\n");
+                puts("Skipping test: not root");
                 return EXIT_TEST_SKIP;
         }
 
-        enter_cgroup_subroot();
+        r = enter_cgroup_subroot();
+        if (r == -ENOMEDIUM) {
+                puts("Skipping test: cgroupfs not available");
+                return EXIT_TEST_SKIP;
+        }
 
         assert_se(setenv("XDG_RUNTIME_DIR", "/tmp/", 1) == 0);
         assert_se(set_unit_path(get_testdata_dir("/test-execute")) >= 0);
index 7a23fa7..84ab083 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 4425b5f..e5a0e9d 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -24,6 +25,9 @@
 #include "fd-util.h"
 #include "fileio.h"
 #include "macro.h"
+#include "random-util.h"
+#include "string-util.h"
+#include "util.h"
 
 static void test_close_many(void) {
         int fds[3];
@@ -100,7 +104,55 @@ static void test_open_serialization_fd(void) {
         fd = open_serialization_fd("test");
         assert_se(fd >= 0);
 
-        write(fd, "test\n", 5);
+        assert_se(write(fd, "test\n", 5) == 5);
+}
+
+static void test_acquire_data_fd_one(unsigned flags) {
+        char wbuffer[196*1024 - 7];
+        char rbuffer[sizeof(wbuffer)];
+        int fd;
+
+        fd = acquire_data_fd("foo", 3, flags);
+        assert_se(fd >= 0);
+
+        zero(rbuffer);
+        assert_se(read(fd, rbuffer, sizeof(rbuffer)) == 3);
+        assert_se(streq(rbuffer, "foo"));
+
+        fd = safe_close(fd);
+
+        fd = acquire_data_fd("", 0, flags);
+        assert_se(fd >= 0);
+
+        zero(rbuffer);
+        assert_se(read(fd, rbuffer, sizeof(rbuffer)) == 0);
+        assert_se(streq(rbuffer, ""));
+
+        fd = safe_close(fd);
+
+        random_bytes(wbuffer, sizeof(wbuffer));
+
+        fd = acquire_data_fd(wbuffer, sizeof(wbuffer), flags);
+        assert_se(fd >= 0);
+
+        zero(rbuffer);
+        assert_se(read(fd, rbuffer, sizeof(rbuffer)) == sizeof(rbuffer));
+        assert_se(memcmp(rbuffer, wbuffer, sizeof(rbuffer)) == 0);
+
+        fd = safe_close(fd);
+}
+
+static void test_acquire_data_fd(void) {
+
+        test_acquire_data_fd_one(0);
+        test_acquire_data_fd_one(ACQUIRE_NO_DEV_NULL);
+        test_acquire_data_fd_one(ACQUIRE_NO_MEMFD);
+        test_acquire_data_fd_one(ACQUIRE_NO_DEV_NULL|ACQUIRE_NO_MEMFD);
+        test_acquire_data_fd_one(ACQUIRE_NO_PIPE);
+        test_acquire_data_fd_one(ACQUIRE_NO_DEV_NULL|ACQUIRE_NO_PIPE);
+        test_acquire_data_fd_one(ACQUIRE_NO_MEMFD|ACQUIRE_NO_PIPE);
+        test_acquire_data_fd_one(ACQUIRE_NO_DEV_NULL|ACQUIRE_NO_MEMFD|ACQUIRE_NO_PIPE);
+        test_acquire_data_fd_one(ACQUIRE_NO_DEV_NULL|ACQUIRE_NO_MEMFD|ACQUIRE_NO_PIPE|ACQUIRE_NO_TMPFILE);
 }
 
 int main(int argc, char *argv[]) {
@@ -108,6 +160,7 @@ int main(int argc, char *argv[]) {
         test_close_nointr();
         test_same_fd();
         test_open_serialization_fd();
+        test_acquire_data_fd();
 
         return 0;
 }
index adbf99a..bc5d5d4 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd
 
index 27495fa..286867d 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -465,7 +466,7 @@ static void test_write_string_file_no_create(void) {
         assert_se(write_string_file("/a/file/which/does/not/exists/i/guess", "boohoo", 0) < 0);
         assert_se(write_string_file(fn, "boohoo", 0) == 0);
 
-        assert_se(read(fd, buf, sizeof(buf)) == strlen("boohoo\n"));
+        assert_se(read(fd, buf, sizeof(buf)) == STRLEN("boohoo\n"));
         assert_se(streq(buf, "boohoo\n"));
 
         unlink(fn);
@@ -704,7 +705,6 @@ static void test_read_line_one_file(FILE *f) {
 
 static void test_read_line(void) {
         _cleanup_fclose_ FILE *f = NULL;
-        _cleanup_free_ char *line = NULL;
 
         f = fmemopen((void*) buffer, sizeof(buffer), "re");
         assert_se(f);
index 77e809c..38e433a 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 2ffadf5..b4c2c60 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -347,8 +348,9 @@ static void test_readlink_and_make_absolute(void) {
         char name2[] = "test-readlink_and_make_absolute/original";
         char name_alias[] = "/tmp/test-readlink_and_make_absolute-alias";
         char *r = NULL;
+        _cleanup_free_ char *pwd = NULL;
 
-        assert_se(mkdir_safe(tempdir, 0755, getuid(), getgid()) >= 0);
+        assert_se(mkdir_safe(tempdir, 0755, getuid(), getgid(), false) >= 0);
         assert_se(touch(name) >= 0);
 
         assert_se(symlink(name, name_alias) >= 0);
@@ -357,6 +359,8 @@ static void test_readlink_and_make_absolute(void) {
         free(r);
         assert_se(unlink(name_alias) >= 0);
 
+        assert_se(pwd = get_current_dir_name());
+
         assert_se(chdir(tempdir) >= 0);
         assert_se(symlink(name2, name_alias) >= 0);
         assert_se(readlink_and_make_absolute(name_alias, &r) >= 0);
@@ -364,6 +368,8 @@ static void test_readlink_and_make_absolute(void) {
         free(r);
         assert_se(unlink(name_alias) >= 0);
 
+        assert_se(chdir(pwd) >= 0);
+
         assert_se(rm_rf(tempdir, REMOVE_ROOT|REMOVE_PHYSICAL) >= 0);
 }
 
@@ -397,9 +403,9 @@ static void test_var_tmp(void) {
                 assert_se(tmp_backup);
         }
 
-        assert(unsetenv("TMPDIR") >= 0);
-        assert(unsetenv("TEMP") >= 0);
-        assert(unsetenv("TMP") >= 0);
+        assert_se(unsetenv("TMPDIR") >= 0);
+        assert_se(unsetenv("TEMP") >= 0);
+        assert_se(unsetenv("TMP") >= 0);
 
         assert_se(var_tmp_dir(&tmp_dir) >= 0);
         assert_se(streq(tmp_dir, "/var/tmp"));
@@ -442,6 +448,32 @@ static void test_dot_or_dot_dot(void) {
         assert_se(!dot_or_dot_dot("..foo"));
 }
 
+static void test_access_fd(void) {
+        _cleanup_(rmdir_and_freep) char *p = NULL;
+        _cleanup_close_ int fd = -1;
+
+        assert_se(mkdtemp_malloc("/tmp/access-fd.XXXXXX", &p) >= 0);
+
+        fd = open(p, O_RDONLY|O_DIRECTORY|O_CLOEXEC);
+        assert_se(fd >= 0);
+
+        assert_se(access_fd(fd, R_OK) >= 0);
+        assert_se(access_fd(fd, F_OK) >= 0);
+        assert_se(access_fd(fd, W_OK) >= 0);
+
+        assert_se(fchmod(fd, 0000) >= 0);
+
+        assert_se(access_fd(fd, F_OK) >= 0);
+
+        if (geteuid() == 0) {
+                assert_se(access_fd(fd, R_OK) >= 0);
+                assert_se(access_fd(fd, W_OK) >= 0);
+        } else {
+                assert_se(access_fd(fd, R_OK) == -EACCES);
+                assert_se(access_fd(fd, W_OK) == -EACCES);
+        }
+}
+
 int main(int argc, char *argv[]) {
         test_unlink_noerrno();
         test_get_files_in_directory();
@@ -449,6 +481,7 @@ int main(int argc, char *argv[]) {
         test_var_tmp();
         test_chase_symlinks();
         test_dot_or_dot_dot();
+        test_access_fd();
 
         return 0;
 }
index 63a4b8c..081ec6a 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index af866e0..bd2f8fc 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 02d1cfa..f3b4258 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 0471cd2..1725766 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd
 
index 83cea36..dd91954 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd
 
@@ -37,6 +38,29 @@ static void test_ordered_hashmap_next(void) {
         assert_se(!ordered_hashmap_next(m, INT_TO_PTR(3)));
 }
 
+typedef struct Item {
+        int seen;
+} Item;
+static void item_seen(Item *item) {
+        item->seen++;
+}
+
+static void test_hashmap_free_with_destructor(void) {
+        Hashmap *m;
+        struct Item items[4] = {};
+        unsigned i;
+
+        assert_se(m = hashmap_new(NULL));
+        for (i = 0; i < ELEMENTSOF(items) - 1; i++)
+                assert_se(hashmap_put(m, INT_TO_PTR(i), items + i) == 1);
+
+        m = hashmap_free_with_destructor(m, item_seen);
+        assert_se(items[0].seen == 1);
+        assert_se(items[1].seen == 1);
+        assert_se(items[2].seen == 1);
+        assert_se(items[3].seen == 0);
+}
+
 static void test_uint64_compare_func(void) {
         const uint64_t a = 0x100, b = 0x101;
 
@@ -61,6 +85,7 @@ int main(int argc, const char *argv[]) {
         test_ordered_hashmap_funcs();
 
         test_ordered_hashmap_next();
+        test_hashmap_free_with_destructor();
         test_uint64_compare_func();
         test_trivial_compare_func();
         test_string_compare_func();
index 5b707c3..c371e19 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
 #include "alloc-util.h"
 #include "cgroup-util.h"
 
-void enter_cgroup_subroot(void) {
+int enter_cgroup_subroot(void) {
         _cleanup_free_ char *cgroup_root = NULL, *cgroup_subroot = NULL;
         CGroupMask supported;
+        int r;
+
+        r = cg_pid_get_path(NULL, 0, &cgroup_root);
+        if (r == -ENOMEDIUM)
+                return log_warning_errno(r, "cg_pid_get_path(NULL, 0, ...) failed: %m");
+        assert(r >= 0);
 
-        assert_se(cg_pid_get_path(NULL, 0, &cgroup_root) >= 0);
         assert_se(asprintf(&cgroup_subroot, "%s/%" PRIx64, cgroup_root, random_u64()) >= 0);
         assert_se(cg_mask_supported(&supported) >= 0);
 
         /* If this fails, then we don't mind as the later cgroup operations will fail too, and it's fine if we handle
          * any errors at that point. */
 
-        if (cg_create_everywhere(supported, _CGROUP_MASK_ALL, cgroup_subroot) < 0)
-                return;
+        r = cg_create_everywhere(supported, _CGROUP_MASK_ALL, cgroup_subroot);
+        if (r < 0)
+                return r;
 
-        if (cg_attach_everywhere(supported, cgroup_subroot, 0, NULL, NULL) < 0)
-                return;
+        return cg_attach_everywhere(supported, cgroup_subroot, 0, NULL, NULL);
 }
index 8af32c8..1ee93f5 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -40,4 +41,4 @@
                -ENOMEDIUM /* cannot determine cgroup */         \
                )
 
-void enter_cgroup_subroot(void);
+int enter_cgroup_subroot(void);
index fcae427..4f19cb4 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -106,72 +107,72 @@ static void test_unhexmem(void) {
 static void test_base32hexmem(void) {
         char *b32;
 
-        b32 = base32hexmem("", strlen(""), true);
+        b32 = base32hexmem("", STRLEN(""), true);
         assert_se(b32);
         assert_se(streq(b32, ""));
         free(b32);
 
-        b32 = base32hexmem("f", strlen("f"), true);
+        b32 = base32hexmem("f", STRLEN("f"), true);
         assert_se(b32);
         assert_se(streq(b32, "CO======"));
         free(b32);
 
-        b32 = base32hexmem("fo", strlen("fo"), true);
+        b32 = base32hexmem("fo", STRLEN("fo"), true);
         assert_se(b32);
         assert_se(streq(b32, "CPNG===="));
         free(b32);
 
-        b32 = base32hexmem("foo", strlen("foo"), true);
+        b32 = base32hexmem("foo", STRLEN("foo"), true);
         assert_se(b32);
         assert_se(streq(b32, "CPNMU==="));
         free(b32);
 
-        b32 = base32hexmem("foob", strlen("foob"), true);
+        b32 = base32hexmem("foob", STRLEN("foob"), true);
         assert_se(b32);
         assert_se(streq(b32, "CPNMUOG="));
         free(b32);
 
-        b32 = base32hexmem("fooba", strlen("fooba"), true);
+        b32 = base32hexmem("fooba", STRLEN("fooba"), true);
         assert_se(b32);
         assert_se(streq(b32, "CPNMUOJ1"));
         free(b32);
 
-        b32 = base32hexmem("foobar", strlen("foobar"), true);
+        b32 = base32hexmem("foobar", STRLEN("foobar"), true);
         assert_se(b32);
         assert_se(streq(b32, "CPNMUOJ1E8======"));
         free(b32);
 
-        b32 = base32hexmem("", strlen(""), false);
+        b32 = base32hexmem("", STRLEN(""), false);
         assert_se(b32);
         assert_se(streq(b32, ""));
         free(b32);
 
-        b32 = base32hexmem("f", strlen("f"), false);
+        b32 = base32hexmem("f", STRLEN("f"), false);
         assert_se(b32);
         assert_se(streq(b32, "CO"));
         free(b32);
 
-        b32 = base32hexmem("fo", strlen("fo"), false);
+        b32 = base32hexmem("fo", STRLEN("fo"), false);
         assert_se(b32);
         assert_se(streq(b32, "CPNG"));
         free(b32);
 
-        b32 = base32hexmem("foo", strlen("foo"), false);
+        b32 = base32hexmem("foo", STRLEN("foo"), false);
         assert_se(b32);
         assert_se(streq(b32, "CPNMU"));
         free(b32);
 
-        b32 = base32hexmem("foob", strlen("foob"), false);
+        b32 = base32hexmem("foob", STRLEN("foob"), false);
         assert_se(b32);
         assert_se(streq(b32, "CPNMUOG"));
         free(b32);
 
-        b32 = base32hexmem("fooba", strlen("fooba"), false);
+        b32 = base32hexmem("fooba", STRLEN("fooba"), false);
         assert_se(b32);
         assert_se(streq(b32, "CPNMUOJ1"));
         free(b32);
 
-        b32 = base32hexmem("foobar", strlen("foobar"), false);
+        b32 = base32hexmem("foobar", STRLEN("foobar"), false);
         assert_se(b32);
         assert_se(streq(b32, "CPNMUOJ1E8"));
         free(b32);
@@ -181,161 +182,162 @@ static void test_unbase32hexmem(void) {
         void *mem;
         size_t len;
 
-        assert_se(unbase32hexmem("", strlen(""), true, &mem, &len) == 0);
+        assert_se(unbase32hexmem("", STRLEN(""), true, &mem, &len) == 0);
         assert_se(streq(strndupa(mem, len), ""));
         free(mem);
 
-        assert_se(unbase32hexmem("CO======", strlen("CO======"), true, &mem, &len) == 0);
+        assert_se(unbase32hexmem("CO======", STRLEN("CO======"), true, &mem, &len) == 0);
         assert_se(streq(strndupa(mem, len), "f"));
         free(mem);
 
-        assert_se(unbase32hexmem("CPNG====", strlen("CPNG===="), true, &mem, &len) == 0);
+        assert_se(unbase32hexmem("CPNG====", STRLEN("CPNG===="), true, &mem, &len) == 0);
         assert_se(streq(strndupa(mem, len), "fo"));
         free(mem);
 
-        assert_se(unbase32hexmem("CPNMU===", strlen("CPNMU==="), true, &mem, &len) == 0);
+        assert_se(unbase32hexmem("CPNMU===", STRLEN("CPNMU==="), true, &mem, &len) == 0);
         assert_se(streq(strndupa(mem, len), "foo"));
         free(mem);
 
-        assert_se(unbase32hexmem("CPNMUOG=", strlen("CPNMUOG="), true, &mem, &len) == 0);
+        assert_se(unbase32hexmem("CPNMUOG=", STRLEN("CPNMUOG="), true, &mem, &len) == 0);
         assert_se(streq(strndupa(mem, len), "foob"));
         free(mem);
 
-        assert_se(unbase32hexmem("CPNMUOJ1", strlen("CPNMUOJ1"), true, &mem, &len) == 0);
+        assert_se(unbase32hexmem("CPNMUOJ1", STRLEN("CPNMUOJ1"), true, &mem, &len) == 0);
         assert_se(streq(strndupa(mem, len), "fooba"));
         free(mem);
 
-        assert_se(unbase32hexmem("CPNMUOJ1E8======", strlen("CPNMUOJ1E8======"), true, &mem, &len) == 0);
+        assert_se(unbase32hexmem("CPNMUOJ1E8======", STRLEN("CPNMUOJ1E8======"), true, &mem, &len) == 0);
         assert_se(streq(strndupa(mem, len), "foobar"));
         free(mem);
 
-        assert_se(unbase32hexmem("A", strlen("A"), true, &mem, &len) == -EINVAL);
-        assert_se(unbase32hexmem("A=======", strlen("A======="), true, &mem, &len) == -EINVAL);
-        assert_se(unbase32hexmem("AAA=====", strlen("AAA====="), true, &mem, &len) == -EINVAL);
-        assert_se(unbase32hexmem("AAAAAA==", strlen("AAAAAA=="), true, &mem, &len) == -EINVAL);
-        assert_se(unbase32hexmem("AB======", strlen("AB======"), true, &mem, &len) == -EINVAL);
-        assert_se(unbase32hexmem("AAAB====", strlen("AAAB===="), true, &mem, &len) == -EINVAL);
-        assert_se(unbase32hexmem("AAAAB===", strlen("AAAAB==="), true, &mem, &len) == -EINVAL);
-        assert_se(unbase32hexmem("AAAAAAB=", strlen("AAAAAAB="), true, &mem, &len) == -EINVAL);
-
-        assert_se(unbase32hexmem("XPNMUOJ1", strlen("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
-        assert_se(unbase32hexmem("CXNMUOJ1", strlen("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
-        assert_se(unbase32hexmem("CPXMUOJ1", strlen("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
-        assert_se(unbase32hexmem("CPNXUOJ1", strlen("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
-        assert_se(unbase32hexmem("CPNMXOJ1", strlen("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
-        assert_se(unbase32hexmem("CPNMUXJ1", strlen("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
-        assert_se(unbase32hexmem("CPNMUOX1", strlen("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
-        assert_se(unbase32hexmem("CPNMUOJX", strlen("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
-
-        assert_se(unbase32hexmem("", strlen(""), false, &mem, &len) == 0);
+        assert_se(unbase32hexmem("A", STRLEN("A"), true, &mem, &len) == -EINVAL);
+        assert_se(unbase32hexmem("A=======", STRLEN("A======="), true, &mem, &len) == -EINVAL);
+        assert_se(unbase32hexmem("AAA=====", STRLEN("AAA====="), true, &mem, &len) == -EINVAL);
+        assert_se(unbase32hexmem("AAAAAA==", STRLEN("AAAAAA=="), true, &mem, &len) == -EINVAL);
+        assert_se(unbase32hexmem("AB======", STRLEN("AB======"), true, &mem, &len) == -EINVAL);
+        assert_se(unbase32hexmem("AAAB====", STRLEN("AAAB===="), true, &mem, &len) == -EINVAL);
+        assert_se(unbase32hexmem("AAAAB===", STRLEN("AAAAB==="), true, &mem, &len) == -EINVAL);
+        assert_se(unbase32hexmem("AAAAAAB=", STRLEN("AAAAAAB="), true, &mem, &len) == -EINVAL);
+
+        assert_se(unbase32hexmem("XPNMUOJ1", STRLEN("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
+        assert_se(unbase32hexmem("CXNMUOJ1", STRLEN("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
+        assert_se(unbase32hexmem("CPXMUOJ1", STRLEN("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
+        assert_se(unbase32hexmem("CPNXUOJ1", STRLEN("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
+        assert_se(unbase32hexmem("CPNMXOJ1", STRLEN("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
+        assert_se(unbase32hexmem("CPNMUXJ1", STRLEN("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
+        assert_se(unbase32hexmem("CPNMUOX1", STRLEN("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
+        assert_se(unbase32hexmem("CPNMUOJX", STRLEN("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
+
+        assert_se(unbase32hexmem("", STRLEN(""), false, &mem, &len) == 0);
         assert_se(streq(strndupa(mem, len), ""));
         free(mem);
 
-        assert_se(unbase32hexmem("CO", strlen("CO"), false, &mem, &len) == 0);
+        assert_se(unbase32hexmem("CO", STRLEN("CO"), false, &mem, &len) == 0);
         assert_se(streq(strndupa(mem, len), "f"));
         free(mem);
 
-        assert_se(unbase32hexmem("CPNG", strlen("CPNG"), false, &mem, &len) == 0);
+        assert_se(unbase32hexmem("CPNG", STRLEN("CPNG"), false, &mem, &len) == 0);
         assert_se(streq(strndupa(mem, len), "fo"));
         free(mem);
 
-        assert_se(unbase32hexmem("CPNMU", strlen("CPNMU"), false, &mem, &len) == 0);
+        assert_se(unbase32hexmem("CPNMU", STRLEN("CPNMU"), false, &mem, &len) == 0);
         assert_se(streq(strndupa(mem, len), "foo"));
         free(mem);
 
-        assert_se(unbase32hexmem("CPNMUOG", strlen("CPNMUOG"), false, &mem, &len) == 0);
+        assert_se(unbase32hexmem("CPNMUOG", STRLEN("CPNMUOG"), false, &mem, &len) == 0);
         assert_se(streq(strndupa(mem, len), "foob"));
         free(mem);
 
-        assert_se(unbase32hexmem("CPNMUOJ1", strlen("CPNMUOJ1"), false, &mem, &len) == 0);
+        assert_se(unbase32hexmem("CPNMUOJ1", STRLEN("CPNMUOJ1"), false, &mem, &len) == 0);
         assert_se(streq(strndupa(mem, len), "fooba"));
         free(mem);
 
-        assert_se(unbase32hexmem("CPNMUOJ1E8", strlen("CPNMUOJ1E8"), false, &mem, &len) == 0);
+        assert_se(unbase32hexmem("CPNMUOJ1E8", STRLEN("CPNMUOJ1E8"), false, &mem, &len) == 0);
         assert_se(streq(strndupa(mem, len), "foobar"));
         free(mem);
 
-        assert_se(unbase32hexmem("CPNMUOG=", strlen("CPNMUOG="), false, &mem, &len) == -EINVAL);
-        assert_se(unbase32hexmem("CPNMUOJ1E8======", strlen("CPNMUOJ1E8======"), false, &mem, &len) == -EINVAL);
-        assert_se(unbase32hexmem("A", strlen("A"), false, &mem, &len) == -EINVAL);
-        assert_se(unbase32hexmem("A", strlen("A"), false, &mem, &len) == -EINVAL);
-        assert_se(unbase32hexmem("AAA", strlen("AAA"), false, &mem, &len) == -EINVAL);
-        assert_se(unbase32hexmem("AAAAAA", strlen("AAAAAA"), false, &mem, &len) == -EINVAL);
-        assert_se(unbase32hexmem("AB", strlen("AB"), false, &mem, &len) == -EINVAL);
-        assert_se(unbase32hexmem("AAAB", strlen("AAAB"), false, &mem, &len) == -EINVAL);
-        assert_se(unbase32hexmem("AAAAB", strlen("AAAAB"), false, &mem, &len) == -EINVAL);
-        assert_se(unbase32hexmem("AAAAAAB", strlen("AAAAAAB"), false, &mem, &len) == -EINVAL);
+        assert_se(unbase32hexmem("CPNMUOG=", STRLEN("CPNMUOG="), false, &mem, &len) == -EINVAL);
+        assert_se(unbase32hexmem("CPNMUOJ1E8======", STRLEN("CPNMUOJ1E8======"), false, &mem, &len) == -EINVAL);
+        assert_se(unbase32hexmem("A", STRLEN("A"), false, &mem, &len) == -EINVAL);
+        assert_se(unbase32hexmem("A", STRLEN("A"), false, &mem, &len) == -EINVAL);
+        assert_se(unbase32hexmem("AAA", STRLEN("AAA"), false, &mem, &len) == -EINVAL);
+        assert_se(unbase32hexmem("AAAAAA", STRLEN("AAAAAA"), false, &mem, &len) == -EINVAL);
+        assert_se(unbase32hexmem("AB", STRLEN("AB"), false, &mem, &len) == -EINVAL);
+        assert_se(unbase32hexmem("AAAB", STRLEN("AAAB"), false, &mem, &len) == -EINVAL);
+        assert_se(unbase32hexmem("AAAAB", STRLEN("AAAAB"), false, &mem, &len) == -EINVAL);
+        assert_se(unbase32hexmem("AAAAAAB", STRLEN("AAAAAAB"), false, &mem, &len) == -EINVAL);
 }
 
 /* https://tools.ietf.org/html/rfc4648#section-10 */
 static void test_base64mem(void) {
         char *b64;
 
-        assert_se(base64mem("", strlen(""), &b64) == 0);
+        assert_se(base64mem("", STRLEN(""), &b64) == 0);
         assert_se(streq(b64, ""));
         free(b64);
 
-        assert_se(base64mem("f", strlen("f"), &b64) == 4);
+        assert_se(base64mem("f", STRLEN("f"), &b64) == 4);
         assert_se(streq(b64, "Zg=="));
         free(b64);
 
-        assert_se(base64mem("fo", strlen("fo"), &b64) == 4);
+        assert_se(base64mem("fo", STRLEN("fo"), &b64) == 4);
         assert_se(streq(b64, "Zm8="));
         free(b64);
 
-        assert_se(base64mem("foo", strlen("foo"), &b64) == 4);
+        assert_se(base64mem("foo", STRLEN("foo"), &b64) == 4);
         assert_se(streq(b64, "Zm9v"));
         free(b64);
 
-        assert_se(base64mem("foob", strlen("foob"), &b64) == 8);
+        assert_se(base64mem("foob", STRLEN("foob"), &b64) == 8);
         assert_se(streq(b64, "Zm9vYg=="));
         free(b64);
 
-        assert_se(base64mem("fooba", strlen("fooba"), &b64) == 8);
+        assert_se(base64mem("fooba", STRLEN("fooba"), &b64) == 8);
         assert_se(streq(b64, "Zm9vYmE="));
         free(b64);
 
-        assert_se(base64mem("foobar", strlen("foobar"), &b64) == 8);
+        assert_se(base64mem("foobar", STRLEN("foobar"), &b64) == 8);
         assert_se(streq(b64, "Zm9vYmFy"));
         free(b64);
 }
 
-static void test_unbase64mem(void) {
-        void *mem;
-        size_t len;
-
-        assert_se(unbase64mem("", strlen(""), &mem, &len) == 0);
-        assert_se(streq(strndupa(mem, len), ""));
-        free(mem);
+static void test_unbase64mem_one(const char *input, const char *output, int ret) {
+        _cleanup_free_ void *buffer = NULL;
+        size_t size = 0;
 
-        assert_se(unbase64mem("Zg==", strlen("Zg=="), &mem, &len) == 0);
-        assert_se(streq(strndupa(mem, len), "f"));
-        free(mem);
-
-        assert_se(unbase64mem("Zm8=", strlen("Zm8="), &mem, &len) == 0);
-        assert_se(streq(strndupa(mem, len), "fo"));
-        free(mem);
+        assert_se(unbase64mem(input, (size_t) -1, &buffer, &size) == ret);
 
-        assert_se(unbase64mem("Zm9v", strlen("Zm9v"), &mem, &len) == 0);
-        assert_se(streq(strndupa(mem, len), "foo"));
-        free(mem);
-
-        assert_se(unbase64mem("Zm9vYg==", strlen("Zm9vYg=="), &mem, &len) == 0);
-        assert_se(streq(strndupa(mem, len), "foob"));
-        free(mem);
-
-        assert_se(unbase64mem("Zm9vYmE=", strlen("Zm9vYmE="), &mem, &len) == 0);
-        assert_se(streq(strndupa(mem, len), "fooba"));
-        free(mem);
+        if (ret >= 0) {
+                assert_se(size == strlen(output));
+                assert_se(memcmp(buffer, output, size) == 0);
+                assert_se(((char*) buffer)[size] == 0);
+        }
+}
 
-        assert_se(unbase64mem("Zm9vYmFy", strlen("Zm9vYmFy"), &mem, &len) == 0);
-        assert_se(streq(strndupa(mem, len), "foobar"));
-        free(mem);
+static void test_unbase64mem(void) {
 
-        assert_se(unbase64mem("A", strlen("A"), &mem, &len) == -EINVAL);
-        assert_se(unbase64mem("A====", strlen("A===="), &mem, &len) == -EINVAL);
-        assert_se(unbase64mem("AAB==", strlen("AAB=="), &mem, &len) == -EINVAL);
-        assert_se(unbase64mem("AAAB=", strlen("AAAB="), &mem, &len) == -EINVAL);
+        test_unbase64mem_one("", "", 0);
+        test_unbase64mem_one("Zg==", "f", 0);
+        test_unbase64mem_one("Zm8=", "fo", 0);
+        test_unbase64mem_one("Zm9v", "foo", 0);
+        test_unbase64mem_one("Zm9vYg==", "foob", 0);
+        test_unbase64mem_one("Zm9vYmE=", "fooba", 0);
+        test_unbase64mem_one("Zm9vYmFy", "foobar", 0);
+
+        test_unbase64mem_one(" ", "", 0);
+        test_unbase64mem_one(" \n\r ", "", 0);
+        test_unbase64mem_one("    Zg\n==       ", "f", 0);
+        test_unbase64mem_one(" Zm 8=\r", "fo", 0);
+        test_unbase64mem_one("  Zm9\n\r\r\nv   ", "foo", 0);
+        test_unbase64mem_one(" Z m9vYg==\n\r", "foob", 0);
+        test_unbase64mem_one(" Zm 9vYmE=   ", "fooba", 0);
+        test_unbase64mem_one("   Z m9v    YmFy   ", "foobar", 0);
+
+        test_unbase64mem_one("A", NULL, -EPIPE);
+        test_unbase64mem_one("A====", NULL, -EINVAL);
+        test_unbase64mem_one("AAB==", NULL, -EINVAL);
+        test_unbase64mem_one(" A A A B = ", NULL, -EINVAL);
+        test_unbase64mem_one(" Z m 8 = q u u x ", NULL, -ENAMETOOLONG);
 }
 
 static void test_hexdump(void) {
index d2c3ea5..3293548 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -99,7 +100,7 @@ static void test_hostname_cleanup(void) {
         assert_se(streq(hostname_cleanup(s), "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"));
 }
 
-static void test_read_hostname_config(void) {
+static void test_read_etc_hostname(void) {
         char path[] = "/tmp/hostname.XXXXXX";
         char *hostname;
         int fd;
@@ -109,40 +110,40 @@ static void test_read_hostname_config(void) {
         close(fd);
 
         /* simple hostname */
-        write_string_file(path, "foo", WRITE_STRING_FILE_CREATE);
-        assert_se(read_hostname_config(path, &hostname) == 0);
+        assert_se(write_string_file(path, "foo", WRITE_STRING_FILE_CREATE) == 0);
+        assert_se(read_etc_hostname(path, &hostname) == 0);
         assert_se(streq(hostname, "foo"));
         hostname = mfree(hostname);
 
         /* with comment */
-        write_string_file(path, "# comment\nfoo", WRITE_STRING_FILE_CREATE);
-        assert_se(read_hostname_config(path, &hostname) == 0);
+        assert_se(write_string_file(path, "# comment\nfoo", WRITE_STRING_FILE_CREATE) == 0);
+        assert_se(read_etc_hostname(path, &hostname) == 0);
         assert_se(hostname);
         assert_se(streq(hostname, "foo"));
         hostname = mfree(hostname);
 
         /* with comment and extra whitespace */
-        write_string_file(path, "# comment\n\n foo ", WRITE_STRING_FILE_CREATE);
-        assert_se(read_hostname_config(path, &hostname) == 0);
+        assert_se(write_string_file(path, "# comment\n\n foo ", WRITE_STRING_FILE_CREATE) == 0);
+        assert_se(read_etc_hostname(path, &hostname) == 0);
         assert_se(hostname);
         assert_se(streq(hostname, "foo"));
         hostname = mfree(hostname);
 
         /* cleans up name */
-        write_string_file(path, "!foo/bar.com", WRITE_STRING_FILE_CREATE);
-        assert_se(read_hostname_config(path, &hostname) == 0);
+        assert_se(write_string_file(path, "!foo/bar.com", WRITE_STRING_FILE_CREATE) == 0);
+        assert_se(read_etc_hostname(path, &hostname) == 0);
         assert_se(hostname);
         assert_se(streq(hostname, "foobar.com"));
         hostname = mfree(hostname);
 
         /* no value set */
         hostname = (char*) 0x1234;
-        write_string_file(path, "# nothing here\n", WRITE_STRING_FILE_CREATE);
-        assert_se(read_hostname_config(path, &hostname) == -ENOENT);
+        assert_se(write_string_file(path, "# nothing here\n", WRITE_STRING_FILE_CREATE) == 0);
+        assert_se(read_etc_hostname(path, &hostname) == -ENOENT);
         assert_se(hostname == (char*) 0x1234);  /* does not touch argument on error */
 
         /* nonexisting file */
-        assert_se(read_hostname_config("/non/existing", &hostname) == -ENOENT);
+        assert_se(read_etc_hostname("/non/existing", &hostname) == -ENOENT);
         assert_se(hostname == (char*) 0x1234);  /* does not touch argument on error */
 
         unlink(path);
@@ -154,7 +155,7 @@ int main(int argc, char *argv[]) {
 
         test_hostname_is_valid();
         test_hostname_cleanup();
-        test_read_hostname_config();
+        test_read_etc_hostname();
 
         return 0;
 }
index b38507d..febb4c6 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index e5f4520..b7fca15 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 8b7a122..73692ec 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd
 
index e2754a0..efdd82a 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -766,6 +767,240 @@ static void test_static_instance(const char *root) {
         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "static-instance@foo.service", &state) >= 0 && state == UNIT_FILE_STATIC);
 }
 
+static void test_with_dropin(const char *root) {
+        const char *p;
+        UnitFileState state;
+        UnitFileChange *changes = NULL;
+        unsigned n_changes = 0;
+
+        assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-1.service", &state) == -ENOENT);
+        assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-2.service", &state) == -ENOENT);
+        assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-3.service", &state) == -ENOENT);
+        assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-4a.service", &state) == -ENOENT);
+        assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-4b.service", &state) == -ENOENT);
+
+        p = strjoina(root, "/usr/lib/systemd/system/with-dropin-1.service");
+        assert_se(write_string_file(p,
+                                    "[Install]\n"
+                                    "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0);
+
+        p = strjoina(root, "/usr/lib/systemd/system/with-dropin-1.service.d/dropin.conf");
+        assert_se(mkdir_parents(p, 0755) >= 0);
+        assert_se(write_string_file(p,
+                                    "[Install]\n"
+                                    "WantedBy=graphical.target\n", WRITE_STRING_FILE_CREATE) >= 0);
+
+        assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-1.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
+
+        p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/with-dropin-2.service");
+        assert_se(write_string_file(p,
+                                    "[Install]\n"
+                                    "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0);
+
+        p = strjoina(root, "/usr/lib/systemd/system/with-dropin-2.service.d/dropin.conf");
+        assert_se(mkdir_parents(p, 0755) >= 0);
+        assert_se(write_string_file(p,
+                                    "[Install]\n"
+                                    "WantedBy=graphical.target\n", WRITE_STRING_FILE_CREATE) >= 0);
+
+        assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-2.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
+
+        p = strjoina(root, "/usr/lib/systemd/system/with-dropin-3.service");
+        assert_se(write_string_file(p,
+                                    "[Install]\n"
+                                    "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0);
+
+        p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/with-dropin-3.service.d/dropin.conf");
+        assert_se(mkdir_parents(p, 0755) >= 0);
+        assert_se(write_string_file(p,
+                                    "[Install]\n"
+                                    "WantedBy=graphical.target\n", WRITE_STRING_FILE_CREATE) >= 0);
+
+        assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-3.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
+
+        p = strjoina(root, "/usr/lib/systemd/system/with-dropin-4a.service");
+        assert_se(write_string_file(p,
+                                    "[Install]\n"
+                                    "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0);
+
+        p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/with-dropin-4a.service.d/dropin.conf");
+        assert_se(mkdir_parents(p, 0755) >= 0);
+        assert_se(write_string_file(p,
+                                    "[Install]\n"
+                                    "Also=with-dropin-4b.service\n", WRITE_STRING_FILE_CREATE) >= 0);
+
+        assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-4a.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
+
+        p = strjoina(root, "/usr/lib/systemd/system/with-dropin-4b.service");
+        assert_se(write_string_file(p,
+                                    "[Install]\n"
+                                    "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0);
+
+        assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-4b.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
+
+        assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("with-dropin-1.service"), &changes, &n_changes) == 1);
+        assert_se(n_changes == 2);
+        assert_se(changes[0].type == UNIT_FILE_SYMLINK);
+        assert_se(changes[1].type == UNIT_FILE_SYMLINK);
+        assert_se(streq(changes[0].source, "/usr/lib/systemd/system/with-dropin-1.service"));
+        assert_se(streq(changes[1].source, "/usr/lib/systemd/system/with-dropin-1.service"));
+        p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/with-dropin-1.service");
+        assert_se(streq(changes[0].path, p));
+        p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/graphical.target.wants/with-dropin-1.service");
+        assert_se(streq(changes[1].path, p));
+        unit_file_changes_free(changes, n_changes);
+        changes = NULL; n_changes = 0;
+
+        assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("with-dropin-2.service"), &changes, &n_changes) == 1);
+        assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-2.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
+        assert_se(n_changes == 2);
+        assert_se(changes[0].type == UNIT_FILE_SYMLINK);
+        assert_se(changes[1].type == UNIT_FILE_SYMLINK);
+        assert_se(streq(changes[0].source, SYSTEM_CONFIG_UNIT_PATH"/with-dropin-2.service"));
+        assert_se(streq(changes[1].source, SYSTEM_CONFIG_UNIT_PATH"/with-dropin-2.service"));
+        p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/with-dropin-2.service");
+        assert_se(streq(changes[0].path, p));
+        p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/graphical.target.wants/with-dropin-2.service");
+        assert_se(streq(changes[1].path, p));
+        unit_file_changes_free(changes, n_changes);
+        changes = NULL; n_changes = 0;
+
+        assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("with-dropin-3.service"), &changes, &n_changes) == 1);
+        assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-3.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
+        assert_se(n_changes == 2);
+        assert_se(changes[0].type == UNIT_FILE_SYMLINK);
+        assert_se(changes[1].type == UNIT_FILE_SYMLINK);
+        assert_se(streq(changes[0].source, "/usr/lib/systemd/system/with-dropin-3.service"));
+        assert_se(streq(changes[1].source, "/usr/lib/systemd/system/with-dropin-3.service"));
+        p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/with-dropin-3.service");
+        assert_se(streq(changes[0].path, p));
+        p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/graphical.target.wants/with-dropin-3.service");
+        assert_se(streq(changes[1].path, p));
+        unit_file_changes_free(changes, n_changes);
+        changes = NULL; n_changes = 0;
+
+        assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("with-dropin-4a.service"), &changes, &n_changes) == 1);
+        assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-3.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
+        assert_se(n_changes == 2);
+        assert_se(changes[0].type == UNIT_FILE_SYMLINK);
+        assert_se(changes[1].type == UNIT_FILE_SYMLINK);
+        assert_se(streq(changes[0].source, "/usr/lib/systemd/system/with-dropin-4a.service"));
+        assert_se(streq(changes[1].source, "/usr/lib/systemd/system/with-dropin-4b.service"));
+        p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/with-dropin-4a.service");
+        assert_se(streq(changes[0].path, p));
+        p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/with-dropin-4b.service");
+        assert_se(streq(changes[1].path, p));
+        unit_file_changes_free(changes, n_changes);
+        changes = NULL; n_changes = 0;
+
+        assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-1.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
+        assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-2.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
+        assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-3.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
+        assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-4a.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
+        assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-4b.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
+}
+
+static void test_with_dropin_template(const char *root) {
+        const char *p;
+        UnitFileState state;
+        UnitFileChange *changes = NULL;
+        unsigned n_changes = 0;
+
+        assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-1@.service", &state) == -ENOENT);
+        assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-2@.service", &state) == -ENOENT);
+        assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-3@.service", &state) == -ENOENT);
+
+        p = strjoina(root, "/usr/lib/systemd/system/with-dropin-1@.service");
+        assert_se(write_string_file(p,
+                                    "[Install]\n"
+                                    "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0);
+
+        p = strjoina(root, "/usr/lib/systemd/system/with-dropin-1@.service.d/dropin.conf");
+        assert_se(mkdir_parents(p, 0755) >= 0);
+        assert_se(write_string_file(p,
+                                    "[Install]\n"
+                                    "WantedBy=graphical.target\n", WRITE_STRING_FILE_CREATE) >= 0);
+
+        assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-1@.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
+
+        p = strjoina(root, "/usr/lib/systemd/system/with-dropin-2@.service");
+        assert_se(write_string_file(p,
+                                    "[Install]\n"
+                                    "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0);
+
+        p = strjoina(root, "/usr/lib/systemd/system/with-dropin-2@instance-1.service.d/dropin.conf");
+        assert_se(mkdir_parents(p, 0755) >= 0);
+        assert_se(write_string_file(p,
+                                    "[Install]\n"
+                                    "WantedBy=graphical.target\n", WRITE_STRING_FILE_CREATE) >= 0);
+
+        assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-2@.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
+
+        p = strjoina(root, "/usr/lib/systemd/system/with-dropin-3@.service");
+        assert_se(write_string_file(p,
+                                    "[Install]\n"
+                                    "DefaultInstance=instance-1\n"
+                                    "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0);
+
+        p = strjoina(root, "/usr/lib/systemd/system/with-dropin-3@.service.d/dropin.conf");
+        assert_se(mkdir_parents(p, 0755) >= 0);
+        assert_se(write_string_file(p,
+                                    "[Install]\n"
+                                    "DefaultInstance=instance-2\n", WRITE_STRING_FILE_CREATE) >= 0);
+
+        assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-3@.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
+
+        assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("with-dropin-1@instance-1.service"), &changes, &n_changes) == 1);
+        assert_se(n_changes == 2);
+        assert_se(changes[0].type == UNIT_FILE_SYMLINK);
+        assert_se(changes[1].type == UNIT_FILE_SYMLINK);
+        assert_se(streq(changes[0].source, "/usr/lib/systemd/system/with-dropin-1@.service"));
+        assert_se(streq(changes[1].source, "/usr/lib/systemd/system/with-dropin-1@.service"));
+        p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/with-dropin-1@instance-1.service");
+        assert_se(streq(changes[0].path, p));
+        p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/graphical.target.wants/with-dropin-1@instance-1.service");
+        assert_se(streq(changes[1].path, p));
+        unit_file_changes_free(changes, n_changes);
+        changes = NULL; n_changes = 0;
+
+        assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("with-dropin-2@instance-1.service"), &changes, &n_changes) == 1);
+        assert_se(n_changes == 2);
+        assert_se(changes[0].type == UNIT_FILE_SYMLINK);
+        assert_se(changes[1].type == UNIT_FILE_SYMLINK);
+        assert_se(streq(changes[0].source, "/usr/lib/systemd/system/with-dropin-2@.service"));
+        assert_se(streq(changes[1].source, "/usr/lib/systemd/system/with-dropin-2@.service"));
+        p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/with-dropin-2@instance-1.service");
+        assert_se(streq(changes[0].path, p));
+        p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/graphical.target.wants/with-dropin-2@instance-1.service");
+        assert_se(streq(changes[1].path, p));
+        unit_file_changes_free(changes, n_changes);
+        changes = NULL; n_changes = 0;
+
+        assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("with-dropin-2@instance-2.service"), &changes, &n_changes) == 1);
+        assert_se(n_changes == 1);
+        assert_se(changes[0].type == UNIT_FILE_SYMLINK);
+        assert_se(streq(changes[0].source, "/usr/lib/systemd/system/with-dropin-2@.service"));
+        p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/with-dropin-2@instance-2.service");
+        assert_se(streq(changes[0].path, p));
+        unit_file_changes_free(changes, n_changes);
+        changes = NULL; n_changes = 0;
+
+        assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("with-dropin-3@.service"), &changes, &n_changes) == 1);
+        assert_se(n_changes == 1);
+        assert_se(changes[0].type == UNIT_FILE_SYMLINK);
+        assert_se(streq(changes[0].source, "/usr/lib/systemd/system/with-dropin-3@.service"));
+        p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/with-dropin-3@instance-2.service");
+        assert_se(streq(changes[0].path, p));
+        unit_file_changes_free(changes, n_changes);
+        changes = NULL; n_changes = 0;
+
+        assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-1@instance-1.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
+        assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-2@instance-1.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
+        assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-2@instance-2.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
+        assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-3@instance-1.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
+        assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-3@instance-2.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
+}
+
 int main(int argc, char *argv[]) {
         char root[] = "/tmp/rootXXXXXX";
         const char *p;
@@ -797,6 +1032,8 @@ int main(int argc, char *argv[]) {
         test_preset_order(root);
         test_revert(root);
         test_static_instance(root);
+        test_with_dropin(root);
+        test_with_dropin_template(root);
 
         assert_se(rm_rf(root, REMOVE_ROOT|REMOVE_PHYSICAL) >= 0);
 
index fb36aa8..2f91918 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 10bd383..9ed9864 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index ce6c7aa..c901e35 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 7f0b9f2..46444a0 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index a61212c..931a281 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 0f71c18..408d141 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 0ccd745..25ffd8f 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd
 
index 427c698..4467bdd 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd
 
@@ -50,9 +51,38 @@ static void test_locale_is_valid(void) {
         assert_se(!locale_is_valid("\x01gar\x02 bage\x03"));
 }
 
+static void test_keymaps(void) {
+        _cleanup_strv_free_ char **kmaps = NULL;
+        char **p;
+        int r;
+
+        assert_se(!keymap_is_valid(""));
+        assert_se(!keymap_is_valid("/usr/bin/foo"));
+        assert_se(!keymap_is_valid("\x01gar\x02 bage\x03"));
+
+        r = get_keymaps(&kmaps);
+        if (r == -ENOENT)
+                return; /* skip test if no keymaps are installed */
+
+        assert_se(r >= 0);
+        assert_se(kmaps);
+
+        STRV_FOREACH(p, kmaps) {
+                puts(*p);
+                assert_se(keymap_is_valid(*p));
+        }
+
+        assert_se(keymap_is_valid("uk"));
+        assert_se(keymap_is_valid("de-nodeadkeys"));
+        assert_se(keymap_is_valid("ANSI-dvorak"));
+        assert_se(keymap_is_valid("unicode"));
+}
+
 int main(int argc, char *argv[]) {
         test_get_locales();
         test_locale_is_valid();
 
+        test_keymaps();
+
         return 0;
 }
index 8ab569f..9468349 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index c70633a..3fe897a 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 7c5929d..09a6248 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
 
 #include <sys/mount.h>
 
+#include "alloc-util.h"
+#include "def.h"
+#include "fd-util.h"
+#include "fileio.h"
+#include "hashmap.h"
+#include "log.h"
 #include "log.h"
 #include "mount-util.h"
+#include "path-util.h"
+#include "rm-rf.h"
 #include "string-util.h"
 
 static void test_mount_propagation_flags(const char *name, int ret, unsigned long expected) {
         long unsigned flags;
 
-        assert(mount_propagation_flags_from_string(name, &flags) == ret);
+        assert_se(mount_propagation_flags_from_string(name, &flags) == ret);
 
         if (ret >= 0) {
                 const char *c;
@@ -41,6 +50,217 @@ static void test_mount_propagation_flags(const char *name, int ret, unsigned lon
         }
 }
 
+static void test_mnt_id(void) {
+        _cleanup_fclose_ FILE *f = NULL;
+        Hashmap *h;
+        Iterator i;
+        char *p;
+        void *k;
+        int r;
+
+        assert_se(f = fopen("/proc/self/mountinfo", "re"));
+        assert_se(h = hashmap_new(&trivial_hash_ops));
+
+        for (;;) {
+                _cleanup_free_ char *line = NULL, *path = NULL;
+                int mnt_id;
+
+                r = read_line(f, LONG_LINE_MAX, &line);
+                if (r == 0)
+                        break;
+                assert_se(r > 0);
+
+                assert_se(sscanf(line, "%i %*s %*s %*s %ms", &mnt_id, &path) == 2);
+
+                assert_se(hashmap_put(h, INT_TO_PTR(mnt_id), path) >= 0);
+                path = NULL;
+        }
+
+        HASHMAP_FOREACH_KEY(p, k, h, i) {
+                int mnt_id = PTR_TO_INT(k), mnt_id2;
+
+                r = path_get_mnt_id(p, &mnt_id2);
+                if (r == -EOPNOTSUPP) { /* kernel or file system too old? */
+                        log_debug("%s doesn't support mount IDs\n", p);
+                        continue;
+                }
+                if (IN_SET(r, -EACCES, -EPERM)) {
+                        log_debug("Can't access %s\n", p);
+                        continue;
+                }
+
+                log_debug("mnt id of %s is %i\n", p, mnt_id2);
+
+                if (mnt_id == mnt_id2)
+                        continue;
+
+                /* The ids don't match? If so, then there are two mounts on the same path, let's check if that's really
+                 * the case */
+                assert_se(path_equal_ptr(hashmap_get(h, INT_TO_PTR(mnt_id2)), p));
+        }
+
+        hashmap_free_free(h);
+}
+
+static void test_path_is_mount_point(void) {
+        int fd;
+        char tmp_dir[] = "/tmp/test-path-is-mount-point-XXXXXX";
+        _cleanup_free_ char *file1 = NULL, *file2 = NULL, *link1 = NULL, *link2 = NULL;
+        _cleanup_free_ char *dir1 = NULL, *dir1file = NULL, *dirlink1 = NULL, *dirlink1file = NULL;
+        _cleanup_free_ char *dir2 = NULL, *dir2file = NULL;
+
+        assert_se(path_is_mount_point("/", NULL, AT_SYMLINK_FOLLOW) > 0);
+        assert_se(path_is_mount_point("/", NULL, 0) > 0);
+        assert_se(path_is_mount_point("//", NULL, AT_SYMLINK_FOLLOW) > 0);
+        assert_se(path_is_mount_point("//", NULL, 0) > 0);
+
+        assert_se(path_is_mount_point("/proc", NULL, AT_SYMLINK_FOLLOW) > 0);
+        assert_se(path_is_mount_point("/proc", NULL, 0) > 0);
+        assert_se(path_is_mount_point("/proc/", NULL, AT_SYMLINK_FOLLOW) > 0);
+        assert_se(path_is_mount_point("/proc/", NULL, 0) > 0);
+
+        assert_se(path_is_mount_point("/proc/1", NULL, AT_SYMLINK_FOLLOW) == 0);
+        assert_se(path_is_mount_point("/proc/1", NULL, 0) == 0);
+        assert_se(path_is_mount_point("/proc/1/", NULL, AT_SYMLINK_FOLLOW) == 0);
+        assert_se(path_is_mount_point("/proc/1/", NULL, 0) == 0);
+
+        assert_se(path_is_mount_point("/sys", NULL, AT_SYMLINK_FOLLOW) > 0);
+        assert_se(path_is_mount_point("/sys", NULL, 0) > 0);
+        assert_se(path_is_mount_point("/sys/", NULL, AT_SYMLINK_FOLLOW) > 0);
+        assert_se(path_is_mount_point("/sys/", NULL, 0) > 0);
+
+        /* we'll create a hierarchy of different kinds of dir/file/link
+         * layouts:
+         *
+         * <tmp>/file1, <tmp>/file2
+         * <tmp>/link1 -> file1, <tmp>/link2 -> file2
+         * <tmp>/dir1/
+         * <tmp>/dir1/file
+         * <tmp>/dirlink1 -> dir1
+         * <tmp>/dirlink1file -> dirlink1/file
+         * <tmp>/dir2/
+         * <tmp>/dir2/file
+         */
+
+        /* file mountpoints */
+        assert_se(mkdtemp(tmp_dir) != NULL);
+        file1 = path_join(NULL, tmp_dir, "file1");
+        assert_se(file1);
+        file2 = path_join(NULL, tmp_dir, "file2");
+        assert_se(file2);
+        fd = open(file1, O_WRONLY|O_CREAT|O_EXCL|O_CLOEXEC, 0664);
+        assert_se(fd > 0);
+        close(fd);
+        fd = open(file2, O_WRONLY|O_CREAT|O_EXCL|O_CLOEXEC, 0664);
+        assert_se(fd > 0);
+        close(fd);
+        link1 = path_join(NULL, tmp_dir, "link1");
+        assert_se(link1);
+        assert_se(symlink("file1", link1) == 0);
+        link2 = path_join(NULL, tmp_dir, "link2");
+        assert_se(link1);
+        assert_se(symlink("file2", link2) == 0);
+
+        assert_se(path_is_mount_point(file1, NULL, AT_SYMLINK_FOLLOW) == 0);
+        assert_se(path_is_mount_point(file1, NULL, 0) == 0);
+        assert_se(path_is_mount_point(link1, NULL, AT_SYMLINK_FOLLOW) == 0);
+        assert_se(path_is_mount_point(link1, NULL, 0) == 0);
+
+        /* directory mountpoints */
+        dir1 = path_join(NULL, tmp_dir, "dir1");
+        assert_se(dir1);
+        assert_se(mkdir(dir1, 0755) == 0);
+        dirlink1 = path_join(NULL, tmp_dir, "dirlink1");
+        assert_se(dirlink1);
+        assert_se(symlink("dir1", dirlink1) == 0);
+        dirlink1file = path_join(NULL, tmp_dir, "dirlink1file");
+        assert_se(dirlink1file);
+        assert_se(symlink("dirlink1/file", dirlink1file) == 0);
+        dir2 = path_join(NULL, tmp_dir, "dir2");
+        assert_se(dir2);
+        assert_se(mkdir(dir2, 0755) == 0);
+
+        assert_se(path_is_mount_point(dir1, NULL, AT_SYMLINK_FOLLOW) == 0);
+        assert_se(path_is_mount_point(dir1, NULL, 0) == 0);
+        assert_se(path_is_mount_point(dirlink1, NULL, AT_SYMLINK_FOLLOW) == 0);
+        assert_se(path_is_mount_point(dirlink1, NULL, 0) == 0);
+
+        /* file in subdirectory mountpoints */
+        dir1file = path_join(NULL, dir1, "file");
+        assert_se(dir1file);
+        fd = open(dir1file, O_WRONLY|O_CREAT|O_EXCL|O_CLOEXEC, 0664);
+        assert_se(fd > 0);
+        close(fd);
+
+        assert_se(path_is_mount_point(dir1file, NULL, AT_SYMLINK_FOLLOW) == 0);
+        assert_se(path_is_mount_point(dir1file, NULL, 0) == 0);
+        assert_se(path_is_mount_point(dirlink1file, NULL, AT_SYMLINK_FOLLOW) == 0);
+        assert_se(path_is_mount_point(dirlink1file, NULL, 0) == 0);
+
+        /* these tests will only work as root */
+        if (mount(file1, file2, NULL, MS_BIND, NULL) >= 0) {
+                int rf, rt, rdf, rdt, rlf, rlt, rl1f, rl1t;
+                const char *file2d;
+
+                /* files */
+                /* capture results in vars, to avoid dangling mounts on failure */
+                log_info("%s: %s", __func__, file2);
+                rf = path_is_mount_point(file2, NULL, 0);
+                rt = path_is_mount_point(file2, NULL, AT_SYMLINK_FOLLOW);
+
+                file2d = strjoina(file2, "/");
+                log_info("%s: %s", __func__, file2d);
+                rdf = path_is_mount_point(file2d, NULL, 0);
+                rdt = path_is_mount_point(file2d, NULL, AT_SYMLINK_FOLLOW);
+
+                log_info("%s: %s", __func__, link2);
+                rlf = path_is_mount_point(link2, NULL, 0);
+                rlt = path_is_mount_point(link2, NULL, AT_SYMLINK_FOLLOW);
+
+                assert_se(umount(file2) == 0);
+
+                assert_se(rf == 1);
+                assert_se(rt == 1);
+                assert_se(rdf == -ENOTDIR);
+                assert_se(rdt == -ENOTDIR);
+                assert_se(rlf == 0);
+                assert_se(rlt == 1);
+
+                /* dirs */
+                dir2file = path_join(NULL, dir2, "file");
+                assert_se(dir2file);
+                fd = open(dir2file, O_WRONLY|O_CREAT|O_EXCL|O_CLOEXEC, 0664);
+                assert_se(fd > 0);
+                close(fd);
+
+                assert_se(mount(dir2, dir1, NULL, MS_BIND, NULL) >= 0);
+
+                log_info("%s: %s", __func__, dir1);
+                rf = path_is_mount_point(dir1, NULL, 0);
+                rt = path_is_mount_point(dir1, NULL, AT_SYMLINK_FOLLOW);
+                log_info("%s: %s", __func__, dirlink1);
+                rlf = path_is_mount_point(dirlink1, NULL, 0);
+                rlt = path_is_mount_point(dirlink1, NULL, AT_SYMLINK_FOLLOW);
+                log_info("%s: %s", __func__, dirlink1file);
+                /* its parent is a mount point, but not /file itself */
+                rl1f = path_is_mount_point(dirlink1file, NULL, 0);
+                rl1t = path_is_mount_point(dirlink1file, NULL, AT_SYMLINK_FOLLOW);
+
+                assert_se(umount(dir1) == 0);
+
+                assert_se(rf == 1);
+                assert_se(rt == 1);
+                assert_se(rlf == 0);
+                assert_se(rlt == 1);
+                assert_se(rl1f == 0);
+                assert_se(rl1t == 0);
+
+        } else
+                printf("Skipping bind mount file test: %m\n");
+
+        assert_se(rm_rf(tmp_dir, REMOVE_ROOT|REMOVE_PHYSICAL) == 0);
+}
+
 int main(int argc, char *argv[]) {
 
         log_set_max_level(LOG_DEBUG);
@@ -53,5 +273,8 @@ int main(int argc, char *argv[]) {
         test_mount_propagation_flags("xxxx", -EINVAL, 0);
         test_mount_propagation_flags(" ", -EINVAL, 0);
 
+        test_mnt_id();
+        test_path_is_mount_point();
+
         return 0;
 }
index de7be1f..3b84b01 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index bc6dd09..3b10b69 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
 #include "sd-netlink.h"
 
 #include "macro.h"
+#include "module-util.h"
 #include "util.h"
 
 static int load_module(const char *mod_name) {
-        struct kmod_ctx *ctx;
-        struct kmod_list *list = NULL, *l;
+        _cleanup_(kmod_unrefp) struct kmod_ctx *ctx = NULL;
+        _cleanup_(kmod_module_unref_listp) struct kmod_list *list = NULL;
+        struct kmod_list *l;
         int r;
 
         ctx = kmod_new(NULL, NULL);
-        if (!ctx) {
-                kmod_unref(ctx);
-                return -ENOMEM;
-        }
+        if (!ctx)
+                return log_oom();
 
         r = kmod_module_new_from_lookup(ctx, mod_name, &list);
         if (r < 0)
-                return -1;
+                return r;
 
         kmod_list_foreach(l, list) {
-                struct kmod_module *mod = kmod_module_get_module(l);
+                _cleanup_(kmod_module_unrefp) struct kmod_module *mod = NULL;
 
-                r = kmod_module_probe_insert_module(mod, 0, NULL, NULL, NULL, NULL);
-                if (r >= 0)
-                        r = 0;
-                else
-                        r = -1;
+                mod = kmod_module_get_module(l);
 
-                kmod_module_unref(mod);
+                r = kmod_module_probe_insert_module(mod, 0, NULL, NULL, NULL, NULL);
+                if (r > 0)
+                        r = -EINVAL;
         }
 
-        kmod_module_unref_list(list);
-        kmod_unref(ctx);
-
         return r;
 }
 
index b142c3a..76e2b38 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -46,7 +47,7 @@ int main(int argc, char *argv[]) {
                 NULL
         };
 
-        static const NameSpaceInfo ns_info = {
+        static const NamespaceInfo ns_info = {
                 .private_dev = true,
                 .protect_control_groups = true,
                 .protect_kernel_tunables = true,
index 9f73bc9..acfb676 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 4e5cbd2..b67f9aa 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
 #include <locale.h>
 #include <math.h>
 
+#include "alloc-util.h"
+#include "errno-list.h"
 #include "log.h"
 #include "parse-util.h"
+#include "string-util.h"
 
 static void test_parse_boolean(void) {
         assert_se(parse_boolean("1") == 1);
@@ -79,6 +83,9 @@ static void test_parse_pid(void) {
 
         r = parse_pid("junk", &pid);
         assert_se(r == -EINVAL);
+
+        r = parse_pid("", &pid);
+        assert_se(r == -EINVAL);
 }
 
 static void test_parse_mode(void) {
@@ -98,6 +105,8 @@ static void test_parse_mode(void) {
 static void test_parse_size(void) {
         uint64_t bytes;
 
+        assert_se(parse_size("", 1024, &bytes) == -EINVAL);
+
         assert_se(parse_size("111", 1024, &bytes) == 0);
         assert_se(bytes == 111);
 
@@ -257,6 +266,10 @@ static void test_parse_range(void) {
         assert_se(lower == 9999);
         assert_se(upper == 9999);
 
+        assert_se(parse_range("-123", &lower, &upper) == -EINVAL);
+        assert_se(lower == 9999);
+        assert_se(upper == 9999);
+
         assert_se(parse_range("-111-123", &lower, &upper) == -EINVAL);
         assert_se(lower == 9999);
         assert_se(upper == 9999);
@@ -370,6 +383,15 @@ static void test_safe_atolli(void) {
 
         r = safe_atolli("junk", &l);
         assert_se(r == -EINVAL);
+
+        r = safe_atolli("123x", &l);
+        assert_se(r == -EINVAL);
+
+        r = safe_atolli("12.3", &l);
+        assert_se(r == -EINVAL);
+
+        r = safe_atolli("", &l);
+        assert_se(r == -EINVAL);
 }
 
 static void test_safe_atou16(void) {
@@ -398,6 +420,12 @@ static void test_safe_atou16(void) {
 
         r = safe_atou16("123x", &l);
         assert_se(r == -EINVAL);
+
+        r = safe_atou16("12.3", &l);
+        assert_se(r == -EINVAL);
+
+        r = safe_atou16("", &l);
+        assert_se(r == -EINVAL);
 }
 
 static void test_safe_atoi16(void) {
@@ -431,6 +459,12 @@ static void test_safe_atoi16(void) {
 
         r = safe_atoi16("123x", &l);
         assert_se(r == -EINVAL);
+
+        r = safe_atoi16("12.3", &l);
+        assert_se(r == -EINVAL);
+
+        r = safe_atoi16("", &l);
+        assert_se(r == -EINVAL);
 }
 
 static void test_safe_atoux16(void) {
@@ -497,6 +531,12 @@ static void test_safe_atou64(void) {
 
         r = safe_atou64("123x", &l);
         assert_se(r == -EINVAL);
+
+        r = safe_atou64("12.3", &l);
+        assert_se(r == -EINVAL);
+
+        r = safe_atou64("", &l);
+        assert_se(r == -EINVAL);
 }
 
 static void test_safe_atoi64(void) {
@@ -530,6 +570,12 @@ static void test_safe_atoi64(void) {
 
         r = safe_atoi64("123x", &l);
         assert_se(r == -EINVAL);
+
+        r = safe_atoi64("12.3", &l);
+        assert_se(r == -EINVAL);
+
+        r = safe_atoi64("", &l);
+        assert_se(r == -EINVAL);
 }
 
 static void test_safe_atod(void) {
@@ -551,6 +597,9 @@ static void test_safe_atod(void) {
         strtod("0,5", &e);
         assert_se(*e == ',');
 
+        r = safe_atod("", &d);
+        assert_se(r == -EINVAL);
+
         /* Check if this really is locale independent */
         if (setlocale(LC_NUMERIC, "de_DE.utf8")) {
 
@@ -563,6 +612,9 @@ static void test_safe_atod(void) {
 
                 errno = 0;
                 assert_se(fabs(strtod("0,5", &e) - 0.5) < 0.00001);
+
+                r = safe_atod("", &d);
+                assert_se(r == -EINVAL);
         }
 
         /* And check again, reset */
@@ -578,6 +630,9 @@ static void test_safe_atod(void) {
         errno = 0;
         strtod("0,5", &e);
         assert_se(*e == ',');
+
+        r = safe_atod("", &d);
+        assert_se(r == -EINVAL);
 }
 
 static void test_parse_percent(void) {
@@ -596,6 +651,7 @@ static void test_parse_percent(void) {
         assert_se(parse_percent("%%") == -EINVAL);
         assert_se(parse_percent("%1") == -EINVAL);
         assert_se(parse_percent("1%%") == -EINVAL);
+        assert_se(parse_percent("3.2%") == -EINVAL);
 }
 
 static void test_parse_percent_unbounded(void) {
@@ -634,6 +690,8 @@ static void test_parse_nice(void) {
 static void test_parse_dev(void) {
         dev_t dev;
 
+        assert_se(parse_dev("", &dev) == -EINVAL);
+        assert_se(parse_dev("junk", &dev) == -EINVAL);
         assert_se(parse_dev("0", &dev) == -EINVAL);
         assert_se(parse_dev("5", &dev) == -EINVAL);
         assert_se(parse_dev("5:", &dev) == -EINVAL);
@@ -644,6 +702,74 @@ static void test_parse_dev(void) {
         assert_se(parse_dev("8:11", &dev) >= 0 && major(dev) == 8 && minor(dev) == 11);
 }
 
+static void test_parse_errno(void) {
+        assert_se(parse_errno("EILSEQ") == EILSEQ);
+        assert_se(parse_errno("EINVAL") == EINVAL);
+        assert_se(parse_errno("0") == 0);
+        assert_se(parse_errno("1") == 1);
+        assert_se(parse_errno("4095") == 4095);
+
+        assert_se(parse_errno("-1") == -ERANGE);
+        assert_se(parse_errno("-3") == -ERANGE);
+        assert_se(parse_errno("4096") == -ERANGE);
+
+        assert_se(parse_errno("") == -EINVAL);
+        assert_se(parse_errno("12.3") == -EINVAL);
+        assert_se(parse_errno("123junk") == -EINVAL);
+        assert_se(parse_errno("junk123") == -EINVAL);
+        assert_se(parse_errno("255EILSEQ") == -EINVAL);
+        assert_se(parse_errno("EINVAL12") == -EINVAL);
+        assert_se(parse_errno("-EINVAL") == -EINVAL);
+        assert_se(parse_errno("EINVALaaa") == -EINVAL);
+}
+
+static void test_parse_syscall_and_errno(void) {
+        _cleanup_free_ char *n = NULL;
+        int e;
+
+        assert_se(parse_syscall_and_errno("uname:EILSEQ", &n, &e) >= 0);
+        assert_se(streq(n, "uname"));
+        assert_se(e == errno_from_name("EILSEQ") && e >= 0);
+        n = mfree(n);
+
+        assert_se(parse_syscall_and_errno("uname:EINVAL", &n, &e) >= 0);
+        assert_se(streq(n, "uname"));
+        assert_se(e == errno_from_name("EINVAL") && e >= 0);
+        n = mfree(n);
+
+        assert_se(parse_syscall_and_errno("@sync:4095", &n, &e) >= 0);
+        assert_se(streq(n, "@sync"));
+        assert_se(e == 4095);
+        n = mfree(n);
+
+        /* If errno is omitted, then e is set to -1 */
+        assert_se(parse_syscall_and_errno("mount", &n, &e) >= 0);
+        assert_se(streq(n, "mount"));
+        assert_se(e == -1);
+        n = mfree(n);
+
+        /* parse_syscall_and_errno() does not check the syscall name is valid or not. */
+        assert_se(parse_syscall_and_errno("hoge:255", &n, &e) >= 0);
+        assert_se(streq(n, "hoge"));
+        assert_se(e == 255);
+        n = mfree(n);
+
+        /* The function checks the syscall name is empty or not. */
+        assert_se(parse_syscall_and_errno("", &n, &e) == -EINVAL);
+        assert_se(parse_syscall_and_errno(":255", &n, &e) == -EINVAL);
+
+        /* errno must be a valid errno name or number between 0 and ERRNO_MAX == 4095 */
+        assert_se(parse_syscall_and_errno("hoge:4096", &n, &e) == -ERANGE);
+        assert_se(parse_syscall_and_errno("hoge:-3", &n, &e) == -ERANGE);
+        assert_se(parse_syscall_and_errno("hoge:12.3", &n, &e) == -EINVAL);
+        assert_se(parse_syscall_and_errno("hoge:123junk", &n, &e) == -EINVAL);
+        assert_se(parse_syscall_and_errno("hoge:junk123", &n, &e) == -EINVAL);
+        assert_se(parse_syscall_and_errno("hoge:255:EILSEQ", &n, &e) == -EINVAL);
+        assert_se(parse_syscall_and_errno("hoge:-EINVAL", &n, &e) == -EINVAL);
+        assert_se(parse_syscall_and_errno("hoge:EINVALaaa", &n, &e) == -EINVAL);
+        assert_se(parse_syscall_and_errno("hoge:", &n, &e) == -EINVAL);
+}
+
 int main(int argc, char *argv[]) {
         log_parse_environment();
         log_open();
@@ -664,6 +790,8 @@ int main(int argc, char *argv[]) {
         test_parse_percent_unbounded();
         test_parse_nice();
         test_parse_dev();
+        test_parse_errno();
+        test_parse_syscall_and_errno();
 
         return 0;
 }
index 096326d..834b061 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -46,7 +47,7 @@ static void test_paths(UnitFileScope scope) {
         assert_se(strv_length(lp_with_env.search_path) == 1);
         assert_se(streq(lp_with_env.search_path[0], systemd_unit_path));
         assert_se(lookup_paths_reduce(&lp_with_env) >= 0);
-        assert_se(strv_length(lp_with_env.search_path) == 0);
+        assert_se(strv_isempty(lp_with_env.search_path));
 
         assert_se(rm_rf(template, REMOVE_ROOT|REMOVE_PHYSICAL) >= 0);
 }
index ff46a89..0db8356 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -18,7 +19,6 @@
 ***/
 
 #include <stdio.h>
-#include <sys/mount.h>
 #include <unistd.h>
 
 #include "alloc-util.h"
@@ -375,143 +375,6 @@ static void test_prefix_root(void) {
         test_prefix_root_one("/foo///", "//bar", "/foo/bar");
 }
 
-static void test_path_is_mount_point(void) {
-        int fd;
-        char tmp_dir[] = "/tmp/test-path-is-mount-point-XXXXXX";
-        _cleanup_free_ char *file1 = NULL, *file2 = NULL, *link1 = NULL, *link2 = NULL;
-        _cleanup_free_ char *dir1 = NULL, *dir1file = NULL, *dirlink1 = NULL, *dirlink1file = NULL;
-        _cleanup_free_ char *dir2 = NULL, *dir2file = NULL;
-
-        assert_se(path_is_mount_point("/", NULL, AT_SYMLINK_FOLLOW) > 0);
-        assert_se(path_is_mount_point("/", NULL, 0) > 0);
-
-        assert_se(path_is_mount_point("/proc", NULL, AT_SYMLINK_FOLLOW) > 0);
-        assert_se(path_is_mount_point("/proc", NULL, 0) > 0);
-
-        assert_se(path_is_mount_point("/proc/1", NULL, AT_SYMLINK_FOLLOW) == 0);
-        assert_se(path_is_mount_point("/proc/1", NULL, 0) == 0);
-
-        assert_se(path_is_mount_point("/sys", NULL, AT_SYMLINK_FOLLOW) > 0);
-        assert_se(path_is_mount_point("/sys", NULL, 0) > 0);
-
-        /* we'll create a hierarchy of different kinds of dir/file/link
-         * layouts:
-         *
-         * <tmp>/file1, <tmp>/file2
-         * <tmp>/link1 -> file1, <tmp>/link2 -> file2
-         * <tmp>/dir1/
-         * <tmp>/dir1/file
-         * <tmp>/dirlink1 -> dir1
-         * <tmp>/dirlink1file -> dirlink1/file
-         * <tmp>/dir2/
-         * <tmp>/dir2/file
-         */
-
-        /* file mountpoints */
-        assert_se(mkdtemp(tmp_dir) != NULL);
-        file1 = path_join(NULL, tmp_dir, "file1");
-        assert_se(file1);
-        file2 = path_join(NULL, tmp_dir, "file2");
-        assert_se(file2);
-        fd = open(file1, O_WRONLY|O_CREAT|O_EXCL|O_CLOEXEC, 0664);
-        assert_se(fd > 0);
-        close(fd);
-        fd = open(file2, O_WRONLY|O_CREAT|O_EXCL|O_CLOEXEC, 0664);
-        assert_se(fd > 0);
-        close(fd);
-        link1 = path_join(NULL, tmp_dir, "link1");
-        assert_se(link1);
-        assert_se(symlink("file1", link1) == 0);
-        link2 = path_join(NULL, tmp_dir, "link2");
-        assert_se(link1);
-        assert_se(symlink("file2", link2) == 0);
-
-        assert_se(path_is_mount_point(file1, NULL, AT_SYMLINK_FOLLOW) == 0);
-        assert_se(path_is_mount_point(file1, NULL, 0) == 0);
-        assert_se(path_is_mount_point(link1, NULL, AT_SYMLINK_FOLLOW) == 0);
-        assert_se(path_is_mount_point(link1, NULL, 0) == 0);
-
-        /* directory mountpoints */
-        dir1 = path_join(NULL, tmp_dir, "dir1");
-        assert_se(dir1);
-        assert_se(mkdir(dir1, 0755) == 0);
-        dirlink1 = path_join(NULL, tmp_dir, "dirlink1");
-        assert_se(dirlink1);
-        assert_se(symlink("dir1", dirlink1) == 0);
-        dirlink1file = path_join(NULL, tmp_dir, "dirlink1file");
-        assert_se(dirlink1file);
-        assert_se(symlink("dirlink1/file", dirlink1file) == 0);
-        dir2 = path_join(NULL, tmp_dir, "dir2");
-        assert_se(dir2);
-        assert_se(mkdir(dir2, 0755) == 0);
-
-        assert_se(path_is_mount_point(dir1, NULL, AT_SYMLINK_FOLLOW) == 0);
-        assert_se(path_is_mount_point(dir1, NULL, 0) == 0);
-        assert_se(path_is_mount_point(dirlink1, NULL, AT_SYMLINK_FOLLOW) == 0);
-        assert_se(path_is_mount_point(dirlink1, NULL, 0) == 0);
-
-        /* file in subdirectory mountpoints */
-        dir1file = path_join(NULL, dir1, "file");
-        assert_se(dir1file);
-        fd = open(dir1file, O_WRONLY|O_CREAT|O_EXCL|O_CLOEXEC, 0664);
-        assert_se(fd > 0);
-        close(fd);
-
-        assert_se(path_is_mount_point(dir1file, NULL, AT_SYMLINK_FOLLOW) == 0);
-        assert_se(path_is_mount_point(dir1file, NULL, 0) == 0);
-        assert_se(path_is_mount_point(dirlink1file, NULL, AT_SYMLINK_FOLLOW) == 0);
-        assert_se(path_is_mount_point(dirlink1file, NULL, 0) == 0);
-
-        /* these tests will only work as root */
-        if (mount(file1, file2, NULL, MS_BIND, NULL) >= 0) {
-                int rt, rf, rlt, rlf, rl1t, rl1f;
-
-                /* files */
-                /* capture results in vars, to avoid dangling mounts on failure */
-                rf = path_is_mount_point(file2, NULL, 0);
-                rt = path_is_mount_point(file2, NULL, AT_SYMLINK_FOLLOW);
-                rlf = path_is_mount_point(link2, NULL, 0);
-                rlt = path_is_mount_point(link2, NULL, AT_SYMLINK_FOLLOW);
-
-                assert_se(umount(file2) == 0);
-
-                assert_se(rf == 1);
-                assert_se(rt == 1);
-                assert_se(rlf == 0);
-                assert_se(rlt == 1);
-
-                /* dirs */
-                dir2file = path_join(NULL, dir2, "file");
-                assert_se(dir2file);
-                fd = open(dir2file, O_WRONLY|O_CREAT|O_EXCL|O_CLOEXEC, 0664);
-                assert_se(fd > 0);
-                close(fd);
-
-                assert_se(mount(dir2, dir1, NULL, MS_BIND, NULL) >= 0);
-
-                rf = path_is_mount_point(dir1, NULL, 0);
-                rt = path_is_mount_point(dir1, NULL, AT_SYMLINK_FOLLOW);
-                rlf = path_is_mount_point(dirlink1, NULL, 0);
-                rlt = path_is_mount_point(dirlink1, NULL, AT_SYMLINK_FOLLOW);
-                /* its parent is a mount point, but not /file itself */
-                rl1f = path_is_mount_point(dirlink1file, NULL, 0);
-                rl1t = path_is_mount_point(dirlink1file, NULL, AT_SYMLINK_FOLLOW);
-
-                assert_se(umount(dir1) == 0);
-
-                assert_se(rf == 1);
-                assert_se(rt == 1);
-                assert_se(rlf == 0);
-                assert_se(rlt == 1);
-                assert_se(rl1f == 0);
-                assert_se(rl1t == 0);
-
-        } else
-                printf("Skipping bind mount file test: %m\n");
-
-        assert_se(rm_rf(tmp_dir, REMOVE_ROOT|REMOVE_PHYSICAL) == 0);
-}
-
 static void test_file_in_same_dir(void) {
         char *t;
 
@@ -536,6 +399,21 @@ static void test_file_in_same_dir(void) {
         free(t);
 }
 
+static void test_last_path_component(void) {
+        assert_se(streq(last_path_component("a/b/c"), "c"));
+        assert_se(streq(last_path_component("a/b/c/"), "c/"));
+        assert_se(streq(last_path_component("/"), "/"));
+        assert_se(streq(last_path_component("//"), "/"));
+        assert_se(streq(last_path_component("///"), "/"));
+        assert_se(streq(last_path_component("."), "."));
+        assert_se(streq(last_path_component("./."), "."));
+        assert_se(streq(last_path_component("././"), "./"));
+        assert_se(streq(last_path_component("././/"), ".//"));
+        assert_se(streq(last_path_component("/foo/a"), "a"));
+        assert_se(streq(last_path_component("/foo/a/"), "a/"));
+        assert_se(streq(last_path_component(""), ""));
+}
+
 static void test_filename_is_valid(void) {
         char foo[FILENAME_MAX+2];
         int i;
@@ -620,8 +498,8 @@ int main(int argc, char **argv) {
         test_strv_resolve();
         test_path_startswith();
         test_prefix_root();
-        test_path_is_mount_point();
         test_file_in_same_dir();
+        test_last_path_component();
         test_filename_is_valid();
         test_hidden_or_backup_file();
         test_skip_dev_prefix();
index c191501..3f579b0 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -45,7 +46,11 @@ static int setup_test(Manager **m) {
 
         assert_se(m);
 
-        enter_cgroup_subroot();
+        r = enter_cgroup_subroot();
+        if (r == -ENOMEDIUM) {
+                log_notice_errno(r, "Skipping test: cgroupfs not available");
+                return -EXIT_TEST_SKIP;
+        }
 
         r = manager_new(UNIT_FILE_USER, MANAGER_TEST_RUN_MINIMAL, &tmp);
         if (MANAGER_SKIP_TEST(r)) {
index d81880a..f558384 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 12dac85..01b8cf0 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 0f0e2cb..a38f917 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -48,7 +49,7 @@ static void test_get_process_comm(pid_t pid) {
         struct stat st;
         _cleanup_free_ char *a = NULL, *c = NULL, *d = NULL, *f = NULL, *i = NULL;
         _cleanup_free_ char *env = NULL;
-        char path[strlen("/proc//comm") + DECIMAL_STR_MAX(pid_t)];
+        char path[STRLEN("/proc//comm") + DECIMAL_STR_MAX(pid_t)];
         pid_t e;
         uid_t u;
         gid_t g;
@@ -381,7 +382,7 @@ static void test_rename_process_now(const char *p, int ret) {
         /* we cannot expect cmdline to be renamed properly without privileges */
         if (geteuid() == 0) {
                 log_info("cmdline = <%s>", cmdline);
-                assert_se(strneq(p, cmdline, strlen("test-process-util")));
+                assert_se(strneq(p, cmdline, STRLEN("test-process-util")));
                 assert_se(startswith(p, cmdline));
         } else
                 log_info("cmdline = <%s> (not verified)", cmdline);
@@ -424,7 +425,7 @@ static void test_rename_process_multi(void) {
         /* child */
         test_rename_process_now("one", 1);
         test_rename_process_now("more", 0); /* longer than "one", hence truncated */
-        setresuid(99, 99, 99);
+        (void) setresuid(99, 99, 99); /* change uid when running privileged */
         test_rename_process_now("time!", 0);
         test_rename_process_now("0", 1); /* shorter than "one", should fit */
         test_rename_process_one("", -EINVAL);
index 50f4da2..d7ccc91 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 990b834..dcfa60e 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd
 
index 60e05d0..56ce99e 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 62afd2d..9372443 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd
 
index 9bed4b3..804cee3 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -34,7 +35,11 @@ int main(int argc, char *argv[]) {
         FDSet *fdset = NULL;
         int r;
 
-        enter_cgroup_subroot();
+        r = enter_cgroup_subroot();
+        if (r == -ENOMEDIUM) {
+                log_notice_errno(r, "Skipping test: cgroupfs not available");
+                return EXIT_TEST_SKIP;
+        }
 
         /* prepare the test */
         assert_se(set_unit_path(get_testdata_dir("")) >= 0);
index 4d63b68..36b49eb 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
+#include <poll.h>
 #include <sched.h>
 #include <stdlib.h>
 #include <sys/eventfd.h>
 #include <sys/mman.h>
 #include <sys/personality.h>
-#include <sys/poll.h>
 #include <sys/shm.h>
 #include <sys/types.h>
 #include <unistd.h>
@@ -519,7 +520,7 @@ static void test_load_syscall_filter_set_raw(void) {
         assert_se(pid >= 0);
 
         if (pid == 0) {
-                _cleanup_set_free_ Set *s = NULL;
+                _cleanup_hashmap_free_ Hashmap *s = NULL;
 
                 assert_se(access("/", F_OK) >= 0);
                 assert_se(poll(NULL, 0, 0) == 0);
@@ -528,11 +529,11 @@ static void test_load_syscall_filter_set_raw(void) {
                 assert_se(access("/", F_OK) >= 0);
                 assert_se(poll(NULL, 0, 0) == 0);
 
-                assert_se(s = set_new(NULL));
+                assert_se(s = hashmap_new(NULL));
 #if SCMP_SYS(access) >= 0
-                assert_se(set_put(s, UINT32_TO_PTR(__NR_access + 1)) >= 0);
+                assert_se(hashmap_put(s, UINT32_TO_PTR(__NR_access + 1), INT_TO_PTR(-1)) >= 0);
 #else
-                assert_se(set_put(s, UINT32_TO_PTR(__NR_faccessat + 1)) >= 0);
+                assert_se(hashmap_put(s, UINT32_TO_PTR(__NR_faccessat + 1), INT_TO_PTR(-1)) >= 0);
 #endif
 
                 assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, s, SCMP_ACT_ERRNO(EUCLEAN)) >= 0);
@@ -542,23 +543,56 @@ static void test_load_syscall_filter_set_raw(void) {
 
                 assert_se(poll(NULL, 0, 0) == 0);
 
-                s = set_free(s);
+                s = hashmap_free(s);
 
-                assert_se(s = set_new(NULL));
+                assert_se(s = hashmap_new(NULL));
+#if SCMP_SYS(access) >= 0
+                assert_se(hashmap_put(s, UINT32_TO_PTR(__NR_access + 1), INT_TO_PTR(EILSEQ)) >= 0);
+#else
+                assert_se(hashmap_put(s, UINT32_TO_PTR(__NR_faccessat + 1), INT_TO_PTR(EILSEQ)) >= 0);
+#endif
+
+                assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, s, SCMP_ACT_ERRNO(EUCLEAN)) >= 0);
+
+                assert_se(access("/", F_OK) < 0);
+                assert_se(errno == EILSEQ);
+
+                assert_se(poll(NULL, 0, 0) == 0);
+
+                s = hashmap_free(s);
+
+                assert_se(s = hashmap_new(NULL));
 #if SCMP_SYS(poll) >= 0
-                assert_se(set_put(s, UINT32_TO_PTR(__NR_poll + 1)) >= 0);
+                assert_se(hashmap_put(s, UINT32_TO_PTR(__NR_poll + 1), INT_TO_PTR(-1)) >= 0);
 #else
-                assert_se(set_put(s, UINT32_TO_PTR(__NR_ppoll + 1)) >= 0);
+                assert_se(hashmap_put(s, UINT32_TO_PTR(__NR_ppoll + 1), INT_TO_PTR(-1)) >= 0);
 #endif
 
                 assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, s, SCMP_ACT_ERRNO(EUNATCH)) >= 0);
 
                 assert_se(access("/", F_OK) < 0);
-                assert_se(errno == EUCLEAN);
+                assert_se(errno == EILSEQ);
 
                 assert_se(poll(NULL, 0, 0) < 0);
                 assert_se(errno == EUNATCH);
 
+                s = hashmap_free(s);
+
+                assert_se(s = hashmap_new(NULL));
+#if SCMP_SYS(poll) >= 0
+                assert_se(hashmap_put(s, UINT32_TO_PTR(__NR_poll + 1), INT_TO_PTR(EILSEQ)) >= 0);
+#else
+                assert_se(hashmap_put(s, UINT32_TO_PTR(__NR_ppoll + 1), INT_TO_PTR(EILSEQ)) >= 0);
+#endif
+
+                assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, s, SCMP_ACT_ERRNO(EUNATCH)) >= 0);
+
+                assert_se(access("/", F_OK) < 0);
+                assert_se(errno == EILSEQ);
+
+                assert_se(poll(NULL, 0, 0) < 0);
+                assert_se(errno == EILSEQ);
+
                 _exit(EXIT_SUCCESS);
         }
 
index 190736a..f954dbb 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 3fab350..0a29a62 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd
 
@@ -39,6 +40,29 @@ static void test_set_steal_first(void) {
         assert_se(set_isempty(m));
 }
 
+typedef struct Item {
+        int seen;
+} Item;
+static void item_seen(Item *item) {
+        item->seen++;
+}
+
+static void test_set_free_with_destructor(void) {
+        Set *m;
+        struct Item items[4] = {};
+        unsigned i;
+
+        assert_se(m = set_new(NULL));
+        for (i = 0; i < ELEMENTSOF(items) - 1; i++)
+                assert_se(set_put(m, items + i) == 1);
+
+        m = set_free_with_destructor(m, item_seen);
+        assert_se(items[0].seen == 1);
+        assert_se(items[1].seen == 1);
+        assert_se(items[2].seen == 1);
+        assert_se(items[3].seen == 0);
+}
+
 static void test_set_put(void) {
         _cleanup_set_free_ Set *m = NULL;
 
@@ -101,6 +125,7 @@ static void test_set_make(void) {
 
 int main(int argc, const char *argv[]) {
         test_set_steal_first();
+        test_set_free_with_destructor();
         test_set_put();
         test_set_make();
 
index bcc08b2..75df851 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 92e3927..13a1d2b 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index b74b7ad..7469457 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index bfc421e..f472edc 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 97b6f30..3c2b115 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 8ac1d79..6a91baf 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd
 
diff --git a/src/test/test-specifier.c b/src/test/test-specifier.c
new file mode 100644 (file)
index 0000000..6bf3120
--- /dev/null
@@ -0,0 +1,66 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+/***
+  This file is part of systemd.
+
+  Copyright 2017 Lennart Poettering
+
+  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.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "alloc-util.h"
+#include "log.h"
+#include "specifier.h"
+#include "string-util.h"
+#include "strv.h"
+
+static void test_specifier_escape_one(const char *a, const char *b) {
+        _cleanup_free_ char *x = NULL;
+
+        x = specifier_escape(a);
+        assert_se(streq_ptr(x, b));
+}
+
+static void test_specifier_escape(void) {
+        test_specifier_escape_one(NULL, NULL);
+        test_specifier_escape_one("", "");
+        test_specifier_escape_one("%", "%%");
+        test_specifier_escape_one("foo bar", "foo bar");
+        test_specifier_escape_one("foo%bar", "foo%%bar");
+        test_specifier_escape_one("%%%%%", "%%%%%%%%%%");
+}
+
+static void test_specifier_escape_strv_one(char **a, char **b) {
+        _cleanup_strv_free_ char **x = NULL;
+
+        assert_se(specifier_escape_strv(a, &x) >= 0);
+        assert_se(strv_equal(x, b));
+}
+
+static void test_specifier_escape_strv(void) {
+        test_specifier_escape_strv_one(NULL, NULL);
+        test_specifier_escape_strv_one(STRV_MAKE(NULL), STRV_MAKE(NULL));
+        test_specifier_escape_strv_one(STRV_MAKE(""), STRV_MAKE(""));
+        test_specifier_escape_strv_one(STRV_MAKE("foo"), STRV_MAKE("foo"));
+        test_specifier_escape_strv_one(STRV_MAKE("%"), STRV_MAKE("%%"));
+        test_specifier_escape_strv_one(STRV_MAKE("foo", "%", "foo%", "%foo", "foo%foo", "quux", "%%%"), STRV_MAKE("foo", "%%", "foo%%", "%%foo", "foo%%foo", "quux", "%%%%%%"));
+}
+
+int main(int argc, char *argv[]) {
+        log_set_max_level(LOG_DEBUG);
+
+        test_specifier_escape();
+        test_specifier_escape_strv();
+
+        return 0;
+}
index 9d56a71..fb0d943 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -77,16 +78,16 @@ static void test_path_is_os_tree(void) {
         assert_se(path_is_os_tree("/idontexist") == -ENOENT);
 }
 
-static void test_path_check_fstype(void) {
+static void test_path_is_fs_type(void) {
         /* run might not be a mount point in build chroots */
         if (path_is_mount_point("/run", NULL, AT_SYMLINK_FOLLOW) > 0) {
-                assert_se(path_check_fstype("/run", TMPFS_MAGIC) > 0);
-                assert_se(path_check_fstype("/run", BTRFS_SUPER_MAGIC) == 0);
+                assert_se(path_is_fs_type("/run", TMPFS_MAGIC) > 0);
+                assert_se(path_is_fs_type("/run", BTRFS_SUPER_MAGIC) == 0);
         }
-        assert_se(path_check_fstype("/proc", PROC_SUPER_MAGIC) > 0);
-        assert_se(path_check_fstype("/proc", BTRFS_SUPER_MAGIC) == 0);
-        assert_se(path_check_fstype("/proc", BTRFS_SUPER_MAGIC) == 0);
-        assert_se(path_check_fstype("/i-dont-exist", BTRFS_SUPER_MAGIC) == -ENOENT);
+        assert_se(path_is_fs_type("/proc", PROC_SUPER_MAGIC) > 0);
+        assert_se(path_is_fs_type("/proc", BTRFS_SUPER_MAGIC) == 0);
+        assert_se(path_is_fs_type("/proc", BTRFS_SUPER_MAGIC) == 0);
+        assert_se(path_is_fs_type("/i-dont-exist", BTRFS_SUPER_MAGIC) == -ENOENT);
 }
 
 static void test_path_is_temporary_fs(void) {
@@ -101,7 +102,7 @@ int main(int argc, char *argv[]) {
         test_files_same();
         test_is_symlink();
         test_path_is_os_tree();
-        test_path_check_fstype();
+        test_path_is_fs_type();
         test_path_is_temporary_fs();
 
         return 0;
index 513218c..891d7b1 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 604701f..07ee984 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -103,9 +104,37 @@ static void test_strstrip(void) {
 }
 
 static void test_strextend(void) {
-        _cleanup_free_ char *str = strdup("0123");
-        strextend(&str, "456", "78", "9", NULL);
-        assert_se(streq(str, "0123456789"));
+        _cleanup_free_ char *str = NULL;
+
+        assert_se(strextend(&str, NULL));
+        assert_se(streq_ptr(str, ""));
+        assert_se(strextend(&str, "", "0", "", "", "123", NULL));
+        assert_se(streq_ptr(str, "0123"));
+        assert_se(strextend(&str, "456", "78", "9", NULL));
+        assert_se(streq_ptr(str, "0123456789"));
+}
+
+static void test_strextend_with_separator(void) {
+        _cleanup_free_ char *str = NULL;
+
+        assert_se(strextend_with_separator(&str, NULL, NULL));
+        assert_se(streq_ptr(str, ""));
+        str = mfree(str);
+
+        assert_se(strextend_with_separator(&str, "...", NULL));
+        assert_se(streq_ptr(str, ""));
+        assert_se(strextend_with_separator(&str, "...", NULL));
+        assert_se(streq_ptr(str, ""));
+        str = mfree(str);
+
+        assert_se(strextend_with_separator(&str, "xyz", "a", "bb", "ccc", NULL));
+        assert_se(streq_ptr(str, "axyzbbxyzccc"));
+        str = mfree(str);
+
+        assert_se(strextend_with_separator(&str, ",", "start", "", "1", "234", NULL));
+        assert_se(streq_ptr(str, "start,,1,234"));
+        assert_se(strextend_with_separator(&str, ";", "more", "5", "678", NULL));
+        assert_se(streq_ptr(str, "start,,1,234;more;5;678"));
 }
 
 static void test_strrep(void) {
@@ -288,11 +317,60 @@ static void test_endswith_no_case(void) {
 }
 
 static void test_delete_chars(void) {
-        char *r;
-        char input[] = "   hello, waldo.   abc";
+        char *s, input[] = "   hello, waldo.   abc";
+
+        s = delete_chars(input, WHITESPACE);
+        assert_se(streq(s, "hello,waldo.abc"));
+        assert_se(s == input);
+}
+
+static void test_delete_trailing_chars(void) {
+
+        char *s,
+                input1[] = " \n \r k \n \r ",
+                input2[] = "kkkkthiskkkiskkkaktestkkk",
+                input3[] = "abcdef";
+
+        s = delete_trailing_chars(input1, WHITESPACE);
+        assert_se(streq(s, " \n \r k"));
+        assert_se(s == input1);
+
+        s = delete_trailing_chars(input2, "kt");
+        assert_se(streq(s, "kkkkthiskkkiskkkaktes"));
+        assert_se(s == input2);
+
+        s = delete_trailing_chars(input3, WHITESPACE);
+        assert_se(streq(s, "abcdef"));
+        assert_se(s == input3);
+
+        s = delete_trailing_chars(input3, "fe");
+        assert_se(streq(s, "abcd"));
+        assert_se(s == input3);
+}
+
+static void test_delete_trailing_slashes(void) {
+        char s1[] = "foobar//",
+             s2[] = "foobar/",
+             s3[] = "foobar",
+             s4[] = "";
+
+        assert_se(streq(delete_trailing_chars(s1, "_"), "foobar//"));
+        assert_se(streq(delete_trailing_chars(s1, "/"), "foobar"));
+        assert_se(streq(delete_trailing_chars(s2, "/"), "foobar"));
+        assert_se(streq(delete_trailing_chars(s3, "/"), "foobar"));
+        assert_se(streq(delete_trailing_chars(s4, "/"), ""));
+}
+
+static void test_skip_leading_chars(void) {
+        char input1[] = " \n \r k \n \r ",
+                input2[] = "kkkkthiskkkiskkkaktestkkk",
+                input3[] = "abcdef";
 
-        r = delete_chars(input, WHITESPACE);
-        assert_se(streq(r, "hello,waldo.abc"));
+        assert_se(streq(skip_leading_chars(input1, WHITESPACE), "k \n \r "));
+        assert_se(streq(skip_leading_chars(input2, "k"), "thiskkkiskkkaktestkkk"));
+        assert_se(streq(skip_leading_chars(input2, "tk"), "hiskkkiskkkaktestkkk"));
+        assert_se(streq(skip_leading_chars(input3, WHITESPACE), "abcdef"));
+        assert_se(streq(skip_leading_chars(input3, "bcaef"), "def"));
 }
 
 static void test_in_charset(void) {
@@ -349,6 +427,7 @@ int main(int argc, char *argv[]) {
         test_streq_ptr();
         test_strstrip();
         test_strextend();
+        test_strextend_with_separator();
         test_strrep();
         test_strappend();
         test_string_has_cc();
@@ -361,6 +440,9 @@ int main(int argc, char *argv[]) {
         test_endswith();
         test_endswith_no_case();
         test_delete_chars();
+        test_delete_trailing_chars();
+        test_delete_trailing_slashes();
+        test_skip_leading_chars();
         test_in_charset();
         test_split_pair();
         test_first_word();
index 72b0f6f..aabb7c4 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 88da69e..aec00eb 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index d95945f..7e2d3c2 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
diff --git a/src/test/test-systemd-tmpfiles.py b/src/test/test-systemd-tmpfiles.py
new file mode 100755 (executable)
index 0000000..7e56355
--- /dev/null
@@ -0,0 +1,140 @@
+#!/usr/bin/env python3
+#  SPDX-License-Identifier: LGPL-2.1+
+#
+#  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.
+
+import os
+import sys
+import socket
+import subprocess
+import tempfile
+import pwd
+
+try:
+    from systemd import id128
+except ImportError:
+    id128 = None
+
+EX_DATAERR = 65 # from sysexits.h
+EXIT_TEST_SKIP = 77
+
+try:
+    subprocess.run
+except AttributeError:
+    sys.exit(EXIT_TEST_SKIP)
+
+exe_with_args = sys.argv[1:]
+
+def test_line(line, *, user, returncode=EX_DATAERR, extra={}):
+    args = ['--user'] if user else []
+    print('Running {} on {!r}'.format(' '.join(exe_with_args + args), line))
+    c = subprocess.run(exe_with_args + ['--create', '-'] + args,
+                       input=line, stdout=subprocess.PIPE, universal_newlines=True,
+                       **extra)
+    assert c.returncode == returncode, c
+
+def test_invalids(*, user):
+    test_line('asdfa', user=user)
+    test_line('f "open quote', user=user)
+    test_line('f closed quote""', user=user)
+    test_line('Y /unknown/letter', user=user)
+    test_line('w non/absolute/path', user=user)
+    test_line('s', user=user) # s is for short
+    test_line('f!! /too/many/bangs', user=user)
+    test_line('f++ /too/many/plusses', user=user)
+    test_line('f+!+ /too/many/plusses', user=user)
+    test_line('f!+! /too/many/bangs', user=user)
+    test_line('w /unresolved/argument - - - - "%Y"', user=user)
+    test_line('w /unresolved/argument/sandwich - - - - "%v%Y%v"', user=user)
+    test_line('w /unresolved/filename/%Y - - - - "whatever"', user=user)
+    test_line('w /unresolved/filename/sandwich/%v%Y%v - - - - "whatever"', user=user)
+    test_line('w - - - - - "no file specfied"', user=user)
+    test_line('C - - - - - "no file specfied"', user=user)
+    test_line('C non/absolute/path - - - - -', user=user)
+    test_line('b - - - - - -', user=user)
+    test_line('b 1234 - - - - -', user=user)
+    test_line('c - - - - - -', user=user)
+    test_line('c 1234 - - - - -', user=user)
+    test_line('t - - -', user=user)
+    test_line('T - - -', user=user)
+    test_line('a - - -', user=user)
+    test_line('A - - -', user=user)
+    test_line('h - - -', user=user)
+    test_line('H - - -', user=user)
+
+def test_unitialized_t():
+    if os.getuid() == 0:
+        return
+
+    test_line('w /foo - - - - "specifier for --user %t"',
+              user=True, returncode=0, extra={'env':{}})
+
+def test_content(line, expected, *, user, extra={}):
+    d = tempfile.TemporaryDirectory(prefix='test-systemd-tmpfiles.')
+    arg = d.name + '/arg'
+    spec = line.format(arg)
+    test_line(spec, user=user, returncode=0, extra=extra)
+    content = open(arg).read()
+    print('expect: {!r}\nactual: {!r}'.format(expected, content))
+    assert content == expected
+
+def test_valid_specifiers(*, user):
+    test_content('f {} - - - - two words', 'two words', user=user)
+    if id128:
+        try:
+            test_content('f {} - - - - %m', '{}'.format(id128.get_machine().hex), user=user)
+        except AssertionError as e:
+            print(e)
+            print('/etc/machine-id: {!r}'.format(open('/etc/machine-id').read()))
+            print('/proc/cmdline: {!r}'.format(open('/proc/cmdline').read()))
+            print('skipping')
+        test_content('f {} - - - - %b', '{}'.format(id128.get_boot().hex), user=user)
+    test_content('f {} - - - - %H', '{}'.format(socket.gethostname()), user=user)
+    test_content('f {} - - - - %v', '{}'.format(os.uname().release), user=user)
+    test_content('f {} - - - - %U', '{}'.format(os.getuid()), user=user)
+
+    user = pwd.getpwuid(os.getuid())
+    test_content('f {} - - - - %u', '{}'.format(user.pw_name), user=user)
+
+    # Note that %h is the only specifier in which we look the environment,
+    # because we check $HOME. Should we even be doing that?
+    home = os.path.expanduser("~")
+    test_content('f {} - - - - %h', '{}'.format(home), user=user)
+
+    xdg_runtime_dir = os.getenv('XDG_RUNTIME_DIR')
+    if xdg_runtime_dir is not None or not user:
+        test_content('f {} - - - - %t',
+                     xdg_runtime_dir if user else '/run',
+                     user=user)
+
+    xdg_config_home = os.getenv('XDG_CONFIG_HOME')
+    if xdg_config_home is not None or not user:
+        test_content('f {} - - - - %S',
+                     xdg_config_home if user else '/var/lib',
+                     user=user)
+
+    xdg_cache_home = os.getenv('XDG_CACHE_HOME')
+    if xdg_cache_home is not None or not user:
+        test_content('f {} - - - - %C',
+                     xdg_cache_home if user else '/var/cache',
+                     user=user)
+
+    if xdg_config_home is not None or not user:
+        test_content('f {} - - - - %L',
+                     xdg_config_home + '/log' if user else '/var/log',
+                     user=user)
+
+    test_content('f {} - - - - %%', '%', user=user)
+
+if __name__ == '__main__':
+    test_invalids(user=False)
+    test_invalids(user=True)
+    test_unitialized_t()
+
+    test_valid_specifiers(user=False)
+    test_valid_specifiers(user=True)
index a16b04d..023fae0 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd
 
index 373a1b7..51b3306 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
similarity index 96%
rename from src/test/test-time.c
rename to src/test/test-time-util.c
index b7a06c7..ebf85fc 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -382,6 +383,22 @@ static void test_usec_shift_clock(void) {
         }
 }
 
+static void test_in_utc_timezone(void) {
+        assert_se(setenv("TZ", ":UTC", 1) >= 0);
+        assert_se(in_utc_timezone());
+        assert_se(streq(tzname[0], "UTC"));
+        assert_se(streq(tzname[1], "UTC"));
+        assert_se(timezone == 0);
+        assert_se(daylight == 0);
+
+        assert_se(setenv("TZ", "Europe/Berlin", 1) >= 0);
+        assert_se(!in_utc_timezone());
+        assert_se(streq(tzname[0], "CET"));
+        assert_se(streq(tzname[1], "CEST"));
+
+        assert_se(unsetenv("TZ") >= 0);
+}
+
 int main(int argc, char *argv[]) {
         uintmax_t x;
 
@@ -408,6 +425,7 @@ int main(int argc, char *argv[]) {
         test_format_timestamp_utc();
         test_dual_timestamp_deserialize();
         test_usec_shift_clock();
+        test_in_utc_timezone();
 
         /* Ensure time_t is signed */
         assert_cc((time_t) -1 < (time_t) 1);
index b4c7604..c479ecc 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index c84bd89..e765f71 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 41f06a5..ce461d6 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 4f64398..00445fa 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd
 
index 07f21d0..40eeba6 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -445,6 +446,73 @@ static void test_config_parse_exec(void) {
         manager_free(m);
 }
 
+static void test_config_parse_log_extra_fields(void) {
+        /* int config_parse_log_extra_fields(
+                const char *unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) */
+
+        int r;
+
+        Manager *m = NULL;
+        Unit *u = NULL;
+        ExecContext c = {};
+
+        r = manager_new(UNIT_FILE_USER, MANAGER_TEST_RUN_MINIMAL, &m);
+        if (MANAGER_SKIP_TEST(r)) {
+                log_notice_errno(r, "Skipping test: manager_new: %m");
+                return;
+        }
+
+        assert_se(r >= 0);
+        assert_se(manager_startup(m, NULL, NULL) >= 0);
+
+        assert_se(u = unit_new(m, sizeof(Service)));
+
+        log_info("/* %s – basic test */", __func__);
+        r = config_parse_log_extra_fields(NULL, "fake", 1, "section", 1,
+                                          "LValue", 0, "FOO=BAR \"QOOF=quux '  ' \"",
+                                          &c, u);
+        assert_se(r >= 0);
+        assert_se(c.n_log_extra_fields == 2);
+        assert_se(strneq(c.log_extra_fields[0].iov_base, "FOO=BAR", c.log_extra_fields[0].iov_len));
+        assert_se(strneq(c.log_extra_fields[1].iov_base, "QOOF=quux '  ' ", c.log_extra_fields[1].iov_len));
+
+        log_info("/* %s – add some */", __func__);
+        r = config_parse_log_extra_fields(NULL, "fake", 1, "section", 1,
+                                          "LValue", 0, "FOO2=BAR2 QOOF2=quux '  '",
+                                          &c, u);
+        assert_se(r >= 0);
+        assert_se(c.n_log_extra_fields == 4);
+        assert_se(strneq(c.log_extra_fields[0].iov_base, "FOO=BAR", c.log_extra_fields[0].iov_len));
+        assert_se(strneq(c.log_extra_fields[1].iov_base, "QOOF=quux '  ' ", c.log_extra_fields[1].iov_len));
+        assert_se(strneq(c.log_extra_fields[2].iov_base, "FOO2=BAR2", c.log_extra_fields[2].iov_len));
+        assert_se(strneq(c.log_extra_fields[3].iov_base, "QOOF2=quux", c.log_extra_fields[3].iov_len));
+
+        exec_context_dump(&c, stdout, "    --> ");
+
+        log_info("/* %s – reset */", __func__);
+        r = config_parse_log_extra_fields(NULL, "fake", 1, "section", 1,
+                                          "LValue", 0, "",
+                                          &c, u);
+        assert_se(r >= 0);
+        assert_se(c.n_log_extra_fields == 0);
+
+        exec_context_free_log_extra_fields(&c);
+
+        unit_free(u);
+        manager_free(m);
+
+        log_info("/* %s – bye */", __func__);
+}
+
 #define env_file_1                              \
         "a=a\n"                                 \
         "b=b\\\n"                               \
@@ -858,12 +926,17 @@ int main(int argc, char *argv[]) {
         log_parse_environment();
         log_open();
 
-        enter_cgroup_subroot();
+        r = enter_cgroup_subroot();
+        if (r == -ENOMEDIUM) {
+                log_notice_errno(r, "Skipping test: cgroupfs not available");
+                return EXIT_TEST_SKIP;
+        }
 
         assert_se(runtime_dir = setup_fake_runtime_dir());
 
         r = test_unit_file_get_set();
         test_config_parse_exec();
+        test_config_parse_log_extra_fields();
         test_config_parse_capability_set();
         test_config_parse_rlimit();
         test_config_parse_pass_environ();
index 1992357..e24892b 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -206,7 +207,7 @@ static int test_unit_printf(void) {
         assert_se(specifier_machine_id('m', NULL, NULL, &mid) >= 0 && mid);
         assert_se(specifier_boot_id('b', NULL, NULL, &bid) >= 0 && bid);
         assert_se(host = gethostname_malloc());
-        assert_se(user = getusername_malloc());
+        assert_se(user = uid_to_name(getuid()));
         assert_se(asprintf(&uid, UID_FMT, getuid()));
         assert_se(get_home_dir(&home) >= 0);
         assert_se(get_shell(&shell) >= 0);
@@ -465,12 +466,16 @@ static void test_unit_name_path_unescape(void) {
 
 int main(int argc, char* argv[]) {
         _cleanup_(rm_rf_physical_and_freep) char *runtime_dir = NULL;
-        int rc = 0;
+        int r, rc = 0;
 
         log_parse_environment();
         log_open();
 
-        enter_cgroup_subroot();
+        r = enter_cgroup_subroot();
+        if (r == -ENOMEDIUM) {
+                log_notice_errno(r, "Skipping test: cgroupfs not available");
+                return EXIT_TEST_SKIP;
+        }
 
         assert_se(runtime_dir = setup_fake_runtime_dir());
 
index 2a344a9..17a8520 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -22,6 +23,7 @@
 #include "string-util.h"
 #include "user-util.h"
 #include "util.h"
+#include "path-util.h"
 
 static void test_uid_to_name_one(uid_t uid, const char *name) {
         _cleanup_free_ char *t = NULL;
@@ -143,17 +145,51 @@ static void test_valid_home(void) {
         assert_se(valid_home("/home/foo"));
 }
 
+static void test_get_user_creds_one(const char *id, const char *name, uid_t uid, gid_t gid, const char *home, const char *shell) {
+        const char *rhome;
+        const char *rshell;
+        uid_t ruid;
+        gid_t rgid;
+
+        assert_se(get_user_creds(&id, &ruid, &rgid, &rhome, &rshell) >= 0);
+        assert_se(streq_ptr(id, name));
+        assert_se(ruid == uid);
+        assert_se(rgid == gid);
+        assert_se(path_equal(rhome, home));
+        assert_se(path_equal(rshell, shell));
+}
+
+static void test_get_group_creds_one(const char *id, const char *name, gid_t gid) {
+        gid_t rgid;
+
+        assert_se(get_group_creds(&id, &rgid) >= 0);
+        assert_se(streq_ptr(id, name));
+        assert_se(rgid == gid);
+}
+
 int main(int argc, char*argv[]) {
 
         test_uid_to_name_one(0, "root");
+        test_uid_to_name_one(UID_NOBODY, NOBODY_USER_NAME);
         test_uid_to_name_one(0xFFFF, "65535");
         test_uid_to_name_one(0xFFFFFFFF, "4294967295");
 
         test_gid_to_name_one(0, "root");
+        test_gid_to_name_one(GID_NOBODY, NOBODY_GROUP_NAME);
         test_gid_to_name_one(TTY_GID, "tty");
         test_gid_to_name_one(0xFFFF, "65535");
         test_gid_to_name_one(0xFFFFFFFF, "4294967295");
 
+        test_get_user_creds_one("root", "root", 0, 0, "/root", "/bin/sh");
+        test_get_user_creds_one("0", "root", 0, 0, "/root", "/bin/sh");
+        test_get_user_creds_one(NOBODY_USER_NAME, NOBODY_USER_NAME, UID_NOBODY, GID_NOBODY, "/", "/sbin/nologin");
+        test_get_user_creds_one("65534", NOBODY_USER_NAME, UID_NOBODY, GID_NOBODY, "/", "/sbin/nologin");
+
+        test_get_group_creds_one("root", "root", 0);
+        test_get_group_creds_one("0", "root", 0);
+        test_get_group_creds_one(NOBODY_GROUP_NAME, NOBODY_GROUP_NAME, GID_NOBODY);
+        test_get_group_creds_one("65534", NOBODY_GROUP_NAME, GID_NOBODY);
+
         test_parse_uid();
         test_uid_ptr();
 
index 1ce5a5a..1ea0901 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index f8bf0cb..2124511 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -104,6 +105,11 @@ static void test_max(void) {
         assert_se(CLAMP(CLAMP(0, -10, 10), CLAMP(-5, 10, 20), CLAMP(100, -5, 20)) == 10);
 }
 
+#pragma GCC diagnostic push
+#ifdef __clang__
+#  pragma GCC diagnostic ignored "-Waddress-of-packed-member"
+#endif
+
 static void test_container_of(void) {
         struct mytype {
                 uint8_t pad1[3];
@@ -122,6 +128,8 @@ static void test_container_of(void) {
                                v1) == &myval);
 }
 
+#pragma GCC diagnostic pop
+
 static void test_div_round_up(void) {
         int div;
 
index 0fcdd9e..88276a2 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 276b803..e068d1d 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 79a3a13..f59a196 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 267f294..01c371a 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index b0b72fa..5b9abc1 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index ce92a6b..80e5cd2 100644 (file)
@@ -1,14 +1,32 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
+# Copyright 2017 Zbigniew Jędrzejewski-Szmek
+#
+# 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.
+#
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
 if conf.get('ENABLE_TIMEDATED') == 1
         install_data('org.freedesktop.timedate1.conf',
                      install_dir : dbuspolicydir)
         install_data('org.freedesktop.timedate1.service',
                      install_dir : dbussystemservicedir)
 
-        custom_target(
+        i18n.merge_file(
                 'org.freedesktop.timedate1.policy',
                 input : 'org.freedesktop.timedate1.policy.in',
                 output : 'org.freedesktop.timedate1.policy',
-                command : intltool_command,
+                po_dir : po_dir,
+                data_dirs : po_dir,
                 install : install_polkit,
                 install_dir : polkitpolicydir)
 endif
index 36557d5..53f6c84 100644 (file)
@@ -3,6 +3,8 @@
         "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   systemd is free software; you can redistribute it and/or modify it
index aa30b70..cc2e165 100644 (file)
@@ -3,6 +3,8 @@
         "http://www.freedesktop.org/standards/PolicyKit/1/policyconfig.dtd">
 
 <!--
+  SPDX-License-Identifier: LGPL-2.1+
+
   This file is part of systemd.
 
   systemd is free software; you can redistribute it and/or modify it
@@ -17,8 +19,8 @@
         <vendor_url>http://www.freedesktop.org/wiki/Software/systemd</vendor_url>
 
         <action id="org.freedesktop.timedate1.set-time">
-                <_description>Set system time</_description>
-                <_message>Authentication is required to set the system time.</_message>
+                <description>Set system time</description>
+                <message>Authentication is required to set the system time.</message>
                 <defaults>
                         <allow_any>auth_admin_keep</allow_any>
                         <allow_inactive>auth_admin_keep</allow_inactive>
@@ -28,8 +30,8 @@
         </action>
 
         <action id="org.freedesktop.timedate1.set-timezone">
-                <_description>Set system timezone</_description>
-                <_message>Authentication is required to set the system timezone.</_message>
+                <description>Set system timezone</description>
+                <message>Authentication is required to set the system timezone.</message>
                 <defaults>
                         <allow_any>auth_admin_keep</allow_any>
                         <allow_inactive>auth_admin_keep</allow_inactive>
@@ -38,9 +40,9 @@
         </action>
 
         <action id="org.freedesktop.timedate1.set-local-rtc">
-                <_description>Set RTC to local timezone or UTC</_description>
-                <_message>Authentication is required to control whether
-                the RTC stores the local or UTC time.</_message>
+                <description>Set RTC to local timezone or UTC</description>
+                <message>Authentication is required to control whether
+                the RTC stores the local or UTC time.</message>
                 <defaults>
                         <allow_any>auth_admin_keep</allow_any>
                         <allow_inactive>auth_admin_keep</allow_inactive>
@@ -49,9 +51,9 @@
         </action>
 
         <action id="org.freedesktop.timedate1.set-ntp">
-                <_description>Turn network time synchronization on or off</_description>
-                <_message>Authentication is required to control whether
-                network time synchronization shall be enabled.</_message>
+                <description>Turn network time synchronization on or off</description>
+                <message>Authentication is required to control whether
+                network time synchronization shall be enabled.</message>
                 <defaults>
                         <allow_any>auth_admin_keep</allow_any>
                         <allow_inactive>auth_admin_keep</allow_inactive>
index 875f4be..d5f3a6e 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index a30e783..d80a917 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -40,18 +41,6 @@ static BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
 static char *arg_host = NULL;
 static bool arg_adjust_system_clock = false;
 
-static void polkit_agent_open_if_enabled(void) {
-
-        /* Open the polkit agent as a child process if necessary */
-        if (!arg_ask_password)
-                return;
-
-        if (arg_transport != BUS_TRANSPORT_LOCAL)
-                return;
-
-        polkit_agent_open();
-}
-
 typedef struct StatusInfo {
         usec_t time;
         char *timezone;
@@ -72,12 +61,13 @@ static void status_info_clear(StatusInfo *info) {
 }
 
 static void print_status_info(const StatusInfo *i) {
-        char a[FORMAT_TIMESTAMP_MAX];
+        char a[LINE_MAX];
         struct tm tm;
         time_t sec;
         bool have_time = false;
         const char *old_tz = NULL, *tz;
         int r;
+        size_t n;
 
         assert(i);
 
@@ -102,11 +92,11 @@ static void print_status_info(const StatusInfo *i) {
                 log_warning("Could not get time from timedated and not operating locally, ignoring.");
 
         if (have_time) {
-                xstrftime(a, "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&sec, &tm));
-                printf("                      Local time: %.*s\n", (int) sizeof(a), a);
+                n = strftime(a, sizeof a, "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&sec, &tm));
+                printf("                      Local time: %s\n", n > 0 ? a : "n/a");
 
-                xstrftime(a, "%a %Y-%m-%d %H:%M:%S UTC", gmtime_r(&sec, &tm));
-                printf("                  Universal time: %.*s\n", (int) sizeof(a), a);
+                n = strftime(a, sizeof a, "%a %Y-%m-%d %H:%M:%S UTC", gmtime_r(&sec, &tm));
+                printf("                  Universal time: %s\n", n > 0 ? a : "n/a");
         } else {
                 printf("                      Local time: %s\n", "n/a");
                 printf("                  Universal time: %s\n", "n/a");
@@ -116,13 +106,13 @@ static void print_status_info(const StatusInfo *i) {
                 time_t rtc_sec;
 
                 rtc_sec = (time_t) (i->rtc_time / USEC_PER_SEC);
-                xstrftime(a, "%a %Y-%m-%d %H:%M:%S", gmtime_r(&rtc_sec, &tm));
-                printf("                        RTC time: %.*s\n", (int) sizeof(a), a);
+                n = strftime(a, sizeof a, "%a %Y-%m-%d %H:%M:%S", gmtime_r(&rtc_sec, &tm));
+                printf("                        RTC time: %s\n", n > 0 ? a : "n/a");
         } else
                 printf("                        RTC time: %s\n", "n/a");
 
         if (have_time)
-                xstrftime(a, "%Z, %z", localtime_r(&sec, &tm));
+                n = strftime(a, sizeof a, "%Z, %z", localtime_r(&sec, &tm));
 
         /* Restore the $TZ */
         if (old_tz)
@@ -134,11 +124,11 @@ static void print_status_info(const StatusInfo *i) {
         else
                 tzset();
 
-        printf("                       Time zone: %s (%.*s)\n"
+        printf("                       Time zone: %s (%s)\n"
                "       System clock synchronized: %s\n"
                "systemd-timesyncd.service active: %s\n"
                "                 RTC in local TZ: %s\n",
-               strna(i->timezone), (int) sizeof(a), have_time ? a : "n/a",
+               strna(i->timezone), have_time && n > 0 ? a : "n/a",
                i->ntp_capable ? yes_no(i->ntp_enabled) : "n/a",
                yes_no(i->ntp_synced),
                yes_no(i->rtc_local));
@@ -194,7 +184,7 @@ static int set_time(sd_bus *bus, char **args, unsigned n) {
         assert(args);
         assert(n == 2);
 
-        polkit_agent_open_if_enabled();
+        polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
 
         r = parse_timestamp(args[1], &t);
         if (r < 0) {
@@ -223,7 +213,7 @@ static int set_timezone(sd_bus *bus, char **args, unsigned n) {
         assert(args);
         assert(n == 2);
 
-        polkit_agent_open_if_enabled();
+        polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
 
         r = sd_bus_call_method(bus,
                                "org.freedesktop.timedate1",
@@ -246,7 +236,7 @@ static int set_local_rtc(sd_bus *bus, char **args, unsigned n) {
         assert(args);
         assert(n == 2);
 
-        polkit_agent_open_if_enabled();
+        polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
 
         b = parse_boolean(args[1]);
         if (b < 0) {
@@ -275,7 +265,7 @@ static int set_ntp(sd_bus *bus, char **args, unsigned n) {
         assert(args);
         assert(n == 2);
 
-        polkit_agent_open_if_enabled();
+        polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
 
         b = parse_boolean(args[1]);
         if (b < 0) {
@@ -483,7 +473,7 @@ static int timedatectl_main(sd_bus *bus, int argc, char *argv[]) {
 }
 
 int main(int argc, char *argv[]) {
-        sd_bus *bus = NULL;
+        _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
         int r;
 
         setlocale(LC_ALL, "");
@@ -503,7 +493,6 @@ int main(int argc, char *argv[]) {
         r = timedatectl_main(bus, argc, argv);
 
 finish:
-        sd_bus_flush_close_unref(bus);
         pager_close();
 
         return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
index 1061b09..a55a929 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -74,9 +75,7 @@ static int context_read_data(Context *c) {
         else if (r < 0)
                 log_warning_errno(r, "Failed to get target of /etc/localtime: %m");
 
-        free(c->zone);
-        c->zone = t;
-        t = NULL;
+        free_and_replace(c->zone, t);
 
         c->local_rtc = clock_is_localtime(NULL) > 0;
 
index 690af95..e8bd3d5 100644 (file)
@@ -1,3 +1,20 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
+# Copyright 2017 Zbigniew Jędrzejewski-Szmek
+#
+# 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.
+#
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
 systemd_timesyncd_sources = files('''
         timesyncd.c
         timesyncd-manager.c
index a5a3433..7d5cd38 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index f394d0a..124d03d 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -106,11 +107,27 @@ int config_parse_servers(
 }
 
 int manager_parse_config_file(Manager *m) {
+        int r;
+
         assert(m);
 
-        return config_parse_many_nulstr(PKGSYSCONFDIR "/timesyncd.conf",
-                                        CONF_PATHS_NULSTR("systemd/timesyncd.conf.d"),
-                                        "Time\0",
-                                        config_item_perf_lookup, timesyncd_gperf_lookup,
-                                        false, m);
+        r = config_parse_many_nulstr(PKGSYSCONFDIR "/timesyncd.conf",
+                                     CONF_PATHS_NULSTR("systemd/timesyncd.conf.d"),
+                                     "Time\0",
+                                     config_item_perf_lookup, timesyncd_gperf_lookup,
+                                     CONFIG_PARSE_WARN, m);
+        if (r < 0)
+                return r;
+
+        if (m->poll_interval_min_usec < 16 * USEC_PER_SEC) {
+                log_warning("Invalid PollIntervalMinSec=. Using default value.");
+                m->poll_interval_min_usec = NTP_POLL_INTERVAL_MIN_USEC;
+        }
+
+        if (m->poll_interval_max_usec < m->poll_interval_min_usec) {
+                log_warning("PollIntervalMaxSec= is smaller than PollIntervalMinSec=. Using default value.");
+                m->poll_interval_max_usec = MAX(NTP_POLL_INTERVAL_MAX_USEC, m->poll_interval_min_usec * 32);
+        }
+
+        return r;
 }
index 0c4b44e..8252298 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 29a2cfe..7d4cd28 100644 (file)
@@ -1,4 +1,7 @@
 %{
+#if __GNUC__ >= 7
+_Pragma("GCC diagnostic ignored \"-Wimplicit-fallthrough\"")
+#endif
 #include <stddef.h>
 #include "conf-parser.h"
 #include "timesyncd-conf.h"
@@ -14,6 +17,9 @@ struct ConfigPerfItem;
 %struct-type
 %includes
 %%
-Time.NTP,           config_parse_servers, SERVER_SYSTEM,   0
-Time.Servers,       config_parse_servers, SERVER_SYSTEM,   0
-Time.FallbackNTP,   config_parse_servers, SERVER_FALLBACK, 0
+Time.NTP,                 config_parse_servers, SERVER_SYSTEM,   0
+Time.Servers,             config_parse_servers, SERVER_SYSTEM,   0
+Time.FallbackNTP,         config_parse_servers, SERVER_FALLBACK, 0
+Time.RootDistanceMaxSec,  config_parse_sec,     0,               offsetof(Manager, max_root_distance_usec)
+Time.PollIntervalMinSec,  config_parse_sec,     0,               offsetof(Manager, poll_interval_min_usec)
+Time.PollIntervalMaxSec,  config_parse_sec,     0,               offsetof(Manager, poll_interval_max_usec)
index eacb10f..8bd111f 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
 #define NTP_ACCURACY_SEC                0.2
 
 /*
- * "A client MUST NOT under any conditions use a poll interval less
- * than 15 seconds."
- */
-#define NTP_POLL_INTERVAL_MIN_SEC       32
-#define NTP_POLL_INTERVAL_MAX_SEC       2048
-
-/*
  * Maximum delta in seconds which the system clock is gradually adjusted
- * (slew) to approach the network time. Deltas larger that this are set by
+ * (slewed) to approach the network time. Deltas larger that this are set by
  * letting the system time jump. The kernel's limit for adjtime is 0.5s.
  */
 #define NTP_MAX_ADJUST                  0.4
@@ -80,8 +74,8 @@
 #define NTP_FIELD_MODE(f)               ((f) & 7)
 #define NTP_FIELD(l, v, m)              (((l) << 6) | ((v) << 3) | (m))
 
-/* Maximum acceptable root distance in seconds. */
-#define NTP_MAX_ROOT_DISTANCE           5.0
+/* Default of maximum acceptable root distance in microseconds. */
+#define NTP_MAX_ROOT_DISTANCE           (5 * USEC_PER_SEC)
 
 /* Maximum number of missed replies before selecting another source. */
 #define NTP_MAX_MISSED_REPLIES          2
@@ -204,10 +198,10 @@ static int manager_send_request(Manager *m) {
 
         /* re-arm timer with increasing timeout, in case the packets never arrive back */
         if (m->retry_interval > 0) {
-                if (m->retry_interval < NTP_POLL_INTERVAL_MAX_SEC * USEC_PER_SEC)
+                if (m->retry_interval < m->poll_interval_max_usec)
                         m->retry_interval *= 2;
         } else
-                m->retry_interval = NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC;
+                m->retry_interval = m->poll_interval_min_usec;
 
         r = manager_arm_timer(m, m->retry_interval);
         if (r < 0)
@@ -446,27 +440,27 @@ static void manager_adjust_poll(Manager *m, double offset, bool spike) {
         assert(m);
 
         if (m->poll_resync) {
-                m->poll_interval_usec = NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC;
+                m->poll_interval_usec = m->poll_interval_min_usec;
                 m->poll_resync = false;
                 return;
         }
 
         /* set to minimal poll interval */
         if (!spike && fabs(offset) > NTP_ACCURACY_SEC) {
-                m->poll_interval_usec = NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC;
+                m->poll_interval_usec = m->poll_interval_min_usec;
                 return;
         }
 
         /* increase polling interval */
         if (fabs(offset) < NTP_ACCURACY_SEC * 0.25) {
-                if (m->poll_interval_usec < NTP_POLL_INTERVAL_MAX_SEC * USEC_PER_SEC)
+                if (m->poll_interval_usec < m->poll_interval_max_usec)
                         m->poll_interval_usec *= 2;
                 return;
         }
 
         /* decrease polling interval */
         if (spike || fabs(offset) > NTP_ACCURACY_SEC * 0.75) {
-                if (m->poll_interval_usec > NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC)
+                if (m->poll_interval_usec > m->poll_interval_min_usec)
                         m->poll_interval_usec /= 2;
                 return;
         }
@@ -588,7 +582,7 @@ static int manager_receive_response(sd_event_source *source, int fd, uint32_t re
         }
 
         root_distance = ntp_ts_short_to_d(&ntpmsg.root_delay) / 2 + ntp_ts_short_to_d(&ntpmsg.root_dispersion);
-        if (root_distance > NTP_MAX_ROOT_DISTANCE) {
+        if (root_distance > (double) m->max_root_distance_usec / (double) USEC_PER_SEC) {
                 log_debug("Server has too large root distance. Disconnecting.");
                 return manager_connect(m);
         }
@@ -743,7 +737,7 @@ static int manager_begin(Manager *m) {
         m->good = false;
         m->missed_replies = NTP_MAX_MISSED_REPLIES;
         if (m->poll_interval_usec == 0)
-                m->poll_interval_usec = NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC;
+                m->poll_interval_usec = m->poll_interval_min_usec;
 
         server_address_pretty(m->current_server_address, &pretty);
         log_debug("Connecting to time server %s (%s).", strna(pretty), m->current_server_name->string);
@@ -921,7 +915,7 @@ int manager_connect(Manager *m) {
                                 m->exhausted_servers = true;
 
                                 /* Increase the polling interval */
-                                if (m->poll_interval_usec < NTP_POLL_INTERVAL_MAX_SEC * USEC_PER_SEC)
+                                if (m->poll_interval_usec < m->poll_interval_max_usec)
                                         m->poll_interval_usec *= 2;
 
                                 return 0;
@@ -1093,7 +1087,7 @@ static int manager_network_monitor_listen(Manager *m) {
 
         r = sd_network_monitor_new(&m->network_monitor, NULL);
         if (r == -ENOENT) {
-                log_info("Systemd does not appear to be running, not listening for systemd-networkd events.");
+                log_info("systemd does not appear to be running, not listening for systemd-networkd events.");
                 return 0;
         }
         if (r < 0)
@@ -1124,6 +1118,10 @@ int manager_new(Manager **ret) {
         if (!m)
                 return -ENOMEM;
 
+        m->max_root_distance_usec = NTP_MAX_ROOT_DISTANCE;
+        m->poll_interval_min_usec = NTP_POLL_INTERVAL_MIN_USEC;
+        m->poll_interval_max_usec = NTP_POLL_INTERVAL_MAX_USEC;
+
         m->server_socket = m->clock_watch_fd = -1;
 
         RATELIMIT_INIT(m->ratelimit, RATELIMIT_INTERVAL_USEC, RATELIMIT_BURST);
index cf681f6..4d62588 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
 
 #include "list.h"
 #include "ratelimit.h"
+#include "time-util.h"
 
 typedef struct Manager Manager;
 
 #include "timesyncd-server.h"
 
+/*
+ * "A client MUST NOT under any conditions use a poll interval less
+ * than 15 seconds."
+ */
+#define NTP_POLL_INTERVAL_MIN_USEC      (32 * USEC_PER_SEC)
+#define NTP_POLL_INTERVAL_MAX_USEC      (2048 * USEC_PER_SEC)
+
 struct Manager {
         sd_event *event;
         sd_resolve *resolve;
@@ -67,6 +76,8 @@ struct Manager {
         /* poll timer */
         sd_event_source *event_timer;
         usec_t poll_interval_usec;
+        usec_t poll_interval_min_usec;
+        usec_t poll_interval_max_usec;
         bool poll_resync;
 
         /* history data */
@@ -76,6 +87,7 @@ struct Manager {
         } samples[8];
         unsigned int samples_idx;
         double samples_jitter;
+        usec_t max_root_distance_usec;
 
         /* last change */
         bool jumped;
index 57a7bf2..bd0030b 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 8a19e41..2dc51a9 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 6b802c6..962285f 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -69,7 +70,7 @@ static int load_clock_timestamp(uid_t uid, gid_t gid) {
                 }
 
         } else {
-                r = mkdir_safe_label("/var/lib/systemd/timesync", 0755, uid, gid);
+                r = mkdir_safe_label("/var/lib/systemd/timesync", 0755, uid, gid, true);
                 if (r < 0)
                         return log_error_errno(r, "Failed to create state directory: %m");
 
index b6a2ada..f91c034 100644 (file)
@@ -14,3 +14,6 @@
 [Time]
 #NTP=
 #FallbackNTP=@NTP_SERVERS@
+#RootDistanceMaxSec=5
+#PollIntervalMinSec=32
+#PollIntervalMaxSec=2048
index 7f457ca..a7ce1a8 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
 #include <string.h>
 #include <sys/stat.h>
 #include <sys/xattr.h>
+#include <sysexits.h>
 #include <time.h>
 #include <unistd.h>
 
+#include "sd-path.h"
+
 #include "acl-util.h"
 #include "alloc-util.h"
 #include "btrfs-util.h"
@@ -58,6 +62,7 @@
 #include "mkdir.h"
 #include "mount-util.h"
 #include "parse-util.h"
+#include "path-lookup.h"
 #include "path-util.h"
 #include "rm-rf.h"
 #include "selinux-util.h"
@@ -149,6 +154,15 @@ typedef struct ItemArray {
         size_t size;
 } ItemArray;
 
+typedef enum DirectoryType {
+        DIRECTORY_RUNTIME = 0,
+        DIRECTORY_STATE,
+        DIRECTORY_CACHE,
+        DIRECTORY_LOGS,
+        _DIRECTORY_TYPE_MAX,
+} DirectoryType;
+
+static bool arg_user = false;
 static bool arg_create = false;
 static bool arg_clean = false;
 static bool arg_remove = false;
@@ -158,21 +172,148 @@ static char **arg_include_prefixes = NULL;
 static char **arg_exclude_prefixes = NULL;
 static char *arg_root = NULL;
 
-static const char conf_file_dirs[] = CONF_PATHS_NULSTR("tmpfiles.d");
-
 #define MAX_DEPTH 256
 
 static OrderedHashmap *items = NULL, *globs = NULL;
 static Set *unix_sockets = NULL;
 
+static int specifier_machine_id_safe(char specifier, void *data, void *userdata, char **ret);
+static int specifier_directory(char specifier, void *data, void *userdata, char **ret);
+
 static const Specifier specifier_table[] = {
-        { 'm', specifier_machine_id, NULL },
-        { 'b', specifier_boot_id, NULL },
-        { 'H', specifier_host_name, NULL },
-        { 'v', specifier_kernel_release, NULL },
+        { 'm', specifier_machine_id_safe, NULL },
+        { 'b', specifier_boot_id,         NULL },
+        { 'H', specifier_host_name,       NULL },
+        { 'v', specifier_kernel_release,  NULL },
+
+        { 'U', specifier_user_id,         NULL },
+        { 'u', specifier_user_name,       NULL },
+        { 'h', specifier_user_home,       NULL },
+        { 't', specifier_directory,       UINT_TO_PTR(DIRECTORY_RUNTIME) },
+        { 'S', specifier_directory,       UINT_TO_PTR(DIRECTORY_STATE) },
+        { 'C', specifier_directory,       UINT_TO_PTR(DIRECTORY_CACHE) },
+        { 'L', specifier_directory,       UINT_TO_PTR(DIRECTORY_LOGS) },
         {}
 };
 
+static int specifier_machine_id_safe(char specifier, void *data, void *userdata, char **ret) {
+        int r;
+
+        /* If /etc/machine_id is missing (e.g. in a chroot environment), returns
+         * a recognizable error so that the caller can skip the rule
+         * gracefully. */
+
+        r = specifier_machine_id(specifier, data, userdata, ret);
+        if (r == -ENOENT)
+                return -ENXIO;
+
+        return r;
+}
+
+static int specifier_directory(char specifier, void *data, void *userdata, char **ret) {
+        struct table_entry {
+                uint64_t type;
+                const char *suffix;
+        };
+
+        static const struct table_entry paths_system[] = {
+                [DIRECTORY_RUNTIME] = { SD_PATH_SYSTEM_RUNTIME            },
+                [DIRECTORY_STATE] =   { SD_PATH_SYSTEM_STATE_PRIVATE      },
+                [DIRECTORY_CACHE] =   { SD_PATH_SYSTEM_STATE_CACHE        },
+                [DIRECTORY_LOGS] =    { SD_PATH_SYSTEM_STATE_LOGS         },
+        };
+
+        static const struct table_entry paths_user[] = {
+                [DIRECTORY_RUNTIME] = { SD_PATH_USER_RUNTIME              },
+                [DIRECTORY_STATE] =   { SD_PATH_USER_CONFIGURATION        },
+                [DIRECTORY_CACHE] =   { SD_PATH_USER_STATE_CACHE          },
+                [DIRECTORY_LOGS] =    { SD_PATH_USER_CONFIGURATION, "log" },
+        };
+
+        unsigned i;
+        const struct table_entry *paths;
+
+        assert_cc(ELEMENTSOF(paths_system) == ELEMENTSOF(paths_user));
+        paths = arg_user ? paths_user : paths_system;
+
+        i = PTR_TO_UINT(data);
+        assert(i < ELEMENTSOF(paths_system));
+
+        return sd_path_home(paths[i].type, paths[i].suffix, ret);
+}
+
+static int log_unresolvable_specifier(const char *filename, unsigned line) {
+        static bool notified = false;
+
+        /* In system mode, this is called when /etc is not fully initialized (e.g.
+         * in a chroot environment) where some specifiers are unresolvable. In user
+         * mode, this is called when some variables are not defined. These cases are
+         * not considered as an error so log at LOG_NOTICE only for the first time
+         * and then downgrade this to LOG_DEBUG for the rest. */
+
+        log_full(notified ? LOG_DEBUG : LOG_NOTICE,
+                 "[%s:%u] Failed to resolve specifier: %s, skipping",
+                 filename, line,
+                 arg_user ? "Required $XDG_... variable not defined" : "uninitialized /etc detected");
+
+        if (!notified)
+                log_notice("All rules containing unresolvable specifiers will be skipped.");
+
+        notified = true;
+        return 0;
+}
+
+static int user_config_paths(char*** ret) {
+        _cleanup_strv_free_ char **config_dirs = NULL, **data_dirs = NULL;
+        _cleanup_free_ char *persistent_config = NULL, *runtime_config = NULL, *data_home = NULL;
+        _cleanup_strv_free_ char **res = NULL;
+        int r;
+
+        r = xdg_user_dirs(&config_dirs, &data_dirs);
+        if (r < 0)
+                return r;
+
+        r = xdg_user_config_dir(&persistent_config, "/user-tmpfiles.d");
+        if (r < 0 && r != -ENXIO)
+                return r;
+
+        r = xdg_user_runtime_dir(&runtime_config, "/user-tmpfiles.d");
+        if (r < 0 && r != -ENXIO)
+                return r;
+
+        r = xdg_user_data_dir(&data_home, "/user-tmpfiles.d");
+        if (r < 0 && r != -ENXIO)
+                return r;
+
+        r = strv_extend_strv_concat(&res, config_dirs, "/user-tmpfiles.d");
+        if (r < 0)
+                return r;
+
+        r = strv_extend(&res, persistent_config);
+        if (r < 0)
+                return r;
+
+        r = strv_extend(&res, runtime_config);
+        if (r < 0)
+                return r;
+
+        r = strv_extend(&res, data_home);
+        if (r < 0)
+                return r;
+
+        r = strv_extend_strv_concat(&res, data_dirs, "/user-tmpfiles.d");
+        if (r < 0)
+                return r;
+
+        r = path_strv_make_absolute_cwd(res);
+        if (r < 0)
+                return r;
+
+        *ret = res;
+        res = NULL;
+        return 0;
+}
+
 static bool needs_glob(ItemType t) {
         return IN_SET(t,
                       WRITE_FILE,
@@ -310,16 +451,14 @@ static bool unix_socket_alive(const char *fn) {
 
 static int dir_is_mount_point(DIR *d, const char *subdir) {
 
-        union file_handle_union h = FILE_HANDLE_INIT;
         int mount_id_parent, mount_id;
         int r_p, r;
 
-        r_p = name_to_handle_at(dirfd(d), ".", &h.handle, &mount_id_parent, 0);
+        r_p = name_to_handle_at_loop(dirfd(d), ".", NULL, &mount_id_parent, 0);
         if (r_p < 0)
                 r_p = -errno;
 
-        h.handle.handle_bytes = MAX_HANDLE_SZ;
-        r = name_to_handle_at(dirfd(d), subdir, &h.handle, &mount_id, 0);
+        r = name_to_handle_at_loop(dirfd(d), subdir, NULL, &mount_id, 0);
         if (r < 0)
                 r = -errno;
 
@@ -636,9 +775,9 @@ static int path_set_perms(Item *i, const char *path) {
                 return log_error_errno(errno, "Failed to fstat() file %s: %m", path);
 
         if (S_ISLNK(st.st_mode))
-                log_debug("Skipping mode an owner fix for symlink %s.", path);
+                log_debug("Skipping mode and owner fix for symlink %s.", path);
         else {
-                char fn[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(int)];
+                char fn[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)];
                 xsprintf(fn, "/proc/self/fd/%i", fd);
 
                 /* not using i->path directly because it may be a glob */
@@ -693,7 +832,7 @@ static int parse_xattrs_from_arg(Item *i) {
         p = i->argument;
 
         for (;;) {
-                _cleanup_free_ char *name = NULL, *value = NULL, *xattr = NULL, *xattr_replaced = NULL;
+                _cleanup_free_ char *name = NULL, *value = NULL, *xattr = NULL;
 
                 r = extract_first_word(&p, &xattr, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE);
                 if (r < 0)
@@ -701,11 +840,7 @@ static int parse_xattrs_from_arg(Item *i) {
                 if (r <= 0)
                         break;
 
-                r = specifier_printf(xattr, specifier_table, NULL, &xattr_replaced);
-                if (r < 0)
-                        return log_error_errno(r, "Failed to replace specifiers in extended attribute '%s': %m", xattr);
-
-                r = split_pair(xattr_replaced, "=", &name, &value);
+                r = split_pair(xattr, "=", &name, &value);
                 if (r < 0) {
                         log_warning_errno(r, "Failed to parse extended attribute, ignoring: %s", xattr);
                         continue;
@@ -811,7 +946,7 @@ static int path_set_acl(const char *path, const char *pretty, acl_type_t type, a
 static int path_set_acls(Item *item, const char *path) {
         int r = 0;
 #if HAVE_ACL
-        char fn[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(int)];
+        char fn[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)];
         _cleanup_close_ int fd = -1;
         struct stat st;
 
@@ -1024,19 +1159,9 @@ static int write_one_file(Item *i, const char *path) {
         }
 
         if (i->argument) {
-                _cleanup_free_ char *unescaped = NULL, *replaced = NULL;
-
                 log_debug("%s to \"%s\".", i->type == CREATE_FILE ? "Appending" : "Writing", path);
 
-                r = cunescape(i->argument, 0, &unescaped);
-                if (r < 0)
-                        return log_error_errno(r, "Failed to unescape parameter to write: %s", i->argument);
-
-                r = specifier_printf(unescaped, specifier_table, NULL, &replaced);
-                if (r < 0)
-                        return log_error_errno(r, "Failed to replace specifiers in parameter to write '%s': %m", unescaped);
-
-                r = loop_write(fd, replaced, strlen(replaced), false);
+                r = loop_write(fd, i->argument, strlen(i->argument), false);
                 if (r < 0)
                         return log_error_errno(r, "Failed to write file \"%s\": %m", path);
         } else
@@ -1075,7 +1200,7 @@ static int item_do_children(Item *i, const char *path, action_t action) {
 
         d = opendir_nomod(path);
         if (!d)
-                return IN_SET(errno, ENOENT, ENOTDIR) ? 0 : -errno;
+                return IN_SET(errno, ENOENT, ENOTDIR, ELOOP) ? 0 : -errno;
 
         FOREACH_DIRENT_ALL(de, d, r = -errno) {
                 _cleanup_free_ char *p = NULL;
@@ -1145,7 +1270,6 @@ static const char *creation_mode_verb_table[_CREATION_MODE_MAX] = {
 DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(creation_mode_verb, CreationMode);
 
 static int create_item(Item *i) {
-        _cleanup_free_ char *resolved = NULL;
         struct stat st;
         int r = 0;
         int q = 0;
@@ -1171,12 +1295,8 @@ static int create_item(Item *i) {
                 break;
 
         case COPY_FILES: {
-                r = specifier_printf(i->argument, specifier_table, NULL, &resolved);
-                if (r < 0)
-                        return log_error_errno(r, "Failed to substitute specifiers in copy source %s: %m", i->argument);
-
-                log_debug("Copying tree \"%s\" to \"%s\".", resolved, i->path);
-                r = copy_tree(resolved, i->path, i->uid_set ? i->uid : UID_INVALID, i->gid_set ? i->gid : GID_INVALID, COPY_REFLINK);
+                log_debug("Copying tree \"%s\" to \"%s\".", i->argument, i->path);
+                r = copy_tree(i->argument, i->path, i->uid_set ? i->uid : UID_INVALID, i->gid_set ? i->gid : GID_INVALID, COPY_REFLINK);
 
                 if (r == -EROFS && stat(i->path, &st) == 0)
                         r = -EEXIST;
@@ -1187,8 +1307,8 @@ static int create_item(Item *i) {
                         if (r != -EEXIST)
                                 return log_error_errno(r, "Failed to copy files to %s: %m", i->path);
 
-                        if (stat(resolved, &a) < 0)
-                                return log_error_errno(errno, "stat(%s) failed: %m", resolved);
+                        if (stat(i->argument, &a) < 0)
+                                return log_error_errno(errno, "stat(%s) failed: %m", i->argument);
 
                         if (stat(i->path, &b) < 0)
                                 return log_error_errno(errno, "stat(%s) failed: %m", i->path);
@@ -1288,8 +1408,7 @@ static int create_item(Item *i) {
                                 log_debug("Quota for subvolume \"%s\" already in place, no change made.", i->path);
                 }
 
-                /* fall through */
-
+                _fallthrough_;
         case EMPTY_DIRECTORY:
                 r = path_set_perms(i, i->path);
                 if (q < 0)
@@ -1343,26 +1462,22 @@ static int create_item(Item *i) {
         }
 
         case CREATE_SYMLINK: {
-                r = specifier_printf(i->argument, specifier_table, NULL, &resolved);
-                if (r < 0)
-                        return log_error_errno(r, "Failed to substitute specifiers in symlink target %s: %m", i->argument);
-
                 mac_selinux_create_file_prepare(i->path, S_IFLNK);
-                r = symlink(resolved, i->path);
+                r = symlink(i->argument, i->path);
                 mac_selinux_create_file_clear();
 
                 if (r < 0) {
                         _cleanup_free_ char *x = NULL;
 
                         if (errno != EEXIST)
-                                return log_error_errno(errno, "symlink(%s, %s) failed: %m", resolved, i->path);
+                                return log_error_errno(errno, "symlink(%s, %s) failed: %m", i->argument, i->path);
 
                         r = readlink_malloc(i->path, &x);
-                        if (r < 0 || !streq(resolved, x)) {
+                        if (r < 0 || !streq(i->argument, x)) {
 
                                 if (i->force) {
                                         mac_selinux_create_file_prepare(i->path, S_IFLNK);
-                                        r = symlink_atomic(resolved, i->path);
+                                        r = symlink_atomic(i->argument, i->path);
                                         mac_selinux_create_file_clear();
 
                                         if (IN_SET(r, -EEXIST, -ENOTEMPTY)) {
@@ -1371,11 +1486,11 @@ static int create_item(Item *i) {
                                                         return log_error_errno(r, "rm -fr %s failed: %m", i->path);
 
                                                 mac_selinux_create_file_prepare(i->path, S_IFLNK);
-                                                r = symlink(resolved, i->path) < 0 ? -errno : 0;
+                                                r = symlink(i->argument, i->path) < 0 ? -errno : 0;
                                                 mac_selinux_create_file_clear();
                                         }
                                         if (r < 0)
-                                                return log_error_errno(r, "symlink(%s, %s) failed: %m", resolved, i->path);
+                                                return log_error_errno(r, "symlink(%s, %s) failed: %m", i->argument, i->path);
 
                                         creation = CREATION_FORCE;
                                 } else {
@@ -1621,12 +1736,12 @@ static int clean_item(Item *i) {
         case CREATE_SUBVOLUME:
         case CREATE_SUBVOLUME_INHERIT_QUOTA:
         case CREATE_SUBVOLUME_NEW_QUOTA:
-        case EMPTY_DIRECTORY:
         case TRUNCATE_DIRECTORY:
         case IGNORE_PATH:
         case COPY_FILES:
                 clean_item_instance(i, i->path);
                 return 0;
+        case EMPTY_DIRECTORY:
         case IGNORE_DIRECTORY_PATH:
                 return glob_item(i, clean_item_instance, false);
         default:
@@ -1778,14 +1893,60 @@ static bool should_include_path(const char *path) {
 
         /* no matches, so we should include this path only if we
          * have no whitelist at all */
-        if (strv_length(arg_include_prefixes) == 0)
+        if (strv_isempty(arg_include_prefixes))
                 return true;
 
         log_debug("Entry \"%s\" does not match any include prefix, skipping.", path);
         return false;
 }
 
-static int parse_line(const char *fname, unsigned line, const char *buffer) {
+static int specifier_expansion_from_arg(Item *i) {
+        _cleanup_free_ char *unescaped = NULL, *resolved = NULL;
+        char **xattr;
+        int r;
+
+        assert(i);
+
+        if (i->argument == NULL)
+                return 0;
+
+        switch (i->type) {
+        case COPY_FILES:
+        case CREATE_SYMLINK:
+        case CREATE_FILE:
+        case TRUNCATE_FILE:
+        case WRITE_FILE:
+                r = cunescape(i->argument, 0, &unescaped);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to unescape parameter to write: %s", i->argument);
+
+                r = specifier_printf(unescaped, specifier_table, NULL, &resolved);
+                if (r < 0)
+                        return r;
+
+                free_and_replace(i->argument, resolved);
+                break;
+
+        case SET_XATTR:
+        case RECURSIVE_SET_XATTR:
+                assert(i->xattrs);
+
+                STRV_FOREACH (xattr, i->xattrs) {
+                        r = specifier_printf(*xattr, specifier_table, NULL, &resolved);
+                        if (r < 0)
+                                return r;
+
+                        free_and_replace(*xattr, resolved);
+                }
+                break;
+
+        default:
+                break;
+        }
+        return 0;
+}
+
+static int parse_line(const char *fname, unsigned line, const char *buffer, bool *invalid_config) {
 
         _cleanup_free_ char *action = NULL, *mode = NULL, *user = NULL, *group = NULL, *age = NULL, *path = NULL;
         _cleanup_(item_free_contents) Item i = {};
@@ -1809,9 +1970,15 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
                         &group,
                         &age,
                         NULL);
-        if (r < 0)
+        if (r < 0) {
+                if (IN_SET(r, -EINVAL, -EBADSLT))
+                        /* invalid quoting and such or an unknown specifier */
+                        *invalid_config = true;
                 return log_error_errno(r, "[%s:%u] Failed to parse line: %m", fname, line);
+        }
+
         else if (r < 2) {
+                *invalid_config = true;
                 log_error("[%s:%u] Syntax error.", fname, line);
                 return -EIO;
         }
@@ -1823,6 +1990,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
         }
 
         if (isempty(action)) {
+                *invalid_config = true;
                 log_error("[%s:%u] Command too short '%s'.", fname, line, action);
                 return -EINVAL;
         }
@@ -1833,6 +2001,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
                 else if (action[pos] == '+' && !force)
                         force = true;
                 else {
+                        *invalid_config = true;
                         log_error("[%s:%u] Unknown modifiers in command '%s'",
                                   fname, line, action);
                         return -EINVAL;
@@ -1849,9 +2018,12 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
         i.force = force;
 
         r = specifier_printf(path, specifier_table, NULL, &i.path);
+        if (r == -ENXIO)
+                return log_unresolvable_specifier(fname, line);
         if (r < 0) {
-                log_error("[%s:%u] Failed to replace specifiers: %s", fname, line, path);
-                return r;
+                if (IN_SET(r, -EINVAL, -EBADSLT))
+                        *invalid_config = true;
+                return log_error_errno(r, "[%s:%u] Failed to replace specifiers: %s", fname, line, path);
         }
 
         switch (i.type) {
@@ -1889,6 +2061,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
 
         case WRITE_FILE:
                 if (!i.argument) {
+                        *invalid_config = true;
                         log_error("[%s:%u] Write file requires argument.", fname, line);
                         return -EBADMSG;
                 }
@@ -1900,6 +2073,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
                         if (!i.argument)
                                 return log_oom();
                 } else if (!path_is_absolute(i.argument)) {
+                        *invalid_config = true;
                         log_error("[%s:%u] Source path is not absolute.", fname, line);
                         return -EBADMSG;
                 }
@@ -1912,11 +2086,13 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
                 unsigned major, minor;
 
                 if (!i.argument) {
+                        *invalid_config = true;
                         log_error("[%s:%u] Device file requires argument.", fname, line);
                         return -EBADMSG;
                 }
 
                 if (sscanf(i.argument, "%u:%u", &major, &minor) != 2) {
+                        *invalid_config = true;
                         log_error("[%s:%u] Can't parse device file major/minor '%s'.", fname, line, i.argument);
                         return -EBADMSG;
                 }
@@ -1928,6 +2104,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
         case SET_XATTR:
         case RECURSIVE_SET_XATTR:
                 if (!i.argument) {
+                        *invalid_config = true;
                         log_error("[%s:%u] Set extended attribute requires argument.", fname, line);
                         return -EBADMSG;
                 }
@@ -1939,6 +2116,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
         case SET_ACL:
         case RECURSIVE_SET_ACL:
                 if (!i.argument) {
+                        *invalid_config = true;
                         log_error("[%s:%u] Set ACLs requires argument.", fname, line);
                         return -EBADMSG;
                 }
@@ -1950,21 +2128,26 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
         case SET_ATTRIBUTE:
         case RECURSIVE_SET_ATTRIBUTE:
                 if (!i.argument) {
+                        *invalid_config = true;
                         log_error("[%s:%u] Set file attribute requires argument.", fname, line);
                         return -EBADMSG;
                 }
                 r = parse_attribute_from_arg(&i);
+                if (IN_SET(r, -EINVAL, -EBADSLT))
+                        *invalid_config = true;
                 if (r < 0)
                         return r;
                 break;
 
         default:
                 log_error("[%s:%u] Unknown command type '%c'.", fname, line, (char) i.type);
+                *invalid_config = true;
                 return -EBADMSG;
         }
 
         if (!path_is_absolute(i.path)) {
                 log_error("[%s:%u] Path '%s' not absolute.", fname, line, i.path);
+                *invalid_config = true;
                 return -EBADMSG;
         }
 
@@ -1973,6 +2156,16 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
         if (!should_include_path(i.path))
                 return 0;
 
+        r = specifier_expansion_from_arg(&i);
+        if (r == -ENXIO)
+                return log_unresolvable_specifier(fname, line);
+        if (r < 0) {
+                if (IN_SET(r, -EINVAL, -EBADSLT))
+                        *invalid_config = true;
+                return log_error_errno(r, "[%s:%u] Failed to substitute specifiers in argument: %m",
+                                       fname, line);
+        }
+
         if (arg_root) {
                 char *p;
 
@@ -1989,8 +2182,8 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
 
                 r = get_user_creds(&u, &i.uid, NULL, NULL, NULL);
                 if (r < 0) {
-                        log_error("[%s:%u] Unknown user '%s'.", fname, line, user);
-                        return r;
+                        *invalid_config = true;
+                        return log_error_errno(r, "[%s:%u] Unknown user '%s'.", fname, line, user);
                 }
 
                 i.uid_set = true;
@@ -2001,6 +2194,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
 
                 r = get_group_creds(&g, &i.gid);
                 if (r < 0) {
+                        *invalid_config = true;
                         log_error("[%s:%u] Unknown group '%s'.", fname, line, group);
                         return r;
                 }
@@ -2018,6 +2212,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
                 }
 
                 if (parse_mode(mm, &m) < 0) {
+                        *invalid_config = true;
                         log_error("[%s:%u] Invalid mode '%s'.", fname, line, mode);
                         return -EBADMSG;
                 }
@@ -2036,6 +2231,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
                 }
 
                 if (parse_sec(a, &i.age) < 0) {
+                        *invalid_config = true;
                         log_error("[%s:%u] Invalid age '%s'.", fname, line, age);
                         return -EBADMSG;
                 }
@@ -2051,8 +2247,8 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
 
                 for (n = 0; n < existing->count; n++) {
                         if (!item_compatible(existing->items + n, &i)) {
-                                log_warning("[%s:%u] Duplicate line for path \"%s\", ignoring.",
-                                            fname, line, i.path);
+                                log_notice("[%s:%u] Duplicate line for path \"%s\", ignoring.",
+                                           fname, line, i.path);
                                 return 0;
                         }
                 }
@@ -2079,6 +2275,7 @@ static void help(void) {
         printf("%s [OPTIONS...] [CONFIGURATION FILE...]\n\n"
                "Creates, deletes and cleans up volatile and temporary files and directories.\n\n"
                "  -h --help                 Show this help\n"
+               "     --user                 Execute user configuration\n"
                "     --version              Show package version\n"
                "     --create               Create marked files/directories\n"
                "     --clean                Clean up marked directories\n"
@@ -2086,14 +2283,15 @@ static void help(void) {
                "     --boot                 Execute actions only safe at boot\n"
                "     --prefix=PATH          Only apply rules with the specified prefix\n"
                "     --exclude-prefix=PATH  Ignore rules with the specified prefix\n"
-               "     --root=PATH            Operate on an alternate filesystem root\n",
-               program_invocation_short_name);
+               "     --root=PATH            Operate on an alternate filesystem root\n"
+               program_invocation_short_name);
 }
 
 static int parse_argv(int argc, char *argv[]) {
 
         enum {
                 ARG_VERSION = 0x100,
+                ARG_USER,
                 ARG_CREATE,
                 ARG_CLEAN,
                 ARG_REMOVE,
@@ -2105,6 +2303,7 @@ static int parse_argv(int argc, char *argv[]) {
 
         static const struct option options[] = {
                 { "help",           no_argument,         NULL, 'h'                },
+                { "user",           no_argument,         NULL, ARG_USER           },
                 { "version",        no_argument,         NULL, ARG_VERSION        },
                 { "create",         no_argument,         NULL, ARG_CREATE         },
                 { "clean",          no_argument,         NULL, ARG_CLEAN          },
@@ -2132,6 +2331,10 @@ static int parse_argv(int argc, char *argv[]) {
                 case ARG_VERSION:
                         return version();
 
+                case ARG_USER:
+                        arg_user = true;
+                        break;
+
                 case ARG_CREATE:
                         arg_create = true;
                         break;
@@ -2179,7 +2382,7 @@ static int parse_argv(int argc, char *argv[]) {
         return 1;
 }
 
-static int read_config_file(const char *fn, bool ignore_enoent) {
+static int read_config_file(const char **config_dirs, const char *fn, bool ignore_enoent, bool *invalid_config) {
         _cleanup_fclose_ FILE *_f = NULL;
         FILE *f;
         char line[LINE_MAX];
@@ -2195,7 +2398,7 @@ static int read_config_file(const char *fn, bool ignore_enoent) {
                 fn = "<stdin>";
                 f = stdin;
         } else {
-                r = search_and_fopen_nulstr(fn, "re", arg_root, conf_file_dirs, &_f);
+                r = search_and_fopen(fn, "re", arg_root, config_dirs, &_f);
                 if (r < 0) {
                         if (ignore_enoent && r == -ENOENT) {
                                 log_debug_errno(r, "Failed to open \"%s\", ignoring: %m", fn);
@@ -2211,6 +2414,7 @@ static int read_config_file(const char *fn, bool ignore_enoent) {
         FOREACH_LINE(line, f, break) {
                 char *l;
                 int k;
+                bool invalid_line = false;
 
                 v++;
 
@@ -2218,9 +2422,15 @@ static int read_config_file(const char *fn, bool ignore_enoent) {
                 if (IN_SET(*l, 0, '#'))
                         continue;
 
-                k = parse_line(fn, v, l);
-                if (k < 0 && r == 0)
-                        r = k;
+                k = parse_line(fn, v, l, &invalid_line);
+                if (k < 0) {
+                        if (invalid_line)
+                                /* Allow reporting with a special code if the caller requested this */
+                                *invalid_config = true;
+                        else if (r == 0)
+                                /* The first error becomes our return value */
+                                r = k;
+                }
         }
 
         /* we have to determine age parameter for each entry of type X */
@@ -2264,6 +2474,9 @@ int main(int argc, char *argv[]) {
         int r, k;
         ItemArray *a;
         Iterator iterator;
+        _cleanup_strv_free_ char **config_dirs = NULL;
+        bool invalid_config = false;
+        char **f;
 
         r = parse_argv(argc, argv);
         if (r <= 0)
@@ -2287,27 +2500,48 @@ int main(int argc, char *argv[]) {
 
         r = 0;
 
+        if (arg_user) {
+                r = user_config_paths(&config_dirs);
+                if (r < 0) {
+                        log_error_errno(r, "Failed to initialize configuration directory list: %m");
+                        goto finish;
+                }
+        } else {
+                config_dirs = strv_split_nulstr(CONF_PATHS_NULSTR("tmpfiles.d"));
+                if (!config_dirs) {
+                        r = log_oom();
+                        goto finish;
+                }
+        }
+
+        {
+                _cleanup_free_ char *t = NULL;
+
+                t = strv_join(config_dirs, "\n\t");
+                if (t)
+                        log_debug("Looking for configuration files in (higher priority first:\n\t%s", t);
+        }
+
         if (optind < argc) {
                 int j;
 
                 for (j = optind; j < argc; j++) {
-                        k = read_config_file(argv[j], false);
+                        k = read_config_file((const char**) config_dirs, argv[j], false, &invalid_config);
                         if (k < 0 && r == 0)
                                 r = k;
                 }
 
         } else {
                 _cleanup_strv_free_ char **files = NULL;
-                char **f;
 
-                r = conf_files_list_nulstr(&files, ".conf", arg_root, 0, conf_file_dirs);
+                r = conf_files_list_strv(&files, ".conf", arg_root, 0, (const char* const*) config_dirs);
                 if (r < 0) {
                         log_error_errno(r, "Failed to enumerate tmpfiles.d files: %m");
                         goto finish;
                 }
 
                 STRV_FOREACH(f, files) {
-                        k = read_config_file(*f, true);
+                        k = read_config_file((const char**) config_dirs, *f, true, &invalid_config);
                         if (k < 0 && r == 0)
                                 r = k;
                 }
@@ -2330,14 +2564,8 @@ int main(int argc, char *argv[]) {
         }
 
 finish:
-        while ((a = ordered_hashmap_steal_first(items)))
-                item_array_free(a);
-
-        while ((a = ordered_hashmap_steal_first(globs)))
-                item_array_free(a);
-
-        ordered_hashmap_free(items);
-        ordered_hashmap_free(globs);
+        ordered_hashmap_free_with_destructor(items, item_array_free);
+        ordered_hashmap_free_with_destructor(globs, item_array_free);
 
         free(arg_include_prefixes);
         free(arg_exclude_prefixes);
@@ -2347,5 +2575,10 @@ finish:
 
         mac_selinux_finish();
 
-        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+        if (r < 0)
+                return EXIT_FAILURE;
+        else if (invalid_config)
+                return EX_DATAERR;
+        else
+                return EXIT_SUCCESS;
 }
index 495ae46..1553655 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -310,7 +311,7 @@ static int parse_password(const char *filename, char **wall) {
         r = config_parse(NULL, filename, NULL,
                          NULL,
                          config_item_table_lookup, items,
-                         true, false, true, NULL);
+                         CONFIG_PARSE_RELAXED|CONFIG_PARSE_WARN, NULL);
         if (r < 0)
                 return r;
 
@@ -720,7 +721,7 @@ static int ask_on_this_console(const char *tty, pid_t *pid, int argc, char *argv
 
                 for (ac = 0; ac < argc; ac++) {
                         if (streq(argv[ac], "--console")) {
-                                argv[ac] = strjoina("--console=", tty, NULL);
+                                argv[ac] = strjoina("--console=", tty);
                                 break;
                         }
                 }
index 1dc62b6..7e3654c 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * ata_id - reads product/serial number from ATA drives
  *
index b9cf3bd..9644861 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * cdrom_id - optical drive and media information prober
  *
index 52229d8..3e278bd 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * Collect variables across events.
  *
@@ -93,7 +94,7 @@ static int prepare(char *dir, char *filename)
         if (r < 0 && errno != EEXIST)
                 return -errno;
 
-        snprintf(buf, sizeof buf, "%s/%s", dir, filename);
+        xsprintf(buf, "%s/%s", dir, filename);
 
         fd = open(buf, O_RDWR|O_CREAT|O_CLOEXEC, S_IRUSR|S_IWUSR);
         if (fd < 0)
@@ -134,7 +135,8 @@ static int prepare(char *dir, char *filename)
 static int checkout(int fd)
 {
         int len;
-        char *buf, *ptr, *word = NULL;
+        _cleanup_free_ char *buf = NULL;
+        char *ptr, *word = NULL;
         struct _mate *him;
 
  restart:
@@ -154,26 +156,22 @@ static int checkout(int fd)
                                 bufsize = bufsize << 1;
                                 if (debug)
                                         fprintf(stderr, "ID overflow, restarting with size %zu\n", bufsize);
-                                free(buf);
                                 lseek(fd, 0, SEEK_SET);
                                 goto restart;
                         }
                         if (ptr) {
                                 *ptr = '\0';
                                 ptr++;
-                                if (!strlen(word))
+                                if (isempty(word))
                                         continue;
 
                                 if (debug)
                                         fprintf(stderr, "Found word %s\n", word);
                                 him = malloc(sizeof (struct _mate));
-                                if (!him) {
-                                        free(buf);
+                                if (!him)
                                         return log_oom();
-                                }
                                 him->name = strdup(word);
                                 if (!him->name) {
-                                        free(buf);
                                         free(him);
                                         return log_oom();
                                 }
@@ -187,12 +185,9 @@ static int checkout(int fd)
 
                 if (!ptr)
                         ptr = word;
-                if (!ptr)
-                        break;
                 ptr -= len;
         }
 
-        free(buf);
         return 0;
 }
 
index 5724e4e..eb97744 100755 (executable)
@@ -1,5 +1,10 @@
 #!/bin/sh -eu
 awk '   BEGIN {
+                print "%{\n\
+#if __GNUC__ >= 7\n\
+_Pragma(\"GCC diagnostic ignored \\\"-Wimplicit-fallthrough\\\"\")\n\
+#endif\n\
+%}"
                 print "struct key_name { const char* name; unsigned short id; };"
                 print "%null-strings"
                 print "%%"
index dd24b7e..d01cf8f 100644 (file)
@@ -1,3 +1,20 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
+# Copyright 2017 Zbigniew Jędrzejewski-Szmek
+#
+# 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.
+#
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
 udevadm_sources = files('''
         udevadm.c
         udevadm-info.c
index 462fab7..1d692f1 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * Copyright (C) 2010 - Maxim Levitsky
  *
index 68e4954..39841f9 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 #pragma once
 
 /*
index 89bceaa..eb74fe1 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * Copyright (C) 2010 - Maxim Levitsky
  *
index a5b87cf..3ed8a51 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
  This file is part of systemd.
 
index 909b56b..5681472 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index 52bb477..85f0a06 100644 (file)
@@ -1,4 +1,7 @@
 %{
+#if __GNUC__ >= 7
+_Pragma("GCC diagnostic ignored \"-Wimplicit-fallthrough\"")
+#endif
 #include <stddef.h>
 #include "conf-parser.h"
 #include "network-internal.h"
index a5f3b1a..89891f9 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
  This file is part of systemd.
 
@@ -175,7 +176,7 @@ static int load_link(link_config_ctx *ctx, const char *filename) {
         r = config_parse(NULL, filename, file,
                          "Match\0Link\0Ethernet\0",
                          config_item_perf_lookup, link_config_gperf_lookup,
-                         false, false, true, link);
+                         CONFIG_PARSE_WARN, link);
         if (r < 0)
                 return r;
         else
@@ -327,7 +328,7 @@ static bool should_rename(struct udev_device *device, bool respect_predictable)
                 /* the kernel claims to have given a predictable name */
                 if (respect_predictable)
                         return false;
-                /* fall through */
+                _fallthrough_;
         case NET_NAME_ENUM:
         default:
                 /* the name is known to be bad, or of an unknown type */
index ff91a65..a413251 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
index a27a84a..8b759a7 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 #pragma once
 
 /*
index 0abbc51..ab4ee7b 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * Copyright (C) IBM Corp. 2003
  * Copyright (C) SUSE Linux Products GmbH, 2006
index 5c2e1c2..9a33f6a 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 #pragma once
 
 /*
index b56a541..bf6b28e 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * Copyright (C) IBM Corp. 2003
  *
@@ -371,7 +372,7 @@ resend:
         switch (retval) {
                 case SG_ERR_CAT_NOTSUPPORTED:
                         buf[1] = 0;
-                        /* Fallthrough */
+                        _fallthrough_;
                 case SG_ERR_CAT_CLEAN:
                 case SG_ERR_CAT_RECOVERED:
                         retval = 0;
index 4487e82..6ff244e 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * probe disks for filesystems and partitions
  *
index 4d59cc8..9e0f1e0 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 7e76cad..dbfe024 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 60f760e..b13fdb1 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * expose input properties via udev
  *
index e316bb9..0044280 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 9665f67..2530fdf 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * load kernel modules
  *
 #include <stdio.h>
 #include <stdlib.h>
 
+#include "module-util.h"
 #include "string-util.h"
 #include "udev.h"
 
 static struct kmod_ctx *ctx = NULL;
 
 static int load_module(struct udev *udev, const char *alias) {
-        struct kmod_list *list = NULL;
+        _cleanup_(kmod_module_unref_listp) struct kmod_list *list = NULL;
         struct kmod_list *l;
         int err;
 
@@ -42,7 +44,9 @@ static int load_module(struct udev *udev, const char *alias) {
                 log_debug("No module matches '%s'", alias);
 
         kmod_list_foreach(l, list) {
-                struct kmod_module *mod = kmod_module_get_module(l);
+                _cleanup_(kmod_module_unrefp) struct kmod_module *mod = NULL;
+
+                mod = kmod_module_get_module(l);
 
                 err = kmod_module_probe_insert_module(mod, KMOD_PROBE_APPLY_BLACKLIST, NULL, NULL, NULL, NULL);
                 if (err == KMOD_PROBE_APPLY_BLACKLIST)
@@ -51,11 +55,8 @@ static int load_module(struct udev *udev, const char *alias) {
                         log_debug("Inserted '%s'", kmod_module_get_name(mod));
                 else
                         log_debug("Failed to insert '%s'", kmod_module_get_name(mod));
-
-                kmod_module_unref(mod);
         }
 
-        kmod_module_unref_list(list);
         return err;
 }
 
index bc408e8..6e3423c 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 8e47775..40158e0 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -51,10 +52,8 @@ static int builtin_net_setup_link(struct udev_device *dev, int argc, char **argv
         }
 
         r = link_config_apply(ctx, link, dev, &name);
-        if (r < 0) {
-                log_error_errno(r, "Could not apply link config to %s: %m", udev_device_get_sysname(dev));
-                return EXIT_FAILURE;
-        }
+        if (r < 0)
+                log_warning_errno(r, "Could not apply link config to %s, ignoring: %m", udev_device_get_sysname(dev));
 
         udev_builtin_add_property(dev, test, "ID_NET_LINK_FILE", link->filename);
 
index f5d7c23..9ce2079 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * compose persistent device path
  *
 
 #include "alloc-util.h"
 #include "dirent-util.h"
+#include "fd-util.h"
 #include "string-util.h"
+#include "sysexits.h"
 #include "udev.h"
+#include "udev-util.h"
 
 _printf_(2,3)
-static int path_prepend(char **path, const char *fmt, ...) {
+static void path_prepend(char **path, const char *fmt, ...) {
         va_list va;
-        char *pre;
-        int err = 0;
+        _cleanup_free_ char *pre = NULL;
+        int r;
 
         va_start(va, fmt);
-        err = vasprintf(&pre, fmt, va);
+        r = vasprintf(&pre, fmt, va);
         va_end(va);
-        if (err < 0)
-                goto out;
+        if (r < 0) {
+                log_oom();
+                exit(EX_OSERR);
+        }
 
-        if (*path != NULL) {
+        if (*path) {
                 char *new;
 
-                err = asprintf(&new, "%s-%s", pre, *path);
-                free(pre);
-                if (err < 0)
-                        goto out;
-                free(*path);
-                *path = new;
+                new = strjoin(pre, "-", *path);
+                if (!new) {
+                        log_oom();
+                        exit(EX_OSERR);
+                }
+
+                free_and_replace(*path, new);
         } else {
                 *path = pre;
+                pre = NULL;
         }
-out:
-        return err;
 }
 
 /*
 ** Linux only supports 32 bit luns.
 ** See drivers/scsi/scsi_scan.c::scsilun_to_int() for more details.
 */
-static int format_lun_number(struct udev_device *dev, char **path) {
+static void format_lun_number(struct udev_device *dev, char **path) {
         unsigned long lun = strtoul(udev_device_get_sysnum(dev), NULL, 10);
 
-        /* address method 0, peripheral device addressing with bus id of zero */
         if (lun < 256)
-                return path_prepend(path, "lun-%lu", lun);
-        /* handle all other lun addressing methods by using a variant of the original lun format */
-        return path_prepend(path, "lun-0x%04lx%04lx00000000", lun & 0xffff, (lun >> 16) & 0xffff);
+                /* address method 0, peripheral device addressing with bus id of zero */
+                path_prepend(path, "lun-%lu", lun);
+        else
+                /* handle all other lun addressing methods by using a variant of the original lun format */
+                path_prepend(path, "lun-0x%04lx%04lx00000000", lun & 0xffff, (lun >> 16) & 0xffff);
 }
 
 static struct udev_device *skip_subsystem(struct udev_device *dev, const char *subsys) {
@@ -82,167 +89,149 @@ static struct udev_device *skip_subsystem(struct udev_device *dev, const char *s
         assert(dev);
         assert(subsys);
 
-        while (parent != NULL) {
+        while (parent) {
                 const char *subsystem;
 
                 subsystem = udev_device_get_subsystem(parent);
-                if (subsystem == NULL || !streq(subsystem, subsys))
+                if (!streq_ptr(subsystem, subsys))
                         break;
+
                 dev = parent;
                 parent = udev_device_get_parent(parent);
         }
+
         return dev;
 }
 
 static struct udev_device *handle_scsi_fibre_channel(struct udev_device *parent, char **path) {
-        struct udev *udev  = udev_device_get_udev(parent);
+        struct udev *udev;
         struct udev_device *targetdev;
-        struct udev_device *fcdev = NULL;
+        _cleanup_udev_device_unref_ struct udev_device *fcdev = NULL;
         const char *port;
-        char *lun = NULL;
+        _cleanup_free_ char *lun = NULL;
 
         assert(parent);
         assert(path);
 
+        udev = udev_device_get_udev(parent);
+
         targetdev = udev_device_get_parent_with_subsystem_devtype(parent, "scsi", "scsi_target");
-        if (targetdev == NULL)
+        if (!targetdev)
                 return NULL;
 
         fcdev = udev_device_new_from_subsystem_sysname(udev, "fc_transport", udev_device_get_sysname(targetdev));
-        if (fcdev == NULL)
+        if (!fcdev)
                 return NULL;
+
         port = udev_device_get_sysattr_value(fcdev, "port_name");
-        if (port == NULL) {
-                parent = NULL;
-                goto out;
-        }
+        if (!port)
+                return NULL;
 
         format_lun_number(parent, &lun);
         path_prepend(path, "fc-%s-%s", port, lun);
-        free(lun);
-out:
-        udev_device_unref(fcdev);
         return parent;
 }
 
 static struct udev_device *handle_scsi_sas_wide_port(struct udev_device *parent, char **path) {
-        struct udev *udev  = udev_device_get_udev(parent);
-        struct udev_device *targetdev;
-        struct udev_device *target_parent;
-        struct udev_device *sasdev;
+        struct udev *udev;
+        struct udev_device *targetdev, *target_parent;
+        _cleanup_udev_device_unref_ struct udev_device *sasdev = NULL;
         const char *sas_address;
-        char *lun = NULL;
+        _cleanup_free_ char *lun = NULL;
 
         assert(parent);
         assert(path);
 
+        udev = udev_device_get_udev(parent);
+
         targetdev = udev_device_get_parent_with_subsystem_devtype(parent, "scsi", "scsi_target");
-        if (targetdev == NULL)
+        if (!targetdev)
                 return NULL;
 
         target_parent = udev_device_get_parent(targetdev);
-        if (target_parent == NULL)
+        if (!target_parent)
                 return NULL;
 
         sasdev = udev_device_new_from_subsystem_sysname(udev, "sas_device",
-                                udev_device_get_sysname(target_parent));
-        if (sasdev == NULL)
+                                                        udev_device_get_sysname(target_parent));
+        if (!sasdev)
                 return NULL;
 
         sas_address = udev_device_get_sysattr_value(sasdev, "sas_address");
-        if (sas_address == NULL) {
-                parent = NULL;
-                goto out;
-        }
+        if (!sas_address)
+                return NULL;
 
         format_lun_number(parent, &lun);
         path_prepend(path, "sas-%s-%s", sas_address, lun);
-        free(lun);
-out:
-        udev_device_unref(sasdev);
         return parent;
 }
 
 static struct udev_device *handle_scsi_sas(struct udev_device *parent, char **path)
 {
-        struct udev *udev  = udev_device_get_udev(parent);
-        struct udev_device *targetdev;
-        struct udev_device *target_parent;
-        struct udev_device *port;
-        struct udev_device *expander;
-        struct udev_device *target_sasdev = NULL;
-        struct udev_device *expander_sasdev = NULL;
-        struct udev_device *port_sasdev = NULL;
+        struct udev *udev;
+        struct udev_device *targetdev, *target_parent, *port, *expander;
+        _cleanup_udev_device_unref_ struct udev_device
+                *target_sasdev = NULL, *expander_sasdev = NULL, *port_sasdev = NULL;
         const char *sas_address = NULL;
         const char *phy_id;
         const char *phy_count;
-        char *lun = NULL;
+        _cleanup_free_ char *lun = NULL;
 
         assert(parent);
         assert(path);
 
+        udev = udev_device_get_udev(parent);
+
         targetdev = udev_device_get_parent_with_subsystem_devtype(parent, "scsi", "scsi_target");
-        if (targetdev == NULL)
+        if (!targetdev)
                 return NULL;
 
         target_parent = udev_device_get_parent(targetdev);
-        if (target_parent == NULL)
+        if (!target_parent)
                 return NULL;
 
         /* Get sas device */
-        target_sasdev = udev_device_new_from_subsystem_sysname(udev,
-                          "sas_device", udev_device_get_sysname(target_parent));
-        if (target_sasdev == NULL)
+        target_sasdev = udev_device_new_from_subsystem_sysname(
+                        udev, "sas_device", udev_device_get_sysname(target_parent));
+        if (!target_sasdev)
                 return NULL;
 
         /* The next parent is sas port */
         port = udev_device_get_parent(target_parent);
-        if (port == NULL) {
-                parent = NULL;
-                goto out;
-        }
+        if (!port)
+                return NULL;
 
         /* Get port device */
-        port_sasdev = udev_device_new_from_subsystem_sysname(udev,
-                          "sas_port", udev_device_get_sysname(port));
+        port_sasdev = udev_device_new_from_subsystem_sysname(
+                udev, "sas_port", udev_device_get_sysname(port));
 
         phy_count = udev_device_get_sysattr_value(port_sasdev, "num_phys");
-        if (phy_count == NULL) {
-               parent = NULL;
-               goto out;
-        }
+        if (!phy_count)
+                return NULL;
 
         /* Check if we are simple disk */
-        if (strncmp(phy_count, "1", 2) != 0) {
-                 parent = handle_scsi_sas_wide_port(parent, path);
-                 goto out;
-        }
+        if (strncmp(phy_count, "1", 2) != 0)
+                return handle_scsi_sas_wide_port(parent, path);
 
         /* Get connected phy */
         phy_id = udev_device_get_sysattr_value(target_sasdev, "phy_identifier");
-        if (phy_id == NULL) {
-                parent = NULL;
-                goto out;
-        }
+        if (!phy_id)
+                return NULL;
 
         /* The port's parent is either hba or expander */
         expander = udev_device_get_parent(port);
-        if (expander == NULL) {
-                parent = NULL;
-                goto out;
-        }
+        if (!expander)
+                return NULL;
 
         /* Get expander device */
-        expander_sasdev = udev_device_new_from_subsystem_sysname(udev,
-                          "sas_device", udev_device_get_sysname(expander));
-        if (expander_sasdev != NULL) {
+        expander_sasdev = udev_device_new_from_subsystem_sysname(
+                        udev, "sas_device", udev_device_get_sysname(expander));
+        if (expander_sasdev) {
                  /* Get expander's address */
                  sas_address = udev_device_get_sysattr_value(expander_sasdev,
                                                     "sas_address");
-                 if (sas_address == NULL) {
-                        parent = NULL;
-                        goto out;
-                 }
+                 if (!sas_address)
+                         return NULL;
         }
 
         format_lun_number(parent, &lun);
@@ -251,33 +240,27 @@ static struct udev_device *handle_scsi_sas(struct udev_device *parent, char **pa
         else
                  path_prepend(path, "sas-phy%s-%s", phy_id, lun);
 
-        free(lun);
-out:
-        udev_device_unref(target_sasdev);
-        udev_device_unref(expander_sasdev);
-        udev_device_unref(port_sasdev);
         return parent;
 }
 
 static struct udev_device *handle_scsi_iscsi(struct udev_device *parent, char **path) {
-        struct udev *udev  = udev_device_get_udev(parent);
+        struct udev *udev;
         struct udev_device *transportdev;
-        struct udev_device *sessiondev = NULL;
-        const char *target;
-        char *connname;
-        struct udev_device *conndev = NULL;
-        const char *addr;
-        const char *port;
-        char *lun = NULL;
+        _cleanup_udev_device_unref_ struct udev_device
+                *sessiondev = NULL, *conndev = NULL;
+        const char *target, *connname, *addr, *port;
+        _cleanup_free_ char *lun = NULL;
 
         assert(parent);
         assert(path);
 
+        udev = udev_device_get_udev(parent);
+
         /* find iscsi session */
         transportdev = parent;
         for (;;) {
                 transportdev = udev_device_get_parent(transportdev);
-                if (transportdev == NULL)
+                if (!transportdev)
                         return NULL;
                 if (startswith(udev_device_get_sysname(transportdev), "session"))
                         break;
@@ -285,50 +268,39 @@ static struct udev_device *handle_scsi_iscsi(struct udev_device *parent, char **
 
         /* find iscsi session device */
         sessiondev = udev_device_new_from_subsystem_sysname(udev, "iscsi_session", udev_device_get_sysname(transportdev));
-        if (sessiondev == NULL)
+        if (!sessiondev)
                 return NULL;
+
         target = udev_device_get_sysattr_value(sessiondev, "targetname");
-        if (target == NULL) {
-                parent = NULL;
-                goto out;
-        }
+        if (!target)
+                return NULL;
 
-        if (asprintf(&connname, "connection%s:0", udev_device_get_sysnum(transportdev)) < 0) {
-                parent = NULL;
-                goto out;
-        }
+        connname = strjoina("connection", udev_device_get_sysnum(transportdev), ":0");
         conndev = udev_device_new_from_subsystem_sysname(udev, "iscsi_connection", connname);
-        free(connname);
-        if (conndev == NULL) {
-                parent = NULL;
-                goto out;
-        }
+        if (!conndev)
+                return NULL;
+
         addr = udev_device_get_sysattr_value(conndev, "persistent_address");
         port = udev_device_get_sysattr_value(conndev, "persistent_port");
-        if (addr == NULL || port == NULL) {
-                parent = NULL;
-                goto out;
-        }
+        if (!addr || !port)
+                return NULL;
 
         format_lun_number(parent, &lun);
         path_prepend(path, "ip-%s:%s-iscsi-%s-%s", addr, port, target, lun);
-        free(lun);
-out:
-        udev_device_unref(sessiondev);
-        udev_device_unref(conndev);
         return parent;
 }
 
 static struct udev_device *handle_scsi_ata(struct udev_device *parent, char **path) {
-        struct udev *udev  = udev_device_get_udev(parent);
-        struct udev_device *targetdev;
-        struct udev_device *target_parent;
-        struct udev_device *atadev;
+        struct udev *udev;
+        struct udev_device *targetdev, *target_parent;
+        _cleanup_udev_device_unref_ struct udev_device *atadev = NULL;
         const char *port_no;
 
         assert(parent);
         assert(path);
 
+        udev = udev_device_get_udev(parent);
+
         targetdev = udev_device_get_parent_with_subsystem_devtype(parent, "scsi", "scsi_host");
         if (!targetdev)
                 return NULL;
@@ -342,31 +314,26 @@ static struct udev_device *handle_scsi_ata(struct udev_device *parent, char **pa
                 return NULL;
 
         port_no = udev_device_get_sysattr_value(atadev, "port_no");
-        if (!port_no) {
-               parent = NULL;
-               goto out;
-        }
+        if (!port_no)
+                return NULL;
+
         path_prepend(path, "ata-%s", port_no);
-out:
-        udev_device_unref(atadev);
         return parent;
 }
 
 static struct udev_device *handle_scsi_default(struct udev_device *parent, char **path) {
         struct udev_device *hostdev;
         int host, bus, target, lun;
-        const char *name;
-        char *base;
-        char *pos;
-        DIR *dir;
+        const char *name, *base, *pos;
+        _cleanup_closedir_ DIR *dir = NULL;
         struct dirent *dent;
-        int basenum;
+        int basenum = -1;
 
         assert(parent);
         assert(path);
 
         hostdev = udev_device_get_parent_with_subsystem_devtype(parent, "scsi", "scsi_host");
-        if (hostdev == NULL)
+        if (!hostdev)
                 return NULL;
 
         name = udev_device_get_sysname(parent);
@@ -390,21 +357,17 @@ static struct udev_device *handle_scsi_default(struct udev_device *parent, char
          * this. Manual driver unbind/bind, parallel hotplug/unplug will
          * get into the way of this "I hope it works" logic.
          */
-        basenum = -1;
-        base = strdup(udev_device_get_syspath(hostdev));
-        if (base == NULL)
-                return NULL;
+
+        base = udev_device_get_syspath(hostdev);
         pos = strrchr(base, '/');
-        if (pos == NULL) {
-                parent = NULL;
-                goto out;
-        }
-        pos[0] = '\0';
+        if (!pos)
+                return NULL;
+
+        base = strndupa(base, pos - base);
         dir = opendir(base);
-        if (dir == NULL) {
-                parent = NULL;
-                goto out;
-        }
+        if (!dir)
+                return NULL;
+
         FOREACH_DIRENT_ALL(dent, dir, break) {
                 char *rest;
                 int i;
@@ -426,16 +389,11 @@ static struct udev_device *handle_scsi_default(struct udev_device *parent, char
                 if (basenum == -1 || i < basenum)
                         basenum = i;
         }
-        closedir(dir);
-        if (basenum == -1) {
-                parent = NULL;
-                goto out;
-        }
+        if (basenum == -1)
+                return hostdev;
         host -= basenum;
 
         path_prepend(path, "scsi-%u:%u:%u:%u", host, bus, target, lun);
-out:
-        free(base);
         return hostdev;
 }
 
@@ -443,7 +401,7 @@ static struct udev_device *handle_scsi_hyperv(struct udev_device *parent, char *
         struct udev_device *hostdev;
         struct udev_device *vmbusdev;
         const char *guid_str;
-        char *lun = NULL;
+        _cleanup_free_ char *lun = NULL;
         char guid[38];
         size_t i, k;
 
@@ -474,62 +432,49 @@ static struct udev_device *handle_scsi_hyperv(struct udev_device *parent, char *
 
         format_lun_number(parent, &lun);
         path_prepend(path, "vmbus-%s-%s", guid, lun);
-        free(lun);
         return parent;
 }
 
 static struct udev_device *handle_scsi(struct udev_device *parent, char **path, bool *supported_parent) {
-        const char *devtype;
-        const char *name;
-        const char *id;
+        const char *devtype, *id, *name;
 
         devtype = udev_device_get_devtype(parent);
-        if (devtype == NULL || !streq(devtype, "scsi_device"))
+        if (!streq_ptr(devtype, "scsi_device"))
                 return parent;
 
         /* firewire */
         id = udev_device_get_sysattr_value(parent, "ieee1394_id");
-        if (id != NULL) {
-                parent = skip_subsystem(parent, "scsi");
+        if (id) {
                 path_prepend(path, "ieee1394-0x%s", id);
                 *supported_parent = true;
-                goto out;
+                return skip_subsystem(parent, "scsi");
         }
 
         /* scsi sysfs does not have a "subsystem" for the transport */
         name = udev_device_get_syspath(parent);
 
-        if (strstr(name, "/rport-") != NULL) {
-                parent = handle_scsi_fibre_channel(parent, path);
+        if (strstr(name, "/rport-")) {
                 *supported_parent = true;
-                goto out;
+                return handle_scsi_fibre_channel(parent, path);
         }
 
-        if (strstr(name, "/end_device-") != NULL) {
-                parent = handle_scsi_sas(parent, path);
+        if (strstr(name, "/end_device-")) {
                 *supported_parent = true;
-                goto out;
+                return handle_scsi_sas(parent, path);
         }
 
-        if (strstr(name, "/session") != NULL) {
-                parent = handle_scsi_iscsi(parent, path);
+        if (strstr(name, "/session")) {
                 *supported_parent = true;
-                goto out;
+                return handle_scsi_iscsi(parent, path);
         }
 
-        if (strstr(name, "/ata") != NULL) {
-                parent = handle_scsi_ata(parent, path);
-                goto out;
-        }
+        if (strstr(name, "/ata"))
+                return handle_scsi_ata(parent, path);
 
-        if (strstr(name, "/vmbus_") != NULL) {
-                parent = handle_scsi_hyperv(parent, path);
-                goto out;
-        }
+        if (strstr(name, "/vmbus_"))
+                return handle_scsi_hyperv(parent, path);
 
-        parent = handle_scsi_default(parent, path);
-out:
-        return parent;
+        return handle_scsi_default(parent, path);
 }
 
 static struct udev_device *handle_cciss(struct udev_device *parent, char **path) {
@@ -541,44 +486,40 @@ static struct udev_device *handle_cciss(struct udev_device *parent, char **path)
                 return NULL;
 
         path_prepend(path, "cciss-disk%u", disk);
-        parent = skip_subsystem(parent, "cciss");
-        return parent;
+        return skip_subsystem(parent, "cciss");
 }
 
 static void handle_scsi_tape(struct udev_device *dev, char **path) {
         const char *name;
 
         /* must be the last device in the syspath */
-        if (*path != NULL)
+        if (*path)
                 return;
 
         name = udev_device_get_sysname(dev);
-        if (startswith(name, "nst") && strchr("lma", name[3]) != NULL)
+        if (startswith(name, "nst") && strchr("lma", name[3]))
                 path_prepend(path, "nst%c", name[3]);
-        else if (startswith(name, "st") && strchr("lma", name[2]) != NULL)
+        else if (startswith(name, "st") && strchr("lma", name[2]))
                 path_prepend(path, "st%c", name[2]);
 }
 
 static struct udev_device *handle_usb(struct udev_device *parent, char **path) {
-        const char *devtype;
-        const char *str;
-        const char *port;
+        const char *devtype, *str, *port;
 
         devtype = udev_device_get_devtype(parent);
-        if (devtype == NULL)
+        if (!devtype)
                 return parent;
-        if (!streq(devtype, "usb_interface") && !streq(devtype, "usb_device"))
+        if (!STR_IN_SET(devtype, "usb_interface", "usb_device"))
                 return parent;
 
         str = udev_device_get_sysname(parent);
         port = strchr(str, '-');
-        if (port == NULL)
+        if (!port)
                 return parent;
         port++;
 
-        parent = skip_subsystem(parent, "usb");
         path_prepend(path, "usb-0:%s", port);
-        return parent;
+        return skip_subsystem(parent, "usb");
 }
 
 static struct udev_device *handle_bcma(struct udev_device *parent, char **path) {
@@ -603,19 +544,17 @@ static struct udev_device *handle_ap(struct udev_device *parent, char **path) {
         type = udev_device_get_sysattr_value(parent, "type");
         func = udev_device_get_sysattr_value(parent, "ap_functions");
 
-        if (type != NULL && func != NULL) {
+        if (type && func)
                 path_prepend(path, "ap-%s-%s", type, func);
-                goto out;
-        }
-        path_prepend(path, "ap-%s", udev_device_get_sysname(parent));
-out:
-        parent = skip_subsystem(parent, "ap");
-        return parent;
+        else
+                path_prepend(path, "ap-%s", udev_device_get_sysname(parent));
+
+        return skip_subsystem(parent, "ap");
 }
 
 static int builtin_path_id(struct udev_device *dev, int argc, char *argv[], bool test) {
         struct udev_device *parent;
-        char *path = NULL;
+        _cleanup_free_ char *path = NULL;
         bool supported_transport = false;
         bool supported_parent = false;
 
@@ -623,11 +562,11 @@ static int builtin_path_id(struct udev_device *dev, int argc, char *argv[], bool
 
         /* walk up the chain of devices and compose path */
         parent = dev;
-        while (parent != NULL) {
+        while (parent) {
                 const char *subsys;
 
                 subsys = udev_device_get_subsystem(parent);
-                if (subsys == NULL) {
+                if (!subsys) {
                         ;
                 } else if (streq(subsys, "scsi_tape")) {
                         handle_scsi_tape(parent, &path);
@@ -705,13 +644,16 @@ static int builtin_path_id(struct udev_device *dev, int argc, char *argv[], bool
                         parent = udev_device_get_parent(parent);
         }
 
+        if (!path)
+                return EXIT_FAILURE;
+
         /*
          * Do not return devices with an unknown parent device type. They
          * might produce conflicting IDs if the parent does not provide a
          * unique and predictable name.
          */
         if (!supported_parent)
-                path = mfree(path);
+                return EXIT_FAILURE;
 
         /*
          * Do not return block devices without a well-known transport. Some
@@ -719,9 +661,9 @@ static int builtin_path_id(struct udev_device *dev, int argc, char *argv[], bool
          * and predictable name that way.
          */
         if (streq_ptr(udev_device_get_subsystem(dev), "block") && !supported_transport)
-                path = mfree(path);
+                return EXIT_FAILURE;
 
-        if (path != NULL) {
+        {
                 char tag[UTIL_NAME_SIZE];
                 size_t i;
                 const char *p;
@@ -753,10 +695,9 @@ static int builtin_path_id(struct udev_device *dev, int argc, char *argv[], bool
 
                 udev_builtin_add_property(dev, test, "ID_PATH", path);
                 udev_builtin_add_property(dev, test, "ID_PATH_TAG", tag);
-                free(path);
-                return EXIT_SUCCESS;
         }
-        return EXIT_FAILURE;
+
+        return EXIT_SUCCESS;
 }
 
 const struct udev_builtin udev_builtin_path_id = {
index d92a10e..edea242 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * manage device node user ACL
  *
index 3ce075f..6d22dfe 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * USB device properties and persistent device path
  *
index e4dccd0..db2b687 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 92e4f8d..7b81105 100644 (file)
@@ -1,4 +1,5 @@
-/*
+/* SPDX-License-Identifier: LGPL-2.1+
+ *
  * libudev - interface to udev device information
  *
  * Copyright (C) 2008 Kay Sievers <kay@vrfy.org>
index 4cadff7..8f7c28f 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * Copyright (C) 2003-2013 Kay Sievers <kay@vrfy.org>
  *
@@ -230,7 +231,7 @@ static size_t subst_format_var(struct udev_event *event, struct udev_device *dev
                         break;
                 devnode = udev_device_get_devnode(dev_parent);
                 if (devnode != NULL)
-                        l = strpcpy(&s, l, devnode + strlen("/dev/"));
+                        l = strpcpy(&s, l, devnode + STRLEN("/dev/"));
                 break;
         }
         case SUBST_DEVNODE:
@@ -241,7 +242,8 @@ static size_t subst_format_var(struct udev_event *event, struct udev_device *dev
                 if (event->name != NULL)
                         l = strpcpy(&s, l, event->name);
                 else if (udev_device_get_devnode(dev) != NULL)
-                        l = strpcpy(&s, l, udev_device_get_devnode(dev) + strlen("/dev/"));
+                        l = strpcpy(&s, l,
+                                    udev_device_get_devnode(dev) + STRLEN("/dev/"));
                 else
                         l = strpcpy(&s, l, udev_device_get_sysname(dev));
                 break;
@@ -251,9 +253,12 @@ static size_t subst_format_var(struct udev_event *event, struct udev_device *dev
                 list_entry = udev_device_get_devlinks_list_entry(dev);
                 if (list_entry == NULL)
                         break;
-                l = strpcpy(&s, l, udev_list_entry_get_name(list_entry) + strlen("/dev/"));
+                l = strpcpy(&s, l,
+                            udev_list_entry_get_name(list_entry) + STRLEN("/dev/"));
                 udev_list_entry_foreach(list_entry, udev_list_entry_get_next(list_entry))
-                        l = strpcpyl(&s, l, " ", udev_list_entry_get_name(list_entry) + strlen("/dev/"), NULL);
+                        l = strpcpyl(&s, l, " ",
+                                     udev_list_entry_get_name(list_entry) + STRLEN("/dev/"),
+                                     NULL);
                 break;
         }
         case SUBST_ROOT:
index 01e56ca..bb84588 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * Copyright (C) 2003-2013 Kay Sievers <kay@vrfy.org>
  *
@@ -24,6 +25,7 @@
 #include <sys/stat.h>
 #include <unistd.h>
 
+#include "device-nodes.h"
 #include "dirent-util.h"
 #include "format-util.h"
 #include "fs-util.h"
@@ -185,7 +187,7 @@ static void link_update(struct udev_device *dev, const char *slink, bool add) {
         const char *target;
         char buf[UTIL_PATH_SIZE];
 
-        util_path_encode(slink + strlen("/dev"), name_enc, sizeof(name_enc));
+        util_path_encode(slink + STRLEN("/dev"), name_enc, sizeof(name_enc));
         strscpyl(dirname, sizeof(dirname), "/run/udev/links/", name_enc, NULL);
         strscpyl(filename, sizeof(filename), dirname, "/", udev_device_get_id_filename(dev), NULL);
 
@@ -336,7 +338,7 @@ out:
 void udev_node_add(struct udev_device *dev, bool apply,
                    mode_t mode, uid_t uid, gid_t gid,
                    struct udev_list *seclabel_list) {
-        char filename[sizeof("/dev/block/:") + 2*DECIMAL_STR_MAX(unsigned)];
+        char filename[DEV_NUM_PATH_MAX];
         struct udev_list_entry *list_entry;
 
         log_debug("handling device node '%s', devnum=%s, mode=%#o, uid="UID_FMT", gid="GID_FMT,
@@ -346,10 +348,9 @@ void udev_node_add(struct udev_device *dev, bool apply,
                 return;
 
         /* always add /dev/{block,char}/$major:$minor */
-        xsprintf(filename, "/dev/%s/%u:%u",
-                 streq(udev_device_get_subsystem(dev), "block") ? "block" : "char",
-                 major(udev_device_get_devnum(dev)),
-                 minor(udev_device_get_devnum(dev)));
+        xsprintf_dev_num_path(filename,
+                              streq(udev_device_get_subsystem(dev), "block") ? "block" : "char",
+                              udev_device_get_devnum(dev));
         node_symlink(dev, udev_device_get_devnode(dev), filename);
 
         /* create/update symlinks, add symlinks to name index */
@@ -359,16 +360,15 @@ void udev_node_add(struct udev_device *dev, bool apply,
 
 void udev_node_remove(struct udev_device *dev) {
         struct udev_list_entry *list_entry;
-        char filename[sizeof("/dev/block/:") + 2*DECIMAL_STR_MAX(unsigned)];
+        char filename[DEV_NUM_PATH_MAX];
 
         /* remove/update symlinks, remove symlinks from name index */
         udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(dev))
                 link_update(dev, udev_list_entry_get_name(list_entry), false);
 
         /* remove /dev/{block,char}/$major:$minor */
-        xsprintf(filename, "/dev/%s/%u:%u",
-                 streq(udev_device_get_subsystem(dev), "block") ? "block" : "char",
-                 major(udev_device_get_devnum(dev)),
-                 minor(udev_device_get_devnum(dev)));
+        xsprintf_dev_num_path(filename,
+                              streq(udev_device_get_subsystem(dev), "block") ? "block" : "char",
+                              udev_device_get_devnum(dev));
         unlink(filename);
 }
index 9aaec72..f4708bb 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * Copyright (C) 2003-2012 Kay Sievers <kay@vrfy.org>
  *
@@ -1097,7 +1098,8 @@ static void add_rule(struct udev_rules *rules, char *line,
                         rule_add_key(&rule_tmp, TK_M_DRIVER, op, value, NULL);
 
                 } else if (startswith(key, "ATTR{")) {
-                        attr = get_key_attribute(rules->udev, key + strlen("ATTR"));
+                        attr = get_key_attribute(rules->udev,
+                                                 key + STRLEN("ATTR"));
                         if (attr == NULL)
                                 LOG_AND_RETURN("error parsing %s attribute", "ATTR");
 
@@ -1110,7 +1112,8 @@ static void add_rule(struct udev_rules *rules, char *line,
                                 rule_add_key(&rule_tmp, TK_A_ATTR, op, value, attr);
 
                 } else if (startswith(key, "SYSCTL{")) {
-                        attr = get_key_attribute(rules->udev, key + strlen("SYSCTL"));
+                        attr = get_key_attribute(rules->udev,
+                                                 key + STRLEN("SYSCTL"));
                         if (attr == NULL)
                                 LOG_AND_RETURN("error parsing %s attribute", "ATTR");
 
@@ -1123,7 +1126,8 @@ static void add_rule(struct udev_rules *rules, char *line,
                                 rule_add_key(&rule_tmp, TK_A_SYSCTL, op, value, attr);
 
                 } else if (startswith(key, "SECLABEL{")) {
-                        attr = get_key_attribute(rules->udev, key + strlen("SECLABEL"));
+                        attr = get_key_attribute(rules->udev,
+                                                 key + STRLEN("SECLABEL"));
                         if (attr == NULL)
                                 LOG_AND_RETURN("error parsing %s attribute", "SECLABEL");
 
@@ -1154,7 +1158,8 @@ static void add_rule(struct udev_rules *rules, char *line,
                         if (op > OP_MATCH_MAX)
                                 LOG_AND_RETURN("invalid %s operation", "ATTRS");
 
-                        attr = get_key_attribute(rules->udev, key + strlen("ATTRS"));
+                        attr = get_key_attribute(rules->udev,
+                                                 key + STRLEN("ATTRS"));
                         if (attr == NULL)
                                 LOG_AND_RETURN("error parsing %s attribute", "ATTRS");
 
@@ -1171,7 +1176,8 @@ static void add_rule(struct udev_rules *rules, char *line,
                         rule_add_key(&rule_tmp, TK_M_TAGS, op, value, NULL);
 
                 } else if (startswith(key, "ENV{")) {
-                        attr = get_key_attribute(rules->udev, key + strlen("ENV"));
+                        attr = get_key_attribute(rules->udev,
+                                                 key + STRLEN("ENV"));
                         if (attr == NULL)
                                 LOG_AND_RETURN("error parsing %s attribute", "ENV");
 
@@ -1217,7 +1223,8 @@ static void add_rule(struct udev_rules *rules, char *line,
                         rule_add_key(&rule_tmp, TK_M_RESULT, op, value, NULL);
 
                 } else if (startswith(key, "IMPORT")) {
-                        attr = get_key_attribute(rules->udev, key + strlen("IMPORT"));
+                        attr = get_key_attribute(rules->udev,
+                                                 key + STRLEN("IMPORT"));
                         if (attr == NULL) {
                                 LOG_RULE_WARNING("ignoring IMPORT{} with missing type");
                                 continue;
@@ -1261,7 +1268,8 @@ static void add_rule(struct udev_rules *rules, char *line,
                         if (op > OP_MATCH_MAX)
                                 LOG_AND_RETURN("invalid %s operation", "TEST");
 
-                        attr = get_key_attribute(rules->udev, key + strlen("TEST"));
+                        attr = get_key_attribute(rules->udev,
+                                                 key + STRLEN("TEST"));
                         if (attr != NULL) {
                                 mode = strtol(attr, NULL, 8);
                                 rule_add_key(&rule_tmp, TK_M_TEST, op, value, &mode);
@@ -1269,7 +1277,8 @@ static void add_rule(struct udev_rules *rules, char *line,
                                 rule_add_key(&rule_tmp, TK_M_TEST, op, value, NULL);
 
                 } else if (startswith(key, "RUN")) {
-                        attr = get_key_attribute(rules->udev, key + strlen("RUN"));
+                        attr = get_key_attribute(rules->udev,
+                                                 key + STRLEN("RUN"));
                         if (attr == NULL)
                                 attr = "program";
                         if (op == OP_REMOVE)
@@ -1388,14 +1397,14 @@ static void add_rule(struct udev_rules *rules, char *line,
 
                         pos = strstr(value, "link_priority=");
                         if (pos != NULL) {
-                                int prio = atoi(pos + strlen("link_priority="));
+                                int prio = atoi(pos + STRLEN("link_priority="));
 
                                 rule_add_key(&rule_tmp, TK_A_DEVLINK_PRIO, op, NULL, &prio);
                         }
 
                         pos = strstr(value, "string_escape=");
                         if (pos != NULL) {
-                                pos += strlen("string_escape=");
+                                pos += STRLEN("string_escape=");
                                 if (startswith(pos, "none"))
                                         rule_add_key(&rule_tmp, TK_A_STRING_ESCAPE_NONE, op, NULL, NULL);
                                 else if (startswith(pos, "replace"))
@@ -1422,7 +1431,7 @@ static void add_rule(struct udev_rules *rules, char *line,
 
                         pos = strstr(value, "static_node=");
                         if (pos != NULL) {
-                                pos += strlen("static_node=");
+                                pos += STRLEN("static_node=");
                                 rule_add_key(&rule_tmp, TK_A_STATIC_NODE, op, pos, NULL);
                                 rule_tmp.rule.rule.has_static_node = true;
                         }
@@ -1690,7 +1699,7 @@ static int match_attr(struct udev_rules *rules, struct udev_device *dev, struct
         case SB_FORMAT:
                 udev_event_apply_format(event, name, nbuf, sizeof(nbuf), false);
                 name = nbuf;
-                /* fall through */
+                _fallthrough_;
         case SB_NONE:
                 value = udev_device_get_sysattr_value(dev, name);
                 if (value == NULL)
@@ -1783,7 +1792,7 @@ void udev_rules_apply_to_event(struct udev_rules *rules,
                         udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(event->dev)) {
                                 const char *devlink;
 
-                                devlink = udev_list_entry_get_name(list_entry) + strlen("/dev/");
+                                devlink = udev_list_entry_get_name(list_entry) + STRLEN("/dev/");
                                 if (match_key(rules, cur, devlink) == 0) {
                                         match = true;
                                         break;
@@ -1967,7 +1976,7 @@ void udev_rules_apply_to_event(struct udev_rules *rules,
                         } else {
                                 int count;
 
-                                util_remove_trailing_chars(result, '\n');
+                                delete_trailing_chars(result, "\n");
                                 if (IN_SET(esc, ESCAPE_UNSET, ESCAPE_REPLACE)) {
                                         count = util_replace_chars(result, UDEV_ALLOWED_CHARS_INPUT);
                                         if (count > 0)
@@ -2294,7 +2303,7 @@ void udev_rules_apply_to_event(struct udev_rules *rules,
                                         log_debug("%i character(s) replaced", count);
                         }
                         if (major(udev_device_get_devnum(event->dev)) &&
-                            !streq(name_str, udev_device_get_devnode(event->dev) + strlen("/dev/"))) {
+                            !streq(name_str, udev_device_get_devnode(event->dev) + STRLEN("/dev/"))) {
                                 log_error("NAME=\"%s\" ignored, kernel device nodes cannot be renamed; please fix it in %s:%u\n",
                                           name,
                                           rules_str(rules, rule->rule.filename_off),
index aa432bb..351cb63 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * Copyright (C) 2004-2012 Kay Sievers <kay@vrfy.org>
  * Copyright (C) 2009 Canonical Ltd.
index 2204db5..ea11c2d 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 #pragma once
 
 /*
index 6f8e96a..d80d615 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * Copyright (C) 2005-2011 Kay Sievers <kay@vrfy.org>
  *
 #include "time-util.h"
 #include "udev-util.h"
 #include "udev.h"
+#include "udevadm-util.h"
 
 static void print_help(void) {
-        printf("%s control COMMAND\n\n"
+        printf("%s control OPTION\n\n"
                "Control the udev daemon.\n\n"
                "  -h --help                Show this help\n"
-               "     --version             Show package version\n"
+               "  -V --version             Show package version\n"
                "  -e --exit                Instruct the daemon to cleanup and exit\n"
                "  -l --log-priority=LEVEL  Set the udev log level for the daemon\n"
                "  -s --stop-exec-queue     Do not execute events, queue only\n"
@@ -36,7 +38,7 @@ static void print_help(void) {
                "  -R --reload              Reload rules and databases\n"
                "  -p --property=KEY=VALUE  Set a global property for all events\n"
                "  -m --children-max=N      Maximum number of children\n"
-               "     --timeout=SECONDS     Maximum time to block for a reply\n"
+               "  -t --timeout=SECONDS     Maximum time to block for a reply\n"
                , program_invocation_short_name);
 }
 
@@ -56,20 +58,19 @@ static int adm_control(struct udev *udev, int argc, char *argv[]) {
                 { "env",              required_argument, NULL, 'p' }, /* alias for -p */
                 { "children-max",     required_argument, NULL, 'm' },
                 { "timeout",          required_argument, NULL, 't' },
+                { "version",          no_argument,       NULL, 'V' },
                 { "help",             no_argument,       NULL, 'h' },
                 {}
         };
 
-        if (getuid() != 0) {
-                log_error("root privileges required");
+        if (must_be_root() < 0)
                 return 1;
-        }
 
         uctrl = udev_ctrl_new(udev);
         if (uctrl == NULL)
                 return 2;
 
-        while ((c = getopt_long(argc, argv, "el:sSRp:m:h", options, NULL)) >= 0)
+        while ((c = getopt_long(argc, argv, "el:sSRp:m:t:Vh", options, NULL)) >= 0)
                 switch (c) {
                 case 'e':
                         if (udev_ctrl_send_exit(uctrl, timeout) < 0)
@@ -152,6 +153,10 @@ static int adm_control(struct udev *udev, int argc, char *argv[]) {
                         }
                         break;
                 }
+                case 'V':
+                        print_version();
+                        rc = 0;
+                        break;
                 case 'h':
                         print_help();
                         rc = 0;
index 4a23270..ab5dc7a 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -33,6 +34,7 @@
 #include "strbuf.h"
 #include "string-util.h"
 #include "udev.h"
+#include "udevadm-util.h"
 #include "util.h"
 
 /*
@@ -545,12 +547,17 @@ static int import_file(struct udev *udev, struct trie *trie, const char *filenam
 }
 
 static void help(void) {
-        printf("Usage: udevadm hwdb OPTIONS\n"
-               "  -u,--update          update the hardware database\n"
-               "  --usr                generate in " UDEVLIBEXECDIR " instead of /etc/udev\n"
-               "  -t,--test=MODALIAS   query database and print result\n"
-               "  -r,--root=PATH       alternative root path in the filesystem\n"
-               "  -h,--help\n\n");
+        printf("%s hwdb [OPTIONS]\n\n"
+               "  -h --help            Print this message\n"
+               "  -V --version         Print version of the program\n"
+               "  -u --update          Update the hardware database\n"
+               "     --usr             Generate in " UDEVLIBEXECDIR " instead of /etc/udev\n"
+               "  -t --test=MODALIAS   Query database and print result\n"
+               "  -r --root=PATH       Alternative root path in the filesystem\n\n"
+               "NOTE:\n"
+               "The sub-command 'hwdb' is deprecated, and is left for backwards compatibility.\n"
+               "Please use systemd-hwdb instead.\n"
+               , program_invocation_short_name);
 }
 
 static int adm_hwdb(struct udev *udev, int argc, char *argv[]) {
@@ -559,11 +566,12 @@ static int adm_hwdb(struct udev *udev, int argc, char *argv[]) {
         };
 
         static const struct option options[] = {
-                { "update", no_argument,       NULL, 'u' },
-                { "usr",    no_argument,       NULL, ARG_USR },
-                { "test",   required_argument, NULL, 't' },
-                { "root",   required_argument, NULL, 'r' },
-                { "help",   no_argument,       NULL, 'h' },
+                { "update",  no_argument,       NULL, 'u'     },
+                { "usr",     no_argument,       NULL, ARG_USR },
+                { "test",    required_argument, NULL, 't'     },
+                { "root",    required_argument, NULL, 'r'     },
+                { "version", no_argument,       NULL, 'V'     },
+                { "help",    no_argument,       NULL, 'h'     },
                 {}
         };
         const char *test = NULL;
@@ -574,7 +582,7 @@ static int adm_hwdb(struct udev *udev, int argc, char *argv[]) {
         int err, c;
         int rc = EXIT_SUCCESS;
 
-        while ((c = getopt_long(argc, argv, "ut:r:h", options, NULL)) >= 0)
+        while ((c = getopt_long(argc, argv, "ut:r:Vh", options, NULL)) >= 0)
                 switch(c) {
                 case 'u':
                         update = true;
@@ -588,6 +596,9 @@ static int adm_hwdb(struct udev *udev, int argc, char *argv[]) {
                 case 'r':
                         root = optarg;
                         break;
+                case 'V':
+                        print_version();
+                        return EXIT_SUCCESS;
                 case 'h':
                         help();
                         return EXIT_SUCCESS;
index 16b2aab..580e950 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * Copyright (C) 2004-2009 Kay Sievers <kay@vrfy.org>
  *
@@ -136,14 +137,15 @@ static void print_record(struct udev_device *device) {
 
         str = udev_device_get_devnode(device);
         if (str != NULL)
-                printf("N: %s\n", str + strlen("/dev/"));
+                printf("N: %s\n", str + STRLEN("/dev/"));
 
         i = udev_device_get_devlink_priority(device);
         if (i != 0)
                 printf("L: %i\n", i);
 
         udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(device))
-                printf("S: %s\n", udev_list_entry_get_name(list_entry) + strlen("/dev/"));
+                printf("S: %s\n",
+                       udev_list_entry_get_name(list_entry) + STRLEN("/dev/"));
 
         udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(device))
                 printf("E: %s=%s\n",
@@ -249,7 +251,7 @@ static void help(void) {
         printf("%s info [OPTIONS] [DEVPATH|FILE]\n\n"
                "Query sysfs or the udev database.\n\n"
                "  -h --help                   Print this message\n"
-               "     --version                Print version of the program\n"
+               "  -V --version                Print version of the program\n"
                "  -q --query=TYPE             Query device information:\n"
                "       name                     Name of device node\n"
                "       symlink                  Pointing to node\n"
@@ -376,7 +378,7 @@ static int uinfo(struct udev *udev, int argc, char *argv[]) {
                         export_prefix = optarg;
                         break;
                 case 'V':
-                        printf("%s\n", PACKAGE_VERSION);
+                        print_version();
                         return 0;
                 case 'h':
                         help();
@@ -411,7 +413,8 @@ static int uinfo(struct udev *udev, int argc, char *argv[]) {
                         if (root)
                                 printf("%s\n", udev_device_get_devnode(device));
                         else
-                                printf("%s\n", udev_device_get_devnode(device) + strlen("/dev/"));
+                                printf("%s\n",
+                                       udev_device_get_devnode(device) + STRLEN("/dev/"));
                         break;
                 }
                 case QUERY_SYMLINK:
@@ -420,7 +423,8 @@ static int uinfo(struct udev *udev, int argc, char *argv[]) {
                                 if (root)
                                         printf("%s", udev_list_entry_get_name(list_entry));
                                 else
-                                        printf("%s", udev_list_entry_get_name(list_entry) + strlen("/dev/"));
+                                        printf("%s",
+                                               udev_list_entry_get_name(list_entry) + STRLEN("/dev/"));
                                 list_entry = udev_list_entry_get_next(list_entry);
                                 if (list_entry != NULL)
                                         printf(" ");
index 77ae3a9..028ef92 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * Copyright (C) 2004-2010 Kay Sievers <kay@vrfy.org>
  *
@@ -29,6 +30,7 @@
 #include "format-util.h"
 #include "udev-util.h"
 #include "udev.h"
+#include "udevadm-util.h"
 
 static bool udev_exit;
 
@@ -59,10 +61,10 @@ static void print_device(struct udev_device *device, const char *source, int pro
 }
 
 static void help(void) {
-        printf("%s monitor [--property] [--kernel] [--udev] [--help]\n\n"
+        printf("%s monitor [OPTIONS]\n\n"
                "Listen to kernel and udev events.\n\n"
                "  -h --help                                Show this help\n"
-               "     --version                             Show package version\n"
+               "  -V --version                             Show package version\n"
                "  -p --property                            Print the event properties\n"
                "  -k --kernel                              Print kernel uevents\n"
                "  -u --udev                                Print udev events\n"
@@ -93,6 +95,7 @@ static int adm_monitor(struct udev *udev, int argc, char *argv[]) {
                 { "udev",            no_argument,       NULL, 'u' },
                 { "subsystem-match", required_argument, NULL, 's' },
                 { "tag-match",       required_argument, NULL, 't' },
+                { "version",         no_argument,       NULL, 'V' },
                 { "help",            no_argument,       NULL, 'h' },
                 {}
         };
@@ -100,7 +103,7 @@ static int adm_monitor(struct udev *udev, int argc, char *argv[]) {
         udev_list_init(udev, &subsystem_match_list, true);
         udev_list_init(udev, &tag_match_list, true);
 
-        while ((c = getopt_long(argc, argv, "pekus:t:h", options, NULL)) >= 0)
+        while ((c = getopt_long(argc, argv, "pekus:t:Vh", options, NULL)) >= 0)
                 switch (c) {
                 case 'p':
                 case 'e':
@@ -129,6 +132,9 @@ static int adm_monitor(struct udev *udev, int argc, char *argv[]) {
                 case 't':
                         udev_list_entry_add(&tag_match_list, optarg, NULL);
                         break;
+                case 'V':
+                        print_version();
+                        return 0;
                 case 'h':
                         help();
                         return 0;
@@ -144,12 +150,12 @@ static int adm_monitor(struct udev *udev, int argc, char *argv[]) {
         /* set signal handlers */
         act.sa_handler = sig_handler;
         act.sa_flags = SA_RESTART;
-        sigaction(SIGINT, &act, NULL);
-        sigaction(SIGTERM, &act, NULL);
-        sigemptyset(&mask);
-        sigaddset(&mask, SIGINT);
-        sigaddset(&mask, SIGTERM);
-        sigprocmask(SIG_UNBLOCK, &mask, NULL);
+        assert_se(sigaction(SIGINT, &act, NULL) == 0);
+        assert_se(sigaction(SIGTERM, &act, NULL) == 0);
+        assert_se(sigemptyset(&mask) == 0);
+        assert_se(sigaddset(&mask, SIGINT) == 0);
+        assert_se(sigaddset(&mask, SIGTERM) == 0);
+        assert_se(sigprocmask(SIG_UNBLOCK, &mask, NULL) == 0);
 
         /* Callers are expecting to see events as they happen: Line buffering */
         setlinebuf(stdout);
index 6a5dc6e..0af3e64 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * Copyright (C) 2006-2009 Kay Sievers <kay@vrfy.org>
  * Copyright (C) 2009 Canonical Ltd.
 
 #include "parse-util.h"
 #include "udev.h"
+#include "udevadm-util.h"
 #include "util.h"
 
 static void help(void) {
-        printf("%s settle OPTIONS\n\n"
+        printf("%s settle [OPTIONS]\n\n"
                "Wait for pending udev events.\n\n"
                "  -h --help                 Show this help\n"
-               "     --version              Show package version\n"
+               "  -V --version              Show package version\n"
                "  -t --timeout=SECONDS      Maximum time to wait for events\n"
                "  -E --exit-if-exists=FILE  Stop waiting if file exists\n"
                , program_invocation_short_name);
@@ -44,6 +46,7 @@ static int adm_settle(struct udev *udev, int argc, char *argv[]) {
         static const struct option options[] = {
                 { "timeout",        required_argument, NULL, 't' },
                 { "exit-if-exists", required_argument, NULL, 'E' },
+                { "version",        no_argument,       NULL, 'V' },
                 { "help",           no_argument,       NULL, 'h' },
                 { "seq-start",      required_argument, NULL, 's' }, /* removed */
                 { "seq-end",        required_argument, NULL, 'e' }, /* removed */
@@ -58,7 +61,7 @@ static int adm_settle(struct udev *udev, int argc, char *argv[]) {
         struct udev_queue *queue;
         int rc = EXIT_FAILURE;
 
-        while ((c = getopt_long(argc, argv, "t:E:hs:e:q", options, NULL)) >= 0) {
+        while ((c = getopt_long(argc, argv, "t:E:Vhs:e:q", options, NULL)) >= 0) {
                 switch (c) {
 
                 case 't': {
@@ -76,6 +79,10 @@ static int adm_settle(struct udev *udev, int argc, char *argv[]) {
                         exists = optarg;
                         break;
 
+                case 'V':
+                        print_version();
+                        return EXIT_SUCCESS;
+
                 case 'h':
                         help();
                         return EXIT_SUCCESS;
index b5662be..f5a39a1 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * Copyright (C) 2011 Kay Sievers <kay@vrfy.org>
  *
 #include "path-util.h"
 #include "string-util.h"
 #include "udev.h"
+#include "udevadm-util.h"
 
 static void help(struct udev *udev) {
-        printf("%s builtin [--help] COMMAND SYSPATH\n\n"
+        printf("%s test-builtin [OPTIONS] COMMAND DEVPATH\n\n"
                "Test a built-in command.\n\n"
                "  -h --help     Print this message\n"
-               "     --version  Print version of the program\n\n"
+               "  -V --version  Print version of the program\n\n"
                "Commands:\n"
                , program_invocation_short_name);
 
@@ -38,7 +40,8 @@ static void help(struct udev *udev) {
 
 static int adm_builtin(struct udev *udev, int argc, char *argv[]) {
         static const struct option options[] = {
-                { "help", no_argument, NULL, 'h' },
+                { "version", no_argument, NULL, 'V' },
+                { "help",    no_argument, NULL, 'h' },
                 {}
         };
         char *command = NULL;
@@ -48,8 +51,11 @@ static int adm_builtin(struct udev *udev, int argc, char *argv[]) {
         enum udev_builtin_cmd cmd;
         int rc = EXIT_SUCCESS, c;
 
-        while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
+        while ((c = getopt_long(argc, argv, "Vh", options, NULL)) >= 0)
                 switch (c) {
+                case 'V':
+                        print_version();
+                        goto out;
                 case 'h':
                         help(udev);
                         goto out;
@@ -85,7 +91,7 @@ static int adm_builtin(struct udev *udev, int argc, char *argv[]) {
                 strscpyl(filename, sizeof(filename), "/sys", syspath, NULL);
         else
                 strscpy(filename, sizeof(filename), syspath);
-        util_remove_trailing_chars(filename, '/');
+        delete_trailing_chars(filename, "/");
 
         dev = udev_device_new_from_syspath(udev, filename);
         if (dev == NULL) {
index e8ffe2f..ef1f2f0 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * Copyright (C) 2003-2004 Greg Kroah-Hartman <greg@kroah.com>
  * Copyright (C) 2004-2008 Kay Sievers <kay@vrfy.org>
 #include "string-util.h"
 #include "udev-util.h"
 #include "udev.h"
+#include "udevadm-util.h"
 
 static void help(void) {
 
-        printf("%s test OPTIONS <syspath>\n\n"
-               "Test an event run.\n"
+        printf("%s test [OPTIONS] DEVPATH\n\n"
+               "Test an event run.\n\n"
                "  -h --help                            Show this help\n"
-               "     --version                         Show package version\n"
+               "  -V --version                         Show package version\n"
                "  -a --action=ACTION                   Set action string\n"
                "  -N --resolve-names=early|late|never  When to resolve names\n"
                , program_invocation_short_name);
@@ -53,15 +55,16 @@ static int adm_test(struct udev *udev, int argc, char *argv[]) {
         int rc = 0, c;
 
         static const struct option options[] = {
-                { "action", required_argument, NULL, 'a' },
+                { "action",        required_argument, NULL, 'a' },
                 { "resolve-names", required_argument, NULL, 'N' },
-                { "help", no_argument, NULL, 'h' },
+                { "version",       no_argument,       NULL, 'V' },
+                { "help",          no_argument,       NULL, 'h' },
                 {}
         };
 
         log_debug("version %s", PACKAGE_VERSION);
 
-        while ((c = getopt_long(argc, argv, "a:N:h", options, NULL)) >= 0)
+        while ((c = getopt_long(argc, argv, "a:N:Vh", options, NULL)) >= 0)
                 switch (c) {
                 case 'a':
                         action = optarg;
@@ -79,6 +82,9 @@ static int adm_test(struct udev *udev, int argc, char *argv[]) {
                                 exit(EXIT_FAILURE);
                         }
                         break;
+                case 'V':
+                        print_version();
+                        exit(EXIT_SUCCESS);
                 case 'h':
                         help();
                         exit(EXIT_SUCCESS);
@@ -116,7 +122,7 @@ static int adm_test(struct udev *udev, int argc, char *argv[]) {
                 strscpyl(filename, sizeof(filename), "/sys", syspath, NULL);
         else
                 strscpy(filename, sizeof(filename), syspath);
-        util_remove_trailing_chars(filename, '/');
+        delete_trailing_chars(filename, "/");
 
         dev = udev_device_new_from_synthetic_event(udev, filename, action);
         if (dev == NULL) {
index e2ce317..f78a2ba 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * Copyright (C) 2008-2009 Kay Sievers <kay@vrfy.org>
  *
@@ -67,10 +68,10 @@ static const char *keyval(const char *str, const char **val, char *buf, size_t s
 }
 
 static void help(void) {
-        printf("%s trigger OPTIONS\n\n"
+        printf("%s trigger [OPTIONS] DEVPATH\n\n"
                "Request events from the kernel.\n\n"
                "  -h --help                         Show this help\n"
-               "     --version                      Show package version\n"
+               "  -V --version                      Show package version\n"
                "  -v --verbose                      Print the list of devices while running\n"
                "  -n --dry-run                      Do not actually trigger the events\n"
                "  -t --type=                        Type of events to trigger\n"
@@ -108,6 +109,7 @@ static int adm_trigger(struct udev *udev, int argc, char *argv[]) {
                 { "sysname-match",     required_argument, NULL, 'y'      },
                 { "name-match",        required_argument, NULL, ARG_NAME },
                 { "parent-match",      required_argument, NULL, 'b'      },
+                { "version",           no_argument,       NULL, 'V'      },
                 { "help",              no_argument,       NULL, 'h'      },
                 {}
         };
@@ -123,7 +125,7 @@ static int adm_trigger(struct udev *udev, int argc, char *argv[]) {
         if (udev_enumerate == NULL)
                 return 1;
 
-        while ((c = getopt_long(argc, argv, "vno:t:c:s:S:a:A:p:g:y:b:h", options, NULL)) >= 0) {
+        while ((c = getopt_long(argc, argv, "vnt:c:s:S:a:A:p:g:y:b:Vh", options, NULL)) >= 0) {
                 const char *key;
                 const char *val;
                 char buf[UTIL_PATH_SIZE];
@@ -239,6 +241,9 @@ static int adm_trigger(struct udev *udev, int argc, char *argv[]) {
                         break;
                 }
 
+                case 'V':
+                        print_version();
+                        return 0;
                 case 'h':
                         help();
                         return 0;
index beda7c3..b71b9eb 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * Copyright (C) 2008-2009 Kay Sievers <kay@vrfy.org>
  *
index dc712b0..8262a83 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 #pragma once
 
 /*
@@ -22,3 +23,7 @@
 struct udev_device *find_device(struct udev *udev,
                                 const char *id,
                                 const char *prefix);
+
+static inline void print_version(void) {
+        printf("%s\n", PACKAGE_VERSION);
+}
index befc3ba..06be1e8 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * Copyright (C) 2007-2012 Kay Sievers <kay@vrfy.org>
  *
index 83f846f..1644935 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * Copyright (C) 2004-2012 Kay Sievers <kay@vrfy.org>
  * Copyright (C) 2004 Chris Friesen <chris_friesen@sympatico.ca>
@@ -53,6 +54,7 @@
 #include "fs-util.h"
 #include "hashmap.h"
 #include "io-util.h"
+#include "list.h"
 #include "netlink-util.h"
 #include "parse-util.h"
 #include "proc-cmdline.h"
@@ -78,7 +80,7 @@ typedef struct Manager {
         struct udev *udev;
         sd_event *event;
         Hashmap *workers;
-        struct udev_list_node events;
+        LIST_HEAD(struct event, events);
         const char *cgroup;
         pid_t pid; /* the process that originally allocated the manager object */
 
@@ -108,7 +110,7 @@ enum event_state {
 };
 
 struct event {
-        struct udev_list_node node;
+        LIST_FIELDS(struct event, event);
         Manager *manager;
         struct udev *udev;
         struct udev_device *dev;
@@ -127,10 +129,6 @@ struct event {
         sd_event_source *timeout;
 };
 
-static inline struct event *node_to_event(struct udev_list_node *node) {
-        return container_of(node, struct event, node);
-}
-
 static void event_queue_cleanup(Manager *manager, enum event_state type);
 
 enum worker_state {
@@ -142,7 +140,6 @@ enum worker_state {
 
 struct worker {
         Manager *manager;
-        struct udev_list_node node;
         int refcount;
         pid_t pid;
         struct udev_monitor *monitor;
@@ -159,8 +156,9 @@ static void event_free(struct event *event) {
 
         if (!event)
                 return;
+        assert(event->manager);
 
-        udev_list_node_remove(&event->node);
+        LIST_REMOVE(event, event->manager->events, event);
         udev_device_unref(event->dev);
         udev_device_unref(event->dev_kernel);
 
@@ -170,9 +168,7 @@ static void event_free(struct event *event) {
         if (event->worker)
                 event->worker->event = NULL;
 
-        assert(event->manager);
-
-        if (udev_list_node_is_empty(&event->manager->events)) {
+        if (LIST_IS_EMPTY(event->manager->events)) {
                 /* only clean up the queue from the process that created it */
                 if (event->manager->pid == getpid_cached()) {
                         r = unlink("/run/udev/queue");
@@ -619,13 +615,13 @@ static int event_queue_insert(Manager *manager, struct udev_device *dev) {
 
         event->state = EVENT_QUEUED;
 
-        if (udev_list_node_is_empty(&manager->events)) {
+        if (LIST_IS_EMPTY(manager->events)) {
                 r = touch("/run/udev/queue");
                 if (r < 0)
                         log_warning_errno(r, "could not touch /run/udev/queue: %m");
         }
 
-        udev_list_node_append(&event->node, &manager->events);
+        LIST_APPEND(event, manager->events, event);
 
         return 0;
 }
@@ -647,13 +643,11 @@ static void manager_kill_workers(Manager *manager) {
 
 /* lookup event for identical, parent, child device */
 static bool is_devpath_busy(Manager *manager, struct event *event) {
-        struct udev_list_node *loop;
+        struct event *loop_event;
         size_t common;
 
         /* check if queue contains events we depend on */
-        udev_list_node_foreach(loop, &manager->events) {
-                struct event *loop_event = node_to_event(loop);
-
+        LIST_FOREACH(event, loop_event, manager->events) {
                 /* we already found a later event, earlier can not block us, no need to check again */
                 if (loop_event->seqnum < event->delaying_seqnum)
                         continue;
@@ -782,12 +776,12 @@ static void manager_reload(Manager *manager) {
 }
 
 static void event_queue_start(Manager *manager) {
-        struct udev_list_node *loop;
+        struct event *event;
         usec_t usec;
 
         assert(manager);
 
-        if (udev_list_node_is_empty(&manager->events) ||
+        if (LIST_IS_EMPTY(manager->events) ||
             manager->exit || manager->stop_exec_queue)
                 return;
 
@@ -810,9 +804,7 @@ static void event_queue_start(Manager *manager) {
                         return;
         }
 
-        udev_list_node_foreach(loop, &manager->events) {
-                struct event *event = node_to_event(loop);
-
+        LIST_FOREACH(event,event,manager->events) {
                 if (event->state != EVENT_QUEUED)
                         continue;
 
@@ -825,11 +817,9 @@ static void event_queue_start(Manager *manager) {
 }
 
 static void event_queue_cleanup(Manager *manager, enum event_state match_type) {
-        struct udev_list_node *loop, *tmp;
-
-        udev_list_node_foreach_safe(loop, tmp, &manager->events) {
-                struct event *event = node_to_event(loop);
+        struct event *event, *tmp;
 
+        LIST_FOREACH_SAFE(event, event, tmp, manager->events) {
                 if (match_type != EVENT_UNDEF && match_type != event->state)
                         continue;
 
@@ -1246,7 +1236,7 @@ static int on_post(sd_event_source *s, void *userdata) {
 
         assert(manager);
 
-        if (udev_list_node_is_empty(&manager->events)) {
+        if (LIST_IS_EMPTY(manager->events)) {
                 /* no pending events */
                 if (!hashmap_isempty(manager->workers)) {
                         /* there are idle workers */
@@ -1417,13 +1407,13 @@ static void help(void) {
         printf("%s [OPTIONS...]\n\n"
                "Manages devices.\n\n"
                "  -h --help                   Print this message\n"
-               "     --version                Print version of the program\n"
-               "     --daemon                 Detach and run in the background\n"
-               "     --debug                  Enable debug output\n"
-               "     --children-max=INT       Set maximum number of workers\n"
-               "     --exec-delay=SECONDS     Seconds to wait before executing RUN=\n"
-               "     --event-timeout=SECONDS  Seconds to wait before terminating an event\n"
-               "     --resolve-names=early|late|never\n"
+               "  -V --version                Print version of the program\n"
+               "  -d --daemon                 Detach and run in the background\n"
+               "  -D --debug                  Enable debug output\n"
+               "  -c --children-max=INT       Set maximum number of workers\n"
+               "  -e --exec-delay=SECONDS     Seconds to wait before executing RUN=\n"
+               "  -t --event-timeout=SECONDS  Seconds to wait before terminating an event\n"
+               "  -N --resolve-names=early|late|never\n"
                "                              When to resolve users and groups\n"
                , program_invocation_short_name);
 }
@@ -1531,7 +1521,7 @@ static int manager_new(Manager **ret, int fd_ctrl, int fd_uevent, const char *cg
         if (!manager->rules)
                 return log_error_errno(ENOMEM, "error reading rules");
 
-        udev_list_node_init(&manager->events);
+        LIST_HEAD_INIT(manager->events);
         udev_list_init(manager->udev, &manager->properties, true);
 
         manager->cgroup = cgroup;
@@ -1680,10 +1670,9 @@ int main(int argc, char *argv[]) {
                 log_set_max_level(LOG_DEBUG);
         }
 
-        if (getuid() != 0) {
-                r = log_error_errno(EPERM, "root privileges required");
+        r = must_be_root();
+        if (r < 0)
                 goto exit;
-        }
 
         if (arg_children_max == 0) {
                 cpu_set_t cpu_set;
@@ -1725,7 +1714,7 @@ int main(int argc, char *argv[]) {
                    by PID1. otherwise we are not guaranteed to have a dedicated cgroup */
                 r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, 0, &cgroup);
                 if (r < 0) {
-                        if (r == -ENOENT || r == -ENOMEDIUM)
+                        if (IN_SET(r, -ENOENT, -ENOMEDIUM))
                                 log_debug_errno(r, "did not find dedicated cgroup: %m");
                         else
                                 log_warning_errno(r, "failed to get cgroup: %m");
index aec6676..05f31d4 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * Copyright (C) 2009 Kay Sievers <kay@vrfy.org>
  * Copyright (c) 2009 Filippo Argiolas <filippo.argiolas@gmail.com>
index ec467f1..ccf2d47 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index b1b3800..e16f67b 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 9b29b5b..795766a 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index 84b4d57..1113716 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 120057c..745aec4 100644 (file)
@@ -1,3 +1,20 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
+# Copyright 2017 Zbigniew Jędrzejewski-Szmek
+#
+# 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.
+#
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
 if conf.get('ENABLE_VCONSOLE') == 1
         vconsole_rules = configure_file(
                 input : '90-vconsole.rules.in',
index f531aec..e19a163 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -334,7 +335,7 @@ static int find_source_vc(char **ret_path, unsigned *ret_idx) {
         int ret_fd, r, err = 0;
 
         path = new(char, sizeof("/dev/tty63"));
-        if (path == NULL)
+        if (!path)
                 return log_oom();
 
         for (i = 1; i <= 63; i++) {
@@ -395,7 +396,7 @@ static int verify_source_vc(char **ret_path, const char *src_vc) {
                 return log_error_errno(r, "Virtual console %s is not in K_XLATE or K_UNICODE: %m", src_vc);
 
         path = strdup(src_vc);
-        if (path == NULL)
+        if (!path)
                 return log_oom();
 
         *ret_path = path;
index 0bb0bd6..5919b13 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -31,6 +32,7 @@
 #include "mkdir.h"
 #include "parse-util.h"
 #include "proc-cmdline.h"
+#include "specifier.h"
 #include "string-util.h"
 #include "unit-name.h"
 
@@ -41,7 +43,7 @@ static char *arg_data_what = NULL;
 static char *arg_hash_what = NULL;
 
 static int create_device(void) {
-        _cleanup_free_ char *u = NULL, *v = NULL, *d = NULL, *e = NULL;
+        _cleanup_free_ char *u = NULL, *v = NULL, *d = NULL, *e = NULL, *u_escaped = NULL, *v_escaped = NULL, *root_hash_escaped = NULL;
         _cleanup_fclose_ FILE *f = NULL;
         const char *p, *to;
         int r;
@@ -74,6 +76,13 @@ static int create_device(void) {
         if (!v)
                 return log_oom();
 
+        u_escaped = specifier_escape(u);
+        if (!u_escaped)
+                return log_oom();
+        v_escaped = specifier_escape(v);
+        if (!v_escaped)
+                return log_oom();
+
         r = unit_name_from_path(u, ".device", &d);
         if (r < 0)
                 return log_error_errno(r, "Failed to generate unit name: %m");
@@ -81,6 +90,10 @@ static int create_device(void) {
         if (r < 0)
                 return log_error_errno(r, "Failed to generate unit name: %m");
 
+        root_hash_escaped = specifier_escape(arg_root_hash);
+        if (!root_hash_escaped)
+                return log_oom();
+
         f = fopen(p, "wxe");
         if (!f)
                 return log_error_errno(errno, "Failed to create unit file %s: %m", p);
@@ -104,7 +117,7 @@ static int create_device(void) {
                 "ExecStop=" ROOTLIBEXECDIR "/systemd-veritysetup detach root\n",
                 d, e,
                 d, e,
-                u, v, arg_root_hash);
+                u_escaped, v_escaped, root_hash_escaped);
 
         r = fflush_and_check(f);
         if (r < 0)
index c6a7954..d3066ca 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
-#include <libcryptsetup.h>
 #include <stdio.h>
 #include <sys/stat.h>
 
+#include "crypt-util.h"
 #include "log.h"
 #include "hexdecoct.h"
 #include "string-util.h"
@@ -40,12 +41,8 @@ static int help(void) {
         return 0;
 }
 
-static void log_glue(int level, const char *msg, void *usrptr) {
-        log_debug("%s", msg);
-}
-
 int main(int argc, char *argv[]) {
-        struct crypt_device *cd = NULL;
+        _cleanup_(crypt_freep) struct crypt_device *cd = NULL;
         int r;
 
         if (argc <= 1) {
@@ -88,7 +85,7 @@ int main(int argc, char *argv[]) {
                         goto finish;
                 }
 
-                crypt_set_log_callback(cd, log_glue, NULL);
+                crypt_set_log_callback(cd, cryptsetup_log_glue, NULL);
 
                 status = crypt_status(cd, argv[2]);
                 if (IN_SET(status, CRYPT_ACTIVE, CRYPT_BUSY)) {
@@ -126,7 +123,7 @@ int main(int argc, char *argv[]) {
                         goto finish;
                 }
 
-                crypt_set_log_callback(cd, log_glue, NULL);
+                crypt_set_log_callback(cd, cryptsetup_log_glue, NULL);
 
                 r = crypt_deactivate(cd, argv[2]);
                 if (r < 0) {
@@ -143,9 +140,6 @@ int main(int argc, char *argv[]) {
         r = 0;
 
 finish:
-        if (cd)
-                crypt_free(cd);
-
         free(arg_root_hash);
         free(arg_data_what);
         free(arg_hash_what);
index 3c0b6fa..56aaa37 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
index aff9930..e263cf0 100644 (file)
@@ -22,15 +22,12 @@ kernel.sysrq = 16
 kernel.core_uses_pid = 1
 
 # Source route verification
-net.ipv4.conf.default.rp_filter = 1
 net.ipv4.conf.all.rp_filter = 1
 
 # Do not accept source routing
-net.ipv4.conf.default.accept_source_route = 0
 net.ipv4.conf.all.accept_source_route = 0
 
 # Promote secondary addresses when the primary address is removed
-net.ipv4.conf.default.promote_secondaries = 1
 net.ipv4.conf.all.promote_secondaries = 1
 
 # Fair Queue CoDel packet scheduler to fight bufferbloat
index 121874c..1e612de 100644 (file)
@@ -1,3 +1,20 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
+# Copyright 2017 Zbigniew Jędrzejewski-Szmek
+#
+# 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.
+#
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
 install_data(
         '50-default.conf',
         install_dir : sysctldir)
index 7d6021e..8e358c0 100644 (file)
@@ -9,7 +9,7 @@
 u root    0     "Super User" /root
 
 # The nobody user for NFS file systems
-u nobody  65534 "Nobody"     -
+u @NOBODY_USER_NAME@  65534 "Nobody"     -
 
 # Administrator group: can *see* more than normal users
 g adm     -     -            -
@@ -28,10 +28,11 @@ g cdrom   -     -            -
 g dialout -     -            -
 g disk    -     -            -
 g input   -     -            -
-g lp      -     -            -
 g kvm     -     -            -
+g lp      -     -            -
+g render  -     -            -
 g tape    -     -            -
 g video   -     -            -
 
 # Default group for normal users
-g users   -     -            -
+g users   @USERS_GID@     -            -
index 2f3f3eb..a240761 100644 (file)
@@ -1,3 +1,20 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
+# Copyright 2017 Zbigniew Jędrzejewski-Szmek
+#
+# 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.
+#
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
 in_files = ['basic.conf']
 
 enable_sysusers = conf.get('ENABLE_SYSUSERS') == 1
index 83b3626..9889176 100644 (file)
@@ -8,6 +8,3 @@
 m4_ifdef(`HAVE_MICROHTTPD',
 u systemd-journal-remote  - "systemd Journal Remote"
 )m4_dnl
-m4_ifdef(`HAVE_LIBCURL',
-u systemd-journal-upload  - "systemd Journal Upload"
-)m4_dnl
index ef5a3cb..82e23ca 100644 (file)
@@ -12,9 +12,6 @@ u systemd-network   - "systemd Network Management"
 m4_ifdef(`ENABLE_RESOLVE',
 u systemd-resolve   - "systemd Resolver"
 )m4_dnl
-m4_ifdef(`ENABLE_TIMESYNCD',
-u systemd-timesync  - "systemd Time Synchronization"
-)m4_dnl
 m4_ifdef(`ENABLE_COREDUMP',
 u systemd-coredump  - "systemd Core Dumper"
 )m4_dnl
diff --git a/test/Makefile.guess b/test/Makefile.guess
deleted file mode 100644 (file)
index 1916d09..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-# Try to guess the build directory:
-# we look for subdirectories of ../.. that look like ninja build dirs.
-
-ifeq ($(BUILD_DIR),)
-        dirs = $(dir $(wildcard ../../*/.ninja_log))
-        ifeq ($(dirs),)
-                $(error Cannot guess build dir, set BUILD_DIR)
-        endif
-        ifneq ($(firstword $(dirs)),$(dirs))
-                $(warning Candidates: $(dirs))
-                $(error Too many build dirs to pick from, set BUILD_DIR)
-        endif
-        BUILD_DIR=$(dirs)
-endif
index b895de8..3a212a0 100644 (file)
@@ -1,4 +1,4 @@
-include ../Makefile.guess
+BUILD_DIR=$(exec ../../tools/find-build-dir.sh)
 
 all setup clean run:
        @basedir=../.. TEST_BASE_DIR=../ BUILD_DIR=$(BUILD_DIR) ./test.sh --$@
index 1280148..545602e 100755 (executable)
@@ -31,7 +31,7 @@ test_setup() {
     echo -n test >$TESTDIR/keyfile
     cryptsetup -q luksFormat ${LOOPDEV}p2 $TESTDIR/keyfile
     cryptsetup luksOpen ${LOOPDEV}p2 varcrypt <$TESTDIR/keyfile
-    mkfs.ext3 -L var /dev/mapper/varcrypt
+    mkfs.ext4 -L var /dev/mapper/varcrypt
     mkdir -p $TESTDIR/root
     mount ${LOOPDEV}p1 $TESTDIR/root
     mkdir -p $TESTDIR/root/var
@@ -67,7 +67,7 @@ EOF
         cat $initdir/etc/crypttab | ddebug
 
         cat >>$initdir/etc/fstab <<EOF
-/dev/mapper/varcrypt    /var    ext3    defaults 0 1
+/dev/mapper/varcrypt    /var    ext4    defaults 0 1
 EOF
     ) || return 1
 
index 493ff00..260cae0 100755 (executable)
@@ -51,6 +51,18 @@ journalctl --sync
 journalctl -b -o cat -t "$ID" >/output
 cmp /expected /output
 
+# --output-fields restricts output
+ID=$(journalctl --new-id128 | sed -n 2p)
+printf $'foo' | systemd-cat -t "$ID" --level-prefix false
+journalctl --sync
+journalctl -b -o export --output-fields=MESSAGE,FOO --output-fields=PRIORITY,MESSAGE -t "$ID" >/output
+[[ `grep -c . /output` -eq 6 ]]
+grep -q '^__CURSOR=' /output
+grep -q '^MESSAGE=foo$' /output
+grep -q '^PRIORITY=6$' /output
+! grep -q '^FOO=' /output
+! grep -q '^SYSLOG_FACILITY=' /output
+
 # Don't lose streams on restart
 systemctl start forever-print-hola
 sleep 3
index e7eb1cb..2f95e90 100755 (executable)
@@ -3,7 +3,6 @@
 # ex: ts=8 sw=4 sts=4 et filetype=sh
 set -e
 TEST_DESCRIPTION="https://github.com/systemd/systemd/issues/2467"
-TEST_NO_NSPAWN=1
 
 . $TEST_BASE_DIR/test-functions
 SKIP_INITRD=yes
@@ -19,7 +18,7 @@ test_setup() {
         eval $(udevadm info --export --query=env --name=${LOOPDEV}p2)
 
         setup_basic_environment
-        dracut_install nc true rm
+        dracut_install true rm
 
         # setup the testsuite service
         cat >$initdir/etc/systemd/system/testsuite.service <<'EOF'
@@ -29,13 +28,15 @@ After=multi-user.target
 
 [Service]
 Type=oneshot
-ExecStart=/bin/sh -e -x -c 'rm -f /tmp/nonexistent; systemctl start test.socket; echo a | nc -U /run/test.ctl; >/testok'
+StandardOutput=tty
+StandardError=tty
+ExecStart=/bin/sh -e -x -c 'rm -f /tmp/nonexistent; systemctl start test.socket; echo > /run/test.ctl; >/testok'
 TimeoutStartSec=10s
 EOF
 
        cat  >$initdir/etc/systemd/system/test.socket <<'EOF'
 [Socket]
-ListenStream=/run/test.ctl
+ListenFIFO=/run/test.ctl
 EOF
 
        cat > $initdir/etc/systemd/system/test.service <<'EOF'
@@ -49,6 +50,7 @@ EOF
 
         setup_testsuite
     ) || return 1
+    setup_nspawn_root
 
     # mask some services that we do not want to run in these tests
     ln -s /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service
index 41cca23..ddcbbc3 100644 (file)
@@ -1,4 +1,4 @@
-include ../Makefile.guess
+BUILD_DIR=$(exec ../../tools/find-build-dir.sh)
 
 all setup run:
        @basedir=../.. TEST_BASE_DIR=../ BUILD_DIR=$(BUILD_DIR) ./test.sh --$@
index 7f7380f..239c7e0 100755 (executable)
@@ -18,12 +18,12 @@ test_setup() {
         eval $(udevadm info --export --query=env --name=${LOOPDEV}p2)
 
         setup_basic_environment
-        dracut_install busybox chmod rmdir unshare
+        dracut_install busybox chmod rmdir unshare ip
 
         cp create-busybox-container $initdir/
 
         ./create-busybox-container $initdir/nc-container
-        initdir="$initdir/nc-container" dracut_install nc
+        initdir="$initdir/nc-container" dracut_install nc ip
 
         # setup the testsuite service
         cat >$initdir/etc/systemd/system/testsuite.service <<EOF
@@ -34,6 +34,8 @@ After=multi-user.target
 [Service]
 ExecStart=/test-nspawn.sh
 Type=oneshot
+StandardOutput=tty
+StandardError=tty
 EOF
 
         cat >$initdir/test-nspawn.sh <<'EOF'
@@ -107,6 +109,52 @@ function run {
        [[ "$is_user_ns_supported" = "no" && "$3" = "yes" ]] && return 1
     fi
 
+    local _netns_opt="--network-namespace-path=/proc/self/ns/net"
+
+    # --network-namespace-path and network-related options cannot be used together
+    if UNIFIED_CGROUP_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn --register=no -D "$_root" "$_netns_opt" --network-interface=lo -b; then
+       return 1
+    fi
+
+    if UNIFIED_CGROUP_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn --register=no -D "$_root" "$_netns_opt" --network-macvlan=lo -b; then
+       return 1
+    fi
+
+    if UNIFIED_CGROUP_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn --register=no -D "$_root" "$_netns_opt" --network-ipvlan=lo -b; then
+       return 1
+    fi
+
+    if UNIFIED_CGROUP_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn --register=no -D "$_root" "$_netns_opt" --network-veth -b; then
+       return 1
+    fi
+
+    if UNIFIED_CGROUP_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn --register=no -D "$_root" "$_netns_opt" --network-veth-extra=lo -b; then
+       return 1
+    fi
+
+    if UNIFIED_CGROUP_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn --register=no -D "$_root" "$_netns_opt" --network-bridge=lo -b; then
+       return 1
+    fi
+
+    if UNIFIED_CGROUP_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn --register=no -D "$_root" "$_netns_opt" --network-zone=zone -b; then
+       return 1
+    fi
+
+    if UNIFIED_CGROUP_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn --register=no -D "$_root" "$_netns_opt" --private-network -b; then
+       return 1
+    fi
+
+    # test --network-namespace-path works with a network namespace created by "ip netns"
+    ip netns add nspawn_test
+    _netns_opt="--network-namespace-path=/run/netns/nspawn_test"
+    UNIFIED_CGROUP_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn --register=no -D "$_root" "$_netns_opt" ip a | grep -E '^1: lo.*DOWN'
+    local r=$?
+    ip netns del nspawn_test
+
+    if [ $r -ne 0 ]; then
+       return 1
+    fi
+
     return 0
 }
 
index b932060..7342645 100755 (executable)
@@ -2,7 +2,7 @@
 # -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
 # ex: ts=8 sw=4 sts=4 et filetype=sh
 set -e
-TEST_DESCRIPTION="Basic systemd setup"
+TEST_DESCRIPTION="/etc/machine-id testing"
 TEST_NO_NSPAWN=1
 SKIP_INITRD=yes
 . $TEST_BASE_DIR/test-functions
diff --git a/test/TEST-16-EXTEND-TIMEOUT/Makefile b/test/TEST-16-EXTEND-TIMEOUT/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-16-EXTEND-TIMEOUT/assess.sh b/test/TEST-16-EXTEND-TIMEOUT/assess.sh
new file mode 100755 (executable)
index 0000000..e7f643f
--- /dev/null
@@ -0,0 +1,55 @@
+#!/bin/bash
+set -v -x
+
+rm -f /test.log
+
+TL=/test.log.XXXXXXXX
+
+function wait_for()
+{
+    service=${1}
+    result=${2:-success}
+    time=${3:-45}
+
+    while [[ ! -f /${service}.terminated && ! -f /${service}.success && $time -gt 0  ]]
+    do
+        sleep 1
+        time=$(( $time - 1 ))
+    done
+
+    if [[ ! -f /${service}.${result} ]]
+    then
+        journalctl -u testsuite-${service/_/-}.service >> "${TL}"
+    fi
+}
+
+# This checks all stages, start, runtime and stop, can be extended by
+# EXTEND_TIMEOUT_USEC
+
+wait_for success_all
+
+# These check that EXTEND_TIMEOUT_USEC that occurs at greater than the
+# extend timeout interval but less then the stage limit (TimeoutStartSec,
+# RuntimeMaxSec, TimeoutStopSec) still succeed.
+
+wait_for success_start
+wait_for success_runtime
+wait_for success_stop
+
+# These ensure that EXTEND_TIMEOUT_USEC will still timeout in the
+# approprate stage, after the stage limit, when the EXTEND_TIMEOUT_USEC
+# message isn't sent within the extend timeout interval.
+
+wait_for fail_start startfail
+wait_for fail_stop stopfail
+wait_for fail_runtime runtimefail
+
+if [[ -f "${TL}" ]]
+then
+    # no mv
+    cp "${TL}" /test.log
+    exit 1
+else
+    touch /testok
+    exit 0
+fi
diff --git a/test/TEST-16-EXTEND-TIMEOUT/extend_timeout_test_service.sh b/test/TEST-16-EXTEND-TIMEOUT/extend_timeout_test_service.sh
new file mode 100755 (executable)
index 0000000..1fd2768
--- /dev/null
@@ -0,0 +1,70 @@
+#!/bin/bash
+set -x
+set -e
+set -o pipefail
+
+# sleep interval (seconds)
+sleep_interval=1
+# extend_timeout_interval second(s)
+extend_timeout_interval=1
+# number of sleep_intervals before READY=1
+start_intervals=10
+# number of sleep_intervals before exiting
+stop_intervals=10
+# run intervals, number of sleep_intervals to run
+run_intervals=7
+# service name
+SERVICE=unknown
+
+while [ $# -gt 0 ];
+do
+    eval ${1%=*}=${1#*=}
+    shift
+done
+
+# We convert to usec
+extend_timeout_interval=$(( $extend_timeout_interval * 1000000 ))
+
+trap "{ touch /${SERVICE}.terminated; exit 1; }"  SIGTERM SIGABRT
+
+rm -f /${SERVICE}.*
+touch /${SERVICE}.startfail
+
+systemd-notify EXTEND_TIMEOUT_USEC=$extend_timeout_interval
+while [ $start_intervals -gt 0 ]
+do
+    sleep $sleep_interval
+    start_intervals=$(( $start_intervals - 1 ))
+    systemd-notify EXTEND_TIMEOUT_USEC=$extend_timeout_interval
+done
+
+systemd-notify --ready --status="Waiting for your request"
+
+touch /${SERVICE}.runtimefail
+rm /${SERVICE}.startfail
+
+systemd-notify EXTEND_TIMEOUT_USEC=$extend_timeout_interval
+while [ $run_intervals -gt 0 ]
+do
+    sleep $sleep_interval
+    run_intervals=$(( $run_intervals - 1 ))
+    systemd-notify EXTEND_TIMEOUT_USEC=$extend_timeout_interval
+done
+
+systemd-notify STOPPING=1
+
+touch /${SERVICE}.stopfail
+rm /${SERVICE}.runtimefail
+
+systemd-notify EXTEND_TIMEOUT_USEC=$extend_timeout_interval
+while [ $stop_intervals -gt 0 ]
+do
+    sleep $sleep_interval
+    stop_intervals=$(( $stop_intervals - 1 ))
+    systemd-notify EXTEND_TIMEOUT_USEC=$extend_timeout_interval
+done
+
+touch /${SERVICE}.success
+rm /${SERVICE}.stopfail
+
+exit 0
diff --git a/test/TEST-16-EXTEND-TIMEOUT/test.sh b/test/TEST-16-EXTEND-TIMEOUT/test.sh
new file mode 100755 (executable)
index 0000000..4544672
--- /dev/null
@@ -0,0 +1,52 @@
+#!/bin/bash
+# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
+# ex: ts=8 sw=4 sts=4 et filetype=sh
+set -e
+TEST_DESCRIPTION="EXTEND_TIMEOUT_USEC=usec start/runtime/stop tests"
+SKIP_INITRD=yes
+
+. $TEST_BASE_DIR/test-functions
+
+test_setup() {
+    create_empty_image
+    mkdir -p $TESTDIR/root
+    mount ${LOOPDEV}p1 $TESTDIR/root
+
+    # Create what will eventually be our root filesystem onto an overlay
+    (
+        eval $(udevadm info --export --query=env --name=${LOOPDEV}p2)
+
+        setup_basic_environment
+
+        for s in success-all success-start success-stop success-runtime \
+                 fail-start fail-stop fail-runtime
+        do
+            cp testsuite-${s}.service ${initdir}/etc/systemd/system
+        done
+        cp testsuite.service ${initdir}/etc/systemd/system
+
+        cp extend_timeout_test_service.sh ${initdir}/
+        cp assess.sh ${initdir}/
+        cp $BUILD_DIR/systemd-notify ${initdir}/bin
+        cp $BUILD_DIR/src/shared/libsystemd-shared-*.so ${initdir}/usr/lib
+
+        setup_testsuite
+    ) || return 1
+    # mask some services that we do not want to run in these tests
+    ln -s /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service
+    ln -s /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service
+    ln -s /dev/null $initdir/etc/systemd/system/systemd-networkd.service
+    ln -s /dev/null $initdir/etc/systemd/system/systemd-networkd.socket
+    ln -s /dev/null $initdir/etc/systemd/system/systemd-resolved.service
+
+    setup_nspawn_root
+
+    ddebug "umount $TESTDIR/root"
+    umount $TESTDIR/root
+}
+
+test_cleanup() {
+    return 0
+}
+
+do_test "$@"
diff --git a/test/TEST-16-EXTEND-TIMEOUT/testsuite-fail-runtime.service b/test/TEST-16-EXTEND-TIMEOUT/testsuite-fail-runtime.service
new file mode 100644 (file)
index 0000000..e0b9f6a
--- /dev/null
@@ -0,0 +1,13 @@
+
+[Unit]
+Description=Testsuite: Fail Runtime (EXTEND_TIMEOUT_USEC Didn't occur in sufficient time after RuntimeSecMax.)
+
+[Service]
+
+# EXTEND_TIMEOUT_USEC on runtime start (0) and 7 seconds after. Systemd will expect one at 7+5 (extend_timeout_interval)
+# seconds this won't happen until 7 + 7 (sleep interval) seconds. Therefore timeout at 12 seconds.
+Type=notify
+TimeoutStartSec=4
+TimeoutStopSec=4
+RuntimeMaxSec=10
+ExecStart=/extend_timeout_test_service.sh SERVICE=fail_runtime extend_timeout_interval=5 sleep_interval=7 start_intervals=0 run_intervals=2 stop_intervals=0
diff --git a/test/TEST-16-EXTEND-TIMEOUT/testsuite-fail-start.service b/test/TEST-16-EXTEND-TIMEOUT/testsuite-fail-start.service
new file mode 100644 (file)
index 0000000..c3fcf23
--- /dev/null
@@ -0,0 +1,13 @@
+
+[Unit]
+Description=Testsuite: Fail Start (EXTEND_TIMEOUT_USEC Didn't occur in sufficient time after TimeoutStartSec.)
+
+[Service]
+
+# EXTEND_TIMEOUT_USEC on startup and 7 seconds from start. Systemd will expect one at 7+5 (extend_timeout_interval)
+# seconds  this won't happen until 7 + 7 (sleep interval) seconds. Therefore timeout at 12 seconds.
+Type=notify
+TimeoutStartSec=10
+TimeoutStopSec=4
+RuntimeMaxSec=4
+ExecStart=/extend_timeout_test_service.sh SERVICE=fail_start extend_timeout_interval=5 sleep_interval=7 start_intervals=2 run_intervals=0 stop_intervals=0
diff --git a/test/TEST-16-EXTEND-TIMEOUT/testsuite-fail-stop.service b/test/TEST-16-EXTEND-TIMEOUT/testsuite-fail-stop.service
new file mode 100644 (file)
index 0000000..ce76d10
--- /dev/null
@@ -0,0 +1,16 @@
+
+[Unit]
+Description=Testsuite: Fail Stop (EXTEND_TIMEOUT_USEC Didn't occur in sufficient time after TimeoutStopSec.)
+
+[Service]
+
+# EXTEND_TIMEOUT_USEC on stop (0) and 7 seconds after. Systemd will expect one at 7+5 (extend_timeout_interval)
+# seconds this won't happen until 7 + 7 (sleep interval) seconds. Therefore timeout at 12 seconds.
+Type=notify
+TimeoutStartSec=4
+TimeoutStopSec=10
+RuntimeMaxSec=4
+ExecStart=/extend_timeout_test_service.sh SERVICE=fail_stop extend_timeout_interval=5 sleep_interval=7 start_intervals=0 run_intervals=0 stop_intervals=2
+# Due to 6041a7ee2c1bbff6301082f192fc1b0882400d42 SIGTERM isn't sent as the service shuts down with STOPPING=1
+# This file makes the test assess.sh quicker by notifing it that this test has finished.
+ExecStopPost=/bin/bash -c '[[ $SERVICE_RESULT == timeout && $EXIT_CODE == killed ]] && touch /fail_runtime.terminated'
diff --git a/test/TEST-16-EXTEND-TIMEOUT/testsuite-success-all.service b/test/TEST-16-EXTEND-TIMEOUT/testsuite-success-all.service
new file mode 100644 (file)
index 0000000..666f422
--- /dev/null
@@ -0,0 +1,14 @@
+
+[Unit]
+Description=Testsuite: EXTEND_TIMEOUT_USEC Success - extend timeout on all services
+
+[Service]
+
+# Normal success - startup / runtime / shutdown all take 8 seconds which is within the EXTEND_TIMEOUT_USEC=4 seconds interval
+# runtime is 8+8+8 seconds. so we are relying on the EXTEND_TIMEOUT_USEC to exceed all stages, Start, Runtime and Stop.
+# success occurs after 24 seconds
+Type=notify
+TimeoutStartSec=4
+TimeoutStopSec=4
+RuntimeMaxSec=4
+ExecStart=/extend_timeout_test_service.sh SERVICE=success_all extend_timeout_interval=4 sleep_interval=2 start_intervals=3 run_intervals=3 stop_intervals=3
diff --git a/test/TEST-16-EXTEND-TIMEOUT/testsuite-success-runtime.service b/test/TEST-16-EXTEND-TIMEOUT/testsuite-success-runtime.service
new file mode 100644 (file)
index 0000000..dc226f5
--- /dev/null
@@ -0,0 +1,13 @@
+
+[Unit]
+Description=Testsuite: Success Runtime (EXTEND_TIMEOUT_USEC > WATCHDOG_USEC however < RuntimeMaxSec)
+
+[Service]
+
+# EXTEND_TIMEOUT_USEC=4 second once during runtime, but sleep for 6 seconds.
+# Runtime is 6 seconds and < RuntimeMaxSec so still successful.
+Type=notify
+TimeoutStartSec=4
+TimeoutStopSec=4
+RuntimeMaxSec=8
+ExecStart=/extend_timeout_test_service.sh SERVICE=success_runtime extend_timeout_interval=4 sleep_interval=6 start_intervals=0 run_intervals=1 stop_intervals=0
diff --git a/test/TEST-16-EXTEND-TIMEOUT/testsuite-success-start.service b/test/TEST-16-EXTEND-TIMEOUT/testsuite-success-start.service
new file mode 100644 (file)
index 0000000..228eece
--- /dev/null
@@ -0,0 +1,13 @@
+
+[Unit]
+Description=Testsuite: Success Start (EXTEND_TIMEOUT_USEC > WATCHDOG_USEC however < TimeoutStartSec)
+
+[Service]
+
+# EXTEND_TIMEOUT_USEC=4 second interval once at startup, but sleep 6 seconds.
+# Therefore startup is 6 seconds and < TimeoutStartSec so still successful.
+Type=notify
+TimeoutStartSec=8
+TimeoutStopSec=4
+RuntimeMaxSec=4
+ExecStart=/extend_timeout_test_service.sh SERVICE=success_start extend_timeout_interval=4 sleep_interval=6 start_intervals=1 run_intervals=0 stop_intervals=0
diff --git a/test/TEST-16-EXTEND-TIMEOUT/testsuite-success-stop.service b/test/TEST-16-EXTEND-TIMEOUT/testsuite-success-stop.service
new file mode 100644 (file)
index 0000000..b809397
--- /dev/null
@@ -0,0 +1,13 @@
+
+[Unit]
+Description=Testsuite: Success Stop (EXTEND_TIMEOUT_USEC > WATCHDOG_USEC however < TimeoutStopSec)
+
+[Service]
+
+# EXTEND_TIMEOUT_USEC=4 seconds once during shutdown, but sleep for 6 seconds.
+# Therefore stop time is 6 seconds and < TimeoutStopSec so still successful.
+Type=notify
+TimeoutStartSec=4
+TimeoutStopSec=8
+RuntimeMaxSec=4
+ExecStart=/extend_timeout_test_service.sh SERVICE=success_stop extend_timeout_interval=4 sleep_interval=6 start_intervals=0 run_intervals=0 stop_intervals=1
diff --git a/test/TEST-16-EXTEND-TIMEOUT/testsuite.service b/test/TEST-16-EXTEND-TIMEOUT/testsuite.service
new file mode 100644 (file)
index 0000000..e1cd5ca
--- /dev/null
@@ -0,0 +1,18 @@
+
+[Unit]
+Description=Testsuite: Assess all other testsuite-*.services worked as expected
+
+Wants=testsuite-success-all.service
+Wants=testsuite-success-start.service
+Wants=testsuite-success-runtime.service
+Wants=testsuite-success-stop.service
+Wants=testsuite-fail-start.service
+Wants=testsuite-fail-stop.service
+Wants=testsuite-fail-runtime.service
+StopWhenUnneeded=yes
+
+[Service]
+
+Type=simple
+ExecStartPre=/assess.sh
+ExecStart=/bin/true
diff --git a/test/TEST-17-UDEV-WANTS/Makefile b/test/TEST-17-UDEV-WANTS/Makefile
new file mode 100644 (file)
index 0000000..3a212a0
--- /dev/null
@@ -0,0 +1,4 @@
+BUILD_DIR=$(exec ../../tools/find-build-dir.sh)
+
+all setup clean run:
+       @basedir=../.. TEST_BASE_DIR=../ BUILD_DIR=$(BUILD_DIR) ./test.sh --$@
diff --git a/test/TEST-17-UDEV-WANTS/test.sh b/test/TEST-17-UDEV-WANTS/test.sh
new file mode 100755 (executable)
index 0000000..24989eb
--- /dev/null
@@ -0,0 +1,49 @@
+#!/bin/bash
+# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
+# ex: ts=8 sw=4 sts=4 et filetype=sh
+set -e
+TEST_DESCRIPTION="UDEV SYSTEMD_WANTS property"
+TEST_NO_NSPAWN=1
+
+. $TEST_BASE_DIR/test-functions
+QEMU_TIMEOUT=180
+
+test_setup() {
+    create_empty_image
+    mkdir -p $TESTDIR/root
+    mount ${LOOPDEV}p1 $TESTDIR/root
+
+    (
+        LOG_LEVEL=5
+        eval $(udevadm info --export --query=env --name=${LOOPDEV}p2)
+
+        setup_basic_environment
+
+        # mask some services that we do not want to run in these tests
+        ln -s /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service
+        ln -s /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service
+        ln -s /dev/null $initdir/etc/systemd/system/systemd-networkd.service
+        ln -s /dev/null $initdir/etc/systemd/system/systemd-networkd.socket
+        ln -s /dev/null $initdir/etc/systemd/system/systemd-resolved.service
+
+        # setup the testsuite service
+        cat >$initdir/etc/systemd/system/testsuite.service <<EOF
+[Unit]
+Description=Testsuite service
+
+[Service]
+ExecStart=/bin/bash -x /testsuite.sh
+Type=oneshot
+StandardOutput=tty
+StandardError=tty
+EOF
+        cp testsuite.sh $initdir/
+
+        setup_testsuite
+    ) || return 1
+
+    ddebug "umount $TESTDIR/root"
+    umount $TESTDIR/root
+}
+
+do_test "$@"
diff --git a/test/TEST-17-UDEV-WANTS/testsuite.sh b/test/TEST-17-UDEV-WANTS/testsuite.sh
new file mode 100755 (executable)
index 0000000..5f97084
--- /dev/null
@@ -0,0 +1,76 @@
+#!/bin/bash
+# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
+# ex: ts=8 sw=4 sts=4 et filetype=sh
+set -ex
+set -o pipefail
+
+mkdir -p /run/udev/rules.d/
+
+rm -f /run/udev/rules.d/50-testsuite.rules
+udevadm control --reload
+udevadm trigger /dev/sda
+
+while : ; do
+    (
+        udevadm info /dev/sda | grep -q -v SYSTEMD_WANTS=foobar.service
+        udevadm info /dev/sda | grep -q -v SYSTEMD_WANTS=waldo.service
+        systemctl show -p WantedBy foobar.service | grep -q -v sda
+        systemctl show -p WantedBy waldo.service | grep -q -v sda
+    ) && break
+
+    sleep .5
+done
+
+cat > /run/udev/rules.d/50-testsuite.rules <<EOF
+ACTION!="remove", SUBSYSTEM=="block", KERNEL=="sda", ENV{SYSTEMD_WANTS}="foobar.service"
+EOF
+udevadm control --reload
+udevadm trigger /dev/sda
+
+while : ; do
+    (
+        udevadm info /dev/sda | grep -q SYSTEMD_WANTS=foobar.service
+        udevadm info /dev/sda | grep -q -v SYSTEMD_WANTS=waldo.service
+        systemctl show -p WantedBy foobar.service | grep -q sda
+        systemctl show -p WantedBy waldo.service | grep -q -v sda
+    ) && break
+
+    sleep .5
+done
+
+cat > /run/udev/rules.d/50-testsuite.rules <<EOF
+ACTION!="remove", SUBSYSTEM=="block", KERNEL=="sda", ENV{SYSTEMD_WANTS}="waldo.service"
+EOF
+udevadm control --reload
+udevadm trigger /dev/sda
+
+while : ; do
+    (
+        udevadm info /dev/sda | grep -q -v SYSTEMD_WANTS=foobar.service
+        udevadm info /dev/sda | grep -q SYSTEMD_WANTS=waldo.service
+        systemctl show -p WantedBy foobar.service | grep -q -v sda
+        systemctl show -p WantedBy waldo.service | grep -q sda
+    ) && break
+
+    sleep .5
+done
+
+rm /run/udev/rules.d/50-testsuite.rules
+
+udevadm control --reload
+udevadm trigger /dev/sda
+
+while : ; do
+    (
+        udevadm info /dev/sda | grep -q -v SYSTEMD_WANTS=foobar.service
+        udevadm info /dev/sda | grep -q -v SYSTEMD_WANTS=waldo.service
+        systemctl show -p WantedBy foobar.service | grep -q -v sda
+        systemctl show -p WantedBy waldo.service | grep -q -v sda
+    ) && break
+
+    sleep .5
+done
+
+echo OK > /testok
+
+exit 0
diff --git a/test/TEST-18-FAILUREACTION/Makefile b/test/TEST-18-FAILUREACTION/Makefile
new file mode 100644 (file)
index 0000000..3a212a0
--- /dev/null
@@ -0,0 +1,4 @@
+BUILD_DIR=$(exec ../../tools/find-build-dir.sh)
+
+all setup clean run:
+       @basedir=../.. TEST_BASE_DIR=../ BUILD_DIR=$(BUILD_DIR) ./test.sh --$@
diff --git a/test/TEST-18-FAILUREACTION/test.sh b/test/TEST-18-FAILUREACTION/test.sh
new file mode 100755 (executable)
index 0000000..e48ba9b
--- /dev/null
@@ -0,0 +1,42 @@
+#!/bin/bash
+# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
+# ex: ts=8 sw=4 sts=4 et filetype=sh
+set -e
+TEST_DESCRIPTION="FailureAction= operation"
+
+. $TEST_BASE_DIR/test-functions
+QEMU_TIMEOUT=180
+
+test_setup() {
+    create_empty_image
+    mkdir -p $TESTDIR/root
+    mount ${LOOPDEV}p1 $TESTDIR/root
+
+    (
+        LOG_LEVEL=5
+        eval $(udevadm info --export --query=env --name=${LOOPDEV}p2)
+
+        setup_basic_environment
+
+        # setup the testsuite service
+        cat >$initdir/etc/systemd/system/testsuite.service <<EOF
+[Unit]
+Description=Testsuite service
+
+[Service]
+ExecStart=/bin/bash -x /testsuite.sh
+Type=oneshot
+StandardOutput=tty
+StandardError=tty
+EOF
+        cp testsuite.sh $initdir/
+
+        setup_testsuite
+    ) || return 1
+    setup_nspawn_root
+
+    ddebug "umount $TESTDIR/root"
+    umount $TESTDIR/root
+}
+
+do_test "$@"
diff --git a/test/TEST-18-FAILUREACTION/testsuite.sh b/test/TEST-18-FAILUREACTION/testsuite.sh
new file mode 100755 (executable)
index 0000000..1867cc3
--- /dev/null
@@ -0,0 +1,18 @@
+#!/bin/bash
+# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
+# ex: ts=8 sw=4 sts=4 et filetype=sh
+set -ex
+set -o pipefail
+
+systemd-run --wait -p FailureAction=poweroff true
+! systemd-run --wait -p SuccessAction=poweroff false
+
+if test -f /firstphase ; then
+    echo OK > /firstphase
+    systemd-run --wait -p SuccessAction=reboot true
+else
+    echo OK > /testok
+    systemd-run --wait -p FailureAction=poweroff false
+fi
+
+sleep infinity
diff --git a/test/TEST-19-DELEGATE/Makefile b/test/TEST-19-DELEGATE/Makefile
new file mode 100644 (file)
index 0000000..3a212a0
--- /dev/null
@@ -0,0 +1,4 @@
+BUILD_DIR=$(exec ../../tools/find-build-dir.sh)
+
+all setup clean run:
+       @basedir=../.. TEST_BASE_DIR=../ BUILD_DIR=$(BUILD_DIR) ./test.sh --$@
diff --git a/test/TEST-19-DELEGATE/test.sh b/test/TEST-19-DELEGATE/test.sh
new file mode 100755 (executable)
index 0000000..841a29c
--- /dev/null
@@ -0,0 +1,43 @@
+#!/bin/bash
+# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
+# ex: ts=8 sw=4 sts=4 et filetype=sh
+set -e
+TEST_DESCRIPTION="test cgroup delegation in the unifier hierarchy"
+TEST_NO_NSPAWN=1
+
+. $TEST_BASE_DIR/test-functions
+QEMU_TIMEOUT=180
+UNIFIED_CGROUP_HIERARCHY=yes
+
+test_setup() {
+    create_empty_image
+    mkdir -p $TESTDIR/root
+    mount ${LOOPDEV}p1 $TESTDIR/root
+
+    (
+        LOG_LEVEL=5
+        eval $(udevadm info --export --query=env --name=${LOOPDEV}p2)
+
+        setup_basic_environment
+
+        # setup the testsuite service
+        cat >$initdir/etc/systemd/system/testsuite.service <<EOF
+[Unit]
+Description=Testsuite service
+
+[Service]
+ExecStart=/bin/bash -x /testsuite.sh
+Type=oneshot
+StandardOutput=tty
+StandardError=tty
+EOF
+        cp testsuite.sh $initdir/
+
+        setup_testsuite
+    ) || return 1
+
+    ddebug "umount $TESTDIR/root"
+    umount $TESTDIR/root
+}
+
+do_test "$@"
diff --git a/test/TEST-19-DELEGATE/testsuite.sh b/test/TEST-19-DELEGATE/testsuite.sh
new file mode 100755 (executable)
index 0000000..c738bea
--- /dev/null
@@ -0,0 +1,24 @@
+#!/bin/bash
+# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
+# ex: ts=8 sw=4 sts=4 et filetype=sh
+set -ex
+set -o pipefail
+
+if grep -q cgroup2 /proc/filesystems ; then
+        systemd-run --wait --unit=test0.service -p "DynamicUser=1" -p "Delegate=" \
+                    test -w /sys/fs/cgroup/system.slice/test0.service/ -a \
+                    -w /sys/fs/cgroup/system.slice/test0.service/cgroup.procs -a \
+                    -w /sys/fs/cgroup/system.slice/test0.service/cgroup.subtree_control
+
+        systemd-run --wait --unit=test1.service -p "DynamicUser=1" -p "Delegate=memory pids" \
+                    grep memory /sys/fs/cgroup/system.slice/test1.service/cgroup.controllers
+
+        systemd-run --wait --unit=test2.service -p "DynamicUser=1" -p "Delegate=memory pids" \
+                    grep pids /sys/fs/cgroup/system.slice/test2.service/cgroup.controllers
+else
+        echo "Skipping TEST-19-DELEGATE, as the kernel doesn't actually support cgroupsv2" >&2
+fi
+
+echo OK > /testok
+
+exit 0
index a4f1f30..e25f3b4 100755 (executable)
@@ -1,6 +1,8 @@
 #!/usr/bin/env python3
+# SPDX-License-Identifier: LGPL-2.1+
 
 OUTFILE_HEADER = """#!/usr/bin/env python3
+# SPDX-License-Identifier: LGPL-2.1+
 #
 # create-sys-script.py
 #
index 2221c0d..a1f3270 100755 (executable)
@@ -1,5 +1,7 @@
 #!/bin/sh
-# call built systemd-hwdb update on our hwdb files to ensure that they parse
+# SPDX-License-Identifier: LGPL-2.1+
+#
+# Call built systemd-hwdb update on our hwdb files to ensure that they parse
 # without error
 #
 # (C) 2016 Canonical Ltd.
@@ -9,7 +11,7 @@
 # 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.
-
+#
 # systemd is distributed in the hope that it will be useful, but
 # WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
@@ -20,6 +22,7 @@
 
 set -e
 
+export SYSTEMD_LOG_LEVEL=info
 ROOTDIR=$(dirname $(dirname $(readlink -f $0)))
 SYSTEMD_HWDB=./systemd-hwdb
 
index 995a971..5c533f4 100644 (file)
@@ -1,18 +1,38 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
+# Copyright 2017 Zbigniew Jędrzejewski-Szmek
+#
+# 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.
+#
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
 test_data_files = '''
         a.service
-        basic.target
         b.service
+        basic.target
         c.service
-        daughter.service
         d.service
-        end.service
+        daughter.service
         e.service
+        end.service
         f.service
-        grandchild.service
         g.service
+        grandchild.service
+        h.service
         hello-after-sleep.target
         hello.service
-        h.service
+        hwdb/10-bad.hwdb
+        journal-data/journal-1.txt
+        journal-data/journal-2.txt
         parent-deep.slice
         parent.slice
         sched_idle_bad.service
@@ -25,112 +45,124 @@ test_data_files = '''
         sockets.target
         son.service
         sysinit.target
-        testsuite.target
-        timers.target
-        unstoppable.service
-        test-path/paths.target
-        test-path/basic.target
-        test-path/sysinit.target
-        test-path/path-changed.service
-        test-path/path-directorynotempty.service
-        test-path/path-existsglob.service
-        test-path/path-exists.service
-        test-path/path-makedirectory.service
-        test-path/path-modified.service
-        test-path/path-mycustomunit.service
-        test-path/path-service.service
-        test-path/path-changed.path
-        test-path/path-directorynotempty.path
-        test-path/path-existsglob.path
-        test-path/path-exists.path
-        test-path/path-makedirectory.path
-        test-path/path-modified.path
-        test-path/path-unit.path
+        test-execute/exec-bindpaths.service
+        test-execute/exec-capabilityambientset-merge-nfsnobody.service
+        test-execute/exec-capabilityambientset-merge.service
+        test-execute/exec-capabilityambientset-nfsnobody.service
+        test-execute/exec-capabilityambientset.service
+        test-execute/exec-capabilityboundingset-invert.service
+        test-execute/exec-capabilityboundingset-merge.service
+        test-execute/exec-capabilityboundingset-reset.service
+        test-execute/exec-capabilityboundingset-simple.service
+        test-execute/exec-cpuaffinity1.service
+        test-execute/exec-cpuaffinity2.service
+        test-execute/exec-cpuaffinity3.service
+        test-execute/exec-dynamicuser-fixeduser-one-supplementarygroup.service
+        test-execute/exec-dynamicuser-fixeduser.service
+        test-execute/exec-dynamicuser-statedir-migrate-step1.service
+        test-execute/exec-dynamicuser-statedir-migrate-step2.service
+        test-execute/exec-dynamicuser-statedir.service
+        test-execute/exec-dynamicuser-supplementarygroups.service
         test-execute/exec-environment-empty.service
         test-execute/exec-environment-multiple.service
         test-execute/exec-environment.service
+        test-execute/exec-environmentfile.service
+        test-execute/exec-group-nfsnobody.service
+        test-execute/exec-group-nogroup.service
+        test-execute/exec-group.service
+        test-execute/exec-ignoresigpipe-no.service
+        test-execute/exec-ignoresigpipe-yes.service
+        test-execute/exec-inaccessiblepaths-mount-propagation.service
+        test-execute/exec-inaccessiblepaths-proc.service
+        test-execute/exec-ioschedulingclass-best-effort.service
+        test-execute/exec-ioschedulingclass-idle.service
+        test-execute/exec-ioschedulingclass-none.service
+        test-execute/exec-ioschedulingclass-realtime.service
+        test-execute/exec-oomscoreadjust-negative.service
+        test-execute/exec-oomscoreadjust-positive.service
         test-execute/exec-passenvironment-absent.service
         test-execute/exec-passenvironment-empty.service
         test-execute/exec-passenvironment-repeated.service
         test-execute/exec-passenvironment.service
-        test-execute/exec-group.service
-        test-execute/exec-group-nfsnobody.service
-        test-execute/exec-supplementarygroups.service
-        test-execute/exec-supplementarygroups-single-group.service
-        test-execute/exec-supplementarygroups-single-group-user.service
-        test-execute/exec-supplementarygroups-multiple-groups-default-group-user.service
-        test-execute/exec-supplementarygroups-multiple-groups-withgid.service
-        test-execute/exec-supplementarygroups-multiple-groups-withuid.service
-        test-execute/exec-dynamicuser-fixeduser.service
-        test-execute/exec-dynamicuser-fixeduser-one-supplementarygroup.service
-        test-execute/exec-dynamicuser-supplementarygroups.service
-        test-execute/exec-dynamicuser-state-dir.service
-        test-execute/exec-ignoresigpipe-no.service
-        test-execute/exec-ignoresigpipe-yes.service
-        test-execute/exec-personality-x86-64.service
-        test-execute/exec-personality-x86.service
-        test-execute/exec-personality-s390.service
+        test-execute/exec-personality-aarch64.service
         test-execute/exec-personality-ppc64.service
         test-execute/exec-personality-ppc64le.service
-        test-execute/exec-personality-aarch64.service
-        test-execute/exec-privatedevices-no.service
-        test-execute/exec-privatedevices-yes.service
+        test-execute/exec-personality-s390.service
+        test-execute/exec-personality-x86-64.service
+        test-execute/exec-personality-x86.service
         test-execute/exec-privatedevices-no-capability-mknod.service
+        test-execute/exec-privatedevices-no-capability-sys-rawio.service
+        test-execute/exec-privatedevices-no.service
         test-execute/exec-privatedevices-yes-capability-mknod.service
+        test-execute/exec-privatedevices-yes-capability-sys-rawio.service
+        test-execute/exec-privatedevices-yes.service
+        test-execute/exec-privatenetwork-yes.service
+        test-execute/exec-privatetmp-no.service
+        test-execute/exec-privatetmp-yes.service
         test-execute/exec-protectkernelmodules-no-capabilities.service
         test-execute/exec-protectkernelmodules-yes-capabilities.service
         test-execute/exec-protectkernelmodules-yes-mount-propagation.service
-        test-execute/exec-privatetmp-no.service
-        test-execute/exec-privatetmp-yes.service
-        test-execute/exec-readonlypaths.service
         test-execute/exec-readonlypaths-mount-propagation.service
+        test-execute/exec-readonlypaths-simple.service
+        test-execute/exec-readonlypaths-with-bindpaths.service
+        test-execute/exec-readonlypaths.service
         test-execute/exec-readwritepaths-mount-propagation.service
-        test-execute/exec-inaccessiblepaths-mount-propagation.service
-        test-execute/exec-inaccessiblepaths-proc.service
-        test-execute/exec-spec-interpolation.service
-        test-execute/exec-systemcallerrornumber.service
-        test-execute/exec-systemcallfilter-failing2.service
+        test-execute/exec-restrictnamespaces-mnt-blacklist.service
+        test-execute/exec-restrictnamespaces-mnt.service
+        test-execute/exec-restrictnamespaces-no.service
+        test-execute/exec-restrictnamespaces-yes.service
+        test-execute/exec-runtimedirectory-mode.service
+        test-execute/exec-runtimedirectory-owner-nfsnobody.service
+        test-execute/exec-runtimedirectory-owner.service
+        test-execute/exec-runtimedirectory.service
+        test-execute/exec-specifier-interpolation.service
+        test-execute/exec-specifier.service
+        test-execute/exec-specifier@.service
+        test-execute/exec-standardinput-data.service
+        test-execute/exec-standardinput-file.service
+        test-execute/exec-supplementarygroups-multiple-groups-default-group-user.service
+        test-execute/exec-supplementarygroups-multiple-groups-withgid.service
+        test-execute/exec-supplementarygroups-multiple-groups-withuid.service
+        test-execute/exec-supplementarygroups-single-group-user.service
+        test-execute/exec-supplementarygroups-single-group.service
+        test-execute/exec-supplementarygroups.service
+        test-execute/exec-systemcallerrornumber-name.service
+        test-execute/exec-systemcallerrornumber-number.service
         test-execute/exec-systemcallfilter-failing.service
-        test-execute/exec-systemcallfilter-not-failing2.service
+        test-execute/exec-systemcallfilter-failing2.service
         test-execute/exec-systemcallfilter-not-failing.service
-        test-execute/exec-systemcallfilter-system-user.service
+        test-execute/exec-systemcallfilter-not-failing2.service
         test-execute/exec-systemcallfilter-system-user-nfsnobody.service
-        test-execute/exec-unset-environment.service
-        test-execute/exec-user.service
-        test-execute/exec-user-nfsnobody.service
-        test-execute/exec-workingdirectory.service
+        test-execute/exec-systemcallfilter-system-user.service
+        test-execute/exec-systemcallfilter-with-errno-name.service
+        test-execute/exec-systemcallfilter-with-errno-number.service
         test-execute/exec-umask-0177.service
         test-execute/exec-umask-default.service
-        test-execute/exec-privatenetwork-yes.service
-        test-execute/exec-environmentfile.service
-        test-execute/exec-oomscoreadjust-positive.service
-        test-execute/exec-oomscoreadjust-negative.service
-        test-execute/exec-ioschedulingclass-best-effort.service
-        test-execute/exec-ioschedulingclass-idle.service
-        test-execute/exec-ioschedulingclass-none.service
-        test-execute/exec-ioschedulingclass-realtime.service
-        test-execute/exec-capabilityboundingset-invert.service
-        test-execute/exec-capabilityboundingset-merge.service
-        test-execute/exec-capabilityboundingset-reset.service
-        test-execute/exec-capabilityboundingset-simple.service
-        test-execute/exec-capabilityambientset.service
-        test-execute/exec-capabilityambientset-nfsnobody.service
-        test-execute/exec-capabilityambientset-merge.service
-        test-execute/exec-capabilityambientset-merge-nfsnobody.service
-        test-execute/exec-runtimedirectory.service
-        test-execute/exec-runtimedirectory-mode.service
-        test-execute/exec-runtimedirectory-owner.service
-        test-execute/exec-runtimedirectory-owner-nfsnobody.service
-        test-execute/exec-restrict-namespaces-no.service
-        test-execute/exec-restrict-namespaces-yes.service
-        test-execute/exec-restrict-namespaces-mnt.service
-        test-execute/exec-restrict-namespaces-mnt-blacklist.service
-        test-execute/exec-read-only-path-succeed.service
-        test-execute/exec-privatedevices-yes-capability-sys-rawio.service
-        test-execute/exec-privatedevices-no-capability-sys-rawio.service
-        hwdb/10-bad.hwdb
-        journal-data/journal-1.txt
-        journal-data/journal-2.txt
+        test-execute/exec-unsetenvironment.service
+        test-execute/exec-user-nfsnobody.service
+        test-execute/exec-user.service
+        test-execute/exec-workingdirectory.service
+        test-path/basic.target
+        test-path/path-changed.path
+        test-path/path-changed.service
+        test-path/path-directorynotempty.path
+        test-path/path-directorynotempty.service
+        test-path/path-exists.path
+        test-path/path-exists.service
+        test-path/path-existsglob.path
+        test-path/path-existsglob.service
+        test-path/path-makedirectory.path
+        test-path/path-makedirectory.service
+        test-path/path-modified.path
+        test-path/path-modified.service
+        test-path/path-mycustomunit.service
+        test-path/path-service.service
+        test-path/path-unit.path
+        test-path/paths.target
+        test-path/sysinit.target
+        testsuite.target
+        timers.target
+        unstoppable.service
 '''.split()
 
 if conf.get('ENABLE_RESOLVE') == 1
@@ -163,9 +195,18 @@ endif
 
 ############################################################
 
-sysv_generator_test_py = find_program('sysv-generator-test.py')
-test('sysv-generator-test',
-     sysv_generator_test_py)
+rule_syntax_check_py = find_program('rule-syntax-check.py')
+test('rule-syntax-check',
+     rule_syntax_check_py,
+     args : all_rules)
+
+############################################################
+
+if conf.get('HAVE_SYSV_COMPAT') == 1
+        sysv_generator_test_py = find_program('sysv-generator-test.py')
+        test('sysv-generator-test',
+             sysv_generator_test_py)
+endif
 
 ############################################################
 
@@ -181,6 +222,9 @@ udev_test_pl = find_program('udev-test.pl')
 test('udev-test',
      udev_test_pl)
 
-hwdb_test_sh = find_program('hwdb-test.sh')
-test('hwdb-test',
-     hwdb_test_sh)
+if conf.get('ENABLE_HWDB') == 1
+        hwdb_test_sh = find_program('hwdb-test.sh')
+        test('hwdb-test',
+             hwdb_test_sh,
+             timeout : 90)
+endif
index 5760ca5..3918d85 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env python3
+# SPDX-License-Identifier: LGPL-2.1+
 #
 # networkd integration test
 # This uses temporary configuration in /run and temporary veth devices, and
index 14739df..e053b02 100755 (executable)
@@ -1,4 +1,6 @@
 #!/usr/bin/env python3
+# SPDX-License-Identifier: LGPL-2.1+
+#
 # Simple udev rules syntax checker
 #
 # (C) 2010 Canonical Ltd.
@@ -22,17 +24,9 @@ import sys
 import os
 from glob import glob
 
-if len(sys.argv) > 1:
-    # explicit rule file list
-    rules_files = sys.argv[1:]
-else:
-    # take them from the build dir
-    root_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
-    rules_dir = os.path.join(os.environ.get('top_srcdir', root_dir), 'rules')
-    if not os.path.isdir(rules_dir):
-        sys.stderr.write('No rules files given, and %s does not exist, aborting' % rules_dir)
-        sys.exit(2)
-    rules_files = glob(os.path.join(rules_dir, '*.rules'))
+rules_files = sys.argv[1:]
+if not rules_files:
+    sys.exit('Specify files to test as arguments')
 
 no_args_tests = re.compile(r'(ACTION|DEVPATH|KERNELS?|NAME|SYMLINK|SUBSYSTEMS?|DRIVERS?|TAG|RESULT|TEST)\s*(?:=|!)=\s*"([^"]*)"$')
 args_tests = re.compile(r'(ATTRS?|ENV|TEST){([a-zA-Z0-9/_.*%-]+)}\s*(?:=|!)=\s*"([^"]*)"$')
@@ -42,6 +36,7 @@ args_assign = re.compile(r'(ATTR|ENV|IMPORT|RUN){([a-zA-Z0-9/_.*%-]+)}\s*(=|\+=)
 result = 0
 buffer = ''
 for path in rules_files:
+    print('# looking at {}'.format(path))
     lineno = 0
     for line in open(path):
         lineno += 1
@@ -64,9 +59,9 @@ for path in rules_files:
             if not (no_args_tests.match(clause) or args_tests.match(clause) or
                     no_args_assign.match(clause) or args_assign.match(clause)):
 
-                print('Invalid line %s:%i: %s' % (path, lineno, line))
-                print('  clause: %s' % clause)
-                print('')
+                print('Invalid line {}:{}: {}'.format(path, lineno, line))
+                print('  clause:', clause)
+                print()
                 result = 1
                 break
 
diff --git a/test/run-integration-tests.sh b/test/run-integration-tests.sh
new file mode 100755 (executable)
index 0000000..7d70be3
--- /dev/null
@@ -0,0 +1,48 @@
+#!/bin/bash -e
+
+BUILD_DIR="$($(dirname "$0")/../tools/find-build-dir.sh)"
+if [ $# -gt 0 ]; then
+        args="$@"
+else
+        args="clean setup run"
+fi
+
+ninja -C "$BUILD_DIR"
+
+declare -A results
+
+RESULT=0
+FAILURES=0
+
+cd "$(dirname "$0")"
+for TEST in TEST-??-* ; do
+        echo -e "\n--x-- Starting $TEST --x--"
+        set +e
+        make -C "$TEST" "BUILD_DIR=$BUILD_DIR" $args
+        RESULT=$?
+        set -e
+        echo "--x-- Result of $TEST: $RESULT --x--"
+
+        results["$TEST"]="$RESULT"
+
+        [ "$RESULT" -ne "0" ] && FAILURES=$(($FAILURES+1))
+done
+
+echo ""
+
+for TEST in ${!results[@]}; do
+        RESULT="${results[$TEST]}"
+        if [ "$RESULT" -eq "0" ] ; then
+                echo "$TEST: SUCCESS"
+        else
+                echo "$TEST: FAIL"
+        fi
+done | sort
+
+if [ "$FAILURES" -eq 0 ] ; then
+        echo -e "\nALL PASSED"
+else
+        echo -e "\nTOTAL FAILURES: $FAILURES"
+fi
+
+exit "$FAILURES"
index 2de7d7e..468c1dc 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env python3
+# SPDX-License-Identifier: LGPL-2.1+
 #
 # sys-script.py
 #
index 18bb40f..0b4710a 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env python3
+# SPDX-License-Identifier: LGPL-2.1+
 #
 # systemd-sysv-generator integration test
 #
index c3fe082..1b88637 100755 (executable)
@@ -1,5 +1,5 @@
 #!/usr/bin/env python3
-
+# SPDX-License-Identifier: LGPL-2.1+
 #
 #  Copyright 2017 Michal Sekletar <msekleta@redhat.com>
 #
diff --git a/test/test-execute/exec-bindpaths.service b/test/test-execute/exec-bindpaths.service
new file mode 100644 (file)
index 0000000..7bd8fa7
--- /dev/null
@@ -0,0 +1,17 @@
+[Unit]
+Description=Test for BindPaths= and BindReadOnlyPaths=
+
+[Service]
+Type=oneshot
+# Create a file in /tmp/test-exec-bindpaths
+ExecStart=/bin/sh -c 'touch /tmp/test-exec-bindpaths/thisisasimpletest'
+# Then, the file can be access through /tmp
+ExecStart=/bin/sh -c 'test -f /tmp/thisisasimpletest'
+# Also, through /tmp/test-exec-bindreadonlypaths
+ExecStart=/bin/sh -c 'test -f /tmp/test-exec-bindreadonlypaths/thisisasimpletest'
+# The file cannot modify through /tmp/test-exec-bindreadonlypaths
+ExecStart=/bin/sh -x -c '! touch /tmp/test-exec-bindreadonlypaths/thisisasimpletest'
+# Cleanup
+ExecStart=/bin/sh -c 'rm /tmp/thisisasimpletest'
+BindPaths=/tmp:/tmp/test-exec-bindpaths
+BindReadOnlyPaths=/tmp:/tmp/test-exec-bindreadonlypaths
diff --git a/test/test-execute/exec-cpuaffinity1.service b/test/test-execute/exec-cpuaffinity1.service
new file mode 100644 (file)
index 0000000..84d550a
--- /dev/null
@@ -0,0 +1,6 @@
+[Unit]
+Description=Test for CPUAffinity (simple)
+
+[Service]
+ExecStart=/bin/sh -c 'test $$(cat /proc/self/status | grep Cpus_allowed: | rev | cut -c 1) = 1'
+CPUAffinity=0
diff --git a/test/test-execute/exec-cpuaffinity2.service b/test/test-execute/exec-cpuaffinity2.service
new file mode 100644 (file)
index 0000000..0dda77f
--- /dev/null
@@ -0,0 +1,8 @@
+[Unit]
+Description=Test for CPUAffinity (reset)
+
+[Service]
+ExecStart=/bin/sh -c 'test $$(cat /proc/self/status | grep Cpus_allowed: | rev | cut -c 1) = 1'
+CPUAffinity=0-1 3
+CPUAffinity=
+CPUAffinity=0
diff --git a/test/test-execute/exec-cpuaffinity3.service b/test/test-execute/exec-cpuaffinity3.service
new file mode 100644 (file)
index 0000000..4a45d3b
--- /dev/null
@@ -0,0 +1,7 @@
+[Unit]
+Description=Test for CPUAffinity (merge)
+
+[Service]
+ExecStart=/bin/sh -c 'test $$(cat /proc/self/status | grep Cpus_allowed: | rev | cut -c 1) = 7'
+CPUAffinity=0,1
+CPUAffinity=1-2
diff --git a/test/test-execute/exec-dynamicuser-statedir-migrate-step1.service b/test/test-execute/exec-dynamicuser-statedir-migrate-step1.service
new file mode 100644 (file)
index 0000000..83bdfb3
--- /dev/null
@@ -0,0 +1,16 @@
+[Unit]
+Description=Test DynamicUser= migrate StateDirectory= (preparation)
+
+[Service]
+ExecStart=/bin/sh -c 'test -w /var/lib/test-dynamicuser-migrate'
+ExecStart=/bin/sh -c 'test -w /var/lib/test-dynamicuser-migrate2/hoge'
+ExecStart=/bin/sh -c 'test ! -L /var/lib/test-dynamicuser-migrate'
+ExecStart=/bin/sh -c 'test ! -L /var/lib/test-dynamicuser-migrate2/hoge'
+ExecStart=/bin/sh -c 'test -d /var/lib/test-dynamicuser-migrate'
+ExecStart=/bin/sh -c 'test -d /var/lib/test-dynamicuser-migrate2/hoge'
+ExecStart=/bin/sh -c 'touch /var/lib/test-dynamicuser-migrate/yay'
+ExecStart=/bin/sh -c 'touch /var/lib/test-dynamicuser-migrate2/hoge/yayyay'
+
+Type=oneshot
+DynamicUser=no
+StateDirectory=test-dynamicuser-migrate test-dynamicuser-migrate2/hoge
diff --git a/test/test-execute/exec-dynamicuser-statedir-migrate-step2.service b/test/test-execute/exec-dynamicuser-statedir-migrate-step2.service
new file mode 100644 (file)
index 0000000..8154922
--- /dev/null
@@ -0,0 +1,24 @@
+[Unit]
+Description=Test DynamicUser= migrate StateDirectory= (preparation)
+
+[Service]
+ExecStart=/bin/sh -c 'test -w /var/lib/test-dynamicuser-migrate'
+ExecStart=/bin/sh -c 'test -w /var/lib/test-dynamicuser-migrate2/hoge'
+ExecStart=/bin/sh -c 'test -L /var/lib/test-dynamicuser-migrate'
+ExecStart=/bin/sh -c 'test -L /var/lib/test-dynamicuser-migrate2/hoge'
+ExecStart=/bin/sh -c 'test -d /var/lib/test-dynamicuser-migrate'
+ExecStart=/bin/sh -c 'test -d /var/lib/test-dynamicuser-migrate2/hoge'
+ExecStart=/bin/sh -c 'test -f /var/lib/test-dynamicuser-migrate/yay'
+ExecStart=/bin/sh -c 'test -f /var/lib/test-dynamicuser-migrate2/hoge/yayyay'
+ExecStart=/bin/sh -c 'test -d /var/lib/private/test-dynamicuser-migrate'
+ExecStart=/bin/sh -c 'test -d /var/lib/private/test-dynamicuser-migrate2/hoge'
+ExecStart=/bin/sh -c 'test -f /var/lib/private/test-dynamicuser-migrate/yay'
+ExecStart=/bin/sh -c 'test -f /var/lib/private/test-dynamicuser-migrate2/hoge/yayyay'
+ExecStart=/bin/sh -c 'touch /var/lib/test-dynamicuser-migrate/yay'
+ExecStart=/bin/sh -c 'touch /var/lib/test-dynamicuser-migrate2/hoge/yayyay'
+ExecStart=/bin/sh -c 'touch /var/lib/private/test-dynamicuser-migrate/yay'
+ExecStart=/bin/sh -c 'touch /var/lib/private/test-dynamicuser-migrate2/hoge/yayyay'
+
+Type=oneshot
+DynamicUser=yes
+StateDirectory=test-dynamicuser-migrate test-dynamicuser-migrate2/hoge
@@ -2,14 +2,14 @@
 Description=Test DynamicUser= with StateDirectory=
 
 [Service]
-ExecStart=/usr/bin/test -w /var/lib/waldo
-ExecStart=/usr/bin/test -w /var/lib/quux/pief
-ExecStart=/bin/touch /var/lib/waldo/yay
-ExecStart=/bin/touch /var/lib/quux/pief/yayyay
-ExecStart=/usr/bin/test -f /var/lib/waldo/yay
-ExecStart=/usr/bin/test -f /var/lib/quux/pief/yayyay
-ExecStart=/usr/bin/test -f /var/lib/private/waldo/yay
-ExecStart=/usr/bin/test -f /var/lib/private/quux/pief/yayyay
+ExecStart=/bin/sh -c 'test -w /var/lib/waldo'
+ExecStart=/bin/sh -c 'test -w /var/lib/quux/pief'
+ExecStart=/bin/sh -c 'touch /var/lib/waldo/yay'
+ExecStart=/bin/sh -c 'touch /var/lib/quux/pief/yayyay'
+ExecStart=/bin/sh -c 'test -f /var/lib/waldo/yay'
+ExecStart=/bin/sh -c 'test -f /var/lib/quux/pief/yayyay'
+ExecStart=/bin/sh -c 'test -f /var/lib/private/waldo/yay'
+ExecStart=/bin/sh -c 'test -f /var/lib/private/quux/pief/yayyay'
 
 # Make sure that /var/lib/private/waldo is really the only writable directory besides the obvious candidates
 ExecStart=/bin/sh -x -c 'test $$(find / -type d -writable 2> /dev/null | egrep -v -e \'^(/var/tmp$$|/tmp$$|/proc/|/dev/mqueue$$|/dev/shm$$)\' | sort -u | tr -d '\\\\n') = /var/lib/private/quux/pief/var/lib/private/waldo'
diff --git a/test/test-execute/exec-group-nogroup.service b/test/test-execute/exec-group-nogroup.service
new file mode 100644 (file)
index 0000000..cf07732
--- /dev/null
@@ -0,0 +1,7 @@
+[Unit]
+Description=Test for Group
+
+[Service]
+ExecStart=/bin/sh -x -c 'test "$$(id -n -g)" = "nogroup"'
+Type=oneshot
+Group=nogroup
@@ -1,8 +1,11 @@
+[Unit]
+Description=Test for ReadOnlyPaths=
+
 [Service]
 Type=oneshot
 # This should work, as we explicitly disable the effect of ReadOnlyPaths=
-ExecStart=+/bin/touch /tmp/thisisasimpletest
+ExecStart=+/bin/sh -c 'touch /tmp/thisisasimpletest'
 # This should also work, as we do not disable the effect of ReadOnlyPaths= but invert the exit code
-ExecStart=/bin/sh -x -c '! /bin/touch /tmp/thisisasimpletest'
-ExecStart=+/bin/rm /tmp/thisisasimpletest
+ExecStart=/bin/sh -x -c '! touch /tmp/thisisasimpletest'
+ExecStart=+/bin/sh -c 'rm /tmp/thisisasimpletest'
 ReadOnlyPaths=/tmp
diff --git a/test/test-execute/exec-readonlypaths-with-bindpaths.service b/test/test-execute/exec-readonlypaths-with-bindpaths.service
new file mode 100644 (file)
index 0000000..ea92113
--- /dev/null
@@ -0,0 +1,9 @@
+[Unit]
+Description=Test for ReadOnlyPaths=
+
+[Service]
+ReadOnlyPaths=/etc -/i-dont-exist /usr
+# From 6c47cd7d3bf35c8158a0737f34fe2c5dc95e72d6, RuntimeDirectory= implies BindPaths=.
+RuntimeDirectory=foo
+ExecStart=/bin/sh -x -c 'test ! -w /etc && test ! -w /usr && test ! -e /i-dont-exist && test -w /var'
+Type=oneshot
diff --git a/test/test-execute/exec-specifier.service b/test/test-execute/exec-specifier.service
new file mode 100644 (file)
index 0000000..3785239
--- /dev/null
@@ -0,0 +1,24 @@
+[Unit]
+Description=Test for specifiers
+
+[Service]
+Type=oneshot
+ExecStart=/usr/bin/test %n = exec-specifier.service
+ExecStart=/usr/bin/test %N = exec-specifier
+ExecStart=/usr/bin/test %p = exec-specifier
+ExecStart=/usr/bin/test %P = exec/specifier
+ExecStart=/usr/bin/test %i = ""
+ExecStart=/usr/bin/test %I = ""
+ExecStart=/usr/bin/test %f = /exec/specifier
+ExecStart=/usr/bin/test %t = /run
+ExecStart=/usr/bin/test %S = /var/lib
+ExecStart=/usr/bin/test %C = /var/cache
+ExecStart=/usr/bin/test %L = /var/log
+ExecStart=/bin/sh -c 'test %u = $$(id -un 0)'
+ExecStart=/usr/bin/test %U = 0
+ExecStart=/bin/sh -c 'test %h = $$(getent passwd 0 | cut -d: -f 6)
+ExecStart=/bin/sh -c 'test %s = $$(getent passwd 0 | cut -d: -f 7)
+ExecStart=/bin/sh -c 'test %m = $$(cat /etc/machine-id)'
+ExecStart=/bin/sh -c 'test %b = $$(cat /proc/sys/kernel/random/boot_id | sed -e 's/-//g')'
+ExecStart=/bin/sh -c 'test %H = $$(hostname)'
+ExecStart=/bin/sh -c 'test %v = $$(uname -r)'
diff --git a/test/test-execute/exec-specifier@.service b/test/test-execute/exec-specifier@.service
new file mode 100644 (file)
index 0000000..0015dff
--- /dev/null
@@ -0,0 +1,24 @@
+[Unit]
+Description=Test for specifiers (template unit)
+
+[Service]
+Type=oneshot
+ExecStart=/usr/bin/test %n = exec-specifier@foo-bar.service
+ExecStart=/usr/bin/test %N = exec-specifier@foo-bar
+ExecStart=/usr/bin/test %p = exec-specifier
+ExecStart=/usr/bin/test %P = exec/specifier
+ExecStart=/usr/bin/test %i = foo-bar
+ExecStart=/usr/bin/test %I = foo/bar
+ExecStart=/usr/bin/test %f = /foo/bar
+ExecStart=/usr/bin/test %t = /run
+ExecStart=/usr/bin/test %S = /var/lib
+ExecStart=/usr/bin/test %C = /var/cache
+ExecStart=/usr/bin/test %L = /var/log
+ExecStart=/bin/sh -c 'test %u = $$(id -un 0)'
+ExecStart=/usr/bin/test %U = 0
+ExecStart=/bin/sh -c 'test %h = $$(getent passwd 0 | cut -d: -f 6)
+ExecStart=/bin/sh -c 'test %s = $$(getent passwd 0 | cut -d: -f 7)
+ExecStart=/bin/sh -c 'test %m = $$(cat /etc/machine-id)'
+ExecStart=/bin/sh -c 'test %b = $$(cat /proc/sys/kernel/random/boot_id | sed -e 's/-//g')'
+ExecStart=/bin/sh -c 'test %H = $$(hostname)'
+ExecStart=/bin/sh -c 'test %v = $$(uname -r)'
diff --git a/test/test-execute/exec-standardinput-data.service b/test/test-execute/exec-standardinput-data.service
new file mode 100644 (file)
index 0000000..1ca536f
--- /dev/null
@@ -0,0 +1,19 @@
+[Unit]
+Description=Test for StandardInputText= and StandardInputData=
+
+[Service]
+ExecStart=/bin/sh -x -c 'd=$$(mktemp -d -p /tmp); echo -e "this is a test\nand this is more\nsomething encoded!\nsomething   in multiple lines\nand some more\nand a more bas64 data\nsomething with strange\nembedded\tcharacters\nand something with a exec-stdin-data.service specifier" > $d/text ; cmp $d/text ; rm -rf $d'
+Type=oneshot
+StandardInput=data
+StandardInputText=this is a test
+StandardInputText=and this is more
+StandardInputData=c29tZXRoaW5nIGVuY29kZWQhCg==
+StandardInputText=something \
+ in multiple lines
+StandardInputText=\
+and some more
+StandardInputData=YW5kIGEgbW9y \
+    ZSBiYXM2NCBk\
+YXRhCg==
+StandardInputText=something with strange\nembedded\tcharacters
+StandardInputText=and something with a %n specifier
diff --git a/test/test-execute/exec-standardinput-file.service b/test/test-execute/exec-standardinput-file.service
new file mode 100644 (file)
index 0000000..8fd11ca
--- /dev/null
@@ -0,0 +1,7 @@
+[Unit]
+Description=Test for StandardInput=file:
+
+[Service]
+ExecStart=/usr/bin/cmp /usr/bin/cmp
+Type=oneshot
+StandardInput=file:/usr/bin/cmp
@@ -2,7 +2,7 @@
 Description=Test for SystemCallErrorNumber
 
 [Service]
-ExecStart=/bin/sh -x -c 'uname -a'
+ExecStart=/usr/bin/python3 -c 'import os\ntry: os.uname()\nexcept Exception as e: exit(e.errno)'
 Type=oneshot
 SystemCallFilter=~uname
 SystemCallErrorNumber=EACCES
diff --git a/test/test-execute/exec-systemcallerrornumber-number.service b/test/test-execute/exec-systemcallerrornumber-number.service
new file mode 100644 (file)
index 0000000..2032156
--- /dev/null
@@ -0,0 +1,8 @@
+[Unit]
+Description=Test for SystemCallErrorNumber
+
+[Service]
+ExecStart=/usr/bin/python3 -c 'import os\ntry: os.uname()\nexcept Exception as e: exit(e.errno)'
+Type=oneshot
+SystemCallFilter=~uname
+SystemCallErrorNumber=255
index 5c6422f..bcebc99 100644 (file)
@@ -2,7 +2,7 @@
 Description=Test for SystemCallFilter
 
 [Service]
-ExecStart=/bin/echo "This should not be seen"
+ExecStart=/bin/sh -c 'echo "This should not be seen"'
 Type=oneshot
 SystemCallFilter=ioperm
 SystemCallFilter=~ioperm
index 3516078..2fdc0ed 100644 (file)
@@ -2,6 +2,6 @@
 Description=Test for SystemCallFilter
 
 [Service]
-ExecStart=/bin/echo "This should not be seen"
+ExecStart=/bin/sh -c 'echo "This should not be seen"'
 Type=oneshot
 SystemCallFilter=~write open execve exit_group close mmap munmap fstat DONOTEXIST
index c794b67..f3a752b 100644 (file)
@@ -2,7 +2,7 @@
 Description=Test for SystemCallFilter
 
 [Service]
-ExecStart=/bin/echo "Foo bar"
+ExecStart=/bin/sh -c 'echo "Foo bar"'
 Type=oneshot
 SystemCallFilter=~read write open execve ioperm
 SystemCallFilter=ioctl
index a62c81b..1df076a 100644 (file)
@@ -2,6 +2,6 @@
 Description=Test for SystemCallFilter
 
 [Service]
-ExecStart=/bin/echo "Foo bar"
+ExecStart=/bin/sh -c 'echo "Foo bar"'
 Type=oneshot
 SystemCallFilter=
index 9393e0a..b1195d0 100644 (file)
@@ -2,7 +2,7 @@
 Description=Test for SystemCallFilter in system mode with User set
 
 [Service]
-ExecStart=/bin/echo "Foo bar"
+ExecStart=/bin/sh -c 'echo "Foo bar"'
 Type=oneshot
 User=nfsnobody
 SystemCallFilter=~read write open execve ioperm
index 462f941..da129a3 100644 (file)
@@ -2,7 +2,7 @@
 Description=Test for SystemCallFilter in system mode with User set
 
 [Service]
-ExecStart=/bin/echo "Foo bar"
+ExecStart=/bin/sh -c 'echo "Foo bar"'
 Type=oneshot
 User=nobody
 SystemCallFilter=~read write open execve ioperm
diff --git a/test/test-execute/exec-systemcallfilter-with-errno-name.service b/test/test-execute/exec-systemcallfilter-with-errno-name.service
new file mode 100644 (file)
index 0000000..8380d5a
--- /dev/null
@@ -0,0 +1,8 @@
+[Unit]
+Description=Test for SystemCallFilter with errno name
+
+[Service]
+ExecStart=/usr/bin/python3 -c 'import os\ntry: os.uname()\nexcept Exception as e: exit(e.errno)'
+Type=oneshot
+SystemCallFilter=~uname:EILSEQ
+SystemCallErrorNumber=EACCES
diff --git a/test/test-execute/exec-systemcallfilter-with-errno-number.service b/test/test-execute/exec-systemcallfilter-with-errno-number.service
new file mode 100644 (file)
index 0000000..dbb9540
--- /dev/null
@@ -0,0 +1,8 @@
+[Unit]
+Description=Test for SystemCallFilter with errno number
+
+[Service]
+ExecStart=/usr/bin/python3 -c 'import os\ntry: os.uname()\nexcept Exception as e: exit(e.errno)'
+Type=oneshot
+SystemCallFilter=~uname:255
+SystemCallErrorNumber=EACCES
index 50e0a16..5798fac 100644 (file)
@@ -12,15 +12,16 @@ KERNEL_MODS="/lib/modules/$KERNEL_VER/"
 QEMU_TIMEOUT="${QEMU_TIMEOUT:-infinity}"
 NSPAWN_TIMEOUT="${NSPAWN_TIMEOUT:-infinity}"
 TIMED_OUT=  # will be 1 after run_* if *_TIMEOUT is set and test timed out
-[[ "$LOOKS_LIKE_SUSE" ]] && FSTYPE="${FSTYPE:-btrfs}" || FSTYPE="${FSTYPE:-ext3}"
+[[ "$LOOKS_LIKE_SUSE" ]] && FSTYPE="${FSTYPE:-btrfs}" || FSTYPE="${FSTYPE:-ext4}"
 UNIFIED_CGROUP_HIERARCHY="${UNIFIED_CGROUP_HIERARCHY:-default}"
+EFI_MOUNT="$(bootctl -p 2>/dev/null || echo /boot)"
 
 if ! ROOTLIBDIR=$(pkg-config --variable=systemdutildir systemd); then
     echo "WARNING! Cannot determine rootlibdir from pkg-config, assuming /usr/lib/systemd" >&2
     ROOTLIBDIR=/usr/lib/systemd
 fi
 
-BASICTOOLS="test sh bash setsid loadkeys setfont login sulogin gzip sleep echo mount umount cryptsetup date dmsetup modprobe sed cmp tee rm chmod chown ln"
+BASICTOOLS="test sh bash setsid loadkeys setfont login sulogin gzip sleep echo mount umount cryptsetup date dmsetup modprobe sed cmp tee rm chmod chown ln true false"
 DEBUGTOOLS="df free ls stty cat ps ln ip route dmesg dhclient mkdir cp ping dhclient strace less grep id tty touch du sort hostname find"
 
 STATEDIR="${BUILD_DIR:-.}/test/$(basename $(dirname $(realpath $0)))"
@@ -61,10 +62,10 @@ function find_qemu_bin() {
 run_qemu() {
     if [ -f /etc/machine-id ]; then
         read MACHINE_ID < /etc/machine-id
-        [ -z "$INITRD" ] && [ -e "/boot/$MACHINE_ID/$KERNEL_VER/initrd" ] \
-            && INITRD="/boot/$MACHINE_ID/$KERNEL_VER/initrd"
-        [ -z "$KERNEL_BIN" ] && [ -e "/boot/$MACHINE_ID/$KERNEL_VER/linux" ] \
-            && KERNEL_BIN="/boot/$MACHINE_ID/$KERNEL_VER/linux"
+        [ -z "$INITRD" ] && [ -e "$EFI_MOUNT/$MACHINE_ID/$KERNEL_VER/initrd" ] \
+            && INITRD="$EFI_MOUNT/$MACHINE_ID/$KERNEL_VER/initrd"
+        [ -z "$KERNEL_BIN" ] && [ -e "$EFI_MOUNT/$MACHINE_ID/$KERNEL_VER/linux" ] \
+            && KERNEL_BIN="$EFI_MOUNT/$MACHINE_ID/$KERNEL_VER/linux"
     fi
 
     if [[ ! "$KERNEL_BIN" ]]; then
index f8df32e..935ec63 100644 (file)
@@ -1,3 +1,20 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
+# Copyright 2017 Zbigniew Jędrzejewski-Szmek
+#
+# 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.
+#
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
 enable_tmpfiles = conf.get('ENABLE_TMPFILES') == 1
 
 tmpfiles = [['home.conf',            ''],
index 357e498..426ea0d 100755 (executable)
@@ -1,5 +1,6 @@
 #!/usr/bin/env python3
 # -*- Mode: python; coding: utf-8; indent-tabs-mode: nil -*- */
+# SPDX-License-Identifier: MIT
 #
 # This file is part of systemd. It is distrubuted under the MIT license, see
 # below.
diff --git a/tools/find-build-dir.sh b/tools/find-build-dir.sh
new file mode 100755 (executable)
index 0000000..33b40f9
--- /dev/null
@@ -0,0 +1,31 @@
+#!/bin/sh -e
+
+# Try to guess the build directory:
+# we look for subdirectories of the parent directory that look like ninja build dirs.
+
+if [ -n "$BUILD_DIR" ]; then
+        echo "$(realpath "$BUILD_DIR")"
+        exit 0
+fi
+
+root="$(dirname "$(realpath "$0")")"
+
+found=
+for i in "$root"/../*/build.ninja; do
+        c="$(dirname $i)"
+        [ -d "$c" ] || continue
+        [ "$(basename "$c")" != mkosi.builddir ] || continue
+
+        if [ -n "$found" ]; then
+                echo 'Found multiple candidates, specify build directory with $BUILD_DIR' >&2
+                exit 2
+        fi
+        found="$c"
+done
+
+if [ -z "$found" ]; then
+        echo 'Specify build directory with $BUILD_DIR' >&2
+        exit 1
+fi
+
+echo "$(realpath $found)"
index 62ce800..b3c356b 100644 (file)
@@ -1,5 +1,6 @@
 #!/usr/bin/env python3
 #  -*- Mode: python; coding: utf-8; indent-tabs-mode: nil -*- */
+# SPDX-License-Identifier: LGPL-2.1+
 #
 #  This file is part of systemd.
 #
index f9203dd..fb2b0b7 100755 (executable)
@@ -1,5 +1,6 @@
 #!/usr/bin/env python3
 #  -*- Mode: python; coding: utf-8; indent-tabs-mode: nil -*- */
+# SPDX-License-Identifier: LGPL-2.1+
 #
 #  This file is part of systemd.
 #
index 0618e2e..5ff3616 100755 (executable)
@@ -1,5 +1,6 @@
 #!/usr/bin/env python3
 #  -*- Mode: python; coding: utf-8; indent-tabs-mode: nil -*- */
+# SPDX-License-Identifier: LGPL-2.1+
 #
 #  This file is part of systemd.
 #
index e0f18d6..444d4a6 100755 (executable)
@@ -1,5 +1,6 @@
 #!/usr/bin/env python3
 #  -*- Mode: python; coding: utf-8; indent-tabs-mode: nil -*- */
+#  SPDX-License-Identifier: LGPL-2.1+
 #
 #  This file is part of systemd.
 #
index 47a5099..4210491 100755 (executable)
@@ -1,5 +1,7 @@
 #!/bin/sh -eu
 
+export SYSTEMD_LOG_LEVEL=info
+
 # output width
 if "$1"  --help | grep -v 'default:' | grep -E -q '.{80}.'; then
         echo "$(basename "$1") --help output is too wide:"
index 33d603e..e9a78c6 100755 (executable)
@@ -2,7 +2,7 @@
 
 cd "$1"
 
-if [ "$2" != "-n" ]; then
+if [ "${2:-}" != "-n" ]; then
         curl -L -o usb.ids 'http://www.linux-usb.org/usb.ids'
         curl -L -o pci.ids 'http://pci-ids.ucw.cz/v2.2/pci.ids'
         curl -L -o ma-large.txt 'http://standards-oui.ieee.org/oui/oui.txt'
@@ -11,7 +11,9 @@ if [ "$2" != "-n" ]; then
         curl -L -o pnp_id_registry.html 'http://www.uefi.org/uefi-pnp-export'
         curl -L -o acpi_id_registry.html 'http://www.uefi.org/uefi-acpi-export'
 fi
-./ids_parser.py
+
 ./acpi-update.py >20-acpi-vendor.hwdb.base
 patch -p0 -o- 20-acpi-vendor.hwdb.base <20-acpi-vendor.hwdb.patch >20-acpi-vendor.hwdb
 ! diff -u 20-acpi-vendor.hwdb.base 20-acpi-vendor.hwdb >20-acpi-vendor.hwdb.patch
+
+./ids_parser.py
index 0088be5..47434c7 100755 (executable)
@@ -1,5 +1,6 @@
 #!/usr/bin/env python3
 #  -*- Mode: python; coding: utf-8; indent-tabs-mode: nil -*- */
+#  SPDX-License-Identifier: LGPL-2.1+
 #
 #  This file is part of systemd.
 #
@@ -27,9 +28,11 @@ class CustomResolver(tree.Resolver):
 
 _parser = tree.XMLParser()
 _parser.resolvers.add(CustomResolver())
+
 def xml_parse(page):
     doc = tree.parse(page, _parser)
     doc.xinclude()
     return doc
+
 def xml_print(xml):
     return tree.tostring(xml, pretty_print=True, encoding='utf-8')
index 3e3527f..4f44292 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 5e866b4..9e2d7c3 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 4c5a6ba..aea2d41 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index c8d42a6..84f6246 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 6cb28a6..12e4107 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 10b17fd..fdb572b 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 4e8f982..9be7bb3 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 86ad7ac..278ed9b 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index b2adfeb..be32433 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 03f170c..90dab30 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 0760d66..a4e954e 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index f5f953d..0a79533 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 4281910..0e12386 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index f6c78b6..adb98bf 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index c33d446..b311017 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 81f05e8..e1b5ff8 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 87be97e..f3e30e9 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index c8be896..f6c2e9c 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index a21d984..87c3374 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 0e1bc03..8580c65 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 410e131..e5e22b8 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 1099958..0536721 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 7ec838a..33822bd 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 7464e28..8abb548 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 9d44d2d..580c666 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 64f0a92..9b955f6 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 2e883e5..76662fc 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 934d82f..ad82245 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 9320614..e98ca39 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 8be7e2b..a74a447 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 90795d0..706cd70 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 9d3a1c2..8c06878 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index e066718..0b5a0e8 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 809f2ed..9aca15b 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index d2e5429..6ba4930 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 3d40dfd..b4e4c17 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index e07b0bb..224765a 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 42ef93d..ebe6fc7 100644 (file)
@@ -1,3 +1,20 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
+# Copyright 2017 Zbigniew Jędrzejewski-Szmek
+#
+# 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.
+#
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
 units = [
         ['basic.target',                        ''],
         ['bluetooth.target',                    ''],
@@ -48,7 +65,6 @@ units = [
         ['proc-sys-fs-binfmt_misc.mount',       'ENABLE_BINFMT'],
         ['reboot.target',                       '',
          'runlevel6.target ctrl-alt-del.target'],
-        ['remote-cryptsetup-pre.target',        'HAVE_LIBCRYPTSETUP'],
         ['remote-cryptsetup.target',            'HAVE_LIBCRYPTSETUP',
          join_paths(pkgsysconfdir, 'system/multi-user.target.wants/')],
         ['remote-fs-pre.target',                ''],
@@ -208,7 +224,7 @@ in_units = [
          'multi-user.target.wants/ graphical.target.wants/ rescue.target.wants/'],
         ['systemd-update-utmp.service',          'ENABLE_UTMP',
          'sysinit.target.wants/'],
-        ['systemd-user-sessions.service',        '',
+        ['systemd-user-sessions.service',        'HAVE_PAM',
          'multi-user.target.wants/'],
         ['systemd-vconsole-setup.service',       'ENABLE_VCONSOLE',
          'sysinit.target.wants/'],
index 0f0e5e9..386e1b5 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 5130d8c..8b8c785 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 0d54a4c..806eb72 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index f8331b6..3e4fdff 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index c9e3a7c..8d56c8e 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 80023cd..7436b6c 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 25c7fd0..9b6ed1c 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index dd92d81..47c109c 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index a6b86ca..e1fb0d4 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 1067bcd..30a6bc9 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 27773cd..091191e 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 9272427..98a8e61 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 480dddb..5dbd62a 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 668b98d..c2782db 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 60943bd..4445d5d 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
@@ -8,3 +10,9 @@
 [Unit]
 Description=Remote Encrypted Volumes
 Documentation=man:systemd.special(7)
+After=remote-fs-pre.target cryptsetup-pre.target
+DefaultDependencies=no
+Conflicts=shutdown.target
+
+[Install]
+WantedBy=multi-user.target
index 36a196c..3f22605 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 43ffa5c..0d44348 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 2efdf74..96d1807 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index bd92ed2..0e04a94 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index e03e915..801ee4d 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 5ed9f7e..5c85ab1 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 73e302b..d48e6d6 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index a52e7cf..8228541 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 10c7c8d..9409dc6 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index a29310c..84a04d6 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 5fefe84..717ea23 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 26ab065..9af67fd 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 6699ade..19afc2a 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 80d6527..1a156b4 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 23a7d0d..8cef5b6 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 492ceb1..7e7b05c 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index b585f32..e213ca5 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 808dbf0..53ce820 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index a381dcb..9d93517 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 4398190..c4b1cea 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index dc524da..51399f1 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index b95639a..c46bfe7 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 8281fe5..a4d5edf 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 7899ae7..d686ca6 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 2c53ff8..d1ebf40 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index a3ca617..5a356b9 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index e6d1333..5596160 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 9aa0c74..d302285 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 645ef77..2af3f90 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 4cb2460..c9971b9 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index ef58f0c..68fa55c 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 98f6f70..5119ee2 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 405c6f3..d4deba9 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index b31e888..71c0257 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 305ccda..fdb6310 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 33213dd..d1fab67 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 8ecd690..2514d5d 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 5b87358..6455d01 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 82af4f0..90a2b33 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index c0492e0..fdf6649 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index f41fce5..4a62e8f 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 695a5f2..8e93c2d 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 2ff668f..9a86007 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index f628c2e..61f877b 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 0f9fbaa..f735cd0 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index aae5940..86eed15 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 44caa0e..9768928 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 79d9b04..7c3632b 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 92cec21..a94265f 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 076dcae..48d0a65 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 98a4b2b..42da70f 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
@@ -14,11 +16,10 @@ After=network-online.target
 [Service]
 ExecStart=@rootlibexecdir@/systemd-journal-upload --save-state
 User=systemd-journal-upload
+DynamicUser=yes
 SupplementaryGroups=systemd-journal
 WatchdogSec=3min
-PrivateTmp=yes
 PrivateDevices=yes
-ProtectSystem=strict
 ProtectHome=yes
 ProtectControlGroups=yes
 ProtectKernelTunables=yes
index 541f2cf..cb8b774 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index ffd44bb..80ad6ac 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index c120c4e..53bf79a 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 7173701..c95ae5a 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 83af545..e9124d1 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 9d750af..8b1d1f0 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 1c40d95..041f2f4 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index f539fe0..e261e66 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 1fb7707..a3d3494 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 1b2b29a..a889eef 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 89ca865..7666e16 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 932dd63..63ee735 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 9e4e9dd..1133066 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 80d4bc9..bfa3a6c 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
@@ -19,6 +21,7 @@ KillMode=mixed
 Type=notify
 RestartForceExitStatus=133
 SuccessExitStatus=133
+WatchdogSec=3min
 Slice=machine.slice
 Delegate=yes
 SmackProcessLabel=System
index eaa2a27..b432a49 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 1060974..d444fda 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index b244a8c..8903ee8 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index c272969..ff9f28e 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index bc66691..fd645e0 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index cda83ee..8059aa7 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 5cdd747..4b68f0b 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 20ae2f8..c8e9f71 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index e1a3be8..d6e5c81 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index d72c753..19dd27c 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 4d8309a..4d11bbb 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 97130e9..cf13e40 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 8d3f46c..d3bc4e9 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
@@ -23,11 +25,10 @@ RestartSec=0
 ExecStart=!!@rootlibexecdir@/systemd-timesyncd
 WatchdogSec=3min
 User=systemd-timesync
+DynamicUser=yes
 CapabilityBoundingSet=CAP_SYS_TIME
 AmbientCapabilities=CAP_SYS_TIME
-PrivateTmp=yes
 PrivateDevices=yes
-ProtectSystem=strict
 ProtectHome=yes
 ProtectControlGroups=yes
 ProtectKernelTunables=yes
index deeca5f..7c2a563 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
@@ -16,5 +18,6 @@ Before=shutdown.target
 [Service]
 Type=oneshot
 ExecStart=@rootbindir@/systemd-tmpfiles --clean
+SuccessExitStatus=65
 IOSchedulingClass=idle
 SmackProcessLabel=System::Privileged
index 9975dcf..3e30178 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 561be7b..594fe9a 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
@@ -18,4 +20,5 @@ ConditionCapability=CAP_SYS_MODULE
 Type=oneshot
 RemainAfterExit=yes
 ExecStart=@rootbindir@/systemd-tmpfiles --prefix=/dev --create --boot
+SuccessExitStatus=65
 SmackProcessLabel=System::Privileged
index 7f77b82..f573e3c 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
@@ -18,4 +20,5 @@ RefuseManualStop=yes
 Type=oneshot
 RemainAfterExit=yes
 ExecStart=@rootbindir@/systemd-tmpfiles --create --remove --boot --exclude-prefix=/dev
+SuccessExitStatus=65
 SmackProcessLabel=System::Privileged
index ff1374e..62e6314 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 69fb58b..252f25b 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 46f704e..5b8628c 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 1a16206..b2a65f1 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 1b24548..5977a40 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index eaf2f24..9a9a43a 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 6dc47e0..63f05ed 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 850c221..9f5f885 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index b271b12..8b9cef9 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 2cec3bb..a61a98d 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index c5a4ca3..8f228bc 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index debee74..1533c7c 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 251fa68..b1aa8c7 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index a01b61c..3025e91 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 39668d8..54fa5ae 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 9fa6284..3f2d98f 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index afc6e93..1ae8275 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 9853c33..da319ce 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index e8148b7..11a6f8e 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 86d15af..3adfc5a 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index 00d1623..a38eaab 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
index a42b2be..3b7eb9c 100644 (file)
@@ -1,3 +1,20 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
+# Copyright 2017 Zbigniew Jędrzejewski-Szmek
+#
+# 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.
+#
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
 units = [
         'basic.target',
         'bluetooth.target',
@@ -12,6 +29,7 @@ units = [
         'sockets.target',
         'sound.target',
         'timers.target',
+        'systemd-tmpfiles-clean.timer',
 ]
 
 units += [
@@ -32,6 +50,8 @@ meson.add_install_script('../meson-add-wants.sh', userunitdir, 'delayed.target.w
 
 in_units = [
         'systemd-exit.service',
+        'systemd-tmpfiles-clean.service',
+        'systemd-tmpfiles-setup.service',
 ]
 
 foreach file : in_units
index 987fab8..9ce6f1c 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
diff --git a/units/user/systemd-tmpfiles-clean.service.in b/units/user/systemd-tmpfiles-clean.service.in
new file mode 100644 (file)
index 0000000..9cd1972
--- /dev/null
@@ -0,0 +1,21 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
+#  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=Cleanup of User's Temporary Files and Directories
+Documentation=man:tmpfiles.d(5) man:systemd-tmpfiles(8)
+DefaultDependencies=no
+Conflicts=shutdown.target
+Before=basic.target shutdown.target
+
+[Service]
+Type=oneshot
+ExecStart=@rootbindir@/systemd-tmpfiles --user --clean
+SuccessExitStatus=65
+IOSchedulingClass=idle
diff --git a/units/user/systemd-tmpfiles-clean.timer b/units/user/systemd-tmpfiles-clean.timer
new file mode 100644 (file)
index 0000000..d1dbad9
--- /dev/null
@@ -0,0 +1,19 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
+#  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=Daily Cleanup of User's Temporary Directories
+Documentation=man:tmpfiles.d(5) man:systemd-tmpfiles(8)
+
+[Timer]
+OnStartupSec=5min
+OnUnitActiveSec=1d
+
+[Install]
+WantedBy=timers.target
diff --git a/units/user/systemd-tmpfiles-setup.service.in b/units/user/systemd-tmpfiles-setup.service.in
new file mode 100644 (file)
index 0000000..6467dab
--- /dev/null
@@ -0,0 +1,25 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
+#  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=Create User's Volatile Files and Directories
+Documentation=man:tmpfiles.d(5) man:systemd-tmpfiles(8)
+DefaultDependencies=no
+Conflicts=shutdown.target
+Before=basic.target shutdown.target
+RefuseManualStop=yes
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=@rootbindir@/systemd-tmpfiles --user --create --remove --boot
+SuccessExitStatus=65
+
+[Install]
+WantedBy=basic.target
index 02dddd6..d2db769 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it
@@ -18,7 +20,7 @@ ExecStart=-@rootlibexecdir@/systemd --user
 SmackProcessLabel=User
 Slice=user-%i.slice
 KillMode=mixed
-Delegate=yes
+Delegate=pids cpu
 TasksMax=infinity
 Environment=DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/%i/bus
 Environment=XDG_RUNTIME_DIR=/run/user/%i
index 7eba68f..5da0c6f 100644 (file)
@@ -1,3 +1,5 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
 #  This file is part of systemd.
 #
 #  systemd is free software; you can redistribute it and/or modify it