summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2017-12-14 23:22:02 +0100
committerMichael Biebl <biebl@debian.org>2017-12-14 23:22:02 +0100
commit52ad194e0b816b8273dd8d0fea3e6d467f6ca34e (patch)
tree1a3b3117e015f200ca0ce23f5ad27be6d0a7b0fb
parentf5e65279187b6aa0c0c5a00b14dca9eab441ffb2 (diff)
downloadsystemd-52ad194e0b816b8273dd8d0fea3e6d467f6ca34e.tar.gz
New upstream version 236
-rw-r--r--.github/CONTRIBUTING.md2
-rw-r--r--.gitignore2
-rw-r--r--.mailmap10
-rw-r--r--.mkosi/mkosi.arch2
-rw-r--r--.mkosi/mkosi.debian2
-rw-r--r--.mkosi/mkosi.fedora5
-rw-r--r--.ycm_extra_conf.py299
-rw-r--r--CODING_STYLE18
-rw-r--r--HACKING9
-rw-r--r--NEWS252
-rw-r--r--README37
-rw-r--r--README.md3
-rw-r--r--TODO145
-rw-r--r--TRANSIENT-SETTINGS.md447
-rw-r--r--UIDS-GIDS.md242
-rw-r--r--catalog/meson.build21
-rw-r--r--catalog/systemd.be.catalog.in2
-rw-r--r--catalog/systemd.be@latin.catalog.in2
-rw-r--r--catalog/systemd.bg.catalog.in2
-rw-r--r--catalog/systemd.catalog.in21
-rw-r--r--catalog/systemd.da.catalog.in2
-rw-r--r--catalog/systemd.de.catalog.in2
-rw-r--r--catalog/systemd.fr.catalog.in17
-rw-r--r--catalog/systemd.hr.catalog.in2
-rw-r--r--catalog/systemd.hu.catalog.in2
-rw-r--r--catalog/systemd.it.catalog.in2
-rw-r--r--catalog/systemd.ko.catalog.in2
-rw-r--r--catalog/systemd.pl.catalog.in2
-rw-r--r--catalog/systemd.pt_BR.catalog.in2
-rw-r--r--catalog/systemd.ru.catalog.in19
-rw-r--r--catalog/systemd.sr.catalog.in2
-rw-r--r--catalog/systemd.zh_CN.catalog.in2
-rw-r--r--catalog/systemd.zh_TW.catalog.in2
-rw-r--r--coccinelle/const-strlen.cocci10
-rw-r--r--coccinelle/empty-to-null.cocci5
-rw-r--r--coccinelle/equals-null.cocci14
-rw-r--r--coccinelle/in_set.cocci59
-rw-r--r--coccinelle/isempty.cocci15
-rw-r--r--coccinelle/not_in_set.cocci127
-rwxr-xr-xcoccinelle/run-coccinelle.sh11
-rw-r--r--docs/sysvinit/meson.build17
-rw-r--r--docs/var-log/meson.build17
-rw-r--r--hwdb/20-OUI.hwdb1501
-rw-r--r--hwdb/20-acpi-vendor.hwdb53
-rw-r--r--hwdb/20-acpi-vendor.hwdb.patch104
-rw-r--r--hwdb/20-pci-vendor-model.hwdb673
-rw-r--r--hwdb/20-usb-vendor-model.hwdb148
-rw-r--r--hwdb/60-evdev.hwdb8
-rw-r--r--hwdb/60-input-id.hwdb64
-rw-r--r--hwdb/60-sensor.hwdb30
-rw-r--r--hwdb/70-mouse.hwdb9
-rw-r--r--hwdb/70-touchpad.hwdb14
-rw-r--r--hwdb/acpi_id_registry.html2
-rwxr-xr-xhwdb/ids_parser.py6
-rw-r--r--hwdb/ma-large.txt9052
-rw-r--r--hwdb/ma-medium.txt579
-rw-r--r--hwdb/ma-small.txt711
-rw-r--r--hwdb/meson.build17
-rwxr-xr-xhwdb/parse_hwdb.py14
-rw-r--r--hwdb/pci.ids294
-rw-r--r--hwdb/pnp_id_registry.html17
-rw-r--r--hwdb/usb.ids62
-rw-r--r--man/binfmt.d.xml2
-rw-r--r--man/bootctl.xml18
-rw-r--r--man/bootup.xml2
-rw-r--r--man/busctl.xml3
-rw-r--r--man/coredump.conf.xml2
-rw-r--r--man/coredumpctl.xml4
-rw-r--r--man/crypttab.xml16
-rw-r--r--man/custom-entities.ent.in1
-rw-r--r--man/custom-html.xsl2
-rw-r--r--man/custom-man.xsl2
-rw-r--r--man/daemon.xml8
-rw-r--r--man/dnssec-trust-anchors.d.xml2
-rw-r--r--man/environment.d.xml4
-rw-r--r--man/file-hierarchy.xml2
-rw-r--r--man/glib-event-glue.c2
-rw-r--r--man/halt.xml11
-rw-r--r--man/hostname.xml2
-rw-r--r--man/hostnamectl.xml2
-rw-r--r--man/hwdb.xml22
-rw-r--r--man/journal-remote.conf.xml2
-rw-r--r--man/journal-upload.conf.xml2
-rw-r--r--man/journalctl.xml18
-rw-r--r--man/journald.conf.xml4
-rw-r--r--man/kernel-command-line.xml11
-rw-r--r--man/kernel-install.xml2
-rw-r--r--man/less-variables.xml21
-rw-r--r--man/libsystemd-pkgconfig.xml21
-rw-r--r--man/libudev.xml2
-rw-r--r--man/locale.conf.xml2
-rw-r--r--man/localectl.xml3
-rw-r--r--man/localtime.xml2
-rw-r--r--man/loginctl.xml11
-rw-r--r--man/logind.conf.xml2
-rw-r--r--man/machine-id.xml94
-rw-r--r--man/machine-info.xml2
-rw-r--r--man/machinectl.xml35
-rw-r--r--man/meson.build23
-rw-r--r--man/modules-load.d.xml2
-rw-r--r--man/networkctl.xml2
-rw-r--r--man/networkd.conf.xml2
-rw-r--r--man/nss-myhostname.xml4
-rw-r--r--man/nss-mymachines.xml2
-rw-r--r--man/nss-resolve.xml2
-rw-r--r--man/nss-systemd.xml2
-rw-r--r--man/os-release.xml2
-rw-r--r--man/pam_systemd.xml2
-rw-r--r--man/resolved.conf.xml2
-rw-r--r--man/rules/meson.build12
-rw-r--r--man/runlevel.xml2
-rw-r--r--man/sd-bus-errors.xml2
-rw-r--r--man/sd-bus.xml2
-rw-r--r--man/sd-daemon.xml2
-rw-r--r--man/sd-event.xml2
-rw-r--r--man/sd-id128.xml2
-rw-r--r--man/sd-journal.xml2
-rw-r--r--man/sd-login.xml2
-rw-r--r--man/sd_booted.xml2
-rw-r--r--man/sd_bus_add_match.xml2
-rw-r--r--man/sd_bus_creds_get_pid.xml34
-rw-r--r--man/sd_bus_creds_new_from_pid.xml2
-rw-r--r--man/sd_bus_default.xml2
-rw-r--r--man/sd_bus_error.xml2
-rw-r--r--man/sd_bus_error_add_map.xml2
-rw-r--r--man/sd_bus_get_fd.xml2
-rw-r--r--man/sd_bus_message_append.xml2
-rw-r--r--man/sd_bus_message_append_array.xml2
-rw-r--r--man/sd_bus_message_append_basic.xml2
-rw-r--r--man/sd_bus_message_append_string_memfd.xml2
-rw-r--r--man/sd_bus_message_append_strv.xml2
-rw-r--r--man/sd_bus_message_get_cookie.xml2
-rw-r--r--man/sd_bus_message_get_monotonic_usec.xml2
-rw-r--r--man/sd_bus_message_read_basic.xml2
-rw-r--r--man/sd_bus_negotiate_fds.xml2
-rw-r--r--man/sd_bus_new.xml2
-rw-r--r--man/sd_bus_path_encode.xml2
-rw-r--r--man/sd_bus_process.xml2
-rw-r--r--man/sd_bus_request_name.xml2
-rw-r--r--man/sd_bus_track_add_name.xml2
-rw-r--r--man/sd_bus_track_new.xml2
-rw-r--r--man/sd_event_add_child.xml2
-rw-r--r--man/sd_event_add_defer.xml2
-rw-r--r--man/sd_event_add_io.xml2
-rw-r--r--man/sd_event_add_signal.xml2
-rw-r--r--man/sd_event_add_time.xml2
-rw-r--r--man/sd_event_exit.xml2
-rw-r--r--man/sd_event_get_fd.xml2
-rw-r--r--man/sd_event_new.xml2
-rw-r--r--man/sd_event_now.xml2
-rw-r--r--man/sd_event_run.xml2
-rw-r--r--man/sd_event_set_watchdog.xml2
-rw-r--r--man/sd_event_source_get_event.xml2
-rw-r--r--man/sd_event_source_get_pending.xml2
-rw-r--r--man/sd_event_source_set_description.xml2
-rw-r--r--man/sd_event_source_set_enabled.xml2
-rw-r--r--man/sd_event_source_set_prepare.xml2
-rw-r--r--man/sd_event_source_set_priority.xml2
-rw-r--r--man/sd_event_source_set_userdata.xml2
-rw-r--r--man/sd_event_source_unref.xml2
-rw-r--r--man/sd_event_wait.xml2
-rw-r--r--man/sd_get_seats.xml2
-rw-r--r--man/sd_id128_get_machine.xml2
-rw-r--r--man/sd_id128_randomize.xml2
-rw-r--r--man/sd_id128_to_string.xml2
-rw-r--r--man/sd_is_fifo.xml2
-rw-r--r--man/sd_journal_add_match.xml2
-rw-r--r--man/sd_journal_enumerate_fields.xml2
-rw-r--r--man/sd_journal_get_catalog.xml2
-rw-r--r--man/sd_journal_get_cursor.xml2
-rw-r--r--man/sd_journal_get_cutoff_realtime_usec.xml2
-rw-r--r--man/sd_journal_get_data.xml2
-rw-r--r--man/sd_journal_get_fd.xml2
-rw-r--r--man/sd_journal_get_realtime_usec.xml2
-rw-r--r--man/sd_journal_get_usage.xml2
-rw-r--r--man/sd_journal_has_runtime_files.xml2
-rw-r--r--man/sd_journal_next.xml2
-rw-r--r--man/sd_journal_open.xml2
-rw-r--r--man/sd_journal_print.xml2
-rw-r--r--man/sd_journal_query_unique.xml2
-rw-r--r--man/sd_journal_seek_head.xml2
-rw-r--r--man/sd_journal_stream_fd.xml2
-rw-r--r--man/sd_listen_fds.xml2
-rw-r--r--man/sd_login_monitor_new.xml2
-rw-r--r--man/sd_machine_get_class.xml2
-rw-r--r--man/sd_notify.xml68
-rw-r--r--man/sd_pid_get_owner_uid.xml (renamed from man/sd_pid_get_session.xml)112
-rw-r--r--man/sd_seat_get_active.xml2
-rw-r--r--man/sd_session_is_active.xml2
-rw-r--r--man/sd_uid_get_state.xml2
-rw-r--r--man/sd_watchdog_enabled.xml2
-rw-r--r--man/shutdown.xml2
-rw-r--r--man/standard-conf.xml22
-rw-r--r--man/standard-options.xml21
-rw-r--r--man/sysctl.d.xml2
-rw-r--r--man/systemctl.xml56
-rw-r--r--man/systemd-analyze.xml14
-rw-r--r--man/systemd-ask-password-console.service.xml2
-rw-r--r--man/systemd-ask-password.xml2
-rw-r--r--man/systemd-backlight@.service.xml2
-rw-r--r--man/systemd-binfmt.service.xml2
-rw-r--r--man/systemd-cat.xml2
-rw-r--r--man/systemd-cgls.xml2
-rw-r--r--man/systemd-cgtop.xml2
-rw-r--r--man/systemd-coredump.xml4
-rw-r--r--man/systemd-cryptsetup-generator.xml2
-rw-r--r--man/systemd-cryptsetup@.service.xml2
-rw-r--r--man/systemd-debug-generator.xml2
-rw-r--r--man/systemd-delta.xml2
-rw-r--r--man/systemd-detect-virt.xml2
-rw-r--r--man/systemd-environment-d-generator.xml2
-rw-r--r--man/systemd-escape.xml17
-rw-r--r--man/systemd-firstboot.xml22
-rw-r--r--man/systemd-fsck@.service.xml2
-rw-r--r--man/systemd-fstab-generator.xml2
-rw-r--r--man/systemd-getty-generator.xml2
-rw-r--r--man/systemd-gpt-auto-generator.xml2
-rw-r--r--man/systemd-halt.service.xml2
-rw-r--r--man/systemd-hibernate-resume-generator.xml2
-rw-r--r--man/systemd-hibernate-resume@.service.xml2
-rw-r--r--man/systemd-hostnamed.service.xml2
-rw-r--r--man/systemd-hwdb.xml34
-rw-r--r--man/systemd-importd.service.xml2
-rw-r--r--man/systemd-inhibit.xml2
-rw-r--r--man/systemd-initctl.service.xml2
-rw-r--r--man/systemd-journal-gatewayd.service.xml9
-rw-r--r--man/systemd-journal-remote.xml49
-rw-r--r--man/systemd-journal-upload.xml44
-rw-r--r--man/systemd-journald.service.xml30
-rw-r--r--man/systemd-localed.service.xml2
-rw-r--r--man/systemd-logind.service.xml2
-rw-r--r--man/systemd-machine-id-commit.service.xml2
-rw-r--r--man/systemd-machine-id-setup.xml2
-rw-r--r--man/systemd-machined.service.xml2
-rw-r--r--man/systemd-makefs@.service.xml120
-rw-r--r--man/systemd-modules-load.service.xml2
-rw-r--r--man/systemd-mount.xml17
-rw-r--r--man/systemd-networkd-wait-online.service.xml2
-rw-r--r--man/systemd-networkd.service.xml2
-rw-r--r--man/systemd-notify.xml2
-rw-r--r--man/systemd-nspawn.xml80
-rw-r--r--man/systemd-path.xml2
-rw-r--r--man/systemd-quotacheck.service.xml2
-rw-r--r--man/systemd-random-seed.service.xml2
-rw-r--r--man/systemd-remount-fs.service.xml2
-rw-r--r--man/systemd-resolve.xml48
-rw-r--r--man/systemd-resolved.service.xml24
-rw-r--r--man/systemd-rfkill.service.xml2
-rw-r--r--man/systemd-run.xml27
-rw-r--r--man/systemd-sleep.conf.xml2
-rw-r--r--man/systemd-socket-activate.xml2
-rw-r--r--man/systemd-socket-proxyd.xml8
-rw-r--r--man/systemd-suspend.service.xml2
-rw-r--r--man/systemd-sysctl.service.xml2
-rw-r--r--man/systemd-system-update-generator.xml2
-rw-r--r--man/systemd-system.conf.xml17
-rw-r--r--man/systemd-sysusers.xml2
-rw-r--r--man/systemd-sysv-generator.xml2
-rw-r--r--man/systemd-timedated.service.xml2
-rw-r--r--man/systemd-timesyncd.service.xml2
-rw-r--r--man/systemd-tmpfiles.xml46
-rw-r--r--man/systemd-tty-ask-password-agent.xml2
-rw-r--r--man/systemd-udevd.service.xml33
-rw-r--r--man/systemd-update-done.service.xml2
-rw-r--r--man/systemd-update-utmp.service.xml2
-rw-r--r--man/systemd-user-sessions.service.xml2
-rw-r--r--man/systemd-vconsole-setup.service.xml30
-rw-r--r--man/systemd-veritysetup-generator.xml2
-rw-r--r--man/systemd-veritysetup@.service.xml2
-rw-r--r--man/systemd-volatile-root.service.xml2
-rw-r--r--man/systemd.automount.xml2
-rw-r--r--man/systemd.device.xml79
-rw-r--r--man/systemd.dnssd.xml258
-rw-r--r--man/systemd.environment-generator.xml4
-rw-r--r--man/systemd.exec.xml2191
-rw-r--r--man/systemd.generator.xml39
-rw-r--r--man/systemd.journal-fields.xml15
-rw-r--r--man/systemd.kill.xml2
-rw-r--r--man/systemd.link.xml2
-rw-r--r--man/systemd.mount.xml53
-rw-r--r--man/systemd.netdev.xml22
-rw-r--r--man/systemd.network.xml58
-rw-r--r--man/systemd.nspawn.xml4
-rw-r--r--man/systemd.offline-updates.xml3
-rw-r--r--man/systemd.path.xml2
-rw-r--r--man/systemd.preset.xml2
-rw-r--r--man/systemd.resource-control.xml43
-rw-r--r--man/systemd.scope.xml2
-rw-r--r--man/systemd.service.xml46
-rw-r--r--man/systemd.slice.xml4
-rw-r--r--man/systemd.socket.xml2
-rw-r--r--man/systemd.special.xml33
-rw-r--r--man/systemd.swap.xml2
-rw-r--r--man/systemd.target.xml5
-rw-r--r--man/systemd.time.xml9
-rw-r--r--man/systemd.timer.xml2
-rw-r--r--man/systemd.unit.xml499
-rw-r--r--man/systemd.xml6
-rw-r--r--man/sysusers.d.xml2
-rw-r--r--man/telinit.xml2
-rw-r--r--man/timedatectl.xml2
-rw-r--r--man/timesyncd.conf.xml19
-rw-r--r--man/tmpfiles.d.xml149
-rw-r--r--man/udev.conf.xml2
-rw-r--r--man/udev.xml22
-rw-r--r--man/udev_device_get_syspath.xml2
-rw-r--r--man/udev_device_has_tag.xml2
-rw-r--r--man/udev_device_new_from_syspath.xml2
-rw-r--r--man/udev_enumerate_add_match_subsystem.xml2
-rw-r--r--man/udev_enumerate_new.xml2
-rw-r--r--man/udev_enumerate_scan_devices.xml2
-rw-r--r--man/udev_list_entry.xml2
-rw-r--r--man/udev_monitor_filter_update.xml2
-rw-r--r--man/udev_monitor_new_from_netlink.xml2
-rw-r--r--man/udev_monitor_receive_device.xml2
-rw-r--r--man/udev_new.xml2
-rw-r--r--man/udevadm.xml126
-rw-r--r--man/user-system-options.xml22
-rw-r--r--man/vconsole.conf.xml2
-rw-r--r--meson.build224
-rw-r--r--meson_options.txt34
-rwxr-xr-xmkosi.build40
-rw-r--r--modprobe.d/systemd.conf6
-rw-r--r--network/80-container-host0.network2
-rw-r--r--network/80-container-ve.network2
-rw-r--r--network/80-container-vz.network2
-rw-r--r--network/99-default.link9
-rw-r--r--network/meson.build17
-rw-r--r--po/be.po2
-rw-r--r--po/be@latin.po2
-rw-r--r--po/bg.po2
-rw-r--r--po/ca.po2
-rw-r--r--po/cs.po214
-rw-r--r--po/da.po2
-rw-r--r--po/de.po2
-rw-r--r--po/el.po2
-rw-r--r--po/es.po2
-rw-r--r--po/fr.po92
-rw-r--r--po/gl.po2
-rw-r--r--po/hr.po2
-rw-r--r--po/hu.po2
-rw-r--r--po/id.po2
-rw-r--r--po/it.po2
-rw-r--r--po/its/polkit.its8
-rw-r--r--po/its/polkit.loc6
-rw-r--r--po/ko.po2
-rw-r--r--po/meson.build27
-rw-r--r--po/pl.po106
-rw-r--r--po/pt_BR.po2
-rw-r--r--po/ro.po2
-rw-r--r--po/ru.po140
-rw-r--r--po/sk.po2
-rw-r--r--po/sr.po2
-rw-r--r--po/sv.po33
-rw-r--r--po/tr.po106
-rw-r--r--po/uk.po2
-rw-r--r--po/zh_CN.po2
-rw-r--r--po/zh_TW.po2
-rw-r--r--presets/90-systemd.preset (renamed from system-preset/90-systemd.preset)3
-rw-r--r--presets/meson.build22
-rw-r--r--presets/user/90-systemd.preset (renamed from units/remote-cryptsetup-pre.target)13
-rw-r--r--rules/50-udev-default.rules.in7
-rw-r--r--rules/60-input-id.rules1
-rw-r--r--rules/60-persistent-input.rules4
-rw-r--r--rules/60-persistent-storage.rules8
-rw-r--r--rules/99-systemd.rules.in2
-rw-r--r--rules/meson.build20
-rw-r--r--shell-completion/bash/bootctl1
-rw-r--r--shell-completion/bash/busctl1
-rw-r--r--shell-completion/bash/coredumpctl1
-rw-r--r--shell-completion/bash/hostnamectl1
-rw-r--r--shell-completion/bash/journalctl1
-rw-r--r--shell-completion/bash/kernel-install1
-rw-r--r--shell-completion/bash/localectl1
-rw-r--r--shell-completion/bash/loginctl1
-rw-r--r--shell-completion/bash/machinectl1
-rw-r--r--shell-completion/bash/meson.build17
-rw-r--r--shell-completion/bash/networkctl1
-rw-r--r--shell-completion/bash/systemctl.in1
-rw-r--r--shell-completion/bash/systemd-analyze1
-rw-r--r--shell-completion/bash/systemd-cat1
-rw-r--r--shell-completion/bash/systemd-cgls1
-rw-r--r--shell-completion/bash/systemd-cgtop1
-rw-r--r--shell-completion/bash/systemd-delta1
-rw-r--r--shell-completion/bash/systemd-detect-virt1
-rw-r--r--shell-completion/bash/systemd-nspawn1
-rw-r--r--shell-completion/bash/systemd-path1
-rw-r--r--shell-completion/bash/systemd-resolve1
-rw-r--r--shell-completion/bash/systemd-run1
-rw-r--r--shell-completion/bash/timedatectl1
-rw-r--r--shell-completion/bash/udevadm1
-rw-r--r--shell-completion/zsh/_bootctl1
-rw-r--r--shell-completion/zsh/_busctl1
-rw-r--r--shell-completion/zsh/_coredumpctl1
-rw-r--r--shell-completion/zsh/_hostnamectl1
-rw-r--r--shell-completion/zsh/_journalctl1
-rw-r--r--shell-completion/zsh/_kernel-install1
-rw-r--r--shell-completion/zsh/_localectl1
-rw-r--r--shell-completion/zsh/_loginctl1
-rw-r--r--shell-completion/zsh/_machinectl1
-rw-r--r--shell-completion/zsh/_networkctl1
-rw-r--r--shell-completion/zsh/_sd_hosts_or_user_at_host1
-rw-r--r--shell-completion/zsh/_sd_machines1
-rw-r--r--shell-completion/zsh/_sd_outputmodes1
-rw-r--r--shell-completion/zsh/_sd_unit_files1
-rw-r--r--shell-completion/zsh/_systemctl.in7
-rw-r--r--shell-completion/zsh/_systemd1
-rw-r--r--shell-completion/zsh/_systemd-analyze1
-rw-r--r--shell-completion/zsh/_systemd-delta1
-rw-r--r--shell-completion/zsh/_systemd-inhibit1
-rw-r--r--shell-completion/zsh/_systemd-nspawn1
-rw-r--r--shell-completion/zsh/_systemd-resolve1
-rw-r--r--shell-completion/zsh/_systemd-run1
-rw-r--r--shell-completion/zsh/_systemd-tmpfiles1
-rw-r--r--shell-completion/zsh/_timedatectl1
-rw-r--r--shell-completion/zsh/_udevadm1
-rw-r--r--shell-completion/zsh/meson.build17
-rw-r--r--src/ac-power/ac-power.c1
-rw-r--r--src/activate/activate.c1
-rw-r--r--src/analyze/analyze-verify.c3
-rw-r--r--src/analyze/analyze-verify.h1
-rw-r--r--src/analyze/analyze.c109
-rw-r--r--src/analyze/meson.build17
-rw-r--r--src/ask-password/ask-password.c1
-rw-r--r--src/backlight/backlight.c1
-rw-r--r--src/basic/MurmurHash2.c4
-rw-r--r--src/basic/af-list.c1
-rw-r--r--src/basic/af-list.h1
-rw-r--r--src/basic/alloc-util.c3
-rw-r--r--src/basic/alloc-util.h3
-rw-r--r--src/basic/architecture.c1
-rw-r--r--src/basic/architecture.h1
-rw-r--r--src/basic/arphrd-list.c1
-rw-r--r--src/basic/arphrd-list.h1
-rw-r--r--src/basic/async.c1
-rw-r--r--src/basic/async.h1
-rw-r--r--src/basic/audit-util.c1
-rw-r--r--src/basic/audit-util.h1
-rw-r--r--src/basic/barrier.c1
-rw-r--r--src/basic/barrier.h1
-rw-r--r--src/basic/bitmap.c1
-rw-r--r--src/basic/bitmap.h1
-rw-r--r--src/basic/blkid-util.h1
-rw-r--r--src/basic/bpf-program.c1
-rw-r--r--src/basic/bpf-program.h1
-rw-r--r--src/basic/btrfs-util.c23
-rw-r--r--src/basic/btrfs-util.h1
-rw-r--r--src/basic/build.h1
-rw-r--r--src/basic/bus-label.c1
-rw-r--r--src/basic/bus-label.h1
-rw-r--r--src/basic/calendarspec.c50
-rw-r--r--src/basic/calendarspec.h5
-rw-r--r--src/basic/cap-list.c9
-rw-r--r--src/basic/cap-list.h1
-rw-r--r--src/basic/capability-util.c1
-rw-r--r--src/basic/capability-util.h1
-rw-r--r--src/basic/cgroup-util.c254
-rw-r--r--src/basic/cgroup-util.h18
-rw-r--r--src/basic/chattr-util.c1
-rw-r--r--src/basic/chattr-util.h1
-rw-r--r--src/basic/clock-util.c3
-rw-r--r--src/basic/clock-util.h1
-rw-r--r--src/basic/conf-files.c1
-rw-r--r--src/basic/conf-files.h1
-rw-r--r--src/basic/copy.c1
-rw-r--r--src/basic/copy.h1
-rw-r--r--src/basic/cpu-set-util.c74
-rw-r--r--src/basic/cpu-set-util.h26
-rw-r--r--src/basic/crypt-util.c27
-rw-r--r--src/basic/crypt-util.h34
-rw-r--r--src/basic/def.h5
-rw-r--r--src/basic/device-nodes.c3
-rw-r--r--src/basic/device-nodes.h14
-rw-r--r--src/basic/dirent-util.c1
-rw-r--r--src/basic/dirent-util.h1
-rw-r--r--src/basic/env-util.c8
-rw-r--r--src/basic/env-util.h1
-rw-r--r--src/basic/errno-list.c5
-rw-r--r--src/basic/errno-list.h9
-rw-r--r--src/basic/escape.c1
-rw-r--r--src/basic/escape.h1
-rw-r--r--src/basic/ether-addr-util.c5
-rw-r--r--src/basic/ether-addr-util.h1
-rw-r--r--src/basic/exec-util.c3
-rw-r--r--src/basic/exec-util.h1
-rw-r--r--src/basic/exit-status.c1
-rw-r--r--src/basic/exit-status.h1
-rw-r--r--src/basic/extract-word.c1
-rw-r--r--src/basic/extract-word.h1
-rw-r--r--src/basic/fd-util.c204
-rw-r--r--src/basic/fd-util.h13
-rw-r--r--src/basic/fileio-label.c1
-rw-r--r--src/basic/fileio-label.h5
-rw-r--r--src/basic/fileio.c30
-rw-r--r--src/basic/fileio.h15
-rw-r--r--src/basic/format-util.h1
-rw-r--r--src/basic/fs-util.c60
-rw-r--r--src/basic/fs-util.h3
-rwxr-xr-xsrc/basic/generate-gperfs.py6
-rw-r--r--src/basic/glob-util.c1
-rw-r--r--src/basic/glob-util.h1
-rw-r--r--src/basic/hash-funcs.c1
-rw-r--r--src/basic/hash-funcs.h1
-rw-r--r--src/basic/hashmap.c25
-rw-r--r--src/basic/hashmap.h24
-rw-r--r--src/basic/hexdecoct.c210
-rw-r--r--src/basic/hexdecoct.h1
-rw-r--r--src/basic/hostname-util.c101
-rw-r--r--src/basic/hostname-util.h6
-rw-r--r--src/basic/in-addr-util.c1
-rw-r--r--src/basic/in-addr-util.h1
-rw-r--r--src/basic/io-util.c2
-rw-r--r--src/basic/io-util.h1
-rw-r--r--src/basic/journal-importer.c7
-rw-r--r--src/basic/journal-importer.h1
-rw-r--r--src/basic/khash.c5
-rw-r--r--src/basic/khash.h1
-rw-r--r--src/basic/label.c1
-rw-r--r--src/basic/label.h1
-rw-r--r--src/basic/list.h4
-rw-r--r--src/basic/locale-util.c96
-rw-r--r--src/basic/locale-util.h4
-rw-r--r--src/basic/lockfile-util.c1
-rw-r--r--src/basic/lockfile-util.h1
-rw-r--r--src/basic/log.c19
-rw-r--r--src/basic/log.h5
-rw-r--r--src/basic/login-util.c1
-rw-r--r--src/basic/login-util.h1
-rw-r--r--src/basic/macro.h14
-rw-r--r--src/basic/memfd-util.c1
-rw-r--r--src/basic/memfd-util.h1
-rw-r--r--src/basic/mempool.c1
-rw-r--r--src/basic/mempool.h1
-rw-r--r--src/basic/meson.build22
-rw-r--r--src/basic/missing.h21
-rw-r--r--src/basic/missing_syscall.h31
-rw-r--r--src/basic/mkdir-label.c5
-rw-r--r--src/basic/mkdir.c21
-rw-r--r--src/basic/mkdir.h7
-rw-r--r--src/basic/module-util.h29
-rw-r--r--src/basic/mount-util.c176
-rw-r--r--src/basic/mount-util.h13
-rw-r--r--src/basic/nss-util.h1
-rw-r--r--src/basic/ordered-set.c1
-rw-r--r--src/basic/ordered-set.h1
-rw-r--r--src/basic/parse-util.c60
-rw-r--r--src/basic/parse-util.h3
-rw-r--r--src/basic/path-util.c45
-rw-r--r--src/basic/path-util.h4
-rw-r--r--src/basic/prioq.c1
-rw-r--r--src/basic/prioq.h1
-rw-r--r--src/basic/proc-cmdline.c15
-rw-r--r--src/basic/proc-cmdline.h1
-rw-r--r--src/basic/process-util.c82
-rw-r--r--src/basic/process-util.h7
-rw-r--r--src/basic/random-util.c1
-rw-r--r--src/basic/random-util.h1
-rw-r--r--src/basic/ratelimit.c1
-rw-r--r--src/basic/ratelimit.h1
-rw-r--r--src/basic/raw-clone.h1
-rw-r--r--src/basic/refcnt.h1
-rw-r--r--src/basic/replace-var.c1
-rw-r--r--src/basic/replace-var.h1
-rw-r--r--src/basic/rlimit-util.c1
-rw-r--r--src/basic/rlimit-util.h1
-rw-r--r--src/basic/rm-rf.c1
-rw-r--r--src/basic/rm-rf.h1
-rw-r--r--src/basic/securebits-util.c1
-rw-r--r--src/basic/securebits-util.h1
-rw-r--r--src/basic/selinux-util.c1
-rw-r--r--src/basic/selinux-util.h1
-rw-r--r--src/basic/set.c3
-rw-r--r--src/basic/set.h13
-rw-r--r--src/basic/sigbus.c1
-rw-r--r--src/basic/sigbus.h1
-rw-r--r--src/basic/signal-util.c3
-rw-r--r--src/basic/signal-util.h11
-rw-r--r--src/basic/siphash24.c14
-rw-r--r--src/basic/smack-util.c1
-rw-r--r--src/basic/smack-util.h1
-rw-r--r--src/basic/socket-label.c1
-rw-r--r--src/basic/socket-util.c3
-rw-r--r--src/basic/socket-util.h1
-rw-r--r--src/basic/sparse-endian.h4
-rw-r--r--src/basic/special.h1
-rw-r--r--src/basic/stat-util.c19
-rw-r--r--src/basic/stat-util.h6
-rw-r--r--src/basic/stdio-util.h1
-rw-r--r--src/basic/strbuf.c1
-rw-r--r--src/basic/strbuf.h1
-rw-r--r--src/basic/string-table.c1
-rw-r--r--src/basic/string-table.h1
-rw-r--r--src/basic/string-util.c121
-rw-r--r--src/basic/string-util.h17
-rw-r--r--src/basic/strv.c1
-rw-r--r--src/basic/strv.h9
-rw-r--r--src/basic/strxcpyx.c1
-rw-r--r--src/basic/strxcpyx.h1
-rw-r--r--src/basic/syslog-util.c1
-rw-r--r--src/basic/syslog-util.h1
-rw-r--r--src/basic/terminal-util.c4
-rw-r--r--src/basic/terminal-util.h1
-rw-r--r--src/basic/time-util.c12
-rw-r--r--src/basic/time-util.h7
-rw-r--r--src/basic/umask-util.h1
-rw-r--r--src/basic/unaligned.h1
-rw-r--r--src/basic/unit-def.c290
-rw-r--r--src/basic/unit-def.h302
-rw-r--r--src/basic/unit-name.c282
-rw-r--r--src/basic/unit-name.h279
-rw-r--r--src/basic/user-util.c62
-rw-r--r--src/basic/user-util.h21
-rw-r--r--src/basic/utf8.c1
-rw-r--r--src/basic/utf8.h1
-rw-r--r--src/basic/util.c71
-rw-r--r--src/basic/util.h1
-rw-r--r--src/basic/verbs.c9
-rw-r--r--src/basic/verbs.h11
-rw-r--r--src/basic/virt.c114
-rw-r--r--src/basic/virt.h1
-rw-r--r--src/basic/web-util.c1
-rw-r--r--src/basic/web-util.h1
-rw-r--r--src/basic/xattr-util.c3
-rw-r--r--src/basic/xattr-util.h1
-rw-r--r--src/basic/xml.c1
-rw-r--r--src/basic/xml.h1
-rw-r--r--src/binfmt/binfmt.c1
-rw-r--r--src/boot/bootctl.c419
-rw-r--r--src/boot/efi/boot.c71
-rw-r--r--src/boot/efi/console.c1
-rw-r--r--src/boot/efi/console.h1
-rw-r--r--src/boot/efi/disk.c1
-rw-r--r--src/boot/efi/disk.h1
-rw-r--r--src/boot/efi/graphics.c1
-rw-r--r--src/boot/efi/graphics.h1
-rw-r--r--src/boot/efi/linux.c14
-rw-r--r--src/boot/efi/linux.h3
-rw-r--r--src/boot/efi/measure.c86
-rw-r--r--src/boot/efi/measure.h1
-rw-r--r--src/boot/efi/meson.build17
-rw-r--r--src/boot/efi/pe.c1
-rw-r--r--src/boot/efi/pe.h1
-rw-r--r--src/boot/efi/shim.c32
-rw-r--r--src/boot/efi/shim.h1
-rw-r--r--src/boot/efi/splash.c1
-rw-r--r--src/boot/efi/splash.h1
-rw-r--r--src/boot/efi/stub.c3
-rw-r--r--src/boot/efi/util.c1
-rw-r--r--src/boot/efi/util.h1
-rw-r--r--src/busctl/busctl-introspect.c1
-rw-r--r--src/busctl/busctl-introspect.h1
-rw-r--r--src/busctl/busctl.c53
-rw-r--r--src/cgls/cgls.c1
-rw-r--r--src/cgroups-agent/cgroups-agent.c1
-rw-r--r--src/cgtop/cgtop.c6
-rw-r--r--src/core/audit-fd.c1
-rw-r--r--src/core/audit-fd.h1
-rw-r--r--src/core/automount.c36
-rw-r--r--src/core/automount.h1
-rw-r--r--src/core/bpf-firewall.c62
-rw-r--r--src/core/bpf-firewall.h1
-rw-r--r--src/core/cgroup.c175
-rw-r--r--src/core/cgroup.h6
-rw-r--r--src/core/chown-recursive.c1
-rw-r--r--src/core/chown-recursive.h1
-rw-r--r--src/core/dbus-automount.c23
-rw-r--r--src/core/dbus-automount.h3
-rw-r--r--src/core/dbus-cgroup.c356
-rw-r--r--src/core/dbus-cgroup.h3
-rw-r--r--src/core/dbus-device.c1
-rw-r--r--src/core/dbus-device.h1
-rw-r--r--src/core/dbus-execute.c751
-rw-r--r--src/core/dbus-execute.h3
-rw-r--r--src/core/dbus-job.c1
-rw-r--r--src/core/dbus-job.h1
-rw-r--r--src/core/dbus-kill.c21
-rw-r--r--src/core/dbus-kill.h3
-rw-r--r--src/core/dbus-manager.c58
-rw-r--r--src/core/dbus-manager.h1
-rw-r--r--src/core/dbus-mount.c47
-rw-r--r--src/core/dbus-mount.h3
-rw-r--r--src/core/dbus-path.c1
-rw-r--r--src/core/dbus-path.h1
-rw-r--r--src/core/dbus-scope.c92
-rw-r--r--src/core/dbus-scope.h5
-rw-r--r--src/core/dbus-service.c81
-rw-r--r--src/core/dbus-service.h3
-rw-r--r--src/core/dbus-slice.c5
-rw-r--r--src/core/dbus-slice.h3
-rw-r--r--src/core/dbus-socket.c5
-rw-r--r--src/core/dbus-socket.h3
-rw-r--r--src/core/dbus-swap.c5
-rw-r--r--src/core/dbus-swap.h3
-rw-r--r--src/core/dbus-target.c1
-rw-r--r--src/core/dbus-target.h1
-rw-r--r--src/core/dbus-timer.c57
-rw-r--r--src/core/dbus-timer.h3
-rw-r--r--src/core/dbus-unit.c150
-rw-r--r--src/core/dbus-unit.h3
-rw-r--r--src/core/dbus.c1
-rw-r--r--src/core/dbus.h1
-rw-r--r--src/core/device.c133
-rw-r--r--src/core/device.h1
-rw-r--r--src/core/dynamic-user.c177
-rw-r--r--src/core/dynamic-user.h10
-rw-r--r--src/core/emergency-action.c3
-rw-r--r--src/core/emergency-action.h1
-rw-r--r--src/core/execute.c476
-rw-r--r--src/core/execute.h19
-rw-r--r--src/core/hostname-setup.c3
-rw-r--r--src/core/hostname-setup.h1
-rw-r--r--src/core/ima-setup.c3
-rw-r--r--src/core/ima-setup.h1
-rw-r--r--src/core/ip-address-access.c17
-rw-r--r--src/core/ip-address-access.h1
-rw-r--r--src/core/job.c37
-rw-r--r--src/core/job.h1
-rw-r--r--src/core/kill.c1
-rw-r--r--src/core/kill.h1
-rw-r--r--src/core/killall.c7
-rw-r--r--src/core/killall.h1
-rw-r--r--src/core/kmod-setup.c17
-rw-r--r--src/core/kmod-setup.h1
-rw-r--r--src/core/load-dropin.c18
-rw-r--r--src/core/load-dropin.h1
-rw-r--r--src/core/load-fragment-gperf.gperf.m431
-rw-r--r--src/core/load-fragment.c518
-rw-r--r--src/core/load-fragment.h8
-rw-r--r--src/core/locale-setup.c1
-rw-r--r--src/core/locale-setup.h1
-rw-r--r--src/core/loopback-setup.c1
-rw-r--r--src/core/loopback-setup.h1
-rw-r--r--src/core/machine-id-setup.c1
-rw-r--r--src/core/machine-id-setup.h1
-rw-r--r--src/core/macros.systemd.in1
-rw-r--r--src/core/main.c1254
-rw-r--r--src/core/manager.c427
-rw-r--r--src/core/manager.h44
-rw-r--r--src/core/meson.build33
-rw-r--r--src/core/mount-setup.c44
-rw-r--r--src/core/mount-setup.h1
-rw-r--r--src/core/mount.c110
-rw-r--r--src/core/mount.h3
-rw-r--r--src/core/namespace.c54
-rw-r--r--src/core/namespace.h24
-rw-r--r--src/core/org.freedesktop.systemd1.conf2
-rw-r--r--src/core/org.freedesktop.systemd1.policy.in.in22
-rw-r--r--src/core/org.freedesktop.systemd1.service2
-rw-r--r--src/core/path.c43
-rw-r--r--src/core/path.h1
-rw-r--r--src/core/scope.c53
-rw-r--r--src/core/scope.h3
-rw-r--r--src/core/selinux-access.c1
-rw-r--r--src/core/selinux-access.h1
-rw-r--r--src/core/selinux-setup.c1
-rw-r--r--src/core/selinux-setup.h1
-rw-r--r--src/core/service.c421
-rw-r--r--src/core/service.h8
-rw-r--r--src/core/show-status.c1
-rw-r--r--src/core/show-status.h1
-rw-r--r--src/core/shutdown.c126
-rw-r--r--src/core/slice.c3
-rw-r--r--src/core/slice.h1
-rw-r--r--src/core/smack-setup.c23
-rw-r--r--src/core/smack-setup.h1
-rw-r--r--src/core/socket.c56
-rw-r--r--src/core/socket.h3
-rw-r--r--src/core/swap.c45
-rw-r--r--src/core/swap.h3
-rw-r--r--src/core/systemd.pc.in6
-rw-r--r--src/core/target.c20
-rw-r--r--src/core/target.h1
-rw-r--r--src/core/timer.c45
-rw-r--r--src/core/timer.h1
-rw-r--r--src/core/transaction.c32
-rw-r--r--src/core/transaction.h1
-rw-r--r--src/core/triggers.systemd.in1
-rw-r--r--src/core/umount.c167
-rw-r--r--src/core/umount.h1
-rw-r--r--src/core/unit-printf.c57
-rw-r--r--src/core/unit-printf.h1
-rw-r--r--src/core/unit.c1149
-rw-r--r--src/core/unit.h151
-rw-r--r--src/coredump/coredump-vacuum.c14
-rw-r--r--src/coredump/coredump-vacuum.h1
-rw-r--r--src/coredump/coredump.c16
-rw-r--r--src/coredump/coredumpctl.c7
-rw-r--r--src/coredump/meson.build17
-rw-r--r--src/coredump/stacktrace.c6
-rw-r--r--src/coredump/stacktrace.h1
-rw-r--r--src/coredump/test-coredump-vacuum.c1
-rw-r--r--src/cryptsetup/cryptsetup-generator.c70
-rw-r--r--src/cryptsetup/cryptsetup.c72
-rw-r--r--src/debug-generator/debug-generator.c1
-rw-r--r--src/delta/delta.c1
-rw-r--r--src/detect-virt/detect-virt.c1
-rw-r--r--src/dissect/dissect.c39
-rw-r--r--src/environment-d-generator/environment-d-generator.c1
-rw-r--r--src/escape/escape.c1
-rw-r--r--src/firstboot/firstboot.c118
-rw-r--r--src/fsck/fsck.c3
-rw-r--r--src/fstab-generator/fstab-generator.c172
-rw-r--r--src/getty-generator/getty-generator.c1
-rw-r--r--src/gpt-auto-generator/gpt-auto-generator.c24
-rw-r--r--src/hibernate-resume/hibernate-resume-generator.c1
-rw-r--r--src/hibernate-resume/hibernate-resume.c1
-rw-r--r--src/hostname/hostnamectl.c15
-rw-r--r--src/hostname/hostnamed.c3
-rw-r--r--src/hostname/meson.build22
-rw-r--r--src/hostname/org.freedesktop.hostname1.conf2
-rw-r--r--src/hostname/org.freedesktop.hostname1.policy.in14
-rw-r--r--src/hostname/org.freedesktop.hostname1.service2
-rw-r--r--src/hwdb/hwdb.c1
-rw-r--r--src/import/curl-util.c1
-rw-r--r--src/import/curl-util.h1
-rw-r--r--src/import/export-raw.c1
-rw-r--r--src/import/export-raw.h1
-rw-r--r--src/import/export-tar.c1
-rw-r--r--src/import/export-tar.h1
-rw-r--r--src/import/export.c1
-rw-r--r--src/import/import-common.c33
-rw-r--r--src/import/import-common.h1
-rw-r--r--src/import/import-compress.c1
-rw-r--r--src/import/import-compress.h1
-rw-r--r--src/import/import-raw.c5
-rw-r--r--src/import/import-raw.h1
-rw-r--r--src/import/import-tar.c1
-rw-r--r--src/import/import-tar.h1
-rw-r--r--src/import/import.c1
-rw-r--r--src/import/importd.c4
-rw-r--r--src/import/meson.build22
-rw-r--r--src/import/org.freedesktop.import1.conf2
-rw-r--r--src/import/org.freedesktop.import1.policy.in14
-rw-r--r--src/import/org.freedesktop.import1.service2
-rw-r--r--src/import/pull-common.c21
-rw-r--r--src/import/pull-common.h1
-rw-r--r--src/import/pull-job.c1
-rw-r--r--src/import/pull-job.h1
-rw-r--r--src/import/pull-raw.c5
-rw-r--r--src/import/pull-raw.h1
-rw-r--r--src/import/pull-tar.c1
-rw-r--r--src/import/pull-tar.h1
-rw-r--r--src/import/pull.c1
-rw-r--r--src/import/qcow2-util.c1
-rw-r--r--src/import/qcow2-util.h1
-rw-r--r--src/import/test-qcow2.c1
-rw-r--r--src/initctl/initctl.c1
-rw-r--r--src/journal-remote/journal-gatewayd.c3
-rw-r--r--src/journal-remote/journal-remote-parse.c1
-rw-r--r--src/journal-remote/journal-remote-parse.h1
-rw-r--r--src/journal-remote/journal-remote-write.c1
-rw-r--r--src/journal-remote/journal-remote-write.h1
-rw-r--r--src/journal-remote/journal-remote.c62
-rw-r--r--src/journal-remote/journal-remote.h4
-rw-r--r--src/journal-remote/journal-upload-journal.c25
-rw-r--r--src/journal-remote/journal-upload.c5
-rw-r--r--src/journal-remote/meson.build17
-rw-r--r--src/journal-remote/microhttpd-util.c1
-rw-r--r--src/journal-remote/microhttpd-util.h1
-rw-r--r--src/journal/audit-type.c1
-rw-r--r--src/journal/audit-type.h3
-rw-r--r--src/journal/cat.c1
-rw-r--r--src/journal/catalog.c1
-rw-r--r--src/journal/catalog.h1
-rw-r--r--src/journal/compress.c3
-rw-r--r--src/journal/compress.h1
-rw-r--r--src/journal/fsprg.c3
-rw-r--r--src/journal/fsprg.h2
-rw-r--r--src/journal/journal-authenticate.c1
-rw-r--r--src/journal/journal-authenticate.h1
-rw-r--r--src/journal/journal-def.h1
-rw-r--r--src/journal/journal-file.c25
-rw-r--r--src/journal/journal-file.h2
-rw-r--r--src/journal/journal-internal.h1
-rw-r--r--src/journal/journal-qrcode.c8
-rw-r--r--src/journal/journal-qrcode.h1
-rw-r--r--src/journal/journal-send.c7
-rw-r--r--src/journal/journal-vacuum.c1
-rw-r--r--src/journal/journal-vacuum.h1
-rw-r--r--src/journal/journal-verify.c1
-rw-r--r--src/journal/journal-verify.h1
-rw-r--r--src/journal/journalctl.c29
-rw-r--r--src/journal/journald-audit.c74
-rw-r--r--src/journal/journald-audit.h1
-rw-r--r--src/journal/journald-console.c5
-rw-r--r--src/journal/journald-console.h1
-rw-r--r--src/journal/journald-context.c152
-rw-r--r--src/journal/journald-context.h22
-rw-r--r--src/journal/journald-gperf.gperf3
-rw-r--r--src/journal/journald-kmsg.c14
-rw-r--r--src/journal/journald-kmsg.h1
-rw-r--r--src/journal/journald-native.c89
-rw-r--r--src/journal/journald-native.h1
-rw-r--r--src/journal/journald-rate-limit.c1
-rw-r--r--src/journal/journald-rate-limit.h1
-rw-r--r--src/journal/journald-server.c70
-rw-r--r--src/journal/journald-server.h20
-rw-r--r--src/journal/journald-stream.c39
-rw-r--r--src/journal/journald-stream.h1
-rw-r--r--src/journal/journald-syslog.c32
-rw-r--r--src/journal/journald-syslog.h1
-rw-r--r--src/journal/journald-wall.c1
-rw-r--r--src/journal/journald-wall.h1
-rw-r--r--src/journal/journald.c5
-rw-r--r--src/journal/meson.build17
-rw-r--r--src/journal/mmap-cache.c1
-rw-r--r--src/journal/mmap-cache.h1
-rw-r--r--src/journal/sd-journal.c12
-rw-r--r--src/journal/test-audit-type.c1
-rw-r--r--src/journal/test-catalog.c1
-rw-r--r--src/journal/test-compress-benchmark.c1
-rw-r--r--src/journal/test-compress.c10
-rw-r--r--src/journal/test-journal-enum.c1
-rw-r--r--src/journal/test-journal-flush.c1
-rw-r--r--src/journal/test-journal-init.c1
-rw-r--r--src/journal/test-journal-interleaving.c1
-rw-r--r--src/journal/test-journal-match.c1
-rw-r--r--src/journal/test-journal-send.c9
-rw-r--r--src/journal/test-journal-stream.c1
-rw-r--r--src/journal/test-journal-syslog.c1
-rw-r--r--src/journal/test-journal-verify.c1
-rw-r--r--src/journal/test-journal.c1
-rw-r--r--src/journal/test-mmap-cache.c1
-rw-r--r--src/kernel-install/kernel-install1
-rw-r--r--src/kernel-install/meson.build17
-rw-r--r--src/libsystemd-network/arp-util.c1
-rw-r--r--src/libsystemd-network/arp-util.h1
-rw-r--r--src/libsystemd-network/dhcp-identifier.c1
-rw-r--r--src/libsystemd-network/dhcp-identifier.h1
-rw-r--r--src/libsystemd-network/dhcp-internal.h1
-rw-r--r--src/libsystemd-network/dhcp-lease-internal.h1
-rw-r--r--src/libsystemd-network/dhcp-network.c1
-rw-r--r--src/libsystemd-network/dhcp-option.c5
-rw-r--r--src/libsystemd-network/dhcp-packet.c1
-rw-r--r--src/libsystemd-network/dhcp-protocol.h1
-rw-r--r--src/libsystemd-network/dhcp-server-internal.h1
-rw-r--r--src/libsystemd-network/dhcp6-internal.h2
-rw-r--r--src/libsystemd-network/dhcp6-lease-internal.h1
-rw-r--r--src/libsystemd-network/dhcp6-network.c1
-rw-r--r--src/libsystemd-network/dhcp6-option.c28
-rw-r--r--src/libsystemd-network/dhcp6-protocol.h7
-rw-r--r--src/libsystemd-network/icmp6-util.c1
-rw-r--r--src/libsystemd-network/icmp6-util.h1
-rw-r--r--src/libsystemd-network/lldp-internal.h1
-rw-r--r--src/libsystemd-network/lldp-neighbor.c1
-rw-r--r--src/libsystemd-network/lldp-neighbor.h1
-rw-r--r--src/libsystemd-network/lldp-network.c1
-rw-r--r--src/libsystemd-network/lldp-network.h1
-rw-r--r--src/libsystemd-network/meson.build17
-rw-r--r--src/libsystemd-network/ndisc-internal.h1
-rw-r--r--src/libsystemd-network/ndisc-router.c1
-rw-r--r--src/libsystemd-network/ndisc-router.h1
-rw-r--r--src/libsystemd-network/network-internal.c1
-rw-r--r--src/libsystemd-network/network-internal.h1
-rw-r--r--src/libsystemd-network/radv-internal.h3
-rw-r--r--src/libsystemd-network/sd-dhcp-client.c6
-rw-r--r--src/libsystemd-network/sd-dhcp-lease.c27
-rw-r--r--src/libsystemd-network/sd-dhcp-server.c5
-rw-r--r--src/libsystemd-network/sd-dhcp6-client.c43
-rw-r--r--src/libsystemd-network/sd-dhcp6-lease.c1
-rw-r--r--src/libsystemd-network/sd-ipv4acd.c4
-rw-r--r--src/libsystemd-network/sd-ipv4ll.c1
-rw-r--r--src/libsystemd-network/sd-lldp.c1
-rw-r--r--src/libsystemd-network/sd-ndisc.c1
-rw-r--r--src/libsystemd-network/sd-radv.c6
-rw-r--r--src/libsystemd-network/test-acd.c1
-rw-r--r--src/libsystemd-network/test-dhcp-client.c11
-rw-r--r--src/libsystemd-network/test-dhcp-server.c1
-rw-r--r--src/libsystemd-network/test-dhcp6-client.c37
-rw-r--r--src/libsystemd-network/test-ipv4ll-manual.c1
-rw-r--r--src/libsystemd-network/test-ipv4ll.c1
-rw-r--r--src/libsystemd-network/test-lldp.c1
-rw-r--r--src/libsystemd-network/test-ndisc-ra.c3
-rw-r--r--src/libsystemd-network/test-ndisc-rs.c3
-rw-r--r--src/libsystemd/libsystemd.pc.in2
-rw-r--r--src/libsystemd/libsystemd.sym8
-rw-r--r--src/libsystemd/meson.build17
-rw-r--r--src/libsystemd/sd-bus/bus-bloom.c1
-rw-r--r--src/libsystemd/sd-bus/bus-bloom.h1
-rw-r--r--src/libsystemd/sd-bus/bus-common-errors.c1
-rw-r--r--src/libsystemd/sd-bus/bus-common-errors.h3
-rw-r--r--src/libsystemd/sd-bus/bus-container.c1
-rw-r--r--src/libsystemd/sd-bus/bus-container.h1
-rw-r--r--src/libsystemd/sd-bus/bus-control.c1
-rw-r--r--src/libsystemd/sd-bus/bus-control.h1
-rw-r--r--src/libsystemd/sd-bus/bus-convenience.c1
-rw-r--r--src/libsystemd/sd-bus/bus-creds.c1
-rw-r--r--src/libsystemd/sd-bus/bus-creds.h1
-rw-r--r--src/libsystemd/sd-bus/bus-dump.c1
-rw-r--r--src/libsystemd/sd-bus/bus-dump.h1
-rw-r--r--src/libsystemd/sd-bus/bus-error.c1
-rw-r--r--src/libsystemd/sd-bus/bus-error.h1
-rw-r--r--src/libsystemd/sd-bus/bus-gvariant.c1
-rw-r--r--src/libsystemd/sd-bus/bus-gvariant.h1
-rw-r--r--src/libsystemd/sd-bus/bus-internal.c1
-rw-r--r--src/libsystemd/sd-bus/bus-internal.h1
-rw-r--r--src/libsystemd/sd-bus/bus-introspect.c43
-rw-r--r--src/libsystemd/sd-bus/bus-introspect.h1
-rw-r--r--src/libsystemd/sd-bus/bus-kernel.c1
-rw-r--r--src/libsystemd/sd-bus/bus-kernel.h1
-rw-r--r--src/libsystemd/sd-bus/bus-match.c19
-rw-r--r--src/libsystemd/sd-bus/bus-match.h1
-rw-r--r--src/libsystemd/sd-bus/bus-message.c93
-rw-r--r--src/libsystemd/sd-bus/bus-message.h2
-rw-r--r--src/libsystemd/sd-bus/bus-objects.c13
-rw-r--r--src/libsystemd/sd-bus/bus-objects.h1
-rw-r--r--src/libsystemd/sd-bus/bus-protocol.h1
-rw-r--r--src/libsystemd/sd-bus/bus-signature.c1
-rw-r--r--src/libsystemd/sd-bus/bus-signature.h1
-rw-r--r--src/libsystemd/sd-bus/bus-slot.c1
-rw-r--r--src/libsystemd/sd-bus/bus-slot.h1
-rw-r--r--src/libsystemd/sd-bus/bus-socket.c6
-rw-r--r--src/libsystemd/sd-bus/bus-socket.h1
-rw-r--r--src/libsystemd/sd-bus/bus-track.c15
-rw-r--r--src/libsystemd/sd-bus/bus-track.h1
-rw-r--r--src/libsystemd/sd-bus/bus-type.c1
-rw-r--r--src/libsystemd/sd-bus/bus-type.h1
-rw-r--r--src/libsystemd/sd-bus/sd-bus.c9
-rw-r--r--src/libsystemd/sd-bus/test-bus-benchmark.c3
-rw-r--r--src/libsystemd/sd-bus/test-bus-chat.c1
-rw-r--r--src/libsystemd/sd-bus/test-bus-cleanup.c1
-rw-r--r--src/libsystemd/sd-bus/test-bus-creds.c1
-rw-r--r--src/libsystemd/sd-bus/test-bus-error.c1
-rw-r--r--src/libsystemd/sd-bus/test-bus-gvariant.c5
-rw-r--r--src/libsystemd/sd-bus/test-bus-introspect.c1
-rw-r--r--src/libsystemd/sd-bus/test-bus-marshal.c5
-rw-r--r--src/libsystemd/sd-bus/test-bus-match.c3
-rw-r--r--src/libsystemd/sd-bus/test-bus-objects.c1
-rw-r--r--src/libsystemd/sd-bus/test-bus-server.c1
-rw-r--r--src/libsystemd/sd-bus/test-bus-signature.c1
-rw-r--r--src/libsystemd/sd-bus/test-bus-track.c1
-rw-r--r--src/libsystemd/sd-daemon/sd-daemon.c1
-rw-r--r--src/libsystemd/sd-device/device-enumerator-private.h1
-rw-r--r--src/libsystemd/sd-device/device-enumerator.c3
-rw-r--r--src/libsystemd/sd-device/device-internal.h1
-rw-r--r--src/libsystemd/sd-device/device-private.c11
-rw-r--r--src/libsystemd/sd-device/device-private.h1
-rw-r--r--src/libsystemd/sd-device/device-util.h1
-rw-r--r--src/libsystemd/sd-device/sd-device.c35
-rw-r--r--src/libsystemd/sd-event/sd-event.c1
-rw-r--r--src/libsystemd/sd-event/test-event.c11
-rw-r--r--src/libsystemd/sd-hwdb/hwdb-internal.h1
-rw-r--r--src/libsystemd/sd-hwdb/hwdb-util.h1
-rw-r--r--src/libsystemd/sd-hwdb/sd-hwdb.c1
-rw-r--r--src/libsystemd/sd-id128/id128-util.c5
-rw-r--r--src/libsystemd/sd-id128/id128-util.h1
-rw-r--r--src/libsystemd/sd-id128/sd-id128.c1
-rw-r--r--src/libsystemd/sd-login/sd-login.c1
-rw-r--r--src/libsystemd/sd-login/test-login.c1
-rw-r--r--src/libsystemd/sd-netlink/local-addresses.c1
-rw-r--r--src/libsystemd/sd-netlink/local-addresses.h1
-rw-r--r--src/libsystemd/sd-netlink/netlink-internal.h1
-rw-r--r--src/libsystemd/sd-netlink/netlink-message.c1
-rw-r--r--src/libsystemd/sd-netlink/netlink-socket.c1
-rw-r--r--src/libsystemd/sd-netlink/netlink-types.c13
-rw-r--r--src/libsystemd/sd-netlink/netlink-types.h2
-rw-r--r--src/libsystemd/sd-netlink/netlink-util.c1
-rw-r--r--src/libsystemd/sd-netlink/netlink-util.h1
-rw-r--r--src/libsystemd/sd-netlink/rtnl-message.c1
-rw-r--r--src/libsystemd/sd-netlink/sd-netlink.c1
-rw-r--r--src/libsystemd/sd-netlink/test-local-addresses.c1
-rw-r--r--src/libsystemd/sd-netlink/test-netlink.c1
-rw-r--r--src/libsystemd/sd-network/network-util.c1
-rw-r--r--src/libsystemd/sd-network/network-util.h1
-rw-r--r--src/libsystemd/sd-network/sd-network.c22
-rw-r--r--src/libsystemd/sd-path/sd-path.c1
-rw-r--r--src/libsystemd/sd-resolve/sd-resolve.c49
-rw-r--r--src/libsystemd/sd-resolve/test-resolve.c14
-rw-r--r--src/libsystemd/sd-utf8/sd-utf8.c1
-rw-r--r--src/libudev/libudev-device-internal.h1
-rw-r--r--src/libudev/libudev-device-private.c1
-rw-r--r--src/libudev/libudev-device.c1
-rw-r--r--src/libudev/libudev-enumerate.c1
-rw-r--r--src/libudev/libudev-hwdb.c4
-rw-r--r--src/libudev/libudev-list.c1
-rw-r--r--src/libudev/libudev-monitor.c24
-rw-r--r--src/libudev/libudev-private.h2
-rw-r--r--src/libudev/libudev-queue.c4
-rw-r--r--src/libudev/libudev-util.c12
-rw-r--r--src/libudev/libudev.c4
-rw-r--r--src/libudev/libudev.h1
-rw-r--r--src/libudev/libudev.pc.in2
-rw-r--r--src/libudev/libudev.sym2
-rw-r--r--src/libudev/meson.build17
-rw-r--r--src/locale/keymap-util.c23
-rw-r--r--src/locale/keymap-util.h1
-rw-r--r--src/locale/localectl.c85
-rw-r--r--src/locale/localed.c5
-rw-r--r--src/locale/meson.build22
-rw-r--r--src/locale/org.freedesktop.locale1.conf2
-rw-r--r--src/locale/org.freedesktop.locale1.policy.in10
-rw-r--r--src/locale/org.freedesktop.locale1.service2
-rw-r--r--src/locale/test-keymap-util.c1
-rw-r--r--src/login/70-power-switch.rules2
-rw-r--r--src/login/70-uaccess.rules7
-rw-r--r--src/login/71-seat.rules.in2
-rw-r--r--src/login/73-seat-late.rules.in2
-rw-r--r--src/login/inhibit.c1
-rw-r--r--src/login/loginctl.c51
-rw-r--r--src/login/logind-acl.c1
-rw-r--r--src/login/logind-acl.h1
-rw-r--r--src/login/logind-action.c1
-rw-r--r--src/login/logind-action.h1
-rw-r--r--src/login/logind-button.c1
-rw-r--r--src/login/logind-button.h1
-rw-r--r--src/login/logind-core.c1
-rw-r--r--src/login/logind-dbus.c152
-rw-r--r--src/login/logind-device.c1
-rw-r--r--src/login/logind-device.h1
-rw-r--r--src/login/logind-gperf.gperf3
-rw-r--r--src/login/logind-inhibit.c7
-rw-r--r--src/login/logind-inhibit.h1
-rw-r--r--src/login/logind-seat-dbus.c21
-rw-r--r--src/login/logind-seat.c11
-rw-r--r--src/login/logind-seat.h1
-rw-r--r--src/login/logind-session-dbus.c16
-rw-r--r--src/login/logind-session-device.c42
-rw-r--r--src/login/logind-session-device.h2
-rw-r--r--src/login/logind-session.c6
-rw-r--r--src/login/logind-session.h1
-rw-r--r--src/login/logind-user-dbus.c6
-rw-r--r--src/login/logind-user.c58
-rw-r--r--src/login/logind-user.h1
-rw-r--r--src/login/logind-utmp.c1
-rw-r--r--src/login/logind.c3
-rw-r--r--src/login/logind.h1
-rw-r--r--src/login/meson.build22
-rw-r--r--src/login/org.freedesktop.login1.conf2
-rw-r--r--src/login/org.freedesktop.login1.policy.in130
-rw-r--r--src/login/org.freedesktop.login1.service2
-rw-r--r--src/login/pam_systemd.c1
-rw-r--r--src/login/pam_systemd.sym2
-rw-r--r--src/login/sysfs-show.c28
-rw-r--r--src/login/sysfs-show.h7
-rw-r--r--src/login/test-inhibit.c1
-rw-r--r--src/login/test-login-shared.c1
-rw-r--r--src/login/test-login-tables.c1
-rw-r--r--src/machine-id-setup/machine-id-setup-main.c1
-rw-r--r--src/machine/image-dbus.c177
-rw-r--r--src/machine/image-dbus.h4
-rw-r--r--src/machine/machine-dbus.c89
-rw-r--r--src/machine/machine-dbus.h1
-rw-r--r--src/machine/machine.c16
-rw-r--r--src/machine/machine.h1
-rw-r--r--src/machine/machinectl.c174
-rw-r--r--src/machine/machined-dbus.c80
-rw-r--r--src/machine/machined.c7
-rw-r--r--src/machine/machined.h1
-rw-r--r--src/machine/meson.build22
-rw-r--r--src/machine/operation.c1
-rw-r--r--src/machine/operation.h1
-rw-r--r--src/machine/org.freedesktop.machine1.conf24
-rw-r--r--src/machine/org.freedesktop.machine1.policy.in34
-rw-r--r--src/machine/org.freedesktop.machine1.service2
-rw-r--r--src/machine/test-machine-tables.c1
-rw-r--r--src/modules-load/modules-load.c26
-rw-r--r--src/mount/mount-tool.c93
-rw-r--r--src/network/meson.build25
-rw-r--r--src/network/netdev/bond.c1
-rw-r--r--src/network/netdev/bond.h1
-rw-r--r--src/network/netdev/bridge.c4
-rw-r--r--src/network/netdev/bridge.h1
-rw-r--r--src/network/netdev/dummy.c1
-rw-r--r--src/network/netdev/dummy.h1
-rw-r--r--src/network/netdev/geneve.c1
-rw-r--r--src/network/netdev/geneve.h1
-rw-r--r--src/network/netdev/ipvlan.c1
-rw-r--r--src/network/netdev/ipvlan.h1
-rw-r--r--src/network/netdev/macvlan.c1
-rw-r--r--src/network/netdev/macvlan.h1
-rw-r--r--src/network/netdev/netdev-gperf.gperf5
-rw-r--r--src/network/netdev/netdev.c8
-rw-r--r--src/network/netdev/netdev.h2
-rw-r--r--src/network/netdev/tunnel.c2
-rw-r--r--src/network/netdev/tunnel.h1
-rw-r--r--src/network/netdev/tuntap.c1
-rw-r--r--src/network/netdev/tuntap.h1
-rw-r--r--src/network/netdev/vcan.c1
-rw-r--r--src/network/netdev/vcan.h1
-rw-r--r--src/network/netdev/veth.c1
-rw-r--r--src/network/netdev/veth.h1
-rw-r--r--src/network/netdev/vlan.c1
-rw-r--r--src/network/netdev/vlan.h1
-rw-r--r--src/network/netdev/vrf.c1
-rw-r--r--src/network/netdev/vrf.h1
-rw-r--r--src/network/netdev/vxcan.c89
-rw-r--r--src/network/netdev/vxcan.h38
-rw-r--r--src/network/netdev/vxlan.c1
-rw-r--r--src/network/netdev/vxlan.h1
-rw-r--r--src/network/networkctl.c3
-rw-r--r--src/network/networkd-address-label.c1
-rw-r--r--src/network/networkd-address-label.h1
-rw-r--r--src/network/networkd-address-pool.c1
-rw-r--r--src/network/networkd-address-pool.h1
-rw-r--r--src/network/networkd-address.c25
-rw-r--r--src/network/networkd-address.h1
-rw-r--r--src/network/networkd-brvlan.c3
-rw-r--r--src/network/networkd-brvlan.h1
-rw-r--r--src/network/networkd-conf.c3
-rw-r--r--src/network/networkd-conf.h1
-rw-r--r--src/network/networkd-dhcp4.c144
-rw-r--r--src/network/networkd-dhcp6.c30
-rw-r--r--src/network/networkd-fdb.c1
-rw-r--r--src/network/networkd-fdb.h1
-rw-r--r--src/network/networkd-gperf.gperf3
-rw-r--r--src/network/networkd-ipv4ll.c1
-rw-r--r--src/network/networkd-ipv6-proxy-ndp.c9
-rw-r--r--src/network/networkd-ipv6-proxy-ndp.h1
-rw-r--r--src/network/networkd-link-bus.c1
-rw-r--r--src/network/networkd-link.c223
-rw-r--r--src/network/networkd-link.h12
-rw-r--r--src/network/networkd-lldp-tx.c1
-rw-r--r--src/network/networkd-lldp-tx.h1
-rw-r--r--src/network/networkd-manager-bus.c1
-rw-r--r--src/network/networkd-manager.c71
-rw-r--r--src/network/networkd-manager.h1
-rw-r--r--src/network/networkd-ndisc.c9
-rw-r--r--src/network/networkd-ndisc.h1
-rw-r--r--src/network/networkd-network-bus.c1
-rw-r--r--src/network/networkd-network-gperf.gperf10
-rw-r--r--src/network/networkd-network.c14
-rw-r--r--src/network/networkd-network.h5
-rw-r--r--src/network/networkd-radv.c163
-rw-r--r--src/network/networkd-radv.h2
-rw-r--r--src/network/networkd-route.c9
-rw-r--r--src/network/networkd-route.h3
-rw-r--r--src/network/networkd-routing-policy-rule.c206
-rw-r--r--src/network/networkd-routing-policy-rule.h14
-rw-r--r--src/network/networkd-util.c1
-rw-r--r--src/network/networkd-util.h1
-rw-r--r--src/network/networkd.c9
-rw-r--r--src/network/org.freedesktop.network1.service2
-rw-r--r--src/network/test-network.c69
-rw-r--r--src/network/test-networkd-conf.c1
-rw-r--r--src/network/test-routing-policy-rule.c106
-rw-r--r--src/network/wait-online/link.c3
-rw-r--r--src/network/wait-online/link.h3
-rw-r--r--src/network/wait-online/manager.c4
-rw-r--r--src/network/wait-online/manager.h1
-rw-r--r--src/network/wait-online/wait-online.c1
-rw-r--r--src/notify/notify.c1
-rw-r--r--src/nspawn/meson.build40
-rw-r--r--src/nspawn/nspawn-cgroup.c28
-rw-r--r--src/nspawn/nspawn-cgroup.h3
-rw-r--r--src/nspawn/nspawn-def.h27
-rw-r--r--src/nspawn/nspawn-expose-ports.c1
-rw-r--r--src/nspawn/nspawn-expose-ports.h1
-rw-r--r--src/nspawn/nspawn-gperf.gperf3
-rw-r--r--src/nspawn/nspawn-mount.c108
-rw-r--r--src/nspawn/nspawn-mount.h1
-rw-r--r--src/nspawn/nspawn-network.c1
-rw-r--r--src/nspawn/nspawn-network.h1
-rw-r--r--src/nspawn/nspawn-patch-uid.c126
-rw-r--r--src/nspawn/nspawn-patch-uid.h3
-rw-r--r--src/nspawn/nspawn-register.c46
-rw-r--r--src/nspawn/nspawn-register.h7
-rw-r--r--src/nspawn/nspawn-seccomp.c1
-rw-r--r--src/nspawn/nspawn-seccomp.h1
-rw-r--r--src/nspawn/nspawn-settings.c11
-rw-r--r--src/nspawn/nspawn-settings.h1
-rw-r--r--src/nspawn/nspawn-setuid.c3
-rw-r--r--src/nspawn/nspawn-setuid.h1
-rw-r--r--src/nspawn/nspawn-stub-pid1.c1
-rw-r--r--src/nspawn/nspawn-stub-pid1.h1
-rw-r--r--src/nspawn/nspawn.c371
-rw-r--r--src/nspawn/test-patch-uid.c1
-rw-r--r--src/nss-myhostname/nss-myhostname.c1
-rw-r--r--src/nss-myhostname/nss-myhostname.sym2
-rw-r--r--src/nss-mymachines/nss-mymachines.c5
-rw-r--r--src/nss-mymachines/nss-mymachines.sym2
-rw-r--r--src/nss-resolve/nss-resolve.c1
-rw-r--r--src/nss-resolve/nss-resolve.sym2
-rw-r--r--src/nss-systemd/nss-systemd.c14
-rw-r--r--src/nss-systemd/nss-systemd.sym2
-rw-r--r--src/partition/growfs.c323
-rw-r--r--src/partition/makefs.c110
-rw-r--r--src/path/path.c1
-rw-r--r--src/quotacheck/quotacheck.c1
-rw-r--r--src/random-seed/random-seed.c1
-rw-r--r--src/rc-local-generator/rc-local-generator.c1
-rw-r--r--src/remount-fs/remount-fs.c1
-rw-r--r--src/reply-password/reply-password.c1
-rw-r--r--src/resolve/RFCs1
-rw-r--r--src/resolve/dns-type.c1
-rw-r--r--src/resolve/dns-type.h1
-rwxr-xr-xsrc/resolve/generate-dns_type-gperf.py6
-rw-r--r--src/resolve/meson.build38
-rw-r--r--src/resolve/org.freedesktop.resolve1.policy.in43
-rw-r--r--src/resolve/org.freedesktop.resolve1.service2
-rw-r--r--src/resolve/resolv.conf14
-rw-r--r--src/resolve/resolve-tool.c383
-rw-r--r--src/resolve/resolved-bus.c241
-rw-r--r--src/resolve/resolved-bus.h1
-rw-r--r--src/resolve/resolved-conf.c161
-rw-r--r--src/resolve/resolved-conf.h6
-rw-r--r--src/resolve/resolved-def.h1
-rw-r--r--src/resolve/resolved-dns-answer.c1
-rw-r--r--src/resolve/resolved-dns-answer.h1
-rw-r--r--src/resolve/resolved-dns-cache.c1
-rw-r--r--src/resolve/resolved-dns-cache.h1
-rw-r--r--src/resolve/resolved-dns-dnssec.c226
-rw-r--r--src/resolve/resolved-dns-dnssec.h1
-rw-r--r--src/resolve/resolved-dns-packet.c20
-rw-r--r--src/resolve/resolved-dns-packet.h1
-rw-r--r--src/resolve/resolved-dns-query.c1
-rw-r--r--src/resolve/resolved-dns-query.h1
-rw-r--r--src/resolve/resolved-dns-question.c1
-rw-r--r--src/resolve/resolved-dns-question.h1
-rw-r--r--src/resolve/resolved-dns-rr.c42
-rw-r--r--src/resolve/resolved-dns-rr.h5
-rw-r--r--src/resolve/resolved-dns-scope.c215
-rw-r--r--src/resolve/resolved-dns-scope.h6
-rw-r--r--src/resolve/resolved-dns-search-domain.c1
-rw-r--r--src/resolve/resolved-dns-search-domain.h1
-rw-r--r--src/resolve/resolved-dns-server.c1
-rw-r--r--src/resolve/resolved-dns-server.h1
-rw-r--r--src/resolve/resolved-dns-stream.c1
-rw-r--r--src/resolve/resolved-dns-stream.h1
-rw-r--r--src/resolve/resolved-dns-stub.c1
-rw-r--r--src/resolve/resolved-dns-stub.h1
-rw-r--r--src/resolve/resolved-dns-synthesize.c5
-rw-r--r--src/resolve/resolved-dns-synthesize.h1
-rw-r--r--src/resolve/resolved-dns-transaction.c71
-rw-r--r--src/resolve/resolved-dns-transaction.h3
-rw-r--r--src/resolve/resolved-dns-trust-anchor.c14
-rw-r--r--src/resolve/resolved-dns-trust-anchor.h1
-rw-r--r--src/resolve/resolved-dns-zone.c71
-rw-r--r--src/resolve/resolved-dns-zone.h4
-rw-r--r--src/resolve/resolved-dnssd-bus.c146
-rw-r--r--src/resolve/resolved-dnssd-bus.h29
-rw-r--r--src/resolve/resolved-dnssd-gperf.gperf24
-rw-r--r--src/resolve/resolved-dnssd.c387
-rw-r--r--src/resolve/resolved-dnssd.h78
-rw-r--r--src/resolve/resolved-etc-hosts.c1
-rw-r--r--src/resolve/resolved-etc-hosts.h1
-rw-r--r--src/resolve/resolved-gperf.gperf3
-rw-r--r--src/resolve/resolved-link-bus.c1
-rw-r--r--src/resolve/resolved-link-bus.h1
-rw-r--r--src/resolve/resolved-link.c65
-rw-r--r--src/resolve/resolved-link.h1
-rw-r--r--src/resolve/resolved-llmnr.c15
-rw-r--r--src/resolve/resolved-llmnr.h1
-rw-r--r--src/resolve/resolved-manager.c94
-rw-r--r--src/resolve/resolved-manager.h8
-rw-r--r--src/resolve/resolved-mdns.c189
-rw-r--r--src/resolve/resolved-mdns.h1
-rw-r--r--src/resolve/resolved-resolv-conf.c149
-rw-r--r--src/resolve/resolved-resolv-conf.h3
-rw-r--r--src/resolve/resolved.c7
-rw-r--r--src/resolve/test-dns-packet.c1
-rw-r--r--src/resolve/test-dnssec-complex.c1
-rw-r--r--src/resolve/test-dnssec.c187
-rw-r--r--src/resolve/test-resolve-tables.c1
-rw-r--r--src/resolve/test-resolved-packet.c1
-rw-r--r--src/rfkill/rfkill.c7
-rw-r--r--src/run/run.c262
-rw-r--r--src/shared/acl-util.c3
-rw-r--r--src/shared/acl-util.h1
-rw-r--r--src/shared/acpi-fpdt.c1
-rw-r--r--src/shared/acpi-fpdt.h1
-rw-r--r--src/shared/apparmor-util.c1
-rw-r--r--src/shared/apparmor-util.h1
-rw-r--r--src/shared/ask-password-api.c7
-rw-r--r--src/shared/ask-password-api.h1
-rw-r--r--src/shared/base-filesystem.c1
-rw-r--r--src/shared/base-filesystem.h1
-rw-r--r--src/shared/boot-timestamps.c1
-rw-r--r--src/shared/boot-timestamps.h1
-rw-r--r--src/shared/bootspec.c654
-rw-r--r--src/shared/bootspec.h64
-rw-r--r--src/shared/bus-unit-util.c434
-rw-r--r--src/shared/bus-unit-util.h1
-rw-r--r--src/shared/bus-util.c10
-rw-r--r--src/shared/bus-util.h1
-rw-r--r--src/shared/cgroup-show.c1
-rw-r--r--src/shared/cgroup-show.h1
-rw-r--r--src/shared/clean-ipc.c1
-rw-r--r--src/shared/clean-ipc.h1
-rw-r--r--src/shared/condition.c9
-rw-r--r--src/shared/condition.h1
-rw-r--r--src/shared/conf-parser.c173
-rw-r--r--src/shared/conf-parser.h19
-rw-r--r--src/shared/dev-setup.c1
-rw-r--r--src/shared/dev-setup.h1
-rw-r--r--src/shared/dissect-image.c336
-rw-r--r--src/shared/dissect-image.h26
-rw-r--r--src/shared/dns-domain.c26
-rw-r--r--src/shared/dns-domain.h2
-rw-r--r--src/shared/dropin.c7
-rw-r--r--src/shared/dropin.h1
-rw-r--r--src/shared/efivars.c30
-rw-r--r--src/shared/efivars.h1
-rw-r--r--src/shared/fdset.c1
-rw-r--r--src/shared/fdset.h1
-rw-r--r--src/shared/firewall-util.c4
-rw-r--r--src/shared/firewall-util.h1
-rw-r--r--src/shared/fstab-util.c1
-rw-r--r--src/shared/fstab-util.h1
-rw-r--r--src/shared/gcrypt-util.c1
-rw-r--r--src/shared/gcrypt-util.h1
-rw-r--r--src/shared/generator.c225
-rw-r--r--src/shared/generator.h22
-rw-r--r--src/shared/gpt.h1
-rw-r--r--src/shared/ima-util.c1
-rw-r--r--src/shared/ima-util.h1
-rw-r--r--src/shared/import-util.c1
-rw-r--r--src/shared/import-util.h1
-rw-r--r--src/shared/install-printf.c31
-rw-r--r--src/shared/install-printf.h1
-rw-r--r--src/shared/install.c130
-rw-r--r--src/shared/install.h1
-rw-r--r--src/shared/journal-util.c39
-rw-r--r--src/shared/journal-util.h4
-rw-r--r--src/shared/linux/auto_dev-ioctl.h1
-rw-r--r--src/shared/logs-show.c203
-rw-r--r--src/shared/logs-show.h2
-rw-r--r--src/shared/loop-util.c5
-rw-r--r--src/shared/loop-util.h1
-rw-r--r--src/shared/machine-image.c274
-rw-r--r--src/shared/machine-image.h15
-rw-r--r--src/shared/machine-pool.c1
-rw-r--r--src/shared/machine-pool.h1
-rw-r--r--src/shared/meson.build21
-rw-r--r--src/shared/nsflags.c1
-rw-r--r--src/shared/nsflags.h1
-rw-r--r--src/shared/output-mode.c1
-rw-r--r--src/shared/output-mode.h1
-rw-r--r--src/shared/pager.c6
-rw-r--r--src/shared/pager.h1
-rw-r--r--src/shared/path-lookup.c82
-rw-r--r--src/shared/path-lookup.h9
-rw-r--r--src/shared/ptyfwd.c51
-rw-r--r--src/shared/ptyfwd.h3
-rw-r--r--src/shared/resolve-util.c1
-rw-r--r--src/shared/resolve-util.h1
-rw-r--r--src/shared/seccomp-util.c34
-rw-r--r--src/shared/seccomp-util.h5
-rw-r--r--src/shared/sleep-config.c9
-rw-r--r--src/shared/sleep-config.h1
-rw-r--r--src/shared/spawn-ask-password-agent.c1
-rw-r--r--src/shared/spawn-ask-password-agent.h1
-rw-r--r--src/shared/spawn-polkit-agent.c1
-rw-r--r--src/shared/spawn-polkit-agent.h18
-rw-r--r--src/shared/specifier.c103
-rw-r--r--src/shared/specifier.h14
-rw-r--r--src/shared/switch-root.c1
-rw-r--r--src/shared/switch-root.h1
-rw-r--r--src/shared/sysctl-util.c3
-rw-r--r--src/shared/sysctl-util.h1
-rw-r--r--src/shared/test-tables.h1
-rw-r--r--src/shared/tests.c1
-rw-r--r--src/shared/tests.h1
-rw-r--r--src/shared/tomoyo-util.c33
-rw-r--r--src/shared/tomoyo-util.h25
-rw-r--r--src/shared/udev-util.c1
-rw-r--r--src/shared/udev-util.h1
-rw-r--r--src/shared/uid-range.c1
-rw-r--r--src/shared/uid-range.h1
-rw-r--r--src/shared/utmp-wtmp.c3
-rw-r--r--src/shared/utmp-wtmp.h1
-rw-r--r--src/shared/vlan-util.c1
-rw-r--r--src/shared/vlan-util.h1
-rw-r--r--src/shared/volatile-util.c1
-rw-r--r--src/shared/volatile-util.h1
-rw-r--r--src/shared/watchdog.c10
-rw-r--r--src/shared/watchdog.h6
-rw-r--r--src/sleep/sleep.c1
-rw-r--r--src/socket-proxy/socket-proxyd.c14
-rw-r--r--src/stdio-bridge/stdio-bridge.c10
-rw-r--r--src/sulogin-shell/meson.build8
-rw-r--r--src/sulogin-shell/sulogin-shell.c64
-rw-r--r--src/sysctl/sysctl.c15
-rw-r--r--src/system-update-generator/system-update-generator.c1
-rw-r--r--src/systemctl/systemctl.c335
-rw-r--r--src/systemd/_sd-common.h1
-rw-r--r--src/systemd/meson.build17
-rw-r--r--src/systemd/sd-bus-protocol.h1
-rw-r--r--src/systemd/sd-bus-vtable.h1
-rw-r--r--src/systemd/sd-bus.h4
-rw-r--r--src/systemd/sd-daemon.h39
-rw-r--r--src/systemd/sd-device.h1
-rw-r--r--src/systemd/sd-dhcp-client.h1
-rw-r--r--src/systemd/sd-dhcp-lease.h1
-rw-r--r--src/systemd/sd-dhcp-server.h1
-rw-r--r--src/systemd/sd-dhcp6-client.h6
-rw-r--r--src/systemd/sd-dhcp6-lease.h1
-rw-r--r--src/systemd/sd-event.h1
-rw-r--r--src/systemd/sd-hwdb.h1
-rw-r--r--src/systemd/sd-id128.h1
-rw-r--r--src/systemd/sd-ipv4acd.h1
-rw-r--r--src/systemd/sd-ipv4ll.h1
-rw-r--r--src/systemd/sd-journal.h1
-rw-r--r--src/systemd/sd-lldp.h1
-rw-r--r--src/systemd/sd-login.h1
-rw-r--r--src/systemd/sd-messages.h3
-rw-r--r--src/systemd/sd-ndisc.h1
-rw-r--r--src/systemd/sd-netlink.h1
-rw-r--r--src/systemd/sd-network.h9
-rw-r--r--src/systemd/sd-path.h1
-rw-r--r--src/systemd/sd-radv.h6
-rw-r--r--src/systemd/sd-resolve.h1
-rw-r--r--src/systemd/sd-utf8.h1
-rw-r--r--src/sysusers/sysusers.c12
-rw-r--r--src/sysv-generator/sysv-generator.c42
-rw-r--r--src/test/meson.build33
-rw-r--r--src/test/test-acl-util.c3
-rw-r--r--src/test/test-af-list.c2
-rw-r--r--src/test/test-alloc-util.c33
-rw-r--r--src/test/test-architecture.c19
-rw-r--r--src/test/test-arphrd-list.c2
-rw-r--r--src/test/test-ask-password-api.c1
-rw-r--r--src/test/test-async.c1
-rw-r--r--src/test/test-barrier.c1
-rw-r--r--src/test/test-bitmap.c12
-rw-r--r--src/test/test-boot-timestamps.c1
-rw-r--r--src/test/test-bpf.c14
-rw-r--r--src/test/test-btrfs.c1
-rw-r--r--src/test/test-calendarspec.c1
-rw-r--r--src/test/test-cap-list.c101
-rw-r--r--src/test/test-capability.c42
-rw-r--r--src/test/test-cgroup-mask.c36
-rw-r--r--src/test/test-cgroup-util.c33
-rw-r--r--src/test/test-cgroup.c1
-rw-r--r--src/test/test-clock.c1
-rw-r--r--src/test/test-condition.c3
-rw-r--r--src/test/test-conf-files.c1
-rw-r--r--src/test/test-conf-parser.c3
-rw-r--r--src/test/test-copy.c1
-rw-r--r--src/test/test-cpu-set-util.c21
-rw-r--r--src/test/test-daemon.c1
-rw-r--r--src/test/test-date.c1
-rw-r--r--src/test/test-device-nodes.c1
-rw-r--r--src/test/test-dissect-image.c1
-rw-r--r--src/test/test-dlopen.c1
-rw-r--r--src/test/test-dns-domain.c31
-rw-r--r--src/test/test-ellipsize.c1
-rw-r--r--src/test/test-engine.c34
-rw-r--r--src/test/test-env-util.c9
-rw-r--r--src/test/test-escape.c1
-rw-r--r--src/test/test-exec-util.c1
-rw-r--r--src/test/test-execute.c244
-rw-r--r--src/test/test-extract-word.c1
-rw-r--r--src/test/test-fd-util.c55
-rw-r--r--src/test/test-fdset.c1
-rw-r--r--src/test/test-fileio.c4
-rw-r--r--src/test/test-firewall-util.c1
-rw-r--r--src/test/test-fs-util.c106
-rw-r--r--src/test/test-fstab-util.c1
-rw-r--r--src/test/test-glob-util.c1
-rw-r--r--src/test/test-hash.c1
-rw-r--r--src/test/test-hashmap-plain.c1
-rw-r--r--src/test/test-hashmap.c25
-rw-r--r--src/test/test-helper.c18
-rw-r--r--src/test/test-helper.h3
-rw-r--r--src/test/test-hexdecoct.c192
-rw-r--r--src/test/test-hostname-util.c27
-rw-r--r--src/test/test-hostname.c1
-rw-r--r--src/test/test-id128.c1
-rw-r--r--src/test/test-in-addr-util.c1
-rw-r--r--src/test/test-install-root.c237
-rw-r--r--src/test/test-install.c1
-rw-r--r--src/test/test-io-util.c1
-rw-r--r--src/test/test-ipcrm.c1
-rw-r--r--src/test/test-job-type.c1
-rw-r--r--src/test/test-journal-importer.c1
-rw-r--r--src/test/test-libudev.c1
-rw-r--r--src/test/test-list.c1
-rw-r--r--src/test/test-locale-util.c30
-rw-r--r--src/test/test-log.c1
-rw-r--r--src/test/test-loopback.c1
-rw-r--r--src/test/test-mount-util.c225
-rw-r--r--src/test/test-namespace.c1
-rw-r--r--src/test/test-netlink-manual.c30
-rw-r--r--src/test/test-ns.c3
-rw-r--r--src/test/test-nss.c1
-rw-r--r--src/test/test-parse-util.c128
-rw-r--r--src/test/test-path-lookup.c3
-rw-r--r--src/test/test-path-util.c156
-rw-r--r--src/test/test-path.c7
-rw-r--r--src/test/test-prioq.c1
-rw-r--r--src/test/test-proc-cmdline.c1
-rw-r--r--src/test/test-process-util.c7
-rw-r--r--src/test/test-random-util.c1
-rw-r--r--src/test/test-ratelimit.c1
-rw-r--r--src/test/test-replace-var.c1
-rw-r--r--src/test/test-rlimit-util.c1
-rw-r--r--src/test/test-sched-prio.c7
-rw-r--r--src/test/test-seccomp.c54
-rw-r--r--src/test/test-selinux.c1
-rw-r--r--src/test/test-set.c25
-rw-r--r--src/test/test-sigbus.c1
-rw-r--r--src/test/test-signal-util.c1
-rw-r--r--src/test/test-siphash24.c1
-rw-r--r--src/test/test-sizeof.c1
-rw-r--r--src/test/test-sleep.c1
-rw-r--r--src/test/test-socket-util.c1
-rw-r--r--src/test/test-specifier.c66
-rw-r--r--src/test/test-stat-util.c17
-rw-r--r--src/test/test-strbuf.c1
-rw-r--r--src/test/test-string-util.c96
-rw-r--r--src/test/test-strip-tab-ansi.c1
-rw-r--r--src/test/test-strv.c1
-rw-r--r--src/test/test-strxcpyx.c1
-rwxr-xr-xsrc/test/test-systemd-tmpfiles.py140
-rw-r--r--src/test/test-tables.c1
-rw-r--r--src/test/test-terminal-util.c1
-rw-r--r--src/test/test-time-util.c (renamed from src/test/test-time.c)18
-rw-r--r--src/test/test-tmpfiles.c1
-rw-r--r--src/test/test-udev.c1
-rw-r--r--src/test/test-uid-range.c1
-rw-r--r--src/test/test-unaligned.c1
-rw-r--r--src/test/test-unit-file.c75
-rw-r--r--src/test/test-unit-name.c11
-rw-r--r--src/test/test-user-util.c36
-rw-r--r--src/test/test-utf8.c1
-rw-r--r--src/test/test-util.c8
-rw-r--r--src/test/test-verbs.c1
-rw-r--r--src/test/test-watchdog.c1
-rw-r--r--src/test/test-web-util.c1
-rw-r--r--src/test/test-xattr-util.c1
-rw-r--r--src/test/test-xml.c1
-rw-r--r--src/timedate/meson.build22
-rw-r--r--src/timedate/org.freedesktop.timedate1.conf2
-rw-r--r--src/timedate/org.freedesktop.timedate1.policy.in22
-rw-r--r--src/timedate/org.freedesktop.timedate1.service2
-rw-r--r--src/timedate/timedatectl.c45
-rw-r--r--src/timedate/timedated.c5
-rw-r--r--src/timesync/meson.build17
-rw-r--r--src/timesync/test-timesync.c1
-rw-r--r--src/timesync/timesyncd-conf.c27
-rw-r--r--src/timesync/timesyncd-conf.h1
-rw-r--r--src/timesync/timesyncd-gperf.gperf12
-rw-r--r--src/timesync/timesyncd-manager.c38
-rw-r--r--src/timesync/timesyncd-manager.h12
-rw-r--r--src/timesync/timesyncd-server.c1
-rw-r--r--src/timesync/timesyncd-server.h1
-rw-r--r--src/timesync/timesyncd.c3
-rw-r--r--src/timesync/timesyncd.conf.in3
-rw-r--r--src/tmpfiles/tmpfiles.c397
-rw-r--r--src/tty-ask-password-agent/tty-ask-password-agent.c5
-rw-r--r--src/udev/ata_id/ata_id.c1
-rw-r--r--src/udev/cdrom_id/cdrom_id.c1
-rw-r--r--src/udev/collect/collect.c17
-rwxr-xr-xsrc/udev/generate-keyboard-keys-gperf.sh5
-rw-r--r--src/udev/meson.build17
-rw-r--r--src/udev/mtd_probe/mtd_probe.c1
-rw-r--r--src/udev/mtd_probe/mtd_probe.h1
-rw-r--r--src/udev/mtd_probe/probe_smartmedia.c1
-rw-r--r--src/udev/net/ethtool-util.c1
-rw-r--r--src/udev/net/ethtool-util.h1
-rw-r--r--src/udev/net/link-config-gperf.gperf3
-rw-r--r--src/udev/net/link-config.c5
-rw-r--r--src/udev/net/link-config.h1
-rw-r--r--src/udev/scsi_id/scsi.h1
-rw-r--r--src/udev/scsi_id/scsi_id.c1
-rw-r--r--src/udev/scsi_id/scsi_id.h1
-rw-r--r--src/udev/scsi_id/scsi_serial.c3
-rw-r--r--src/udev/udev-builtin-blkid.c1
-rw-r--r--src/udev/udev-builtin-btrfs.c1
-rw-r--r--src/udev/udev-builtin-hwdb.c1
-rw-r--r--src/udev/udev-builtin-input_id.c1
-rw-r--r--src/udev/udev-builtin-keyboard.c1
-rw-r--r--src/udev/udev-builtin-kmod.c11
-rw-r--r--src/udev/udev-builtin-net_id.c5
-rw-r--r--src/udev/udev-builtin-net_setup_link.c7
-rw-r--r--src/udev/udev-builtin-path_id.c387
-rw-r--r--src/udev/udev-builtin-uaccess.c1
-rw-r--r--src/udev/udev-builtin-usb_id.c1
-rw-r--r--src/udev/udev-builtin.c1
-rw-r--r--src/udev/udev-ctrl.c3
-rw-r--r--src/udev/udev-event.c13
-rw-r--r--src/udev/udev-node.c22
-rw-r--r--src/udev/udev-rules.c39
-rw-r--r--src/udev/udev-watch.c1
-rw-r--r--src/udev/udev.h1
-rw-r--r--src/udev/udevadm-control.c19
-rw-r--r--src/udev/udevadm-hwdb.c35
-rw-r--r--src/udev/udevadm-info.c16
-rw-r--r--src/udev/udevadm-monitor.c24
-rw-r--r--src/udev/udevadm-settle.c13
-rw-r--r--src/udev/udevadm-test-builtin.c16
-rw-r--r--src/udev/udevadm-test.c20
-rw-r--r--src/udev/udevadm-trigger.c11
-rw-r--r--src/udev/udevadm-util.c1
-rw-r--r--src/udev/udevadm-util.h5
-rw-r--r--src/udev/udevadm.c1
-rw-r--r--src/udev/udevd.c67
-rw-r--r--src/udev/v4l_id/v4l_id.c1
-rw-r--r--src/update-done/update-done.c1
-rw-r--r--src/update-utmp/update-utmp.c1
-rw-r--r--src/user-sessions/user-sessions.c1
-rw-r--r--src/vconsole/90-vconsole.rules.in2
-rw-r--r--src/vconsole/meson.build17
-rw-r--r--src/vconsole/vconsole-setup.c5
-rw-r--r--src/veritysetup/veritysetup-generator.c17
-rw-r--r--src/veritysetup/veritysetup.c16
-rw-r--r--src/volatile-root/volatile-root.c1
-rw-r--r--sysctl.d/50-default.conf3
-rw-r--r--sysctl.d/meson.build17
-rw-r--r--sysusers.d/basic.conf.in7
-rw-r--r--sysusers.d/meson.build17
-rw-r--r--sysusers.d/systemd-remote.conf.m43
-rw-r--r--sysusers.d/systemd.conf.m43
-rw-r--r--test/Makefile.guess14
-rw-r--r--test/TEST-01-BASIC/Makefile2
-rwxr-xr-xtest/TEST-02-CRYPTSETUP/test.sh4
-rwxr-xr-xtest/TEST-04-JOURNAL/test-journal.sh12
-rwxr-xr-xtest/TEST-10-ISSUE-2467/test.sh10
-rw-r--r--test/TEST-13-NSPAWN-SMOKE/Makefile2
-rwxr-xr-xtest/TEST-13-NSPAWN-SMOKE/test.sh52
-rwxr-xr-xtest/TEST-14-MACHINE-ID/test.sh2
l---------test/TEST-16-EXTEND-TIMEOUT/Makefile1
-rwxr-xr-xtest/TEST-16-EXTEND-TIMEOUT/assess.sh55
-rwxr-xr-xtest/TEST-16-EXTEND-TIMEOUT/extend_timeout_test_service.sh70
-rwxr-xr-xtest/TEST-16-EXTEND-TIMEOUT/test.sh52
-rw-r--r--test/TEST-16-EXTEND-TIMEOUT/testsuite-fail-runtime.service13
-rw-r--r--test/TEST-16-EXTEND-TIMEOUT/testsuite-fail-start.service13
-rw-r--r--test/TEST-16-EXTEND-TIMEOUT/testsuite-fail-stop.service16
-rw-r--r--test/TEST-16-EXTEND-TIMEOUT/testsuite-success-all.service14
-rw-r--r--test/TEST-16-EXTEND-TIMEOUT/testsuite-success-runtime.service13
-rw-r--r--test/TEST-16-EXTEND-TIMEOUT/testsuite-success-start.service13
-rw-r--r--test/TEST-16-EXTEND-TIMEOUT/testsuite-success-stop.service13
-rw-r--r--test/TEST-16-EXTEND-TIMEOUT/testsuite.service18
-rw-r--r--test/TEST-17-UDEV-WANTS/Makefile4
-rwxr-xr-xtest/TEST-17-UDEV-WANTS/test.sh49
-rwxr-xr-xtest/TEST-17-UDEV-WANTS/testsuite.sh76
-rw-r--r--test/TEST-18-FAILUREACTION/Makefile4
-rwxr-xr-xtest/TEST-18-FAILUREACTION/test.sh42
-rwxr-xr-xtest/TEST-18-FAILUREACTION/testsuite.sh18
-rw-r--r--test/TEST-19-DELEGATE/Makefile4
-rwxr-xr-xtest/TEST-19-DELEGATE/test.sh43
-rwxr-xr-xtest/TEST-19-DELEGATE/testsuite.sh24
-rwxr-xr-xtest/create-sys-script.py2
-rwxr-xr-xtest/hwdb-test.sh7
-rw-r--r--test/meson.build236
-rwxr-xr-xtest/networkd-test.py1
-rwxr-xr-xtest/rule-syntax-check.py23
-rwxr-xr-xtest/run-integration-tests.sh48
-rwxr-xr-xtest/sys-script.py1
-rwxr-xr-xtest/sysv-generator-test.py1
-rwxr-xr-xtest/test-exec-deserialization.py2
-rw-r--r--test/test-execute/exec-bindpaths.service17
-rw-r--r--test/test-execute/exec-cpuaffinity1.service6
-rw-r--r--test/test-execute/exec-cpuaffinity2.service8
-rw-r--r--test/test-execute/exec-cpuaffinity3.service7
-rw-r--r--test/test-execute/exec-dynamicuser-statedir-migrate-step1.service16
-rw-r--r--test/test-execute/exec-dynamicuser-statedir-migrate-step2.service24
-rw-r--r--test/test-execute/exec-dynamicuser-statedir.service (renamed from test/test-execute/exec-dynamicuser-state-dir.service)16
-rw-r--r--test/test-execute/exec-group-nogroup.service7
-rw-r--r--test/test-execute/exec-readonlypaths-simple.service (renamed from test/test-execute/exec-read-only-path-succeed.service)9
-rw-r--r--test/test-execute/exec-readonlypaths-with-bindpaths.service9
-rw-r--r--test/test-execute/exec-restrictnamespaces-mnt-blacklist.service (renamed from test/test-execute/exec-restrict-namespaces-mnt-blacklist.service)0
-rw-r--r--test/test-execute/exec-restrictnamespaces-mnt.service (renamed from test/test-execute/exec-restrict-namespaces-mnt.service)0
-rw-r--r--test/test-execute/exec-restrictnamespaces-no.service (renamed from test/test-execute/exec-restrict-namespaces-no.service)0
-rw-r--r--test/test-execute/exec-restrictnamespaces-yes.service (renamed from test/test-execute/exec-restrict-namespaces-yes.service)0
-rw-r--r--test/test-execute/exec-specifier-interpolation.service (renamed from test/test-execute/exec-spec-interpolation.service)0
-rw-r--r--test/test-execute/exec-specifier.service24
-rw-r--r--test/test-execute/exec-specifier@.service24
-rw-r--r--test/test-execute/exec-standardinput-data.service19
-rw-r--r--test/test-execute/exec-standardinput-file.service7
-rw-r--r--test/test-execute/exec-systemcallerrornumber-name.service (renamed from test/test-execute/exec-systemcallerrornumber.service)2
-rw-r--r--test/test-execute/exec-systemcallerrornumber-number.service8
-rw-r--r--test/test-execute/exec-systemcallfilter-failing.service2
-rw-r--r--test/test-execute/exec-systemcallfilter-failing2.service2
-rw-r--r--test/test-execute/exec-systemcallfilter-not-failing.service2
-rw-r--r--test/test-execute/exec-systemcallfilter-not-failing2.service2
-rw-r--r--test/test-execute/exec-systemcallfilter-system-user-nfsnobody.service2
-rw-r--r--test/test-execute/exec-systemcallfilter-system-user.service2
-rw-r--r--test/test-execute/exec-systemcallfilter-with-errno-name.service8
-rw-r--r--test/test-execute/exec-systemcallfilter-with-errno-number.service8
-rw-r--r--test/test-execute/exec-unsetenvironment.service (renamed from test/test-execute/exec-unset-environment.service)0
-rw-r--r--test/test-functions13
-rw-r--r--tmpfiles.d/etc.conf.m42
-rw-r--r--tmpfiles.d/meson.build17
-rwxr-xr-xtools/catalog-report.py1
-rwxr-xr-xtools/find-build-dir.sh31
-rw-r--r--tools/gdb-sd_dump_hashmaps.py1
-rwxr-xr-xtools/make-directive-index.py1
-rwxr-xr-xtools/make-man-index.py1
-rwxr-xr-xtools/make-man-rules.py1
-rwxr-xr-xtools/meson-check-help.sh2
-rwxr-xr-xtools/meson-hwdb-update.sh6
-rwxr-xr-xtools/xml_helper.py3
-rw-r--r--units/basic.target2
-rw-r--r--units/bluetooth.target2
-rw-r--r--units/busnames.target2
-rw-r--r--units/console-getty.service.m4.in2
-rw-r--r--units/container-getty@.service.m4.in2
-rw-r--r--units/cryptsetup-pre.target2
-rw-r--r--units/cryptsetup.target2
-rw-r--r--units/debug-shell.service.in2
-rw-r--r--units/dev-hugepages.mount2
-rw-r--r--units/dev-mqueue.mount2
-rw-r--r--units/emergency.service.in2
-rw-r--r--units/emergency.target2
-rw-r--r--units/exit.target2
-rw-r--r--units/final.target2
-rw-r--r--units/getty-pre.target2
-rw-r--r--units/getty.target2
-rw-r--r--units/getty@.service.m42
-rw-r--r--units/graphical.target2
-rw-r--r--units/halt-local.service.in2
-rw-r--r--units/halt.target2
-rw-r--r--units/hibernate.target2
-rw-r--r--units/hybrid-sleep.target2
-rw-r--r--units/initrd-cleanup.service.in2
-rw-r--r--units/initrd-fs.target2
-rw-r--r--units/initrd-parse-etc.service.in2
-rw-r--r--units/initrd-root-device.target2
-rw-r--r--units/initrd-root-fs.target2
-rw-r--r--units/initrd-switch-root.service.in2
-rw-r--r--units/initrd-switch-root.target2
-rw-r--r--units/initrd-udevadm-cleanup-db.service.in2
-rw-r--r--units/initrd.target2
-rw-r--r--units/kexec.target2
-rw-r--r--units/kmod-static-nodes.service.in2
-rw-r--r--units/ldconfig.service2
-rw-r--r--units/local-fs-pre.target2
-rw-r--r--units/local-fs.target2
-rw-r--r--units/machine.slice2
-rw-r--r--units/machines.target2
-rw-r--r--units/meson.build20
-rw-r--r--units/multi-user.target2
-rw-r--r--units/network-online.target2
-rw-r--r--units/network-pre.target2
-rw-r--r--units/network.target2
-rw-r--r--units/nss-lookup.target2
-rw-r--r--units/nss-user-lookup.target2
-rw-r--r--units/paths.target2
-rw-r--r--units/poweroff.target2
-rw-r--r--units/printer.target2
-rw-r--r--units/proc-sys-fs-binfmt_misc.automount2
-rw-r--r--units/proc-sys-fs-binfmt_misc.mount2
-rw-r--r--units/quotaon.service.in2
-rw-r--r--units/rc-local.service.in2
-rw-r--r--units/reboot.target2
-rw-r--r--units/remote-cryptsetup.target8
-rw-r--r--units/remote-fs-pre.target2
-rw-r--r--units/remote-fs.target2
-rw-r--r--units/rescue.service.in2
-rw-r--r--units/rescue.target2
-rw-r--r--units/rpcbind.target2
-rw-r--r--units/serial-getty@.service.m42
-rw-r--r--units/shutdown.target2
-rw-r--r--units/sigpwr.target2
-rw-r--r--units/sleep.target2
-rw-r--r--units/slices.target2
-rw-r--r--units/smartcard.target2
-rw-r--r--units/sockets.target2
-rw-r--r--units/sound.target2
-rw-r--r--units/suspend.target2
-rw-r--r--units/swap.target2
-rw-r--r--units/sys-fs-fuse-connections.mount2
-rw-r--r--units/sys-kernel-config.mount2
-rw-r--r--units/sys-kernel-debug.mount2
-rw-r--r--units/sysinit.target2
-rw-r--r--units/syslog.socket2
-rw-r--r--units/system-update-cleanup.service.in2
-rw-r--r--units/system-update.target2
-rw-r--r--units/system.slice2
-rw-r--r--units/systemd-ask-password-console.path2
-rw-r--r--units/systemd-ask-password-console.service.in2
-rw-r--r--units/systemd-ask-password-wall.path2
-rw-r--r--units/systemd-ask-password-wall.service.in2
-rw-r--r--units/systemd-backlight@.service.in2
-rw-r--r--units/systemd-binfmt.service.in2
-rw-r--r--units/systemd-coredump.socket2
-rw-r--r--units/systemd-coredump@.service.in2
-rw-r--r--units/systemd-exit.service.in2
-rw-r--r--units/systemd-firstboot.service.in2
-rw-r--r--units/systemd-fsck-root.service.in2
-rw-r--r--units/systemd-fsck@.service.in2
-rw-r--r--units/systemd-halt.service.in2
-rw-r--r--units/systemd-hibernate-resume@.service.in2
-rw-r--r--units/systemd-hibernate.service.in2
-rw-r--r--units/systemd-hostnamed.service.in2
-rw-r--r--units/systemd-hwdb-update.service.in2
-rw-r--r--units/systemd-hybrid-sleep.service.in2
-rw-r--r--units/systemd-importd.service.in2
-rw-r--r--units/systemd-initctl.service.in2
-rw-r--r--units/systemd-initctl.socket2
-rw-r--r--units/systemd-journal-catalog-update.service.in2
-rw-r--r--units/systemd-journal-flush.service.in2
-rw-r--r--units/systemd-journal-gatewayd.service.in2
-rw-r--r--units/systemd-journal-gatewayd.socket2
-rw-r--r--units/systemd-journal-remote.service.in2
-rw-r--r--units/systemd-journal-remote.socket2
-rw-r--r--units/systemd-journal-upload.service.in5
-rw-r--r--units/systemd-journald-audit.socket2
-rw-r--r--units/systemd-journald-dev-log.socket2
-rw-r--r--units/systemd-journald.service.in2
-rw-r--r--units/systemd-journald.socket2
-rw-r--r--units/systemd-kexec.service.in2
-rw-r--r--units/systemd-localed.service.in2
-rw-r--r--units/systemd-logind.service.in2
-rw-r--r--units/systemd-machine-id-commit.service.in2
-rw-r--r--units/systemd-machined.service.in2
-rw-r--r--units/systemd-modules-load.service.in2
-rw-r--r--units/systemd-networkd-wait-online.service.in2
-rw-r--r--units/systemd-networkd.service.in2
-rw-r--r--units/systemd-networkd.socket2
-rw-r--r--units/systemd-nspawn@.service.in3
-rw-r--r--units/systemd-poweroff.service.in2
-rw-r--r--units/systemd-quotacheck.service.in2
-rw-r--r--units/systemd-random-seed.service.in2
-rw-r--r--units/systemd-reboot.service.in2
-rw-r--r--units/systemd-remount-fs.service.in2
-rw-r--r--units/systemd-resolved.service.in2
-rw-r--r--units/systemd-rfkill.service.in2
-rw-r--r--units/systemd-rfkill.socket2
-rw-r--r--units/systemd-suspend.service.in2
-rw-r--r--units/systemd-sysctl.service.in2
-rw-r--r--units/systemd-sysusers.service.in2
-rw-r--r--units/systemd-timedated.service.in2
-rw-r--r--units/systemd-timesyncd.service.in5
-rw-r--r--units/systemd-tmpfiles-clean.service.in3
-rw-r--r--units/systemd-tmpfiles-clean.timer2
-rw-r--r--units/systemd-tmpfiles-setup-dev.service.in3
-rw-r--r--units/systemd-tmpfiles-setup.service.in3
-rw-r--r--units/systemd-udev-settle.service.in2
-rw-r--r--units/systemd-udev-trigger.service.in2
-rw-r--r--units/systemd-udevd-control.socket2
-rw-r--r--units/systemd-udevd-kernel.socket2
-rw-r--r--units/systemd-udevd.service.in2
-rw-r--r--units/systemd-update-done.service.in2
-rw-r--r--units/systemd-update-utmp-runlevel.service.in2
-rw-r--r--units/systemd-update-utmp.service.in2
-rw-r--r--units/systemd-user-sessions.service.in2
-rw-r--r--units/systemd-vconsole-setup.service.in2
-rw-r--r--units/systemd-volatile-root.service.in2
-rw-r--r--units/time-sync.target2
-rw-r--r--units/timers.target2
-rw-r--r--units/tmp.mount2
-rw-r--r--units/umount.target2
-rw-r--r--units/user.slice2
-rw-r--r--units/user/basic.target2
-rw-r--r--units/user/default.target2
-rw-r--r--units/user/exit.target2
-rw-r--r--units/user/graphical-session-pre.target2
-rw-r--r--units/user/graphical-session.target2
-rw-r--r--units/user/meson.build20
-rw-r--r--units/user/systemd-exit.service.in2
-rw-r--r--units/user/systemd-tmpfiles-clean.service.in21
-rw-r--r--units/user/systemd-tmpfiles-clean.timer19
-rw-r--r--units/user/systemd-tmpfiles-setup.service.in25
-rw-r--r--units/user@.service.in4
-rw-r--r--units/var-lib-machines.mount2
1947 files changed, 39313 insertions, 14618 deletions
diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index ba43f29601..6f197441cb 100644
--- a/.github/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -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
diff --git a/.gitignore b/.gitignore
index 4f0c6a7892..1970002350 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,6 +21,7 @@
/GSYMS
/GTAGS
/TAGS
+/ID
/build*
/coverage/
/image.raw
@@ -28,5 +29,6 @@
/image.raw.cache-pre-inst
/install-tree
/mkosi.builddir/
+/mkosi.output/
/tags
__pycache__/
diff --git a/.mailmap b/.mailmap
index 5f021b6b74..55bd44b677 100644
--- 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>
diff --git a/.mkosi/mkosi.arch b/.mkosi/mkosi.arch
index c2487c9ef2..a823a95e70 100644
--- a/.mkosi/mkosi.arch
+++ b/.mkosi/mkosi.arch
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
# This file is part of systemd.
#
# Copyright 2016 Zeal Jagannatha
diff --git a/.mkosi/mkosi.debian b/.mkosi/mkosi.debian
index 1a3b517d0f..a93eb7b539 100644
--- a/.mkosi/mkosi.debian
+++ b/.mkosi/mkosi.debian
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
# This file is part of systemd.
#
# Copyright 2016 Daniel Rusek
diff --git a/.mkosi/mkosi.fedora b/.mkosi/mkosi.fedora
index 4cfdcb0b36..4d7168c00b 100644
--- a/.mkosi/mkosi.fedora
+++ b/.mkosi/mkosi.fedora
@@ -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
diff --git a/.ycm_extra_conf.py b/.ycm_extra_conf.py
index 4edd3c8a74..f297deefe2 100644
--- a/.ycm_extra_conf.py
+++ b/.ycm_extra_conf.py
@@ -1,67 +1,250 @@
-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
+ }
diff --git a/CODING_STYLE b/CODING_STYLE
index ed61ea9d28..4119cfec23 100644
--- a/CODING_STYLE
+++ b/CODING_STYLE
@@ -218,7 +218,7 @@
- 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!
@@ -350,8 +350,7 @@
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
@@ -363,7 +362,7 @@
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
@@ -385,7 +384,7 @@
- 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
@@ -395,14 +394,14 @@
- 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.
@@ -434,3 +433,8 @@
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 d9d2043821..6267c58e22 100644
--- 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 d4d45c237a..1def98212d 100644
--- 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 e36a1f9fa1..b245564f54 100644
--- 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.
diff --git a/README.md b/README.md
index c406aca8dc..06fd69142a 100644
--- 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 81f009918c..0c20012b29 100644
--- 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
@@ -237,8 +276,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)
@@ -250,8 +287,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
@@ -279,8 +314,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
@@ -317,8 +350,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
@@ -374,8 +405,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.
@@ -510,8 +539,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
@@ -597,7 +624,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,
@@ -626,19 +652,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]
@@ -656,7 +684,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:
@@ -696,11 +723,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
@@ -787,7 +811,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
@@ -942,8 +965,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
index 0000000000..17fe0604ec
--- /dev/null
+++ b/TRANSIENT-SETTINGS.md
@@ -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
index 0000000000..d44d93d144
--- /dev/null
+++ b/UIDS-GIDS.md
@@ -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.
diff --git a/catalog/meson.build b/catalog/meson.build
index 3e61e6fc5b..69f970388a 100644
--- a/catalog/meson.build
+++ b/catalog/meson.build
@@ -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))
diff --git a/catalog/systemd.be.catalog.in b/catalog/systemd.be.catalog.in
index 5b1cdf2492..28de086be7 100644
--- a/catalog/systemd.be.catalog.in
+++ b/catalog/systemd.be.catalog.in
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
# This file is part of systemd.
#
# Copyright 2012 Lennart Poettering
diff --git a/catalog/systemd.be@latin.catalog.in b/catalog/systemd.be@latin.catalog.in
index 764432c0dc..dc5f9b731f 100644
--- a/catalog/systemd.be@latin.catalog.in
+++ b/catalog/systemd.be@latin.catalog.in
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
# This file is part of systemd.
#
# Copyright 2012 Lennart Poettering
diff --git a/catalog/systemd.bg.catalog.in b/catalog/systemd.bg.catalog.in
index 4b6cf118be..202b192b30 100644
--- a/catalog/systemd.bg.catalog.in
+++ b/catalog/systemd.bg.catalog.in
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
# This file is part of systemd.
#
# Copyright 2012 Lennart Poettering
diff --git a/catalog/systemd.catalog.in b/catalog/systemd.catalog.in
index 1efa021fdc..118fe860fe 100644
--- a/catalog/systemd.catalog.in
+++ b/catalog/systemd.catalog.in
@@ -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@.
diff --git a/catalog/systemd.da.catalog.in b/catalog/systemd.da.catalog.in
index a5570f47d5..69446fb7f0 100644
--- a/catalog/systemd.da.catalog.in
+++ b/catalog/systemd.da.catalog.in
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
# This file is part of systemd.
#
# Copyright 2012 Lennart Poettering
diff --git a/catalog/systemd.de.catalog.in b/catalog/systemd.de.catalog.in
index b69a8be198..8fdedafc09 100644
--- a/catalog/systemd.de.catalog.in
+++ b/catalog/systemd.de.catalog.in
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
# This file is part of systemd.
#
# Copyright 2012 Lennart Poettering
diff --git a/catalog/systemd.fr.catalog.in b/catalog/systemd.fr.catalog.in
index c4b1a81ceb..36c87147a7 100644
--- a/catalog/systemd.fr.catalog.in
+++ b/catalog/systemd.fr.catalog.in
@@ -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.
diff --git a/catalog/systemd.hr.catalog.in b/catalog/systemd.hr.catalog.in
index d30e955e28..f6e238e7c1 100644
--- a/catalog/systemd.hr.catalog.in
+++ b/catalog/systemd.hr.catalog.in
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
# This file is part of systemd.
#
# Copyright 2012 Lennart Poettering
diff --git a/catalog/systemd.hu.catalog.in b/catalog/systemd.hu.catalog.in
index 23c1cd44db..9f5e87893b 100644
--- a/catalog/systemd.hu.catalog.in
+++ b/catalog/systemd.hu.catalog.in
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
# This file is part of systemd.
#
# Copyright 2012 Lennart Poettering
diff --git a/catalog/systemd.it.catalog.in b/catalog/systemd.it.catalog.in
index 208ac2bfdc..df1e225eaf 100644
--- a/catalog/systemd.it.catalog.in
+++ b/catalog/systemd.it.catalog.in
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
# This file is part of systemd.
#
# Copyright 2013 Daniele Medri
diff --git a/catalog/systemd.ko.catalog.in b/catalog/systemd.ko.catalog.in
index 4e8d7008c3..e57818081d 100644
--- a/catalog/systemd.ko.catalog.in
+++ b/catalog/systemd.ko.catalog.in
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
# This file is part of systemd.
#
# Copyright 2012 Lennart Poettering
diff --git a/catalog/systemd.pl.catalog.in b/catalog/systemd.pl.catalog.in
index 278b699e26..3641db2e66 100644
--- a/catalog/systemd.pl.catalog.in
+++ b/catalog/systemd.pl.catalog.in
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
# This file is part of systemd.
#
# Copyright 2012 Lennart Poettering
diff --git a/catalog/systemd.pt_BR.catalog.in b/catalog/systemd.pt_BR.catalog.in
index 192fd33c1c..6a30dd3e10 100644
--- a/catalog/systemd.pt_BR.catalog.in
+++ b/catalog/systemd.pt_BR.catalog.in
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
# This file is part of systemd.
#
# Copyright 2012 Lennart Poettering
diff --git a/catalog/systemd.ru.catalog.in b/catalog/systemd.ru.catalog.in
index 367ed89d96..25ee6acfba 100644
--- a/catalog/systemd.ru.catalog.in
+++ b/catalog/systemd.ru.catalog.in
@@ -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@ завершен. ПриводитÑÑ ÑтатиÑтика по потребленным им реÑурÑам.
diff --git a/catalog/systemd.sr.catalog.in b/catalog/systemd.sr.catalog.in
index 674eb557b5..1d494ffce2 100644
--- a/catalog/systemd.sr.catalog.in
+++ b/catalog/systemd.sr.catalog.in
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
# This file is part of systemd.
#
# Copyright 2012 Lennart Poettering
diff --git a/catalog/systemd.zh_CN.catalog.in b/catalog/systemd.zh_CN.catalog.in
index 78a8a8ca62..92e32200de 100644
--- a/catalog/systemd.zh_CN.catalog.in
+++ b/catalog/systemd.zh_CN.catalog.in
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
# This file is part of systemd.
#
# Copyright 2012 Lennart Poettering
diff --git a/catalog/systemd.zh_TW.catalog.in b/catalog/systemd.zh_TW.catalog.in
index d262b88a01..66db58d162 100644
--- a/catalog/systemd.zh_TW.catalog.in
+++ b/catalog/systemd.zh_TW.catalog.in
@@ -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
index 0000000000..38bf9b118f
--- /dev/null
+++ b/coccinelle/const-strlen.cocci
@@ -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
index 0000000000..fbc75b9c34
--- /dev/null
+++ b/coccinelle/empty-to-null.cocci
@@ -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
index 0000000000..957d828a83
--- /dev/null
+++ b/coccinelle/equals-null.cocci
@@ -0,0 +1,14 @@
+@@
+expression e;
+statement s;
+@@
+- if (e == NULL)
++ if (!e)
+s
+@@
+expression e;
+statement s;
+@@
+- if (e != NULL)
++ if (e)
+s
diff --git a/coccinelle/in_set.cocci b/coccinelle/in_set.cocci
index f5ddd3d334..12d5475fd9 100644
--- a/coccinelle/in_set.cocci
+++ b/coccinelle/in_set.cocci
@@ -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
index 0000000000..1374ee40d7
--- /dev/null
+++ b/coccinelle/isempty.cocci
@@ -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)
diff --git a/coccinelle/not_in_set.cocci b/coccinelle/not_in_set.cocci
index e6bcf47893..7cf98500cd 100644
--- a/coccinelle/not_in_set.cocci
+++ b/coccinelle/not_in_set.cocci
@@ -1,147 +1,54 @@
@@
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
index 0000000000..1373b53c5f
--- /dev/null
+++ b/coccinelle/run-coccinelle.sh
@@ -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
diff --git a/docs/sysvinit/meson.build b/docs/sysvinit/meson.build
index 115ad39ce2..5c1aa4cc20 100644
--- a/docs/sysvinit/meson.build
+++ b/docs/sysvinit/meson.build
@@ -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',
diff --git a/docs/var-log/meson.build b/docs/var-log/meson.build
index 60acf494ef..fc14c0405e 100644
--- a/docs/var-log/meson.build
+++ b/docs/var-log/meson.build
@@ -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',
diff --git a/hwdb/20-OUI.hwdb b/hwdb/20-OUI.hwdb
index 1eec2977b7..20d168c488 100644
--- a/hwdb/20-OUI.hwdb
+++ b/hwdb/20-OUI.hwdb
@@ -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
diff --git a/hwdb/20-acpi-vendor.hwdb b/hwdb/20-acpi-vendor.hwdb
index 42e21dbbfb..10b427c2cd 100644
--- a/hwdb/20-acpi-vendor.hwdb
+++ b/hwdb/20-acpi-vendor.hwdb
@@ -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
diff --git a/hwdb/20-acpi-vendor.hwdb.patch b/hwdb/20-acpi-vendor.hwdb.patch
index b8f877e1c1..0d9be60539 100644
--- a/hwdb/20-acpi-vendor.hwdb.patch
+++ b/hwdb/20-acpi-vendor.hwdb.patch
@@ -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
@@ -107,7 +107,7 @@
acpi:BMS*:
ID_VENDOR_FROM_DATABASE=BIOMEDISYS
-@@ -1051,6 +1071,9 @@
+@@ -1063,6 +1083,9 @@
acpi:BNO*:
ID_VENDOR_FROM_DATABASE=Bang & Olufsen
@@ -117,7 +117,7 @@
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
@@ -127,7 +127,7 @@
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.
@@ -137,7 +137,7 @@
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*:
@@ -146,7 +146,7 @@
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
@@ -156,7 +156,7 @@
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
@@ -166,7 +166,7 @@
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.
@@ -176,7 +176,7 @@
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
@@ -186,7 +186,7 @@
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
@@ -196,7 +196,7 @@
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.
@@ -206,7 +206,7 @@
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
@@ -216,7 +216,7 @@
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
@@ -226,7 +226,7 @@
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
@@ -236,7 +236,7 @@
acpi:LEG*:
ID_VENDOR_FROM_DATABASE=Legerity, Inc
-@@ -3829,6 +3885,9 @@
+@@ -3847,6 +3903,9 @@
acpi:LGC*:
ID_VENDOR_FROM_DATABASE=Logic Ltd
@@ -246,7 +246,7 @@
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
@@ -256,7 +256,7 @@
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*:
@@ -265,7 +265,7 @@
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.
@@ -275,7 +275,7 @@
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
@@ -285,7 +285,7 @@
acpi:MOS*:
ID_VENDOR_FROM_DATABASE=Moses Corporation
-@@ -4534,6 +4602,9 @@
+@@ -4558,6 +4626,9 @@
acpi:NAL*:
ID_VENDOR_FROM_DATABASE=Network Alchemy
@@ -295,7 +295,7 @@
acpi:NAT*:
ID_VENDOR_FROM_DATABASE=NaturalPoint Inc.
-@@ -5032,6 +5103,9 @@
+@@ -5062,6 +5133,9 @@
acpi:PCX*:
ID_VENDOR_FROM_DATABASE=PC Xperten
@@ -305,7 +305,7 @@
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
@@ -315,7 +315,7 @@
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.
@@ -325,7 +325,7 @@
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
@@ -341,7 +341,7 @@
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
@@ -351,7 +351,7 @@
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
@@ -361,7 +361,7 @@
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
@@ -371,7 +371,7 @@
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
@@ -381,7 +381,7 @@
acpi:TAA*:
ID_VENDOR_FROM_DATABASE=Tandberg
-@@ -6418,6 +6480,9 @@
+@@ -6454,6 +6516,9 @@
acpi:TDG*:
ID_VENDOR_FROM_DATABASE=Six15 Technologies
@@ -391,9 +391,9 @@
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
@@ -401,7 +401,7 @@
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
@@ -411,7 +411,7 @@
acpi:TNM*:
ID_VENDOR_FROM_DATABASE=TECNIMAGEN SA
-@@ -6874,14 +6939,14 @@
+@@ -6916,14 +6981,14 @@
acpi:UNC*:
ID_VENDOR_FROM_DATABASE=Unisys Corporation
@@ -432,7 +432,7 @@
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
@@ -442,7 +442,7 @@
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
@@ -452,7 +452,7 @@
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*:
@@ -461,17 +461,17 @@
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.
@@ -481,7 +481,7 @@
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
diff --git a/hwdb/20-pci-vendor-model.hwdb b/hwdb/20-pci-vendor-model.hwdb
index c756e2e18b..e6ed2e377c 100644
--- a/hwdb/20-pci-vendor-model.hwdb
+++ b/hwdb/20-pci-vendor-model.hwdb
@@ -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)
diff --git a/hwdb/20-usb-vendor-model.hwdb b/hwdb/20-usb-vendor-model.hwdb
index 549f6da8c7..632c46f3bf 100644
--- a/hwdb/20-usb-vendor-model.hwdb
+++ b/hwdb/20-usb-vendor-model.hwdb
@@ -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
diff --git a/hwdb/60-evdev.hwdb b/hwdb/60-evdev.hwdb
index f688ef269f..eb04de6863 100644
--- a/hwdb/60-evdev.hwdb
+++ b/hwdb/60-evdev.hwdb
@@ -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
index 0000000000..b05b402d74
--- /dev/null
+++ b/hwdb/60-input-id.hwdb
@@ -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
diff --git a/hwdb/60-sensor.hwdb b/hwdb/60-sensor.hwdb
index 9dca1dd8d8..b46e0564d7 100644
--- a/hwdb/60-sensor.hwdb
+++ b/hwdb/60-sensor.hwdb
@@ -38,12 +38,22 @@
#
# [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
-
diff --git a/hwdb/70-mouse.hwdb b/hwdb/70-mouse.hwdb
index bade5e4b05..840fa4c9ac 100644
--- a/hwdb/70-mouse.hwdb
+++ b/hwdb/70-mouse.hwdb
@@ -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
diff --git a/hwdb/70-touchpad.hwdb b/hwdb/70-touchpad.hwdb
index 12d97de69b..979635357d 100644
--- a/hwdb/70-touchpad.hwdb
+++ b/hwdb/70-touchpad.hwdb
@@ -36,27 +36,15 @@
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
-
diff --git a/hwdb/acpi_id_registry.html b/hwdb/acpi_id_registry.html
index d5ddc878b8..df9158ba8c 100644
--- a/hwdb/acpi_id_registry.html
+++ b/hwdb/acpi_id_registry.html
@@ -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>
diff --git a/hwdb/ids_parser.py b/hwdb/ids_parser.py
index 3c43649fc1..c80d22258a 100755
--- a/hwdb/ids_parser.py
+++ b/hwdb/ids_parser.py
@@ -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)
diff --git a/hwdb/ma-large.txt b/hwdb/ma-large.txt
index 37fcee3681..f05f35a4b2 100644
--- a/hwdb/ma-large.txt
+++ b/hwdb/ma-large.txt
@@ -176,12 +176,6 @@ CC46D6 (base 16) Cisco Systems, Inc
Dongguan Guangdong 523808
CN
-00-CD-FE (hex) Apple, Inc.
-00CDFE (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
38-F2-3E (hex) Microsoft Mobile Oy
38F23E (base 16) Microsoft Mobile Oy
Keilalahdentie 4
@@ -242,12 +236,6 @@ D83C69 (base 16) Shenzhen TINNO Mobile Technology Corp.
ShenZhen GuangDong 518000
CN
-18-AF-61 (hex) Apple, Inc.
-18AF61 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
BC-83-A7 (hex) SHENZHEN CHUANGWEI-RGB ELECTRONICS CO.,LTD
BC83A7 (base 16) SHENZHEN CHUANGWEI-RGB ELECTRONICS CO.,LTD
Unit A 13-16/F,Skyworth Bldg., Gaoxin Ave.1.S.,Nanshan District
@@ -590,18 +578,6 @@ BC4699 (base 16) TP-LINK TECHNOLOGIES CO.,LTD.
Palo Alto CA 94303
US
-CC-44-63 (hex) Apple, Inc.
-CC4463 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-6C-72-E7 (hex) Apple, Inc.
-6C72E7 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
CC-A2-23 (hex) HUAWEI TECHNOLOGIES CO.,LTD
CCA223 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
@@ -1160,30 +1136,6 @@ ACF2C5 (base 16) Cisco Systems, Inc
San Jose CA 95134
US
-CC-C7-60 (hex) Apple, Inc.
-CCC760 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-08-74-02 (hex) Apple, Inc.
-087402 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-28-5A-EB (hex) Apple, Inc.
-285AEB (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-28-F0-76 (hex) Apple, Inc.
-28F076 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
84-28-5A (hex) Saffron Solutions Inc
84285A (base 16) Saffron Solutions Inc
1337 Mass Ave #273
@@ -1196,180 +1148,12 @@ CCC760 (base 16) Apple, Inc.
San Diego CA 92121
US
-44-D8-84 (hex) Apple, Inc.
-44D884 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-EC-85-2F (hex) Apple, Inc.
-EC852F (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-28-6A-BA (hex) Apple, Inc.
-286ABA (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-70-56-81 (hex) Apple, Inc.
-705681 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-7C-D1-C3 (hex) Apple, Inc.
-7CD1C3 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-F0-DC-E2 (hex) Apple, Inc.
-F0DCE2 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-B0-65-BD (hex) Apple, Inc.
-B065BD (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-A8-20-66 (hex) Apple, Inc.
-A82066 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-BC-67-78 (hex) Apple, Inc.
-BC6778 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-68-96-7B (hex) Apple, Inc.
-68967B (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-84-85-06 (hex) Apple, Inc.
-848506 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-B4-F0-AB (hex) Apple, Inc.
-B4F0AB (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-10-DD-B1 (hex) Apple, Inc.
-10DDB1 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-04-F7-E4 (hex) Apple, Inc.
-04F7E4 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-34-C0-59 (hex) Apple, Inc.
-34C059 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-F0-D1-A9 (hex) Apple, Inc.
-F0D1A9 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-F8-27-93 (hex) Apple, Inc.
-F82793 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-AC-FD-EC (hex) Apple, Inc.
-ACFDEC (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-D0-E1-40 (hex) Apple, Inc.
-D0E140 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
F8-32-E4 (hex) ASUSTek COMPUTER INC.
F832E4 (base 16) ASUSTek COMPUTER INC.
15,Li-Te Rd., Peitou, Taipei 112, Taiwan
Taipei Taiwan 112
TW
-8C-7C-92 (hex) Apple, Inc.
-8C7C92 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-78-31-C1 (hex) Apple, Inc.
-7831C1 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-F4-37-B7 (hex) Apple, Inc.
-F437B7 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-54-AE-27 (hex) Apple, Inc.
-54AE27 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-64-76-BA (hex) Apple, Inc.
-6476BA (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-84-B1-53 (hex) Apple, Inc.
-84B153 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-78-3A-84 (hex) Apple, Inc.
-783A84 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-2C-BE-08 (hex) Apple, Inc.
-2CBE08 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-24-E3-14 (hex) Apple, Inc.
-24E314 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
00-10-FF (hex) Cisco Systems, Inc
0010FF (base 16) Cisco Systems, Inc
170 WEST TASMAN DRIVE
@@ -1400,252 +1184,6 @@ F437B7 (base 16) Apple, Inc.
San Jose CA 95134
US
-60-FE-C5 (hex) Apple, Inc.
-60FEC5 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-00-A0-40 (hex) Apple, Inc.
-00A040 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-BC-3B-AF (hex) Apple, Inc.
-BC3BAF (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-78-6C-1C (hex) Apple, Inc.
-786C1C (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-04-15-52 (hex) Apple, Inc.
-041552 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-38-48-4C (hex) Apple, Inc.
-38484C (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-70-11-24 (hex) Apple, Inc.
-701124 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-C8-6F-1D (hex) Apple, Inc.
-C86F1D (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-68-5B-35 (hex) Apple, Inc.
-685B35 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-38-0F-4A (hex) Apple, Inc.
-380F4A (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-30-10-E4 (hex) Apple, Inc.
-3010E4 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-04-DB-56 (hex) Apple, Inc.
-04DB56 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-88-1F-A1 (hex) Apple, Inc.
-881FA1 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-04-E5-36 (hex) Apple, Inc.
-04E536 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-10-9A-DD (hex) Apple, Inc.
-109ADD (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-40-A6-D9 (hex) Apple, Inc.
-40A6D9 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-7C-F0-5F (hex) Apple, Inc.
-7CF05F (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-A4-B1-97 (hex) Apple, Inc.
-A4B197 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-0C-74-C2 (hex) Apple, Inc.
-0C74C2 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-40-30-04 (hex) Apple, Inc.
-403004 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-48-60-BC (hex) Apple, Inc.
-4860BC (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-50-EA-D6 (hex) Apple, Inc.
-50EAD6 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-28-E0-2C (hex) Apple, Inc.
-28E02C (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-60-C5-47 (hex) Apple, Inc.
-60C547 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-7C-11-BE (hex) Apple, Inc.
-7C11BE (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-00-3E-E1 (hex) Apple, Inc.
-003EE1 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-68-D9-3C (hex) Apple, Inc.
-68D93C (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-2C-F0-EE (hex) Apple, Inc.
-2CF0EE (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-84-78-8B (hex) Apple, Inc.
-84788B (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-6C-94-F8 (hex) Apple, Inc.
-6C94F8 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-70-3E-AC (hex) Apple, Inc.
-703EAC (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-C0-1A-DA (hex) Apple, Inc.
-C01ADA (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-34-36-3B (hex) Apple, Inc.
-34363B (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-C8-1E-E7 (hex) Apple, Inc.
-C81EE7 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-9C-FC-01 (hex) Apple, Inc.
-9CFC01 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-00-0D-93 (hex) Apple, Inc.
-000D93 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-00-1C-B3 (hex) Apple, Inc.
-001CB3 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-64-B9-E8 (hex) Apple, Inc.
-64B9E8 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-34-15-9E (hex) Apple, Inc.
-34159E (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-58-B0-35 (hex) Apple, Inc.
-58B035 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-F0-B4-79 (hex) Apple, Inc.
-F0B479 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
14-13-57 (hex) ATP Electronics, Inc.
141357 (base 16) ATP Electronics, Inc.
2590 North First Street Suite 150
@@ -1865,12 +1403,6 @@ C025A2 (base 16) NEC Platforms, Ltd.
Moscow Moscow 109316
RU
-AC-BC-32 (hex) Apple, Inc.
-ACBC32 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
94-BB-AE (hex) Husqvarna AB
94BBAE (base 16) Husqvarna AB
Drottninggatan 2
@@ -2519,12 +2051,6 @@ DC2F03 (base 16) Step forward Group Co., Ltd.
Nagaokakyo-shi Kyoto 617-8555
JP
-5C-AA-FD (hex) Sonos, Inc.
-5CAAFD (base 16) Sonos, Inc.
- 223 E. De La Guerra Street
- Santa Barbara CA 93101
- US
-
8C-DF-9D (hex) NEC Corporation
8CDF9D (base 16) NEC Corporation
7-1, Shiba 5-chome,
@@ -2807,12 +2333,6 @@ A4A4D3 (base 16) Bluebank Communication Technology Co.Ltd
Peiking 100190
CN
-88-29-50 (hex) Dalian Netmoon Tech Develop Co.,Ltd
-882950 (base 16) Dalian Netmoon Tech Develop Co.,Ltd
- Shahekou District NO.19-2 Wansui Street
- Dalian Liaoning 116000
- CN
-
08-CD-9B (hex) samtec automotive electronics & software GmbH
08CD9B (base 16) samtec automotive electronics & software GmbH
Saarstrasse 27
@@ -4466,12 +3986,6 @@ B49842 (base 16) zte corporation
Eden Prairie MN 55344
US
-90-CC-24 (hex) Synaptics, Inc
-90CC24 (base 16) Synaptics, Inc
- 3120 Scott Blvd.
- Santa Clara CA 95054
- US
-
AC-17-02 (hex) Fibar Group sp. z o.o.
AC1702 (base 16) Fibar Group sp. z o.o.
ul. Lotnicza 1
@@ -7274,12 +6788,6 @@ A0DDE5 (base 16) SHARP Corporation
Richmond BC V6V 3A4
CA
-A4-50-55 (hex) busware.de
-A45055 (base 16) busware.de
- Loessnitzgrundstrasse 115a
- Moritzburg Saxony 01468
- DE
-
C8-93-83 (hex) Embedded Automation, Inc.
C89383 (base 16) Embedded Automation, Inc.
17345 Abbey Drive
@@ -9344,12 +8852,6 @@ A8CE90 (base 16) CVC
Sheffield South Yorkshire S9 3TY
GB
-00-21-94 (hex) Ping Communication
-002194 (base 16) Ping Communication
- Sandakerveien 24C
- Oslo 0473
- NO
-
00-21-8F (hex) Avantgarde Acoustic Lautsprechersysteme GmbH
00218F (base 16) Avantgarde Acoustic Lautsprechersysteme GmbH
Nibelungenstraße 349
@@ -12710,12 +12212,6 @@ A8CE90 (base 16) CVC
Santa Clara California 95054
US
-00-13-86 (hex) ABB Inc./Totalflow
-001386 (base 16) ABB Inc./Totalflow
-
- Bartlesville OK 74006
- US
-
00-13-74 (hex) Atheros Communications, Inc.
001374 (base 16) Atheros Communications, Inc.
529 Almanor Avenue
@@ -20252,12 +19748,6 @@ A8CE90 (base 16) CVC
RESTON VA 22096
US
-00-A0-D5 (hex) SIERRA WIRELESS INC.
-00A0D5 (base 16) SIERRA WIRELESS INC.
- 13811 Wireless Way
- RICHMOND B.C. V6V 3A4
- CA
-
00-20-0F (hex) EBRAINS Inc
00200F (base 16) EBRAINS Inc
Tachibana Bldg
@@ -23240,18 +22730,6 @@ F4F5A5 (base 16) Nokia Corporation
Boston MA 02205
US
-AC-61-EA (hex) Apple, Inc.
-AC61EA (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-38-B5-4D (hex) Apple, Inc.
-38B54D (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
90-A6-2F (hex) NAVER
90A62F (base 16) NAVER
NAVER Green Factory, 6, Buljeong-ro, Bundang-gu
@@ -23300,12 +22778,6 @@ B47443 (base 16) Samsung Electronics Co.,Ltd
New Taipei City Taiwan 22101
TW
-A4-F1-E8 (hex) Apple, Inc.
-A4F1E8 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
00-35-1A (hex) Cisco Systems, Inc
00351A (base 16) Cisco Systems, Inc
80 West Tasman Drive
@@ -23840,30 +23312,6 @@ D8E56D (base 16) TCT mobile ltd
Hui Zhou Guang Dong 516006
CN
-90-C1-C6 (hex) Apple, Inc.
-90C1C6 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-70-A2-B3 (hex) Apple, Inc.
-70A2B3 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-4C-57-CA (hex) Apple, Inc.
-4C57CA (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-68-FB-7E (hex) Apple, Inc.
-68FB7E (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
44-2C-05 (hex) AMPAK Technology, Inc.
442C05 (base 16) AMPAK Technology, Inc.
No.1,Jen Ai Road Hsinchu Industrial Park, Hukou
@@ -25496,18 +24944,6 @@ A01081 (base 16) Samsung Electronics Co.,Ltd
Deer Park IL 60010
US
-9C-F4-8E (hex) Apple, Inc.
-9CF48E (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-FC-D8-48 (hex) Apple, Inc.
-FCD848 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
80-48-A5 (hex) SICHUAN TIANYI COMHEART TELECOMCO.,LTD
8048A5 (base 16) SICHUAN TIANYI COMHEART TELECOMCO.,LTD
FL12,TowerB,TianYi International Hotel
@@ -25718,12 +25154,6 @@ AC233F (base 16) Shenzhen Minew Technologies Co., Ltd.
Shenzhen 518109
CN
-00-0E-58 (hex) Sonos, Inc.
-000E58 (base 16) Sonos, Inc.
- 223 E. De La Guerra St.
- Santa Barbara CA 93101
- US
-
E0-50-8B (hex) Zhejiang Dahua Technology Co., Ltd.
E0508B (base 16) Zhejiang Dahua Technology Co., Ltd.
No.1199,Waterfront Road
@@ -25922,12 +25352,6 @@ F015B9 (base 16) PlayFusion Limited
Cambridge CB4 0WS
GB
-70-70-0D (hex) Apple, Inc.
-70700D (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
24-A7-DC (hex) BSkyB Ltd
24A7DC (base 16) BSkyB Ltd
130 Kings Road
@@ -26270,12 +25694,6 @@ F0D2F1 (base 16) Amazon Technologies Inc.
Reno NV 89507
US
-7C-50-49 (hex) Apple, Inc.
-7C5049 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
F0-A2-25 (hex) Private
F0A225 (base 16) Private
@@ -26372,54 +25790,6 @@ A04C5B (base 16) Shenzhen TINNO Mobile Technology Corp.
HongKong HongKong 999077
HK
-D4-61-9D (hex) Apple, Inc.
-D4619D (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-B0-48-1A (hex) Apple, Inc.
-B0481A (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-98-9E-63 (hex) Apple, Inc.
-989E63 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-DC-A9-04 (hex) Apple, Inc.
-DCA904 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-48-A1-95 (hex) Apple, Inc.
-48A195 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-6C-AB-31 (hex) Apple, Inc.
-6CAB31 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-50-32-37 (hex) Apple, Inc.
-503237 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-00-08-89 (hex) Echostar Technologies Corp
-000889 (base 16) Echostar Technologies Corp
- 94 Inverness Terrace E
- Englewood CO 80112
- US
-
2C-02-9F (hex) 3ALogics
2C029F (base 16) 3ALogics
#704, Hyundai office B'd, Sunae-dong, Bundang-gu
@@ -27785,30 +27155,6 @@ BC88C3 (base 16) Ningbo Dooya Mechanic & Electronic Technology Co., Ltd
Ningbo Zhejiang 315202
CN
-A8-BE-27 (hex) Apple, Inc.
-A8BE27 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-B8-63-4D (hex) Apple, Inc.
-B8634D (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-6C-96-CF (hex) Apple, Inc.
-6C96CF (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-30-35-AD (hex) Apple, Inc.
-3035AD (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
68-1F-40 (hex) Blu Wireless Technology Ltd
681F40 (base 16) Blu Wireless Technology Ltd
Bluwireless Technology, 5th Floor, 1 Temple Way
@@ -28175,42 +27521,6 @@ DC5583 (base 16) GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
Taipei City Neihu Dist 248
TW
-9C-E3-3F (hex) Apple, Inc.
-9CE33F (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-F0-98-9D (hex) Apple, Inc.
-F0989D (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-AC-E4-B5 (hex) Apple, Inc.
-ACE4B5 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-E4-2B-34 (hex) Apple, Inc.
-E42B34 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-1C-36-BB (hex) Apple, Inc.
-1C36BB (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-3C-2E-FF (hex) Apple, Inc.
-3C2EFF (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
24-8B-E0 (hex) SICHUAN TIANYI COMHEART TELECOMCO., LTD
248BE0 (base 16) SICHUAN TIANYI COMHEART TELECOMCO., LTD
FL12, TowerB,Tianyi international Hotel,No.2 West Section One, Second Ring Road,
@@ -28691,12 +28001,6 @@ D89C67 (base 16) Hon Hai Precision Ind. Co.,Ltd.
Gumi Gyeongbuk 730-350
KR
-28-BF-89 (hex) Fiberhome Telecommunication Technologies Co.,LTD
-28BF89 (base 16) Fiberhome Telecommunication Technologies Co.,LTD
- No.5 DongXin Road
- Wuhan Hubei 430074
- CN
-
C8-40-29 (hex) Fiberhome Telecommunication Technologies Co.,LTD
C84029 (base 16) Fiberhome Telecommunication Technologies Co.,LTD
No.5 DongXin Road
@@ -28709,10 +28013,16 @@ CC0677 (base 16) Fiberhome Telecommunication Technologies Co.,LTD
Wuhan Hubei 430074
CN
-B0-E2-E5 (hex) Fiberhome Telecommunication Technologies Co.,LTD
-B0E2E5 (base 16) Fiberhome Telecommunication Technologies Co.,LTD
+1C-39-8A (hex) Fiberhome Telecommunication Technologies Co.,LTD
+1C398A (base 16) Fiberhome Telecommunication Technologies Co.,LTD
No.5 DongXin Road
- Wuhan City Hubei Province 430074
+ Wuhan Hubei 430074
+ CN
+
+10-77-B0 (hex) Fiberhome Telecommunication Technologies Co.,LTD
+1077B0 (base 16) Fiberhome Telecommunication Technologies Co.,LTD
+ No.5 DongXin Road
+ Wuhan Hubei 430074
CN
88-94-7E (hex) Fiberhome Telecommunication Technologies Co.,LTD
@@ -28727,16 +28037,16 @@ F4573E (base 16) Fiberhome Telecommunication Technologies Co.,LTD
Wuhan Hubei 430074
CN
-1C-39-8A (hex) Fiberhome Telecommunication Technologies Co.,LTD
-1C398A (base 16) Fiberhome Telecommunication Technologies Co.,LTD
+28-BF-89 (hex) Fiberhome Telecommunication Technologies Co.,LTD
+28BF89 (base 16) Fiberhome Telecommunication Technologies Co.,LTD
No.5 DongXin Road
Wuhan Hubei 430074
CN
-10-77-B0 (hex) Fiberhome Telecommunication Technologies Co.,LTD
-1077B0 (base 16) Fiberhome Telecommunication Technologies Co.,LTD
+B0-E2-E5 (hex) Fiberhome Telecommunication Technologies Co.,LTD
+B0E2E5 (base 16) Fiberhome Telecommunication Technologies Co.,LTD
No.5 DongXin Road
- Wuhan Hubei 430074
+ Wuhan City Hubei Province 430074
CN
E4-30-22 (hex) Hanwha Techwin Security Vietnam
@@ -28745,6 +28055,1056 @@ E43022 (base 16) Hanwha Techwin Security Vietnam
Nam Son Commune, Bac Ninh City Bac Ninh Province 000
VN
+B4-E6-2D (hex) Espressif Inc.
+B4E62D (base 16) Espressif Inc.
+ Room 204, Building 2, 690 Bibo Road, Pudong New Area
+ Shanghai Shanghai 201203
+ CN
+
+F0-B5-B7 (hex) Disruptive Technologies Research AS
+F0B5B7 (base 16) Disruptive Technologies Research AS
+ Ytrebygdsvegen 215
+ Blomsterdalen Hordaland 5258
+ NO
+
+54-AE-27 (hex) Apple, Inc.
+54AE27 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+F4-37-B7 (hex) Apple, Inc.
+F437B7 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+78-31-C1 (hex) Apple, Inc.
+7831C1 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+8C-7C-92 (hex) Apple, Inc.
+8C7C92 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+D0-E1-40 (hex) Apple, Inc.
+D0E140 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+AC-FD-EC (hex) Apple, Inc.
+ACFDEC (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+24-E3-14 (hex) Apple, Inc.
+24E314 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+2C-BE-08 (hex) Apple, Inc.
+2CBE08 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+78-3A-84 (hex) Apple, Inc.
+783A84 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+84-B1-53 (hex) Apple, Inc.
+84B153 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+64-76-BA (hex) Apple, Inc.
+6476BA (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+70-3E-AC (hex) Apple, Inc.
+703EAC (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+6C-94-F8 (hex) Apple, Inc.
+6C94F8 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+84-78-8B (hex) Apple, Inc.
+84788B (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+2C-F0-EE (hex) Apple, Inc.
+2CF0EE (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+68-D9-3C (hex) Apple, Inc.
+68D93C (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+F8-27-93 (hex) Apple, Inc.
+F82793 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+04-E5-36 (hex) Apple, Inc.
+04E536 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+88-1F-A1 (hex) Apple, Inc.
+881FA1 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+04-DB-56 (hex) Apple, Inc.
+04DB56 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+C8-1E-E7 (hex) Apple, Inc.
+C81EE7 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+34-36-3B (hex) Apple, Inc.
+34363B (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+C0-1A-DA (hex) Apple, Inc.
+C01ADA (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+80-CE-62 (hex) Hewlett Packard
+80CE62 (base 16) Hewlett Packard
+ 11445 Compaq Center Drive
+ Houston TX 77070
+ US
+
+80-1F-12 (hex) Microchip Technology Inc.
+801F12 (base 16) Microchip Technology Inc.
+ 2355 W. Chandler Blvd.
+ Chandler AZ 85224
+ US
+
+50-6C-BE (hex) InnosiliconTechnology Ltd
+506CBE (base 16) InnosiliconTechnology Ltd
+ WuHan East Lake Wuhan New Technology Development Zone
+ Wuhan Hubei Province 430223
+ CN
+
+90-CC-24 (hex) Synaptics, Inc
+90CC24 (base 16) Synaptics, Inc
+ 1251 McKay Drive
+ San Jose CA 95131-1709
+ US
+
+80-41-26 (hex) HUAWEI TECHNOLOGIES CO.,LTD
+804126 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
+ CN
+
+0C-C6-CC (hex) HUAWEI TECHNOLOGIES CO.,LTD
+0CC6CC (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
+ CN
+
+3C-04-61 (hex) ARRIS Group, Inc.
+3C0461 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+04-C2-41 (hex) Nokia
+04C241 (base 16) Nokia
+ 600 March Road
+ Kanata Ontario K2K 2E6
+ CA
+
+30-7B-AC (hex) New H3C Technologies Co., Ltd
+307BAC (base 16) New H3C Technologies Co., Ltd
+ 466 Changhe Road, Binjiang District
+ Hangzhou Zhejiang 310052
+ CN
+
+8C-F7-73 (hex) Nokia
+8CF773 (base 16) Nokia
+ 600 March Road
+ Kanata Ontario K2K 2E6
+ CA
+
+3C-47-9B (hex) Theissen Training Systems, Inc.
+3C479B (base 16) Theissen Training Systems, Inc.
+ 1225 SE 4th Terrace
+ Chiefland FL 32626
+ US
+
+70-5A-AC (hex) Samsung Electronics Co.,Ltd
+705AAC (base 16) Samsung Electronics Co.,Ltd
+ #94-1, Imsoo-Dong
+ Gumi Gyeongbuk 730-350
+ KR
+
+FC-64-3A (hex) Samsung Electronics Co.,Ltd
+FC643A (base 16) Samsung Electronics Co.,Ltd
+ #94-1, Imsoo-Dong
+ Gumi Gyeongbuk 730-350
+ KR
+
+D4-E6-B7 (hex) Samsung Electronics Co.,Ltd
+D4E6B7 (base 16) Samsung Electronics Co.,Ltd
+ #94-1, Imsoo-Dong
+ Gumi Gyeongbuk 730-350
+ KR
+
+28-02-D8 (hex) Samsung Electronics Co.,Ltd
+2802D8 (base 16) Samsung Electronics Co.,Ltd
+ #94-1, Imsoo-Dong
+ Gumi Gyeongbuk 730-350
+ KR
+
+C4-64-E3 (hex) Texas Instruments
+C464E3 (base 16) Texas Instruments
+ 12500 TI Blvd
+ Dallas TX 75243
+ US
+
+F4-84-4C (hex) Texas Instruments
+F4844C (base 16) Texas Instruments
+ 12500 TI Blvd
+ Dallas TX 75243
+ US
+
+00-08-89 (hex) Dish Technologies Corp
+000889 (base 16) Dish Technologies Corp
+ 94 Inverness Terrace E
+ Englewood CO 80112
+ US
+
+6C-C4-D5 (hex) HMD Global Oy
+6CC4D5 (base 16) HMD Global Oy
+ Karaportti 2
+ Espoo 02610
+ FI
+
+60-C5-47 (hex) Apple, Inc.
+60C547 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+28-E0-2C (hex) Apple, Inc.
+28E02C (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+50-EA-D6 (hex) Apple, Inc.
+50EAD6 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+48-60-BC (hex) Apple, Inc.
+4860BC (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+40-30-04 (hex) Apple, Inc.
+403004 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+0C-74-C2 (hex) Apple, Inc.
+0C74C2 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+A4-B1-97 (hex) Apple, Inc.
+A4B197 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+7C-F0-5F (hex) Apple, Inc.
+7CF05F (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+78-6C-1C (hex) Apple, Inc.
+786C1C (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+BC-3B-AF (hex) Apple, Inc.
+BC3BAF (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+F0-D1-A9 (hex) Apple, Inc.
+F0D1A9 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+34-C0-59 (hex) Apple, Inc.
+34C059 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+04-F7-E4 (hex) Apple, Inc.
+04F7E4 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+10-DD-B1 (hex) Apple, Inc.
+10DDB1 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+B4-F0-AB (hex) Apple, Inc.
+B4F0AB (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+00-A0-40 (hex) Apple, Inc.
+00A040 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+60-FE-C5 (hex) Apple, Inc.
+60FEC5 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+CC-44-63 (hex) Apple, Inc.
+CC4463 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+6C-72-E7 (hex) Apple, Inc.
+6C72E7 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+18-AF-61 (hex) Apple, Inc.
+18AF61 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+00-CD-FE (hex) Apple, Inc.
+00CDFE (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+30-10-E4 (hex) Apple, Inc.
+3010E4 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+38-0F-4A (hex) Apple, Inc.
+380F4A (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+68-5B-35 (hex) Apple, Inc.
+685B35 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+C8-6F-1D (hex) Apple, Inc.
+C86F1D (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+70-11-24 (hex) Apple, Inc.
+701124 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+38-48-4C (hex) Apple, Inc.
+38484C (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+04-15-52 (hex) Apple, Inc.
+041552 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+40-A6-D9 (hex) Apple, Inc.
+40A6D9 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+10-9A-DD (hex) Apple, Inc.
+109ADD (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+F0-B4-79 (hex) Apple, Inc.
+F0B479 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+58-B0-35 (hex) Apple, Inc.
+58B035 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+34-15-9E (hex) Apple, Inc.
+34159E (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+28-6A-BA (hex) Apple, Inc.
+286ABA (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+EC-85-2F (hex) Apple, Inc.
+EC852F (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+44-D8-84 (hex) Apple, Inc.
+44D884 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+00-3E-E1 (hex) Apple, Inc.
+003EE1 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+7C-11-BE (hex) Apple, Inc.
+7C11BE (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+28-F0-76 (hex) Apple, Inc.
+28F076 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+28-5A-EB (hex) Apple, Inc.
+285AEB (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+08-74-02 (hex) Apple, Inc.
+087402 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+64-B9-E8 (hex) Apple, Inc.
+64B9E8 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+00-1C-B3 (hex) Apple, Inc.
+001CB3 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+00-0D-93 (hex) Apple, Inc.
+000D93 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+CC-C7-60 (hex) Apple, Inc.
+CCC760 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+9C-FC-01 (hex) Apple, Inc.
+9CFC01 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+AC-BC-32 (hex) Apple, Inc.
+ACBC32 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+A8-BE-27 (hex) Apple, Inc.
+A8BE27 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+B8-63-4D (hex) Apple, Inc.
+B8634D (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+9C-E3-3F (hex) Apple, Inc.
+9CE33F (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+F0-98-9D (hex) Apple, Inc.
+F0989D (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+AC-E4-B5 (hex) Apple, Inc.
+ACE4B5 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+E4-2B-34 (hex) Apple, Inc.
+E42B34 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+1C-36-BB (hex) Apple, Inc.
+1C36BB (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+3C-2E-FF (hex) Apple, Inc.
+3C2EFF (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+F0-76-6F (hex) Apple, Inc.
+F0766F (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+40-CB-C0 (hex) Apple, Inc.
+40CBC0 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+40-98-AD (hex) Apple, Inc.
+4098AD (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+6C-4D-73 (hex) Apple, Inc.
+6C4D73 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+C4-84-66 (hex) Apple, Inc.
+C48466 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+D0-2B-20 (hex) Apple, Inc.
+D02B20 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+70-70-0D (hex) Apple, Inc.
+70700D (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+7C-50-49 (hex) Apple, Inc.
+7C5049 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+50-32-37 (hex) Apple, Inc.
+503237 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+D4-61-9D (hex) Apple, Inc.
+D4619D (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+B0-48-1A (hex) Apple, Inc.
+B0481A (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+98-9E-63 (hex) Apple, Inc.
+989E63 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+DC-A9-04 (hex) Apple, Inc.
+DCA904 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+48-A1-95 (hex) Apple, Inc.
+48A195 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+6C-AB-31 (hex) Apple, Inc.
+6CAB31 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+6C-96-CF (hex) Apple, Inc.
+6C96CF (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+30-35-AD (hex) Apple, Inc.
+3035AD (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+AC-61-EA (hex) Apple, Inc.
+AC61EA (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+38-B5-4D (hex) Apple, Inc.
+38B54D (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+A4-F1-E8 (hex) Apple, Inc.
+A4F1E8 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+70-A2-B3 (hex) Apple, Inc.
+70A2B3 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+4C-57-CA (hex) Apple, Inc.
+4C57CA (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+68-FB-7E (hex) Apple, Inc.
+68FB7E (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+90-C1-C6 (hex) Apple, Inc.
+90C1C6 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+9C-F4-8E (hex) Apple, Inc.
+9CF48E (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+FC-D8-48 (hex) Apple, Inc.
+FCD848 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+84-85-06 (hex) Apple, Inc.
+848506 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+68-96-7B (hex) Apple, Inc.
+68967B (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+BC-67-78 (hex) Apple, Inc.
+BC6778 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+A8-20-66 (hex) Apple, Inc.
+A82066 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+B0-65-BD (hex) Apple, Inc.
+B065BD (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+F0-DC-E2 (hex) Apple, Inc.
+F0DCE2 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+7C-D1-C3 (hex) Apple, Inc.
+7CD1C3 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+70-56-81 (hex) Apple, Inc.
+705681 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+1C-A0-B8 (hex) Hon Hai Precision Ind. Co., Ltd.
+1CA0B8 (base 16) Hon Hai Precision Ind. Co., Ltd.
+ GuangDongShenZhen
+ ShenZhen GuangDong 518109
+ CN
+
+E8-C1-B8 (hex) Nanjing Bangzhong Electronic Commerce Limited
+E8C1B8 (base 16) Nanjing Bangzhong Electronic Commerce Limited
+ No.22, Liuzhou East Road, High - tech Zone
+ Nanjing 210000
+ CN
+
+1C-B0-44 (hex) ASKEY COMPUTER CORP
+1CB044 (base 16) ASKEY COMPUTER CORP
+ 10F,No.119,JIANKANG RD,ZHONGHE DIST
+ NEW TAIPEI TAIWAN 23585
+ TW
+
+90-03-72 (hex) Longnan Junya Digital Technology Co. Ltd.
+900372 (base 16) Longnan Junya Digital Technology Co. Ltd.
+ Champion Asia Road, Xinzhen industrial Park, Longnan national economic and technological development zone, Ganzhou city, JiangXi Province , China
+ ganzhou jiangxi 341700
+ CN
+
+F0-41-C8 (hex) IEEE Registration Authority
+F041C8 (base 16) IEEE Registration Authority
+ 445 Hoes Lane
+ Piscataway NJ 08554
+ US
+
+A4-38-CC (hex) Nintendo Co.,Ltd
+A438CC (base 16) Nintendo Co.,Ltd
+ 11-1 HOKOTATE-CHO KAMITOBA,MINAMI-KU
+ KYOTO KYOTO 601-8501
+ JP
+
+94-6A-B0 (hex) Arcadyan Corporation
+946AB0 (base 16) Arcadyan Corporation
+ No.8, Sec.2, Guangfu Rd.
+ Hsinchu City Hsinchu 30071
+ TW
+
+B4-DE-31 (hex) Cisco Systems, Inc
+B4DE31 (base 16) Cisco Systems, Inc
+ 80 West Tasman Drive
+ San Jose CA 94568
+ US
+
+70-16-9F (hex) EtherCAT Technology Group
+70169F (base 16) EtherCAT Technology Group
+ Ostendstr. 196
+ NUremberg 90482
+ DE
+
+64-98-29 (hex) Integrated Device Technology (Malaysia) Sdn. Bhd.
+649829 (base 16) Integrated Device Technology (Malaysia) Sdn. Bhd.
+ Phase 3, Bayan Lepas FIZ
+ Bayan Lepas Penang 11900
+ MY
+
+08-1D-C4 (hex) Thermo Fisher Scientific Messtechnik GmbH
+081DC4 (base 16) Thermo Fisher Scientific Messtechnik GmbH
+ Frauenauracher Strasse 96
+ Erlangen 91056
+ DE
+
+68-98-61 (hex) Beacon Inc
+689861 (base 16) Beacon Inc
+ 82-1, Anyangcheondong-ro, Dongan-gu
+ anyang Gyeonggi-do 14042
+ KR
+
+88-B3-62 (hex) Nokia Shanghai Bell Co. Ltd.)
+88B362 (base 16) Nokia Shanghai Bell Co. Ltd.)
+ No.388 Ning Qiao Road,Jin Qiao Pudong Shanghai 201206,P.R.China
+ Shanghai Pudong 201206
+ CN
+
+10-A4-B9 (hex) Baidu Online Network Technology (Beijing) Co., Ltd
+10A4B9 (base 16) Baidu Online Network Technology (Beijing) Co., Ltd
+ Baidu Campus, No.10 Shangdi 10th Street, Haidian District
+ Beijing 100085
+ CN
+
+34-7E-CA (hex) NEXTWILL
+347ECA (base 16) NEXTWILL
+ JJ-Building, 20, Deongmyeong-ro 71beon-gil1, Yuseong-gu
+ Daejeon 34155
+ KR
+
+50-14-79 (hex) iRobot Corporation
+501479 (base 16) iRobot Corporation
+ 8 Crosby Drive
+ Bedford MA 01730
+ US
+
+60-84-BD (hex) BUFFALO.INC
+6084BD (base 16) BUFFALO.INC
+ AKAMONDORI Bld.,30-20,Ohsu 3-chome,Naka-ku
+ Nagoya Aichi Pref. 460-8315
+ JP
+
+10-F9-EB (hex) Industria Fueguina de Relojería Electrónica s.a.
+10F9EB (base 16) Industria Fueguina de Relojería Electrónica s.a.
+ Sarmiento 2920
+ Rio Grande Tierra de Fuego V9420GIV
+ AR
+
+B8-94-36 (hex) HUAWEI TECHNOLOGIES CO.,LTD
+B89436 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
+ CN
+
+F8-DF-15 (hex) Sunitec Enterprise Co.,Ltd
+F8DF15 (base 16) Sunitec Enterprise Co.,Ltd
+ 3F.,No.98-1,Mincyuan Rd.Sindian City
+ Taipei County 231 231141
+ CN
+
+A8-DA-01 (hex) Shenzhen NUOLIJIA Digital Technology Co.,Ltd
+A8DA01 (base 16) Shenzhen NUOLIJIA Digital Technology Co.,Ltd
+ 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
+ Shenzhen Guangdong 518000
+ CN
+
+90-94-97 (hex) HUAWEI TECHNOLOGIES CO.,LTD
+909497 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
+ CN
+
+EC-89-14 (hex) HUAWEI TECHNOLOGIES CO.,LTD
+EC8914 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
+ CN
+
+DC-72-9B (hex) HUAWEI TECHNOLOGIES CO.,LTD
+DC729B (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
+ CN
+
+5C-5A-EA (hex) FORD
+5C5AEA (base 16) FORD
+ 17425 Federal Drive
+ Allen Park MI 48101
+ US
+
+5C-AA-FD (hex) Sonos, Inc.
+5CAAFD (base 16) Sonos, Inc.
+ 614 Chapala St
+ Santa Barbara CA 93101
+ US
+
+00-0E-58 (hex) Sonos, Inc.
+000E58 (base 16) Sonos, Inc.
+ 614 Chapala St
+ Santa Barbara CA 93101
+ US
+
+88-29-50 (hex) Netmoon Technology Co., Ltd
+882950 (base 16) Netmoon Technology Co., Ltd
+ 2nd Floor, Building No.1, NO.319, Qingpi Avenue
+ Wenjiang District Chengdu 611130
+ CN
+
+00-21-94 (hex) Ping Communication
+002194 (base 16) Ping Communication
+ Brenden 18
+ Appenzell Meistersrüte AI 9050
+ CH
+
+7C-FF-4D (hex) AVM Audiovisuelles Marketing und Computersysteme GmbH
+7CFF4D (base 16) AVM Audiovisuelles Marketing und Computersysteme GmbH
+ Alt-Moabit 95
+ Berlin Berlin 10559
+ DE
+
+74-70-FD (hex) Intel Corporate
+7470FD (base 16) Intel Corporate
+ Lot 8, Jalan Hi-Tech 2/3
+ Kulim Kedah 09000
+ MY
+
+CC-99-16 (hex) Integrated Device Technology (Malaysia) Sdn. Bhd.
+CC9916 (base 16) Integrated Device Technology (Malaysia) Sdn. Bhd.
+ Phase 3, Bayan Lepas FIZ
+ Bayan Lepas Penang 11900
+ MY
+
+A4-50-55 (hex) BUSWARE.DE
+A45055 (base 16) BUSWARE.DE
+ Lindenstrasse 18
+ Scharbeutz 23684
+ DE
+
+00-13-86 (hex) ABB Inc/Totalflow
+001386 (base 16) ABB Inc/Totalflow
+
+ Bartlesville OK 74006
+ US
+
+A0-66-10 (hex) FUJITSU LIMITED
+A06610 (base 16) FUJITSU LIMITED
+ Mushashi-kosuge Tower Place 13F
+ Kawasaki Kanagawa 211-0063
+ JP
+
+64-CB-5D (hex) SIA TeleSet
+64CB5D (base 16) SIA TeleSet
+ KrÄslavas iela 5
+ Vecstropi, Naujenes par., Daugavpils distr. LV-5413
+ LV
+
+70-69-5A (hex) Cisco Systems, Inc
+70695A (base 16) Cisco Systems, Inc
+ 80 West Tasman Drive
+ San Jose CA 94568
+ US
+
+58-21-E9 (hex) TWPI
+5821E9 (base 16) TWPI
+ PMB# 335; 1121 Annapolis Road
+ Odenton MD 21113
+ US
+
+68-D4-82 (hex) SHENZHEN GONGJIN ELECTRONICS CO.,LT
+68D482 (base 16) SHENZHEN GONGJIN ELECTRONICS CO.,LT
+ SONGGANG
+ SHENZHEN GUANGDONG 518105
+ CN
+
+30-1F-9A (hex) IEEE Registration Authority
+301F9A (base 16) IEEE Registration Authority
+ 445 Hoes Lane
+ Piscataway NJ 08554
+ US
+
+90-79-10 (hex) Integrated Device Technology (Malaysia) Sdn. Bhd.
+907910 (base 16) Integrated Device Technology (Malaysia) Sdn. Bhd.
+ Phase 3, Bayan Lepas FIZ
+ Bayan Lepas Penang 11900
+ MY
+
+00-A0-D5 (hex) Sierra Wireless Inc
+00A0D5 (base 16) Sierra Wireless Inc
+ 13811 Wireless Way
+ RICHMOND B.C. V6V 3A4
+ CA
+
0C-6F-9C (hex) Shaw Communications Inc.
0C6F9C (base 16) Shaw Communications Inc.
Suite 900, 630 3rd Avenue S.W.
@@ -28853,18 +29213,6 @@ ACCF85 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
Dongguan Guangdong 523808
CN
-0C-D7-46 (hex) Apple, Inc.
-0CD746 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-44-00-10 (hex) Apple, Inc.
-440010 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
24-35-CC (hex) Zhongshan Scinan Internet of Things Co.,Ltd.
2435CC (base 16) Zhongshan Scinan Internet of Things Co.,Ltd.
15/F Bldg 1·Dezhong Plaza Torch Development Zone Zhongshan·Guangdong
@@ -28949,18 +29297,6 @@ C8478C (base 16) Beken Corporation
Shanghai 201203
CN
-E4-98-D6 (hex) Apple, Inc.
-E498D6 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-60-69-44 (hex) Apple, Inc.
-606944 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
88-96-B6 (hex) Global Fire Equipment S.A.
8896B6 (base 16) Global Fire Equipment S.A.
Sitio dos Barrabés, Armazém Nave Y,
@@ -29195,24 +29531,6 @@ EC4D47 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
Seongnam-si Gyeonggi-do 463-875
KR
-04-52-F3 (hex) Apple, Inc.
-0452F3 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-24-1E-EB (hex) Apple, Inc.
-241EEB (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-F4-31-C3 (hex) Apple, Inc.
-F431C3 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
C8-7B-5B (hex) zte corporation
C87B5B (base 16) zte corporation
12/F.,zte R&D building,kejinan Road,
@@ -29411,12 +29729,6 @@ F4559C (base 16) HUAWEI TECHNOLOGIES CO.,LTD
Shenzhen Guangdong 518057
CN
-64-A5-C3 (hex) Apple, Inc.
-64A5C3 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
00-1D-0F (hex) TP-LINK TECHNOLOGIES CO.,LTD.
001D0F (base 16) TP-LINK TECHNOLOGIES CO.,LTD.
3/F, Bldg. R1-B,
@@ -29723,90 +30035,6 @@ C8D719 (base 16) Cisco-Linksys, LLC
Irvine 92612
US
-CC-08-E0 (hex) Apple, Inc.
-CC08E0 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-58-55-CA (hex) Apple, Inc.
-5855CA (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-8C-7B-9D (hex) Apple, Inc.
-8C7B9D (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-88-C6-63 (hex) Apple, Inc.
-88C663 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-C8-2A-14 (hex) Apple, Inc.
-C82A14 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-98-03-D8 (hex) Apple, Inc.
-9803D8 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-8C-58-77 (hex) Apple, Inc.
-8C5877 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-34-51-C9 (hex) Apple, Inc.
-3451C9 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-E0-B9-BA (hex) Apple, Inc.
-E0B9BA (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-D0-23-DB (hex) Apple, Inc.
-D023DB (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-B8-8D-12 (hex) Apple, Inc.
-B88D12 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-B8-17-C2 (hex) Apple, Inc.
-B817C2 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-68-A8-6D (hex) Apple, Inc.
-68A86D (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-78-A3-E4 (hex) Apple, Inc.
-78A3E4 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
54-78-1A (hex) Cisco Systems, Inc
54781A (base 16) Cisco Systems, Inc
170 West Tasman Drive
@@ -29969,126 +30197,6 @@ F45FD4 (base 16) Cisco SPVTG
Soma-city, Fukushima-pref., 976-8501
JP
-BC-92-6B (hex) Apple, Inc.
-BC926B (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-00-50-E4 (hex) Apple, Inc.
-0050E4 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-00-30-65 (hex) Apple, Inc.
-003065 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-00-0A-27 (hex) Apple, Inc.
-000A27 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-00-14-51 (hex) Apple, Inc.
-001451 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-00-19-E3 (hex) Apple, Inc.
-0019E3 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-00-23-12 (hex) Apple, Inc.
-002312 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-00-23-32 (hex) Apple, Inc.
-002332 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-00-24-36 (hex) Apple, Inc.
-002436 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-00-25-4B (hex) Apple, Inc.
-00254B (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-00-26-BB (hex) Apple, Inc.
-0026BB (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-E8-06-88 (hex) Apple, Inc.
-E80688 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-98-5A-EB (hex) Apple, Inc.
-985AEB (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-20-78-F0 (hex) Apple, Inc.
-2078F0 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-78-D7-5F (hex) Apple, Inc.
-78D75F (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-E0-AC-CB (hex) Apple, Inc.
-E0ACCB (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-98-E0-D9 (hex) Apple, Inc.
-98E0D9 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-C0-CE-CD (hex) Apple, Inc.
-C0CECD (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-70-E7-2C (hex) Apple, Inc.
-70E72C (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-D0-33-11 (hex) Apple, Inc.
-D03311 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
84-7D-50 (hex) Holley Metering Limited
847D50 (base 16) Holley Metering Limited
181 Wuchang Avenue
@@ -30101,288 +30209,12 @@ D03311 (base 16) Apple, Inc.
BEI JING 100044
CN
-C8-B5-B7 (hex) Apple, Inc.
-C8B5B7 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-A8-BB-CF (hex) Apple, Inc.
-A8BBCF (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-90-B2-1F (hex) Apple, Inc.
-90B21F (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-B8-E8-56 (hex) Apple, Inc.
-B8E856 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-14-99-E2 (hex) Apple, Inc.
-1499E2 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
04-21-4C (hex) Insight Energy Ventures LLC
04214C (base 16) Insight Energy Ventures LLC
123 W. Fifth St
Royal Oak MI 48067
US
-B4-18-D1 (hex) Apple, Inc.
-B418D1 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-80-00-6E (hex) Apple, Inc.
-80006E (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-60-D9-C7 (hex) Apple, Inc.
-60D9C7 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-C8-F6-50 (hex) Apple, Inc.
-C8F650 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-1C-1A-C0 (hex) Apple, Inc.
-1C1AC0 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-E0-66-78 (hex) Apple, Inc.
-E06678 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-5C-8D-4E (hex) Apple, Inc.
-5C8D4E (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-64-A3-CB (hex) Apple, Inc.
-64A3CB (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-44-FB-42 (hex) Apple, Inc.
-44FB42 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-F4-1B-A1 (hex) Apple, Inc.
-F41BA1 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-3C-E0-72 (hex) Apple, Inc.
-3CE072 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-E8-8D-28 (hex) Apple, Inc.
-E88D28 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-CC-78-5F (hex) Apple, Inc.
-CC785F (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-AC-3C-0B (hex) Apple, Inc.
-AC3C0B (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-88-CB-87 (hex) Apple, Inc.
-88CB87 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-EC-35-86 (hex) Apple, Inc.
-EC3586 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-F0-C1-F1 (hex) Apple, Inc.
-F0C1F1 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-F4-F9-51 (hex) Apple, Inc.
-F4F951 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-18-AF-8F (hex) Apple, Inc.
-18AF8F (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-C0-F2-FB (hex) Apple, Inc.
-C0F2FB (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-00-F7-6F (hex) Apple, Inc.
-00F76F (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-AC-87-A3 (hex) Apple, Inc.
-AC87A3 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-48-43-7C (hex) Apple, Inc.
-48437C (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-34-A3-95 (hex) Apple, Inc.
-34A395 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-9C-F3-87 (hex) Apple, Inc.
-9CF387 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-A8-5B-78 (hex) Apple, Inc.
-A85B78 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-90-8D-6C (hex) Apple, Inc.
-908D6C (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-0C-15-39 (hex) Apple, Inc.
-0C1539 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-BC-4C-C4 (hex) Apple, Inc.
-BC4CC4 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-0C-BC-9F (hex) Apple, Inc.
-0CBC9F (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-A4-5E-60 (hex) Apple, Inc.
-A45E60 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-68-09-27 (hex) Apple, Inc.
-680927 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-60-FA-CD (hex) Apple, Inc.
-60FACD (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-1C-AB-A7 (hex) Apple, Inc.
-1CABA7 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-8C-FA-BA (hex) Apple, Inc.
-8CFABA (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-5C-95-AE (hex) Apple, Inc.
-5C95AE (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-E0-C9-7A (hex) Apple, Inc.
-E0C97A (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-BC-52-B7 (hex) Apple, Inc.
-BC52B7 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-14-10-9F (hex) Apple, Inc.
-14109F (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-54-26-96 (hex) Apple, Inc.
-542696 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-D8-D1-CB (hex) Apple, Inc.
-D8D1CB (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
4C-8E-CC (hex) SILKAN SA
4C8ECC (base 16) SILKAN SA
Immeuble le Sirius
@@ -30515,12 +30347,6 @@ D48304 (base 16) SHENZHEN FAST TECHNOLOGIES CO.,LTD
Lawrenceville GA 30044
US
-54-4E-90 (hex) Apple, Inc.
-544E90 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
58-FC-73 (hex) Arria Live Media, Inc.
58FC73 (base 16) Arria Live Media, Inc.
2388 NE Lindsey Drive
@@ -30533,18 +30359,6 @@ D48304 (base 16) SHENZHEN FAST TECHNOLOGIES CO.,LTD
Changsha Hunan 410208
CN
-5C-AD-CF (hex) Apple, Inc.
-5CADCF (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-00-6D-52 (hex) Apple, Inc.
-006D52 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
D8-88-CE (hex) RF Technology Pty Ltd
D888CE (base 16) RF Technology Pty Ltd
46/7 Sefton Rd
@@ -30605,12 +30419,6 @@ DCA3AC (base 16) RBcloudtech
Dalian Liaoning 116600
CN
-0C-91-60 (hex) Hui Zhou Gaoshengda Technology Co.,LTD
-0C9160 (base 16) Hui Zhou Gaoshengda Technology Co.,LTD
- No.75,Zhongkai High-Tech Development District,Huizhou
- Hui Zhou Guangdong 516006
- CN
-
EC-A9-FA (hex) GUANGDONG GENIUS TECHNOLOGY CO.,LTD.
ECA9FA (base 16) GUANGDONG GENIUS TECHNOLOGY CO.,LTD.
#126,BBK Road,Wusha,Chang'An
@@ -39800,12 +39608,6 @@ D0D286 (base 16) Beckman Coulter K.K.
Ljubljana Slovenia 1000
SI
-00-1B-D8 (hex) DVTel LTD
-001BD8 (base 16) DVTel LTD
- 5 Sapir
- 46852 Herzelia
- IL
-
00-1B-CC (hex) KINGTEK CCTV ALLIANCE CO., LTD.
001BCC (base 16) KINGTEK CCTV ALLIANCE CO., LTD.
5F-3, NO. 106, SEC. 3, HSIN YI ROAD
@@ -46019,12 +45821,6 @@ D0D286 (base 16) Beckman Coulter K.K.
Mountain View CA 94041
US
-00-03-97 (hex) Watchfront Limited
-000397 (base 16) Watchfront Limited
- 3 Victoria Walk
- Wokingham RG40 5YL
- GB
-
00-03-9E (hex) Tera System Co., Ltd.
00039E (base 16) Tera System Co., Ltd.
Doosung B/F Rm 302
@@ -46811,12 +46607,6 @@ D0D286 (base 16) Beckman Coulter K.K.
IL
-00-01-B9 (hex) SKF Condition Monitoring
-0001B9 (base 16) SKF Condition Monitoring
- 4141 Ruffin Road
- San Diego CA 92123
- US
-
00-01-B5 (hex) Turin Networks, Inc.
0001B5 (base 16) Turin Networks, Inc.
1415 North McDowell Blvd.
@@ -51932,12 +51722,6 @@ A444D1 (base 16) Wingtech Group (HongKong)Limited
Hong Kong Hong Kong 999077
HK
-1C-9E-46 (hex) Apple, Inc.
-1C9E46 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
00-50-58 (hex) Sangoma Technologies
005058 (base 16) Sangoma Technologies
100 Renfrew Drive, Suite 100
@@ -52004,12 +51788,6 @@ E45D75 (base 16) Samsung Electronics Co.,Ltd
Shanghai Shanghai 200072
CN
-E0-C7-67 (hex) Apple, Inc.
-E0C767 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
2C-09-CB (hex) COBS AB
2C09CB (base 16) COBS AB
Box 9242
@@ -52601,42 +52379,6 @@ D8209F (base 16) Cubro Acronet GesmbH
Vienna Vienna 1110
AT
-A8-60-B6 (hex) Apple, Inc.
-A860B6 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-24-F0-94 (hex) Apple, Inc.
-24F094 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-90-B0-ED (hex) Apple, Inc.
-90B0ED (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-C4-B3-01 (hex) Apple, Inc.
-C4B301 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-E0-5F-45 (hex) Apple, Inc.
-E05F45 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-48-3B-38 (hex) Apple, Inc.
-483B38 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
E4-7B-3F (hex) BEIJING CO-CLOUD TECHNOLOGY LTD.
E47B3F (base 16) BEIJING CO-CLOUD TECHNOLOGY LTD.
903 Room,Power Create E ,No.1 Shangdi East Road
@@ -53693,42 +53435,12 @@ F01DBC (base 16) Microsoft Corporation
REDMOND WA 98052
US
-40-4D-7F (hex) Apple, Inc.
-404D7F (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-7C-04-D0 (hex) Apple, Inc.
-7C04D0 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-BC-9F-EF (hex) Apple, Inc.
-BC9FEF (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-88-66-A5 (hex) Apple, Inc.
-8866A5 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
AC-DC-E5 (hex) Procter & Gamble Company
ACDCE5 (base 16) Procter & Gamble Company
2 Procter & Gamble Plaza
Cincinnati OH 45202
US
-78-4F-43 (hex) Apple, Inc.
-784F43 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
98-D2-93 (hex) Google, Inc.
98D293 (base 16) Google, Inc.
1600 Amphitheatre Parkway
@@ -54095,12 +53807,6 @@ BC60A7 (base 16) Sony Interactive Entertainment Inc.
Palo Alto CA 94301
US
-20-F5-43 (hex) Hui Zhou Gaoshengda Technology Co.,LTD
-20F543 (base 16) Hui Zhou Gaoshengda Technology Co.,LTD
- No.75,Zhongkai High-Tech Development District,Huizhou
- Hui Zhou Guangdong 516006
- CN
-
68-53-88 (hex) P&S Technology
685388 (base 16) P&S Technology
216 Deajiro
@@ -54530,18 +54236,6 @@ BC39D9 (base 16) Z-TEC
Paju Kyeongkido 10832
KR
-88-E8-7F (hex) Apple, Inc.
-88E87F (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-B8-53-AC (hex) Apple, Inc.
-B853AC (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
B0-4B-BF (hex) PT HAN SUNG ELECTORONICS INDONESIA
B04BBF (base 16) PT HAN SUNG ELECTORONICS INDONESIA
JL.PALEM 1 BLOK DS-6
@@ -54554,12 +54248,6 @@ B04BBF (base 16) PT HAN SUNG ELECTORONICS INDONESIA
CALGARY, ALBERTA T2E 8M4
CA
-2C-33-61 (hex) Apple, Inc.
-2C3361 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
78-B8-4B (hex) SICHUAN TIANYI COMHEART TELECOMCO.,LTD
78B84B (base 16) SICHUAN TIANYI COMHEART TELECOMCO.,LTD
FL12,TowerB,Tianyi international Hotel,No.2 West Section One, Second Ring Road,
@@ -55133,12 +54821,6 @@ E05163 (base 16) Arcadyan Corporation
Dongguan Guangdong 523770
CN
-1C-1E-E3 (hex) Hui Zhou Gaoshengda Technology Co.,LTD
-1C1EE3 (base 16) Hui Zhou Gaoshengda Technology Co.,LTD
- No.75,Zhongkai High-Tech Development District,Huizhou
- Hui Zhou Guangdong 516006
- CN
-
F0-27-2D (hex) Amazon Technologies Inc.
F0272D (base 16) Amazon Technologies Inc.
P.O Box 8102
@@ -55223,42 +54905,6 @@ F0D7AA (base 16) Motorola Mobility LLC, a Lenovo Company
shenzhen guangdong 518057
CN
-88-6B-6E (hex) Apple, Inc.
-886B6E (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-4C-74-BF (hex) Apple, Inc.
-4C74BF (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-70-F0-87 (hex) Apple, Inc.
-70F087 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-28-57-67 (hex) Echostar Technologies Corp
-285767 (base 16) Echostar Technologies Corp
- 94 Inverness Terrace E
- Englewood CO 80112
- US
-
-00-24-AF (hex) Echostar Technologies Corp
-0024AF (base 16) Echostar Technologies Corp
- 94 Inverness Terrace E
- Englewood CO 80112
- US
-
-04-C9-D9 (hex) Echostar Technologies Corp
-04C9D9 (base 16) Echostar Technologies Corp
- 94 Inverness Terrace E
- Englewood CO 80112
- US
-
D0-49-8B (hex) ZOOM SERVER
D0498B (base 16) ZOOM SERVER
North keyuan Road
@@ -56279,9 +55925,6 @@ B05508 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
Suwon Gyeonggi-Do 16677
KR
-00-A0-85 (hex) Private
-00A085 (base 16) Private
-
AC-DE-48 (hex) Private
ACDE48 (base 16) Private
@@ -56555,18 +56198,6 @@ B009DA (base 16) Ring Solutions
Ningbo Zhejiang 315202
CN
-84-41-67 (hex) Apple, Inc.
-844167 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-B4-F6-1C (hex) Apple, Inc.
-B4F61C (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
EC-FA-03 (hex) FCA
ECFA03 (base 16) FCA
800 Chrylser Dr
@@ -56969,24 +56600,6 @@ AC84C6 (base 16) TP-LINK TECHNOLOGIES CO.,LTD.
Shenzhen Guangdong 518057
CN
-E4-9A-DC (hex) Apple, Inc.
-E49ADC (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-B8-C1-11 (hex) Apple, Inc.
-B8C111 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-34-08-BC (hex) Apple, Inc.
-3408BC (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
34-D0-B8 (hex) IEEE Registration Authority
34D0B8 (base 16) IEEE Registration Authority
445 Hoes Lane
@@ -57533,6 +57146,1095 @@ CC3ADF (base 16) Neptune Technology Group Inc.
Hsinchu Taiwan ROC. 30352
TW
+A8-5B-78 (hex) Apple, Inc.
+A85B78 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+9C-F3-87 (hex) Apple, Inc.
+9CF387 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+34-A3-95 (hex) Apple, Inc.
+34A395 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+48-43-7C (hex) Apple, Inc.
+48437C (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+AC-87-A3 (hex) Apple, Inc.
+AC87A3 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+00-F7-6F (hex) Apple, Inc.
+00F76F (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+A4-5E-60 (hex) Apple, Inc.
+A45E60 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+0C-BC-9F (hex) Apple, Inc.
+0CBC9F (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+BC-4C-C4 (hex) Apple, Inc.
+BC4CC4 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+0C-15-39 (hex) Apple, Inc.
+0C1539 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+90-8D-6C (hex) Apple, Inc.
+908D6C (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+D0-33-11 (hex) Apple, Inc.
+D03311 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+70-E7-2C (hex) Apple, Inc.
+70E72C (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+C0-CE-CD (hex) Apple, Inc.
+C0CECD (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+98-E0-D9 (hex) Apple, Inc.
+98E0D9 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+E0-AC-CB (hex) Apple, Inc.
+E0ACCB (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+78-D7-5F (hex) Apple, Inc.
+78D75F (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+20-78-F0 (hex) Apple, Inc.
+2078F0 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+98-5A-EB (hex) Apple, Inc.
+985AEB (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+54-4E-90 (hex) Apple, Inc.
+544E90 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+00-6D-52 (hex) Apple, Inc.
+006D52 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+5C-AD-CF (hex) Apple, Inc.
+5CADCF (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+B8-E8-56 (hex) Apple, Inc.
+B8E856 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+90-B2-1F (hex) Apple, Inc.
+90B21F (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+A8-BB-CF (hex) Apple, Inc.
+A8BBCF (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+C8-B5-B7 (hex) Apple, Inc.
+C8B5B7 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+18-AF-8F (hex) Apple, Inc.
+18AF8F (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+F4-F9-51 (hex) Apple, Inc.
+F4F951 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+F0-C1-F1 (hex) Apple, Inc.
+F0C1F1 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+98-03-D8 (hex) Apple, Inc.
+9803D8 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+C8-2A-14 (hex) Apple, Inc.
+C82A14 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+88-C6-63 (hex) Apple, Inc.
+88C663 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+8C-7B-9D (hex) Apple, Inc.
+8C7B9D (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+58-55-CA (hex) Apple, Inc.
+5855CA (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+CC-08-E0 (hex) Apple, Inc.
+CC08E0 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+E8-06-88 (hex) Apple, Inc.
+E80688 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+B8-17-C2 (hex) Apple, Inc.
+B817C2 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+B8-8D-12 (hex) Apple, Inc.
+B88D12 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+D0-23-DB (hex) Apple, Inc.
+D023DB (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+E0-B9-BA (hex) Apple, Inc.
+E0B9BA (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+34-51-C9 (hex) Apple, Inc.
+3451C9 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+8C-58-77 (hex) Apple, Inc.
+8C5877 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+C0-F2-FB (hex) Apple, Inc.
+C0F2FB (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+5C-8D-4E (hex) Apple, Inc.
+5C8D4E (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+E0-66-78 (hex) Apple, Inc.
+E06678 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+1C-1A-C0 (hex) Apple, Inc.
+1C1AC0 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+C8-F6-50 (hex) Apple, Inc.
+C8F650 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+60-D9-C7 (hex) Apple, Inc.
+60D9C7 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+3C-E0-72 (hex) Apple, Inc.
+3CE072 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+F4-1B-A1 (hex) Apple, Inc.
+F41BA1 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+44-FB-42 (hex) Apple, Inc.
+44FB42 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+64-A3-CB (hex) Apple, Inc.
+64A3CB (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+D8-D1-CB (hex) Apple, Inc.
+D8D1CB (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+54-26-96 (hex) Apple, Inc.
+542696 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+EC-35-86 (hex) Apple, Inc.
+EC3586 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+88-CB-87 (hex) Apple, Inc.
+88CB87 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+AC-3C-0B (hex) Apple, Inc.
+AC3C0B (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+CC-78-5F (hex) Apple, Inc.
+CC785F (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+E8-8D-28 (hex) Apple, Inc.
+E88D28 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+14-10-9F (hex) Apple, Inc.
+14109F (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+BC-52-B7 (hex) Apple, Inc.
+BC52B7 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+E0-C9-7A (hex) Apple, Inc.
+E0C97A (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+5C-95-AE (hex) Apple, Inc.
+5C95AE (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+8C-FA-BA (hex) Apple, Inc.
+8CFABA (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+1C-AB-A7 (hex) Apple, Inc.
+1CABA7 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+60-FA-CD (hex) Apple, Inc.
+60FACD (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+68-09-27 (hex) Apple, Inc.
+680927 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+78-A3-E4 (hex) Apple, Inc.
+78A3E4 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+68-A8-6D (hex) Apple, Inc.
+68A86D (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+80-00-6E (hex) Apple, Inc.
+80006E (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+B4-18-D1 (hex) Apple, Inc.
+B418D1 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+14-99-E2 (hex) Apple, Inc.
+1499E2 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+1C-9E-46 (hex) Apple, Inc.
+1C9E46 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+E0-C7-67 (hex) Apple, Inc.
+E0C767 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+A8-60-B6 (hex) Apple, Inc.
+A860B6 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+24-F0-94 (hex) Apple, Inc.
+24F094 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+90-B0-ED (hex) Apple, Inc.
+90B0ED (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+C4-B3-01 (hex) Apple, Inc.
+C4B301 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+E0-5F-45 (hex) Apple, Inc.
+E05F45 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+48-3B-38 (hex) Apple, Inc.
+483B38 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+88-E8-7F (hex) Apple, Inc.
+88E87F (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+B8-53-AC (hex) Apple, Inc.
+B853AC (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+2C-33-61 (hex) Apple, Inc.
+2C3361 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+00-0A-27 (hex) Apple, Inc.
+000A27 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+00-30-65 (hex) Apple, Inc.
+003065 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+00-50-E4 (hex) Apple, Inc.
+0050E4 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+BC-92-6B (hex) Apple, Inc.
+BC926B (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+04-52-F3 (hex) Apple, Inc.
+0452F3 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+24-1E-EB (hex) Apple, Inc.
+241EEB (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+F4-31-C3 (hex) Apple, Inc.
+F431C3 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+64-A5-C3 (hex) Apple, Inc.
+64A5C3 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+60-69-44 (hex) Apple, Inc.
+606944 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+E4-98-D6 (hex) Apple, Inc.
+E498D6 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+0C-D7-46 (hex) Apple, Inc.
+0CD746 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+44-00-10 (hex) Apple, Inc.
+440010 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+78-4F-43 (hex) Apple, Inc.
+784F43 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+40-4D-7F (hex) Apple, Inc.
+404D7F (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+7C-04-D0 (hex) Apple, Inc.
+7C04D0 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+BC-9F-EF (hex) Apple, Inc.
+BC9FEF (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+88-66-A5 (hex) Apple, Inc.
+8866A5 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+70-F0-87 (hex) Apple, Inc.
+70F087 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+88-6B-6E (hex) Apple, Inc.
+886B6E (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+4C-74-BF (hex) Apple, Inc.
+4C74BF (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+84-41-67 (hex) Apple, Inc.
+844167 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+B4-F6-1C (hex) Apple, Inc.
+B4F61C (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+E4-9A-DC (hex) Apple, Inc.
+E49ADC (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+B8-C1-11 (hex) Apple, Inc.
+B8C111 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+34-08-BC (hex) Apple, Inc.
+3408BC (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+D0-81-7A (hex) Apple, Inc.
+D0817A (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+C4-61-8B (hex) Apple, Inc.
+C4618B (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+68-AB-1E (hex) Apple, Inc.
+68AB1E (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+2C-61-F6 (hex) Apple, Inc.
+2C61F6 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+00-26-BB (hex) Apple, Inc.
+0026BB (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+00-25-4B (hex) Apple, Inc.
+00254B (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+00-24-36 (hex) Apple, Inc.
+002436 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+00-23-32 (hex) Apple, Inc.
+002332 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+00-23-12 (hex) Apple, Inc.
+002312 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+00-19-E3 (hex) Apple, Inc.
+0019E3 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+00-14-51 (hex) Apple, Inc.
+001451 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+50-DC-E7 (hex) Amazon Technologies Inc.
+50DCE7 (base 16) Amazon Technologies Inc.
+ P.O Box 8102
+ Reno NV 89507
+ US
+
+04-09-73 (hex) Hewlett Packard Enterprise
+040973 (base 16) Hewlett Packard Enterprise
+ 8000 Foothills Blvd.
+ Roseville CA 95747
+ US
+
+4C-C2-06 (hex) Somfy
+4CC206 (base 16) Somfy
+ 50 avenue du nouveau monde
+ Cluses 74300
+ FR
+
+70-F2-20 (hex) Actiontec Electronics, Inc
+70F220 (base 16) Actiontec Electronics, Inc
+ 760 North Mary Ave
+ Sunnyvale CA 94085
+ US
+
+28-57-67 (hex) Dish Technologies Corp
+285767 (base 16) Dish Technologies Corp
+ 94 Inverness Terrace E
+ Englewood CO 80112
+ US
+
+70-55-F8 (hex) Cerebras Systems Inc
+7055F8 (base 16) Cerebras Systems Inc
+ 175 S San Antonio Rd #100
+ Los Altos CA 94022
+ US
+
+04-C9-D9 (hex) Dish Technologies Corp
+04C9D9 (base 16) Dish Technologies Corp
+ 94 Inverness Terrace E
+ Englewood CO 80112
+ US
+
+00-24-AF (hex) Dish Technologies Corp
+0024AF (base 16) Dish Technologies Corp
+ 94 Inverness Terrace E
+ Englewood CO 80112
+ US
+
+9C-43-1E (hex) IEEE Registration Authority
+9C431E (base 16) IEEE Registration Authority
+ 445 Hoes Lane
+ Piscataway NJ 08554
+ US
+
+80-C5-48 (hex) Shenzhen Zowee Technology Co.,Ltd
+80C548 (base 16) Shenzhen Zowee Technology Co.,Ltd
+ NO.5 Zowee technology building, Science & Technology industrial park of privately Science & Technology industrial park of privately owned enterprises
+ Shenzhen GuangDong 518055
+ CN
+
+6C-54-CD (hex) LAMPEX ELECTRONICS LIMITED
+6C54CD (base 16) LAMPEX ELECTRONICS LIMITED
+ 6-2/231/B, Kukatpally,
+ Hyderabad Telangana 500072
+ IN
+
+88-3D-24 (hex) Google, Inc.
+883D24 (base 16) Google, Inc.
+ 1600 Amphitheatre Parkway
+ Mountain View CA 94043
+ US
+
+E8-DE-FB (hex) MESOTIC SAS
+E8DEFB (base 16) MESOTIC SAS
+ 11, Avenue de la Division Leclerc
+ Cachan 94230
+ FR
+
+90-84-8B (hex) HDR10+ Technologies, LLC
+90848B (base 16) HDR10+ Technologies, LLC
+ 3855 SW 153rd Drive
+ Beaverton OR 97006
+ US
+
+0C-23-69 (hex) Honeywell SPS
+0C2369 (base 16) Honeywell SPS
+ 700 Visions Dr.
+ Skaneateles Falls NY 13153
+ US
+
+8C-16-45 (hex) LCFC(HeFei) Electronics Technology co., ltd
+8C1645 (base 16) LCFC(HeFei) Electronics Technology co., ltd
+ YunGu Road 3188-1
+ Hefei Anhui 230000
+ CN
+
+B4-E9-A3 (hex) port GmbH
+B4E9A3 (base 16) port GmbH
+ Regensburger Str. 7b
+ Halle (S.) 06132
+ DE
+
+6C-B6-CA (hex) DIVUS GmbH
+6CB6CA (base 16) DIVUS GmbH
+ Pillhof 51
+ Eppan 39057
+ IT
+
+B8-DE-5E (hex) LONGCHEER TELECOMMUNICATION LIMITED
+B8DE5E (base 16) LONGCHEER TELECOMMUNICATION LIMITED
+ Building 1,No.401,Caobao Rd
+ Shanghai Xuhui District 200233
+ CN
+
+DC-DD-24 (hex) Energica Motor Company SpA
+DCDD24 (base 16) Energica Motor Company SpA
+ Via Cesare della Chiesa, 150
+ MODENA (MO) Mo 41126
+ IT
+
+94-63-72 (hex) vivo Mobile Communication Co., Ltd.
+946372 (base 16) vivo Mobile Communication Co., Ltd.
+ #283,BBK Road
+ Wusha,Chang'An DongGuan City,Guangdong, 523860
+ CN
+
+44-9E-F9 (hex) vivo Mobile Communication Co., Ltd.
+449EF9 (base 16) vivo Mobile Communication Co., Ltd.
+ #283,BBK Road
+ Wusha,Chang'An DongGuan City,Guangdong, 523860
+ CN
+
+64-1C-B0 (hex) Samsung Electronics Co.,Ltd
+641CB0 (base 16) Samsung Electronics Co.,Ltd
+ 129, Samsung-ro, Youngtongl-Gu
+ Suwon Gyeonggi-Do 16677
+ KR
+
+8C-F9-57 (hex) RuiXingHengFang Network (Shenzhen) Co.,Ltd
+8CF957 (base 16) RuiXingHengFang Network (Shenzhen) Co.,Ltd
+ Room 507, 2nd tower of KangTai biological building NO.6 KeFa Rd. NanShan District
+ Shenzhen Guangdong 518057
+ CN
+
+00-1B-D8 (hex) FLIR Systems Inc
+001BD8 (base 16) FLIR Systems Inc
+ 65 Challenger Road
+ Ridgefield Park NJ 07660-2103
+ US
+
+20-36-5B (hex) Megafone Limited
+20365B (base 16) Megafone Limited
+ Unit 702,7/F,Bankok Bank Building,NO.18 Bonham Strand West
+ Hong Kong 999077
+ HK
+
+E8-DE-00 (hex) ChongQing GuanFang Technology Co.,LTD
+E8DE00 (base 16) ChongQing GuanFang Technology Co.,LTD
+ 2F, A District,No.3 Middle Section of Mount Huangshan Avenue
+ ChongQing ChongQing 401121
+ CN
+
+3C-DC-BC (hex) Samsung Electronics Co.,Ltd
+3CDCBC (base 16) Samsung Electronics Co.,Ltd
+ #94-1, Imsoo-Dong
+ Gumi Gyeongbuk 730-350
+ KR
+
+F4-71-90 (hex) Samsung Electronics Co.,Ltd
+F47190 (base 16) Samsung Electronics Co.,Ltd
+ #94-1, Imsoo-Dong
+ Gumi Gyeongbuk 730-350
+ KR
+
+4C-77-6D (hex) Cisco Systems, Inc
+4C776D (base 16) Cisco Systems, Inc
+ 80 West Tasman Drive
+ San Jose CA 94568
+ US
+
+FC-A6-CD (hex) Fiberhome Telecommunication Technologies Co.,LTD
+FCA6CD (base 16) Fiberhome Telecommunication Technologies Co.,LTD
+ No.5 DongXin Road
+ Wuhan Hubei 430074
+ CN
+
+64-DB-8B (hex) Hangzhou Hikvision Digital Technology Co.,Ltd.
+64DB8B (base 16) Hangzhou Hikvision Digital Technology Co.,Ltd.
+ No.555 Qianmo Road
+ Hangzhou Zhejiang 310052
+ CN
+
+78-25-7A (hex) LEO Innovation Lab
+78257A (base 16) LEO Innovation Lab
+ Silkegade 8
+ Copenhagen K Denmark 1113
+ DK
+
+A4-DA-22 (hex) IEEE Registration Authority
+A4DA22 (base 16) IEEE Registration Authority
+ 445 Hoes Lane
+ Piscataway NJ 08554
+ US
+
+00-03-97 (hex) FireBrick Limited
+000397 (base 16) FireBrick Limited
+ C/O Andrews & Arnold Ltd,
+ Enterprise Court, Downmill Road Bracknell, Berks RG12 1QS
+ GB
+
+A8-61-0A (hex) ARDUINO AG
+A8610A (base 16) ARDUINO AG
+ Corso San Gottardo 6A
+ Chiasso 6830
+ CH
+
+60-97-DD (hex) MicroSys Electronics GmbH
+6097DD (base 16) MicroSys Electronics GmbH
+ Muehlweg 1
+ Sauerlach 82054
+ DE
+
+04-79-70 (hex) HUAWEI TECHNOLOGIES CO.,LTD
+047970 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
+ CN
+
+C4-9F-4C (hex) HUAWEI TECHNOLOGIES CO.,LTD
+C49F4C (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
+ CN
+
+A0-57-E3 (hex) HUAWEI TECHNOLOGIES CO.,LTD
+A057E3 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
+ CN
+
+E0-E6-2E (hex) TCT mobile ltd
+E0E62E (base 16) TCT mobile ltd
+ No.86 hechang 7th road, zhongkai, Hi-Tech District
+ Hui Zhou Guang Dong 516006
+ CN
+
+00-A0-85 (hex) Private
+00A085 (base 16) Private
+
+94-B8-6D (hex) Intel Corporate
+94B86D (base 16) Intel Corporate
+ Lot 8, Jalan Hi-Tech 2/3
+ Kulim Kedah 09000
+ MY
+
+F8-8B-37 (hex) ARRIS Group, Inc.
+F88B37 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+30-FD-38 (hex) Google, Inc.
+30FD38 (base 16) Google, Inc.
+ 1600 Amphitheatre Parkway
+ Mountain View CA 94043
+ US
+
+18-50-2A (hex) SOARNEX
+18502A (base 16) SOARNEX
+ NO.158, RUIHU ST., NEIHU DIST.,
+ TAIPEI CITY TAIWAN (R.O.C.) 11494
+ TW
+
+58-7A-6A (hex) GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+587A6A (base 16) GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+ NO.18 HAIBIN ROAD,
+ DONG GUAN GUANG DONG 523860
+ CN
+
+E4-C4-83 (hex) GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+E4C483 (base 16) GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+ NO.18 HAIBIN ROAD,
+ DONG GUAN GUANG DONG 523860
+ CN
+
+F4-E1-1E (hex) Texas Instruments
+F4E11E (base 16) Texas Instruments
+ 12500 TI Blvd
+ Dallas TX 75243
+ US
+
+30-45-11 (hex) Texas Instruments
+304511 (base 16) Texas Instruments
+ 12500 TI Blvd
+ Dallas TX 75243
+ US
+
+34-03-DE (hex) Texas Instruments
+3403DE (base 16) Texas Instruments
+ 12500 TI Blvd
+ Dallas TX 75243
+ US
+
+10-E7-C6 (hex) Hewlett Packard
+10E7C6 (base 16) Hewlett Packard
+ 11445 Compaq Center Drive
+ Houston TX 77070
+ US
+
+20-F5-43 (hex) Hui Zhou Gaoshengda Technology Co.,LTD
+20F543 (base 16) Hui Zhou Gaoshengda Technology Co.,LTD
+ No.75,Zhongkai High-Tech Development District,Huizhou
+ Hui Zhou Guangdong 516006
+ CN
+
+1C-1E-E3 (hex) Hui Zhou Gaoshengda Technology Co.,LTD
+1C1EE3 (base 16) Hui Zhou Gaoshengda Technology Co.,LTD
+ No.75,Zhongkai High-Tech Development District,Huizhou
+ Hui Zhou Guangdong 516006
+ CN
+
+0C-91-60 (hex) Hui Zhou Gaoshengda Technology Co.,LTD
+0C9160 (base 16) Hui Zhou Gaoshengda Technology Co.,LTD
+ No.75,Zhongkai High-Tech Development District,Huizhou
+ Hui Zhou Guangdong 516006
+ CN
+
+0C-62-A6 (hex) Hui Zhou Gaoshengda Technology Co.,LTD
+0C62A6 (base 16) Hui Zhou Gaoshengda Technology Co.,LTD
+ No.75,Zhongkai High-Tech Development District,Huizhou
+ Hui Zhou Guangdong 516006
+ CN
+
+7C-49-EB (hex) XIAOMI Electronics,CO.,LTD
+7C49EB (base 16) XIAOMI Electronics,CO.,LTD
+ Xiaomi Building, No.68 Qinghe Middle Street,Haidian District
+ Beijing Beijing 100085
+ CN
+
+C4-33-06 (hex) China Mobile Group Device Co.,Ltd.
+C43306 (base 16) China Mobile Group Device Co.,Ltd.
+ 32 Xuanwumen West Street,Xicheng District
+ Beijing 100053
+ CN
+
+68-FE-DA (hex) Fiberhome Telecommunication Technologies Co.,LTD
+68FEDA (base 16) Fiberhome Telecommunication Technologies Co.,LTD
+ No.5 DongXin Road
+ Wuhan Hubei 430074
+ CN
+
+0C-6A-BC (hex) Fiberhome Telecommunication Technologies Co.,LTD
+0C6ABC (base 16) Fiberhome Telecommunication Technologies Co.,LTD
+ No.5 DongXin Road
+ Wuhan Hubei 430074
+ CN
+
+D4-C1-9E (hex) Ruckus Wireless
+D4C19E (base 16) Ruckus Wireless
+ 350 West Java Drive
+ Sunnyvale CA 94089
+ US
+
+00-01-B9 (hex) SKF (U.K.) Limited
+0001B9 (base 16) SKF (U.K.) Limited
+ 2 Michaelson Square Kirkton Campus
+ Livingston West Lothian EH54 7DP
+ GB
+
+64-C3-D6 (hex) Juniper Networks
+64C3D6 (base 16) Juniper Networks
+ 1133 Innovation Way
+ Sunnyvale CA 94089
+ US
+
58-46-E1 (hex) Baxter International Inc
5846E1 (base 16) Baxter International Inc
One Baxter Parkway
@@ -57611,24 +58313,6 @@ DCC0EB (base 16) ASSA ABLOY CÔTE PICARDE
Shenzhen Guangdong 518000
CN
-5C-F9-38 (hex) Apple, Inc.
-5CF938 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-38-71-DE (hex) Apple, Inc.
-3871DE (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-BC-54-36 (hex) Apple, Inc.
-BC5436 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
0C-C7-31 (hex) Currant, Inc.
0CC731 (base 16) Currant, Inc.
927 Industrial Ave
@@ -58385,108 +59069,6 @@ F83DFF (base 16) HUAWEI TECHNOLOGIES CO.,LTD
Shenzhen Guangdong 518129
CN
-00-C6-10 (hex) Apple, Inc.
-00C610 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-70-DE-E2 (hex) Apple, Inc.
-70DEE2 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-18-20-32 (hex) Apple, Inc.
-182032 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-6C-C2-6B (hex) Apple, Inc.
-6CC26B (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-10-40-F3 (hex) Apple, Inc.
-1040F3 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-FC-25-3F (hex) Apple, Inc.
-FC253F (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-18-34-51 (hex) Apple, Inc.
-183451 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-C0-84-7A (hex) Apple, Inc.
-C0847A (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-64-20-0C (hex) Apple, Inc.
-64200C (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-74-E1-B6 (hex) Apple, Inc.
-74E1B6 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-0C-77-1A (hex) Apple, Inc.
-0C771A (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-00-F4-B9 (hex) Apple, Inc.
-00F4B9 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-C8-33-4B (hex) Apple, Inc.
-C8334B (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-B8-F6-B1 (hex) Apple, Inc.
-B8F6B1 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-C0-9F-42 (hex) Apple, Inc.
-C09F42 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-18-9E-FC (hex) Apple, Inc.
-189EFC (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-6C-3E-6D (hex) Apple, Inc.
-6C3E6D (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
00-16-FE (hex) ALPS ELECTRIC CO.,LTD.
0016FE (base 16) ALPS ELECTRIC CO.,LTD.
1-2-1, Okinouchi,
@@ -58685,72 +59267,6 @@ B0FAEB (base 16) Cisco Systems, Inc
San Jose CA 95134
US
-7C-FA-DF (hex) Apple, Inc.
-7CFADF (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-10-1C-0C (hex) Apple, Inc.
-101C0C (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-00-11-24 (hex) Apple, Inc.
-001124 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-00-1D-4F (hex) Apple, Inc.
-001D4F (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-00-1E-52 (hex) Apple, Inc.
-001E52 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-00-1F-5B (hex) Apple, Inc.
-001F5B (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-00-1F-F3 (hex) Apple, Inc.
-001FF3 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-00-21-E9 (hex) Apple, Inc.
-0021E9 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-00-23-6C (hex) Apple, Inc.
-00236C (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-00-25-00 (hex) Apple, Inc.
-002500 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-60-FB-42 (hex) Apple, Inc.
-60FB42 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
14-DA-E9 (hex) ASUSTek COMPUTER INC.
14DAE9 (base 16) ASUSTek COMPUTER INC.
15,Li-Te Rd.,Peitou,
@@ -58799,60 +59315,6 @@ D072DC (base 16) Cisco Systems, Inc
San Jose CA 95134
US
-F8-1E-DF (hex) Apple, Inc.
-F81EDF (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-90-84-0D (hex) Apple, Inc.
-90840D (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-D8-A2-5E (hex) Apple, Inc.
-D8A25E (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-C8-BC-C8 (hex) Apple, Inc.
-C8BCC8 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-28-E7-CF (hex) Apple, Inc.
-28E7CF (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-D8-9E-3F (hex) Apple, Inc.
-D89E3F (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-04-0C-CE (hex) Apple, Inc.
-040CCE (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-A4-D1-D2 (hex) Apple, Inc.
-A4D1D2 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-40-6C-8F (hex) Apple, Inc.
-406C8F (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
C0-67-AF (hex) Cisco Systems, Inc
C067AF (base 16) Cisco Systems, Inc
170 West Tasman Drive
@@ -58937,258 +59399,12 @@ C067AF (base 16) Cisco Systems, Inc
SAN JOSE CA 95134-1706
US
-64-9A-BE (hex) Apple, Inc.
-649ABE (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-94-E9-6A (hex) Apple, Inc.
-94E96A (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-AC-29-3A (hex) Apple, Inc.
-AC293A (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-10-41-7F (hex) Apple, Inc.
-10417F (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-70-14-A6 (hex) Apple, Inc.
-7014A6 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-A8-66-7F (hex) Apple, Inc.
-A8667F (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-D0-25-98 (hex) Apple, Inc.
-D02598 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-CC-29-F5 (hex) Apple, Inc.
-CC29F5 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-6C-70-9F (hex) Apple, Inc.
-6C709F (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-0C-3E-9F (hex) Apple, Inc.
-0C3E9F (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-34-E2-FD (hex) Apple, Inc.
-34E2FD (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-60-92-17 (hex) Apple, Inc.
-609217 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-88-63-DF (hex) Apple, Inc.
-8863DF (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-80-E6-50 (hex) Apple, Inc.
-80E650 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-00-61-71 (hex) Apple, Inc.
-006171 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-90-FD-61 (hex) Apple, Inc.
-90FD61 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-5C-97-F3 (hex) Apple, Inc.
-5C97F3 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-6C-40-08 (hex) Apple, Inc.
-6C4008 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-24-A0-74 (hex) Apple, Inc.
-24A074 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-F0-24-75 (hex) Apple, Inc.
-F02475 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-20-A2-E4 (hex) Apple, Inc.
-20A2E4 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-5C-F5-DA (hex) Apple, Inc.
-5CF5DA (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
D4-B8-FF (hex) Home Control Singapore Pte Ltd
D4B8FF (base 16) Home Control Singapore Pte Ltd
620A Lorong 1 Toa Payoh
Singapore Singapore 217909
SG
-28-E1-4C (hex) Apple, Inc.
-28E14C (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-54-E4-3A (hex) Apple, Inc.
-54E43A (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-C8-E0-EB (hex) Apple, Inc.
-C8E0EB (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-A8-88-08 (hex) Apple, Inc.
-A88808 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-90-72-40 (hex) Apple, Inc.
-907240 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-0C-4D-E9 (hex) Apple, Inc.
-0C4DE9 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-D8-96-95 (hex) Apple, Inc.
-D89695 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-0C-30-21 (hex) Apple, Inc.
-0C3021 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-F0-F6-1C (hex) Apple, Inc.
-F0F61C (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-B0-34-95 (hex) Apple, Inc.
-B03495 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-84-8E-0C (hex) Apple, Inc.
-848E0C (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-8C-2D-AA (hex) Apple, Inc.
-8C2DAA (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-44-4C-0C (hex) Apple, Inc.
-444C0C (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-84-FC-FE (hex) Apple, Inc.
-84FCFE (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-E4-8B-7F (hex) Apple, Inc.
-E48B7F (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-5C-96-9D (hex) Apple, Inc.
-5C969D (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-A8-FA-D8 (hex) Apple, Inc.
-A8FAD8 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-94-94-26 (hex) Apple, Inc.
-949426 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-E0-F5-C6 (hex) Apple, Inc.
-E0F5C6 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
AC-64-62 (hex) zte corporation
AC6462 (base 16) zte corporation
12/F.,zte R&D building ,kejinan Road,Shenzhen,P.R.China
@@ -59315,18 +59531,6 @@ E8DED6 (base 16) Intrising Networks, Inc.
Taipei
TW
-B8-44-D9 (hex) Apple, Inc.
-B844D9 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-DC-2B-2A (hex) Apple, Inc.
-DC2B2A (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
8C-10-D4 (hex) Sagemcom Broadband SAS
8C10D4 (base 16) Sagemcom Broadband SAS
250, route de l'Empereur
@@ -62051,12 +62255,6 @@ D0D6CC (base 16) Wintop
Songjiang District Shanghai 201612
CN
-10-1D-51 (hex) ON-Q LLC dba ON-Q Mesh Networks
-101D51 (base 16) ON-Q LLC dba ON-Q Mesh Networks
- 2859 Mandela Parkway
- Oakland CA 94611
- US
-
34-C9-9D (hex) EIDOLON COMMUNICATIONS TECHNOLOGY CO. LTD.
34C99D (base 16) EIDOLON COMMUNICATIONS TECHNOLOGY CO. LTD.
Room 603, 6/F., Wanchai Central Building, 89 Lockhart Road, Wanchai,
@@ -63002,12 +63200,6 @@ C85645 (base 16) Intermas France
Phoenixville PA 19460
US
-30-B2-16 (hex) Hytec Geraetebau GmbH
-30B216 (base 16) Hytec Geraetebau GmbH
- Cochemer Straße 12 - 14
- Mannheim 68309
- DE
-
34-FC-6F (hex) ALCEA
34FC6F (base 16) ALCEA
3 Rue Joly de Bammeville
@@ -66203,12 +66395,6 @@ A893E6 (base 16) JIANGXI JINGGANGSHAN CKING COMMUNICATION TECHNOLOGY CO.,LT
ANKARA 06370
TR
-00-23-A8 (hex) Marshall Electronics
-0023A8 (base 16) Marshall Electronics
- 1910 E Maple Ave
- El Segundo Ca 90245
- US
-
00-23-9B (hex) Elster Solutions, LLC
00239B (base 16) Elster Solutions, LLC
208 South Rogers Lane
@@ -75632,12 +75818,6 @@ A06A00 (base 16) Verilink Corporation
CN
-00-D0-CE (hex) ASYST ELECTRONIC
-00D0CE (base 16) ASYST ELECTRONIC
- BRODISCE 7, 10C TRZIN
-
- SI
-
00-D0-90 (hex) Cisco Systems, Inc
00D090 (base 16) Cisco Systems, Inc
80 West Tasman Drive
@@ -80222,18 +80402,6 @@ B83241 (base 16) Wuhan Tianyu Information Industry Co., Ltd.
Minato-ku Tokyo 108-0022
JP
-9C-4F-DA (hex) Apple, Inc.
-9C4FDA (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-1C-5C-F2 (hex) Apple, Inc.
-1C5CF2 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
08-21-EF (hex) Samsung Electronics Co.,Ltd
0821EF (base 16) Samsung Electronics Co.,Ltd
#94-1, Imsoo-Dong
@@ -80294,36 +80462,12 @@ B8A175 (base 16) Roku, Inc.
Wichita KS 67226-1397
US
-E4-9A-79 (hex) Apple, Inc.
-E49A79 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-28-A0-2B (hex) Apple, Inc.
-28A02B (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-B4-4B-D2 (hex) Apple, Inc.
-B44BD2 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
00-23-40 (hex) MiXTelematics
002340 (base 16) MiXTelematics
Blaauwklip Office Park 2
Stellenbosch Western Cape 7600
ZA
-B4-8B-19 (hex) Apple, Inc.
-B48B19 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
00-AF-1F (hex) Cisco Systems, Inc
00AF1F (base 16) Cisco Systems, Inc
80 West Tasman Drive
@@ -80912,24 +81056,6 @@ A81559 (base 16) Breathometer, Inc.
Burlingame CA 94010
US
-EC-AD-B8 (hex) Apple, Inc.
-ECADB8 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-98-01-A7 (hex) Apple, Inc.
-9801A7 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-2C-F0-A2 (hex) Apple, Inc.
-2CF0A2 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
C0-97-27 (hex) SAMSUNG ELECTRO-MECHANICS(THAILAND)
C09727 (base 16) SAMSUNG ELECTRO-MECHANICS(THAILAND)
93Moo5T. Bangsamak SEMTHAI, WELLGROW INDUSTRIAL ESTATE
@@ -82616,24 +82742,6 @@ E00DB9 (base 16) Cree, Inc.
anyang-si kyunggi-do 14057
KR
-60-9A-C1 (hex) Apple, Inc.
-609AC1 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-F0-79-60 (hex) Apple, Inc.
-F07960 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-9C-8B-A0 (hex) Apple, Inc.
-9C8BA0 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
98-40-BB (hex) Dell Inc.
9840BB (base 16) Dell Inc.
One Dell Way
@@ -82652,12 +82760,6 @@ E04FBD (base 16) SICHUAN TIANYI COMHEART TELECOMCO.,LTD
San Jose CA 94568
US
-4C-32-75 (hex) Apple, Inc.
-4C3275 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
00-06-F4 (hex) Prime Electronics & Satellitics Inc.
0006F4 (base 16) Prime Electronics & Satellitics Inc.
69,Tung-Yuan Rd
@@ -83081,30 +83183,6 @@ B0F963 (base 16) Hangzhou H3C Technologies Co., Limited
Hangzhou Zhejiang, P.R.China 310052
CN
-E4-E4-AB (hex) Apple, Inc.
-E4E4AB (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-58-40-4E (hex) Apple, Inc.
-58404E (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-DC-0C-5C (hex) Apple, Inc.
-DC0C5C (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-2C-20-0B (hex) Apple, Inc.
-2C200B (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
98-B6-E9 (hex) Nintendo Co.,Ltd
98B6E9 (base 16) Nintendo Co.,Ltd
11-1 HOKOTATE-CHO KAMITOBA,MINAMI-KU
@@ -83447,18 +83525,6 @@ AC63BE (base 16) Amazon Technologies Inc.
Reno NV 89507
US
-DC-A4-CA (hex) Apple, Inc.
-DCA4CA (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-8C-8F-E9 (hex) Apple, Inc.
-8C8FE9 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
40-FA-7F (hex) Preh Car Connect GmbH
40FA7F (base 16) Preh Car Connect GmbH
Gewerbepark 5
@@ -83513,24 +83579,6 @@ F85971 (base 16) Intel Corporate
Kulim Kedah 09000
MY
-98-10-E8 (hex) Apple, Inc.
-9810E8 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-B4-9C-DF (hex) Apple, Inc.
-B49CDF (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-4C-82-CF (hex) Echostar Technologies Corp
-4C82CF (base 16) Echostar Technologies Corp
- 94 Inverness Terrace E
- Englewood CO 80112
- US
-
F4-96-34 (hex) Intel Corporate
F49634 (base 16) Intel Corporate
Lot 8, Jalan Hi-Tech 2/3
@@ -84932,54 +84980,6 @@ CC7EE7 (base 16) Panasonic Corporation AVC Networks Company
San Jose CA 94568
US
-A4-E9-75 (hex) Apple, Inc.
-A4E975 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-C0-A5-3E (hex) Apple, Inc.
-C0A53E (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-98-00-C6 (hex) Apple, Inc.
-9800C6 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-78-7B-8A (hex) Apple, Inc.
-787B8A (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-38-66-F0 (hex) Apple, Inc.
-3866F0 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-20-EE-28 (hex) Apple, Inc.
-20EE28 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-08-F4-AB (hex) Apple, Inc.
-08F4AB (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-8C-85-90 (hex) Apple, Inc.
-8C8590 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
FC-01-7C (hex) Hon Hai Precision Ind. Co.,Ltd.
FC017C (base 16) Hon Hai Precision Ind. Co.,Ltd.
Building D21,No.1, East Zone 1st Road
@@ -85133,12 +85133,6 @@ C850E9 (base 16) Raisecom Technology CO., LTD
Austin TX 78701
US
-50-4E-DC (hex) Ping Communication
-504EDC (base 16) Ping Communication
- Brenden 18
- Appenzell Meistersrüte AI 9050
- CH
-
50-F7-22 (hex) Cisco Systems, Inc
50F722 (base 16) Cisco Systems, Inc
80 West Tasman Drive
@@ -85295,12 +85289,6 @@ F092B4 (base 16) SICHUAN TIANYI COMHEART TELECOMCO., LTD
Hangzhou Zhejiang 310052
CN
-B0-CA-68 (hex) Apple, Inc.
-B0CA68 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
00-12-48 (hex) Dell EMC
001248 (base 16) Dell EMC
176 South Street
@@ -85862,9 +85850,1053 @@ E42F26 (base 16) Fiberhome Telecommunication Technologies Co.,LTD
Wuhan Hubei 430074
CN
+94-8D-EF (hex) Oetiker Schweiz AG
+948DEF (base 16) Oetiker Schweiz AG
+ Spätzstrasse 11
+ Horgen 8810
+ CH
+
+74-72-1E (hex) Edison Labs Inc.
+74721E (base 16) Edison Labs Inc.
+ 1122 Stanyan St
+ San Francisco CA 94117
+ US
+
+A8-36-7A (hex) frogblue TECHNOLOGY GmbH
+A8367A (base 16) frogblue TECHNOLOGY GmbH
+ Luxemburger Straße 6
+ Kaiserslautern Rheinland-Pfalz 67657
+ DE
+
+14-4E-34 (hex) Remote Solution
+144E34 (base 16) Remote Solution
+ 92, Chogokri, Nammyun
+ Kimcheon city Kyungbuk 740-871
+ KR
+
+EC-65-CC (hex) Panasonic Automotive Systems Company of America
+EC65CC (base 16) Panasonic Automotive Systems Company of America
+ 776 Highway 74 South
+ Peachtree City 30269
+ US
+
+DC-4E-F4 (hex) Shenzhen MTN Electronics CO., Ltd
+DC4EF4 (base 16) Shenzhen MTN Electronics CO., Ltd
+ MTN Industrial Park, No. 5, 9 South Futai Road, Pingxi Community, Pingdi Street, Longgang District
+ Shenzhen Guangdong 518117
+ CN
+
AC-F8-5C (hex) Private
ACF85C (base 16) Private
+D4-60-E3 (hex) Sercomm Corporation.
+D460E3 (base 16) Sercomm Corporation.
+ violet_liu@sercomm.com
+ Miao-Lih Hsuan 115
+ TW
+
+D0-25-98 (hex) Apple, Inc.
+D02598 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+A8-66-7F (hex) Apple, Inc.
+A8667F (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+70-14-A6 (hex) Apple, Inc.
+7014A6 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+10-41-7F (hex) Apple, Inc.
+10417F (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+AC-29-3A (hex) Apple, Inc.
+AC293A (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+94-E9-6A (hex) Apple, Inc.
+94E96A (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+0C-4D-E9 (hex) Apple, Inc.
+0C4DE9 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+90-72-40 (hex) Apple, Inc.
+907240 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+A8-88-08 (hex) Apple, Inc.
+A88808 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+C8-E0-EB (hex) Apple, Inc.
+C8E0EB (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+54-E4-3A (hex) Apple, Inc.
+54E43A (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+28-E1-4C (hex) Apple, Inc.
+28E14C (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+84-8E-0C (hex) Apple, Inc.
+848E0C (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+B0-34-95 (hex) Apple, Inc.
+B03495 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+F0-F6-1C (hex) Apple, Inc.
+F0F61C (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+0C-30-21 (hex) Apple, Inc.
+0C3021 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+D8-96-95 (hex) Apple, Inc.
+D89695 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+64-9A-BE (hex) Apple, Inc.
+649ABE (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+5C-F5-DA (hex) Apple, Inc.
+5CF5DA (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+20-A2-E4 (hex) Apple, Inc.
+20A2E4 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+F0-24-75 (hex) Apple, Inc.
+F02475 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+24-A0-74 (hex) Apple, Inc.
+24A074 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+88-63-DF (hex) Apple, Inc.
+8863DF (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+60-92-17 (hex) Apple, Inc.
+609217 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+34-E2-FD (hex) Apple, Inc.
+34E2FD (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+0C-3E-9F (hex) Apple, Inc.
+0C3E9F (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+6C-70-9F (hex) Apple, Inc.
+6C709F (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+6C-40-08 (hex) Apple, Inc.
+6C4008 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+5C-97-F3 (hex) Apple, Inc.
+5C97F3 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+90-FD-61 (hex) Apple, Inc.
+90FD61 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+00-61-71 (hex) Apple, Inc.
+006171 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+80-E6-50 (hex) Apple, Inc.
+80E650 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+DC-2B-2A (hex) Apple, Inc.
+DC2B2A (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+B8-44-D9 (hex) Apple, Inc.
+B844D9 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+E0-F5-C6 (hex) Apple, Inc.
+E0F5C6 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+94-94-26 (hex) Apple, Inc.
+949426 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+CC-29-F5 (hex) Apple, Inc.
+CC29F5 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+58-40-4E (hex) Apple, Inc.
+58404E (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+DC-0C-5C (hex) Apple, Inc.
+DC0C5C (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+2C-20-0B (hex) Apple, Inc.
+2C200B (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+DC-A4-CA (hex) Apple, Inc.
+DCA4CA (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+8C-8F-E9 (hex) Apple, Inc.
+8C8FE9 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+98-10-E8 (hex) Apple, Inc.
+9810E8 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+B4-9C-DF (hex) Apple, Inc.
+B49CDF (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+A4-E9-75 (hex) Apple, Inc.
+A4E975 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+C0-A5-3E (hex) Apple, Inc.
+C0A53E (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+98-00-C6 (hex) Apple, Inc.
+9800C6 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+78-7B-8A (hex) Apple, Inc.
+787B8A (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+38-66-F0 (hex) Apple, Inc.
+3866F0 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+20-EE-28 (hex) Apple, Inc.
+20EE28 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+08-F4-AB (hex) Apple, Inc.
+08F4AB (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+8C-85-90 (hex) Apple, Inc.
+8C8590 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+B4-8B-19 (hex) Apple, Inc.
+B48B19 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+E4-9A-79 (hex) Apple, Inc.
+E49A79 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+28-A0-2B (hex) Apple, Inc.
+28A02B (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+B4-4B-D2 (hex) Apple, Inc.
+B44BD2 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+2C-F0-A2 (hex) Apple, Inc.
+2CF0A2 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+EC-AD-B8 (hex) Apple, Inc.
+ECADB8 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+98-01-A7 (hex) Apple, Inc.
+9801A7 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+60-9A-C1 (hex) Apple, Inc.
+609AC1 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+F0-79-60 (hex) Apple, Inc.
+F07960 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+9C-8B-A0 (hex) Apple, Inc.
+9C8BA0 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+4C-32-75 (hex) Apple, Inc.
+4C3275 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+E4-E4-AB (hex) Apple, Inc.
+E4E4AB (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+C8-33-4B (hex) Apple, Inc.
+C8334B (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+00-F4-B9 (hex) Apple, Inc.
+00F4B9 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+0C-77-1A (hex) Apple, Inc.
+0C771A (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+74-E1-B6 (hex) Apple, Inc.
+74E1B6 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+64-20-0C (hex) Apple, Inc.
+64200C (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+C0-84-7A (hex) Apple, Inc.
+C0847A (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+18-34-51 (hex) Apple, Inc.
+183451 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+FC-25-3F (hex) Apple, Inc.
+FC253F (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+10-40-F3 (hex) Apple, Inc.
+1040F3 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+6C-C2-6B (hex) Apple, Inc.
+6CC26B (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+18-20-32 (hex) Apple, Inc.
+182032 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+70-DE-E2 (hex) Apple, Inc.
+70DEE2 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+00-C6-10 (hex) Apple, Inc.
+00C610 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+10-1C-0C (hex) Apple, Inc.
+101C0C (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+7C-FA-DF (hex) Apple, Inc.
+7CFADF (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+5C-F9-38 (hex) Apple, Inc.
+5CF938 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+38-71-DE (hex) Apple, Inc.
+3871DE (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+BC-54-36 (hex) Apple, Inc.
+BC5436 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+9C-4F-DA (hex) Apple, Inc.
+9C4FDA (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+1C-5C-F2 (hex) Apple, Inc.
+1C5CF2 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+60-FB-42 (hex) Apple, Inc.
+60FB42 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+00-25-00 (hex) Apple, Inc.
+002500 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+00-23-6C (hex) Apple, Inc.
+00236C (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+00-21-E9 (hex) Apple, Inc.
+0021E9 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+00-1F-F3 (hex) Apple, Inc.
+001FF3 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+00-1F-5B (hex) Apple, Inc.
+001F5B (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+00-1E-52 (hex) Apple, Inc.
+001E52 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+00-1D-4F (hex) Apple, Inc.
+001D4F (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+00-11-24 (hex) Apple, Inc.
+001124 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+A8-FA-D8 (hex) Apple, Inc.
+A8FAD8 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+5C-96-9D (hex) Apple, Inc.
+5C969D (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+E4-8B-7F (hex) Apple, Inc.
+E48B7F (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+84-FC-FE (hex) Apple, Inc.
+84FCFE (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+44-4C-0C (hex) Apple, Inc.
+444C0C (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+8C-2D-AA (hex) Apple, Inc.
+8C2DAA (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+6C-3E-6D (hex) Apple, Inc.
+6C3E6D (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+18-9E-FC (hex) Apple, Inc.
+189EFC (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+C0-9F-42 (hex) Apple, Inc.
+C09F42 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+B8-F6-B1 (hex) Apple, Inc.
+B8F6B1 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+40-6C-8F (hex) Apple, Inc.
+406C8F (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+A4-D1-D2 (hex) Apple, Inc.
+A4D1D2 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+04-0C-CE (hex) Apple, Inc.
+040CCE (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+D8-9E-3F (hex) Apple, Inc.
+D89E3F (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+28-E7-CF (hex) Apple, Inc.
+28E7CF (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+C8-BC-C8 (hex) Apple, Inc.
+C8BCC8 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+D8-A2-5E (hex) Apple, Inc.
+D8A25E (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+90-84-0D (hex) Apple, Inc.
+90840D (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+F8-1E-DF (hex) Apple, Inc.
+F81EDF (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+B0-CA-68 (hex) Apple, Inc.
+B0CA68 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+98-CA-33 (hex) Apple, Inc.
+98CA33 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+68-EF-43 (hex) Apple, Inc.
+68EF43 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+CC-2D-B7 (hex) Apple, Inc.
+CC2DB7 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+D4-A3-3D (hex) Apple, Inc.
+D4A33D (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+E4-E0-A6 (hex) Apple, Inc.
+E4E0A6 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+70-EF-00 (hex) Apple, Inc.
+70EF00 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+A0-39-EE (hex) Sagemcom Broadband SAS
+A039EE (base 16) Sagemcom Broadband SAS
+ 250, route de l'Empereur
+ Rueil Malmaison Cedex hauts de seine 92848
+ FR
+
+A4-40-27 (hex) zte corporation
+A44027 (base 16) zte corporation
+ 12/F.,zte R&D building ,kejinan Road,Shenzhen,P.R.China
+ shenzhen guangdong 518057
+ CN
+
+1C-11-61 (hex) Ciena Corporation
+1C1161 (base 16) Ciena Corporation
+ 7035 Ridge Road
+ Hanover MD 21076
+ US
+
+4C-82-CF (hex) Dish Technologies Corp
+4C82CF (base 16) Dish Technologies Corp
+ 94 Inverness Terrace E
+ Englewood CO 80112
+ US
+
+F0-C9-D1 (hex) GD Midea Air-Conditioning Equipment Co.,Ltd.
+F0C9D1 (base 16) GD Midea Air-Conditioning Equipment Co.,Ltd.
+ Midea Global Innovation Center,Beijiao Town,Shunde
+ Foshan Guangdong 528311
+ CN
+
+D4-9C-F4 (hex) Palo Alto Networks
+D49CF4 (base 16) Palo Alto Networks
+ 3000 Tannery Way
+ Santa Clara CA 95054
+ US
+
+3C-57-4F (hex) China Mobile Group Device Co.,Ltd.
+3C574F (base 16) China Mobile Group Device Co.,Ltd.
+ 32 Xuanwumen West Street,Xicheng District
+ Beijing 100053
+ CN
+
+50-6B-4B (hex) Mellanox Technologies, Inc.
+506B4B (base 16) Mellanox Technologies, Inc.
+ 350 Oakmead Parkway, Suite 100
+ Sunnyvale CA 94085
+ US
+
+F8-C1-20 (hex) Xi'an Link-Science Technology Co.,Ltd
+F8C120 (base 16) Xi'an Link-Science Technology Co.,Ltd
+ 1/F,Block F,Building zhichao Weilai,No.999,10#Caotan Road,Xi'an
+ xi'an 710016
+ CN
+
+90-3A-72 (hex) Ruckus Wireless
+903A72 (base 16) Ruckus Wireless
+ 350 West Java Drive
+ Sunnyvale CA 94089
+ US
+
+3C-E8-24 (hex) HUAWEI TECHNOLOGIES CO.,LTD
+3CE824 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
+ CN
+
+E8-AB-F3 (hex) HUAWEI TECHNOLOGIES CO.,LTD
+E8ABF3 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
+ CN
+
+70-06-AC (hex) Eastcompeace Technology Co., Ltd
+7006AC (base 16) Eastcompeace Technology Co., Ltd
+ Number 8 Pinggong Zhong Road,Nanping S&T Industry Community,Zhuhai,Guangdong,519060 China
+ Zhuhai Guangdong 519060
+ CN
+
+50-6F-77 (hex) HUAWEI TECHNOLOGIES CO.,LTD
+506F77 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
+ CN
+
+2C-95-69 (hex) ARRIS Group, Inc.
+2C9569 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+50-95-51 (hex) ARRIS Group, Inc.
+509551 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+60-98-13 (hex) Shanghai Visking Digital Technology Co. LTD
+609813 (base 16) Shanghai Visking Digital Technology Co. LTD
+ Room 1301, Building A8, No.1688 Guoquan North Road, Yangpu District
+ Shanghai 200082
+ CN
+
+8C-4C-AD (hex) Evoluzn Inc.
+8C4CAD (base 16) Evoluzn Inc.
+ 34 Samoset Lane
+ Schaumburg IL 60193
+ US
+
+A4-D4-B2 (hex) Shenzhen MeiG Smart Technology Co.,Ltd
+A4D4B2 (base 16) Shenzhen MeiG Smart Technology Co.,Ltd
+ #88 Qinjiang Road, Xuhui District
+ Shanghai 200233
+ CN
+
+DC-E5-33 (hex) IEEE Registration Authority
+DCE533 (base 16) IEEE Registration Authority
+ 445 Hoes Lane
+ Piscataway NJ 08554
+ US
+
+8C-F7-10 (hex) AMPAK Technology, Inc.
+8CF710 (base 16) AMPAK Technology, Inc.
+ No.1,Jen Ai Road Hsinchu Industrial Park, Hukou
+ Hsinchu Taiwan ROC. 30352
+ TW
+
+38-E1-AA (hex) zte corporation
+38E1AA (base 16) zte corporation
+ 12/F.,zte R&D building ,kejinan Road,Shenzhen,P.R.China
+ shenzhen guangdong 518057
+ CN
+
+18-A2-8A (hex) Essel-T Co., Ltd
+18A28A (base 16) Essel-T Co., Ltd
+ 1211 kranztechno, 388 Dunchon-daero
+ Seongnam-si Jungwon-gu, Gyeonggi-do 13403
+ KR
+
+38-DE-AD (hex) Intel Corporate
+38DEAD (base 16) Intel Corporate
+ Lot 8, Jalan Hi-Tech 2/3
+ Kulim Kedah 09000
+ MY
+
+74-E1-82 (hex) Texas Instruments
+74E182 (base 16) Texas Instruments
+ 12500 TI Blvd
+ Dallas TX 75243
+ US
+
+40-BD-32 (hex) Texas Instruments
+40BD32 (base 16) Texas Instruments
+ 12500 TI Blvd
+ Dallas TX 75243
+ US
+
+3C-17-10 (hex) Sagemcom Broadband SAS
+3C1710 (base 16) Sagemcom Broadband SAS
+ 250, route de l'Empereur
+ Rueil Malmaison Cedex hauts de seine 92848
+ FR
+
+C8-FA-E1 (hex) ARQ Digital LLC
+C8FAE1 (base 16) ARQ Digital LLC
+ 2430 Auto Park Way
+ Escondido CA 92029
+ US
+
+80-AD-16 (hex) Xiaomi Communications Co Ltd
+80AD16 (base 16) Xiaomi Communications Co Ltd
+ The Rainbow City of China Resources
+ NO.68, Qinghe Middle Street Haidian District, Beijing 100085
+ CN
+
+04-4E-AF (hex) LG Innotek
+044EAF (base 16) LG Innotek
+ 26, Hanamsandan 5beon-ro
+ Gwangju Gwangsan-gu 506-731
+ KR
+
+DC-A3-33 (hex) Shenzhen YOUHUA Technology Co., Ltd
+DCA333 (base 16) Shenzhen YOUHUA Technology Co., Ltd
+ Room 407 Shenzhen University-town Business Park,Lishan Road,Taoyuan Street,Nanshan District
+ Shenzhen Guangdong 518055
+ CN
+
+BC-DD-C2 (hex) Espressif Inc.
+BCDDC2 (base 16) Espressif Inc.
+ Room 204, Building 2, 690 Bibo Road, Pudong New Area
+ Shanghai Shanghai 201203
+ CN
+
+FC-7C-02 (hex) Phicomm (Shanghai) Co., Ltd.
+FC7C02 (base 16) Phicomm (Shanghai) Co., Ltd.
+ 3666 SiXian Rd.,Songjiang District
+ Shanghai Shanghai 201616
+ CN
+
+88-A9-A7 (hex) IEEE Registration Authority
+88A9A7 (base 16) IEEE Registration Authority
+ 445 Hoes Lane
+ Piscataway NJ 08554
+ US
+
+F0-E3-DC (hex) Tecon MT, LLC
+F0E3DC (base 16) Tecon MT, LLC
+ 3rd Khoroshevskaya st - 20
+ Moscow 123298
+ RU
+
+30-B2-16 (hex) ABB AG - Power Grids - Grid Automation
+30B216 (base 16) ABB AG - Power Grids - Grid Automation
+ Kallstadter Strasse 1
+ Mannheim 68309
+ DE
+
+00-D0-CE (hex) iSystem Labs
+00D0CE (base 16) iSystem Labs
+ BRODISCE 7, 10C
+ Trzin 1236
+ SI
+
+00-BE-75 (hex) Cisco Systems, Inc
+00BE75 (base 16) Cisco Systems, Inc
+ 80 West Tasman Drive
+ San Jose CA 94568
+ US
+
+50-4E-DC (hex) Ping Communication
+504EDC (base 16) Ping Communication
+ Brenden 18
+ Appenzell Meistersrüte AI 9050
+ CH
+
+20-67-7C (hex) Hewlett Packard Enterprise
+20677C (base 16) Hewlett Packard Enterprise
+ 8000 Foothills Blvd.
+ Roseville CA 95747
+ US
+
+C4-2C-4F (hex) Qingdao Hisense Mobile Communication Technology Co,Ltd
+C42C4F (base 16) Qingdao Hisense Mobile Communication Technology Co,Ltd
+ No.399, Song Ling Road
+ Qingdao Shandong 266100
+ CN
+
+24-CA-CB (hex) Fiberhome Telecommunication Technologies Co.,LTD
+24CACB (base 16) Fiberhome Telecommunication Technologies Co.,LTD
+ No.5 DongXin Road
+ Wuhan Hubei 430074
+ CN
+
+24-0A-63 (hex) ARRIS Group, Inc.
+240A63 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+44-FF-BA (hex) zte corporation
+44FFBA (base 16) zte corporation
+ 12/F.,zte R&D building ,kejinan Road,Shenzhen,P.R.China
+ shenzhen guangdong 518057
+ CN
+
+00-23-A8 (hex) Marshall Electronics
+0023A8 (base 16) Marshall Electronics
+ 20608 Madrona Ave
+ Torrance CA 90503
+ US
+
+B4-81-BF (hex) Meta-Networks, LLC
+B481BF (base 16) Meta-Networks, LLC
+ Office 106C, 5/2, Varshavskaya street
+ Saint-Petersburg Saint-Petersburg 196128
+ RU
+
+10-1D-51 (hex) 8Mesh Networks
+101D51 (base 16) 8Mesh Networks
+ Unit 607, 6/F, Yen Sheng Centre,
+ 64 Hoi Yuen Road Kwun Tong 000
+ HK
+
+0C-AE-7D (hex) Texas Instruments
+0CAE7D (base 16) Texas Instruments
+ 12500 TI Blvd
+ Dallas TX 75243
+ US
+
D8-6C-E9 (hex) Sagemcom Broadband SAS
D86CE9 (base 16) Sagemcom Broadband SAS
250 route de l'Empereur
@@ -85901,18 +86933,6 @@ D86CE9 (base 16) Sagemcom Broadband SAS
Irvine CA 92612
US
-6C-8D-C1 (hex) Apple, Inc.
-6C8DC1 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-38-CA-DA (hex) Apple, Inc.
-38CADA (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
8C-57-9B (hex) Wistron Neweb Corporation
8C579B (base 16) Wistron Neweb Corporation
No.20,Park Avenue II,Hsinchu Science Park
@@ -85943,18 +86963,6 @@ B436A9 (base 16) Fibocom Wireless Inc.
Dongguan Guangdong 523808
CN
-68-DB-CA (hex) Apple, Inc.
-68DBCA (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-04-4B-ED (hex) Apple, Inc.
-044BED (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
3C-BB-73 (hex) Shenzhen Xinguodu Technology Co., Ltd.
3CBB73 (base 16) Shenzhen Xinguodu Technology Co., Ltd.
F17A, JinSong Building, Tairan Industrial & Trade Park, Chegongmiao, Shennan Road,Futian District
@@ -86339,18 +87347,6 @@ EC52DC (base 16) WORLD MEDIA AND TECHNOLOGY Corp.
Miami 33132
US
-A4-D1-8C (hex) Apple, Inc.
-A4D18C (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-CC-25-EF (hex) Apple, Inc.
-CC25EF (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
24-09-95 (hex) HUAWEI TECHNOLOGIES CO.,LTD
240995 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
@@ -86897,78 +87893,6 @@ FC9947 (base 16) Cisco Systems, Inc
San Jose CA 95134
US
-7C-C5-37 (hex) Apple, Inc.
-7CC537 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-70-CD-60 (hex) Apple, Inc.
-70CD60 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-24-AB-81 (hex) Apple, Inc.
-24AB81 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-58-1F-AA (hex) Apple, Inc.
-581FAA (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-A4-67-06 (hex) Apple, Inc.
-A46706 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-3C-07-54 (hex) Apple, Inc.
-3C0754 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-E4-CE-8F (hex) Apple, Inc.
-E4CE8F (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-E8-04-0B (hex) Apple, Inc.
-E8040B (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-B8-C7-5D (hex) Apple, Inc.
-B8C75D (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-40-3C-FC (hex) Apple, Inc.
-403CFC (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-28-6A-B8 (hex) Apple, Inc.
-286AB8 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-7C-C3-A1 (hex) Apple, Inc.
-7CC3A1 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
00-E1-6D (hex) Cisco Systems, Inc
00E16D (base 16) Cisco Systems, Inc
170 West Tasman Drive
@@ -87029,84 +87953,6 @@ E0D173 (base 16) Cisco Systems, Inc
San Jose CA 95134
US
-B8-78-2E (hex) Apple, Inc.
-B8782E (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-00-05-02 (hex) Apple, Inc.
-000502 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-00-10-FA (hex) Apple, Inc.
-0010FA (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-00-03-93 (hex) Apple, Inc.
-000393 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-00-16-CB (hex) Apple, Inc.
-0016CB (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-00-17-F2 (hex) Apple, Inc.
-0017F2 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-00-1B-63 (hex) Apple, Inc.
-001B63 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-00-1E-C2 (hex) Apple, Inc.
-001EC2 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-00-26-08 (hex) Apple, Inc.
-002608 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-7C-6D-62 (hex) Apple, Inc.
-7C6D62 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-40-D3-2D (hex) Apple, Inc.
-40D32D (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-D8-30-62 (hex) Apple, Inc.
-D83062 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-C4-2C-03 (hex) Apple, Inc.
-C42C03 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
6C-20-56 (hex) Cisco Systems, Inc
6C2056 (base 16) Cisco Systems, Inc
170 West Tasman Drive
@@ -87149,54 +87995,6 @@ F872EA (base 16) Cisco Systems, Inc
San Jose CA 95134
US
-78-9F-70 (hex) Apple, Inc.
-789F70 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-DC-37-14 (hex) Apple, Inc.
-DC3714 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-40-33-1A (hex) Apple, Inc.
-40331A (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-94-F6-A3 (hex) Apple, Inc.
-94F6A3 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-D8-1D-72 (hex) Apple, Inc.
-D81D72 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-70-EC-E4 (hex) Apple, Inc.
-70ECE4 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-38-C9-86 (hex) Apple, Inc.
-38C986 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-FC-FC-48 (hex) Apple, Inc.
-FCFC48 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
28-57-BE (hex) Hangzhou Hikvision Digital Technology Co.,Ltd.
2857BE (base 16) Hangzhou Hikvision Digital Technology Co.,Ltd.
No.469,Jianghui Road
@@ -87221,258 +88019,6 @@ F0F249 (base 16) Hitron Technologies. Inc
Hsin-chu Taiwan 300
TW
-A4-C3-61 (hex) Apple, Inc.
-A4C361 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-AC-7F-3E (hex) Apple, Inc.
-AC7F3E (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-28-0B-5C (hex) Apple, Inc.
-280B5C (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-90-B9-31 (hex) Apple, Inc.
-90B931 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-24-A2-E1 (hex) Apple, Inc.
-24A2E1 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-80-EA-96 (hex) Apple, Inc.
-80EA96 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-60-03-08 (hex) Apple, Inc.
-600308 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-04-F1-3E (hex) Apple, Inc.
-04F13E (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-54-72-4F (hex) Apple, Inc.
-54724F (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-48-74-6E (hex) Apple, Inc.
-48746E (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-3C-AB-8E (hex) Apple, Inc.
-3CAB8E (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-7C-6D-F8 (hex) Apple, Inc.
-7C6DF8 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-48-D7-05 (hex) Apple, Inc.
-48D705 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-3C-D0-F8 (hex) Apple, Inc.
-3CD0F8 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-98-D6-BB (hex) Apple, Inc.
-98D6BB (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-4C-B1-99 (hex) Apple, Inc.
-4CB199 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-64-E6-82 (hex) Apple, Inc.
-64E682 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-80-49-71 (hex) Apple, Inc.
-804971 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-98-FE-94 (hex) Apple, Inc.
-98FE94 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-D8-00-4D (hex) Apple, Inc.
-D8004D (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-98-B8-E3 (hex) Apple, Inc.
-98B8E3 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-80-92-9F (hex) Apple, Inc.
-80929F (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-88-53-95 (hex) Apple, Inc.
-885395 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-9C-04-EB (hex) Apple, Inc.
-9C04EB (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-78-FD-94 (hex) Apple, Inc.
-78FD94 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-C8-85-50 (hex) Apple, Inc.
-C88550 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-D4-F4-6F (hex) Apple, Inc.
-D4F46F (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-78-7E-61 (hex) Apple, Inc.
-787E61 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-60-F8-1D (hex) Apple, Inc.
-60F81D (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-4C-7C-5F (hex) Apple, Inc.
-4C7C5F (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-48-E9-F1 (hex) Apple, Inc.
-48E9F1 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-FC-E9-98 (hex) Apple, Inc.
-FCE998 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-F0-99-BF (hex) Apple, Inc.
-F099BF (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-68-64-4B (hex) Apple, Inc.
-68644B (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-A8-96-8A (hex) Apple, Inc.
-A8968A (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-4C-8D-79 (hex) Apple, Inc.
-4C8D79 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-20-7D-74 (hex) Apple, Inc.
-207D74 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-F4-F1-5A (hex) Apple, Inc.
-F4F15A (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-04-26-65 (hex) Apple, Inc.
-042665 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-2C-B4-3A (hex) Apple, Inc.
-2CB43A (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-68-9C-70 (hex) Apple, Inc.
-689C70 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-08-70-45 (hex) Apple, Inc.
-087045 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
CC-E0-C3 (hex) Mangstor, Inc.
CCE0C3 (base 16) Mangstor, Inc.
108 Wild Basin Rd
@@ -87635,24 +88181,6 @@ D0C193 (base 16) SKYBELL, INC
IRVINE CA 92618
US
-20-9B-CD (hex) Apple, Inc.
-209BCD (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-F0-B0-E7 (hex) Apple, Inc.
-F0B0E7 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-CC-20-E8 (hex) Apple, Inc.
-CC20E8 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
E4-35-C8 (hex) HUAWEI TECHNOLOGIES CO.,LTD
E435C8 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
@@ -89003,12 +89531,6 @@ B0D7C5 (base 16) Logipix Ltd
Budapest - 1158
HU
-38-C9-A9 (hex) SMART High Reliability Solutions, Inc.
-38C9A9 (base 16) SMART High Reliability Solutions, Inc.
- 2600 W. Geronimo Place
- Chandler AZ 85224
- US
-
BC-1A-67 (hex) YF Technology Co., Ltd
BC1A67 (base 16) YF Technology Co., Ltd
No.62,South Fumin Road,
@@ -90650,12 +91172,6 @@ CC262D (base 16) Verifi, LLC
Hangzhou Zhejiang 310013
CN
-7C-B2-32 (hex) Hui Zhou Gaoshengda Technology Co.,LTD
-7CB232 (base 16) Hui Zhou Gaoshengda Technology Co.,LTD
- No.75,Zhongkai High-Tech Development District,Huizhou
- Hui Zhou Guangdong 516006
- CN
-
54-DF-63 (hex) Intrakey technologies GmbH
54DF63 (base 16) Intrakey technologies GmbH
Wiener Strasse 114-116
@@ -93251,12 +93767,6 @@ A04041 (base 16) SAMWONFA Co.,Ltd.
Busan 608-042
KR
-78-8C-54 (hex) Eltek Technologies LTD
-788C54 (base 16) Eltek Technologies LTD
- Glatt Tower
- 8301 Glattzentrum ZH
- CH
-
94-11-DA (hex) ITF Fröschl GmbH
9411DA (base 16) ITF Fröschl GmbH
Hauserbachstraße 9
@@ -93353,12 +93863,6 @@ AC6123 (base 16) Drivven, Inc.
Seoul 153-793
KR
-D4-66-A8 (hex) Riedo Networks GmbH
-D466A8 (base 16) Riedo Networks GmbH
- Warpelstrasse 10
- Duedingen FR 3186
- CH
-
98-E1-65 (hex) Accutome
98E165 (base 16) Accutome
3222 Phoenixville Pike
@@ -97142,12 +97646,6 @@ EC3091 (base 16) Cisco Systems, Inc
Aalen Baden-Württemberg 73434
DE
-00-1B-D9 (hex) Edgewater Computer Systems
-001BD9 (base 16) Edgewater Computer Systems
- 1125 Innovation Drive
- Ottawa Ontario K2K-3G6
- CA
-
00-1B-DB (hex) Valeo VECS
001BDB (base 16) Valeo VECS
2 Avenue Fernand Pouillon
@@ -109082,12 +109580,6 @@ DC0077 (base 16) TP-LINK TECHNOLOGIES CO.,LTD.
Yokohama, Kanagawa 231-0021
JP
-F4-5C-89 (hex) Apple, Inc.
-F45C89 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
00-21-FD (hex) LACROIX TRAFFIC S.A.U
0021FD (base 16) LACROIX TRAFFIC S.A.U
Majada 4
@@ -109124,24 +109616,6 @@ F45C89 (base 16) Apple, Inc.
Sydney NSW 2000
AU
-BC-EC-5D (hex) Apple, Inc.
-BCEC5D (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-DC-41-5F (hex) Apple, Inc.
-DC415F (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-30-63-6B (hex) Apple, Inc.
-30636B (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
84-68-3E (hex) Intel Corporate
84683E (base 16) Intel Corporate
Lot 8, Jalan Hi-Tech 2/3
@@ -109622,12 +110096,6 @@ BC7574 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
Gyeonggi-Do 14523
KR
-A0-67-BE (hex) Sicon srl
-A067BE (base 16) Sicon srl
- Via Sila 1/3
- Isola Vicentina Vicenza 36033
- IT
-
C4-CA-D9 (hex) Hangzhou H3C Technologies Co., Limited
C4CAD9 (base 16) Hangzhou H3C Technologies Co., Limited
310 Liuhe Road, Zhijiang Science Park
@@ -109700,24 +110168,6 @@ C02FF1 (base 16) Volta Networks
Heuchelheim Hessen 35452
DE
-0C-51-01 (hex) Apple, Inc.
-0C5101 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-08-6D-41 (hex) Apple, Inc.
-086D41 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-04-D3-CF (hex) Apple, Inc.
-04D3CF (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
30-C8-2A (hex) WI-BIZ srl
30C82A (base 16) WI-BIZ srl
Via Carlo Ferrero 10
@@ -110696,30 +111146,12 @@ CCA260 (base 16) SICHUAN TIANYI COMHEART TELECOMCO.,LTD
Chengdu Sichuan 610000
CN
-20-3C-AE (hex) Apple, Inc.
-203CAE (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-74-8D-08 (hex) Apple, Inc.
-748D08 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
00-D7-8F (hex) Cisco Systems, Inc
00D78F (base 16) Cisco Systems, Inc
80 West Tasman Drive
San Jose CA 94568
US
-A0-3B-E3 (hex) Apple, Inc.
-A03BE3 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
88-6B-0F (hex) Bluegiga Technologies OY
886B0F (base 16) Bluegiga Technologies OY
P.O. BOX 120
@@ -111812,36 +112244,6 @@ CCA219 (base 16) SHENZHEN ALONG INVESTMENT CO.,LTD
Vienna 1030
AT
-64-B0-A6 (hex) Apple, Inc.
-64B0A6 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-84-FC-AC (hex) Apple, Inc.
-84FCAC (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-6C-19-C0 (hex) Apple, Inc.
-6C19C0 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-20-AB-37 (hex) Apple, Inc.
-20AB37 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-18-65-90 (hex) Apple, Inc.
-186590 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
2C-0B-E9 (hex) Cisco Systems, Inc
2C0BE9 (base 16) Cisco Systems, Inc
80 West Tasman Drive
@@ -112298,36 +112700,6 @@ A8A198 (base 16) TCT mobile ltd
Round Rock TX 78682
US
-C0-D0-12 (hex) Apple, Inc.
-C0D012 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-D4-DC-CD (hex) Apple, Inc.
-D4DCCD (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-48-4B-AA (hex) Apple, Inc.
-484BAA (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-F8-03-77 (hex) Apple, Inc.
-F80377 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-14-BD-61 (hex) Apple, Inc.
-14BD61 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
08-27-CE (hex) NAGANO KEIKI CO., LTD.
0827CE (base 16) NAGANO KEIKI CO., LTD.
2150 IKUTA
@@ -113660,24 +114032,6 @@ B8EE0E (base 16) Sagemcom Broadband SAS
Rueil Malmaison Cedex hauts de seine 92848
FR
-78-88-6D (hex) Apple, Inc.
-78886D (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-A8-5C-2C (hex) Apple, Inc.
-A85C2C (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-00-DB-70 (hex) Apple, Inc.
-00DB70 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
38-6E-A2 (hex) vivo Mobile Communication Co., Ltd.
386EA2 (base 16) vivo Mobile Communication Co., Ltd.
#283,BBK Road
@@ -114011,30 +114365,6 @@ F06E0B (base 16) Microsoft Corporation
Zhubei City Hsinchu County 302
TW
-80-B0-3D (hex) Apple, Inc.
-80B03D (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-C8-3C-85 (hex) Apple, Inc.
-C83C85 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-A0-4E-A7 (hex) Apple, Inc.
-A04EA7 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-40-9C-28 (hex) Apple, Inc.
-409C28 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
50-C9-A0 (hex) SKIPPER AS
50C9A0 (base 16) SKIPPER AS
Enebakkvn 150
@@ -114194,6 +114524,222 @@ D4AD2D (base 16) Fiberhome Telecommunication Technologies Co.,LTD
Wuhan Hubei 430074
CN
+68-57-2D (hex) HANGZHOU AIXIANGJI TECHNOLOGY CO., LTD
+68572D (base 16) HANGZHOU AIXIANGJI TECHNOLOGY CO., LTD
+ 7 Floor, 3 Blvd., More Centre, 87 Gudun Rd., Xihu District
+ Hangzhou Zhejiang 310012
+ CN
+
+F0-B0-E7 (hex) Apple, Inc.
+F0B0E7 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+20-9B-CD (hex) Apple, Inc.
+209BCD (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+CC-20-E8 (hex) Apple, Inc.
+CC20E8 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+10-C2-5A (hex) Technicolor CH USA Inc.
+10C25A (base 16) Technicolor CH USA Inc.
+ 101 West 103rd St.
+ Indianapolis IN 46290
+ US
+
+8C-59-73 (hex) Zyxel Communications Corporation
+8C5973 (base 16) Zyxel Communications Corporation
+ No. 6 Innovation Road II, Science Park
+ Hsichu Taiwan 300
+ TW
+
+94-FE-9D (hex) SHENZHEN GONGJIN ELECTRONICS CO.,LT
+94FE9D (base 16) SHENZHEN GONGJIN ELECTRONICS CO.,LT
+ SONGGANG
+ SHENZHEN GUANGDONG 518105
+ CN
+
+04-D1-3A (hex) Xiaomi Communications Co Ltd
+04D13A (base 16) Xiaomi Communications Co Ltd
+ The Rainbow City of China Resources
+ NO.68, Qinghe Middle Street Haidian District, Beijing 100085
+ CN
+
+24-7E-12 (hex) Cisco Systems, Inc
+247E12 (base 16) Cisco Systems, Inc
+ 80 West Tasman Drive
+ San Jose CA 94568
+ US
+
+E4-2D-7B (hex) China Mobile IOT Company Limited
+E42D7B (base 16) China Mobile IOT Company Limited
+ NO.8 Yu Ma Road, NanAn Area Chongqing,China
+ Chongqing Chongqing 401336
+ CN
+
+04-EC-BB (hex) Fiberhome Telecommunication Technologies Co.,LTD
+04ECBB (base 16) Fiberhome Telecommunication Technologies Co.,LTD
+ No.5 DongXin Road
+ Wuhan Hubei 430074
+ CN
+
+0C-54-15 (hex) Intel Corporate
+0C5415 (base 16) Intel Corporate
+ Lot 8, Jalan Hi-Tech 2/3
+ Kulim Kedah 09000
+ MY
+
+84-DB-9E (hex) Aifloo AB
+84DB9E (base 16) Aifloo AB
+ Postbox 2005
+ Stockholm 10311
+ SE
+
+B0-B3-AD (hex) HUMAX Co., Ltd.
+B0B3AD (base 16) HUMAX Co., Ltd.
+ HUMAX Village, 216, Hwangsaeul-ro, Bu
+ Seongnam-si Gyeonggi-do 463-875
+ KR
+
+38-78-62 (hex) Sony Mobile Communications AB
+387862 (base 16) Sony Mobile Communications AB
+ Nya Vattentornet
+ Lund SE 22128
+ SE
+
+18-31-BF (hex) ASUSTek COMPUTER INC.
+1831BF (base 16) ASUSTek COMPUTER INC.
+ 15,Li-Te Rd., Peitou, Taipei 112, Taiwan
+ Taipei Taiwan 112
+ TW
+
+7C-25-86 (hex) Juniper Networks
+7C2586 (base 16) Juniper Networks
+ 1133 Innovation Way
+ Sunnyvale CA 94089
+ US
+
+00-1B-D9 (hex) Edgewater Wireless Systems Inc
+001BD9 (base 16) Edgewater Wireless Systems Inc
+ 50 HInes Road Suite 200
+ Ottawa Ontario K2K-2M5
+ CA
+
+54-3E-64 (hex) Fiberhome Telecommunication Technologies Co.,LTD
+543E64 (base 16) Fiberhome Telecommunication Technologies Co.,LTD
+ No.5 DongXin Road
+ Wuhan Hubei 430074
+ CN
+
+D4-F7-86 (hex) Fiberhome Telecommunication Technologies Co.,LTD
+D4F786 (base 16) Fiberhome Telecommunication Technologies Co.,LTD
+ No.5 DongXin Road
+ Wuhan Hubei 430074
+ CN
+
+64-02-CB (hex) ARRIS Group, Inc.
+6402CB (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+F0-FC-C8 (hex) ARRIS Group, Inc.
+F0FCC8 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+EC-7F-C6 (hex) ECCEL CORPORATION SAS
+EC7FC6 (base 16) ECCEL CORPORATION SAS
+ CRA 106 15A 25 LT 88 MZ 17 BG 1, ZONA FRANCA BOGOTA
+ BOGOTA D.C. 110921
+ CO
+
+A4-33-D7 (hex) MitraStar Technology Corp.
+A433D7 (base 16) MitraStar Technology Corp.
+ No. 6, Innovation Road II,
+ Hsinchu 300
+ TW
+
+B0-AC-D2 (hex) zte corporation
+B0ACD2 (base 16) zte corporation
+ 12/F.,zte R&D building ,kejinan Road,Shenzhen,P.R.China
+ shenzhen guangdong 518057
+ CN
+
+7C-2A-31 (hex) Intel Corporate
+7C2A31 (base 16) Intel Corporate
+ Lot 8, Jalan Hi-Tech 2/3
+ Kulim Kedah 09000
+ MY
+
+0C-F3-46 (hex) Xiaomi Communications Co Ltd
+0CF346 (base 16) Xiaomi Communications Co Ltd
+ The Rainbow City of China Resources
+ NO.68, Qinghe Middle Street Haidian District, Beijing 100085
+ CN
+
+20-2D-23 (hex) Collinear Networks Inc.
+202D23 (base 16) Collinear Networks Inc.
+ 2901 Tasman Drive
+ Santa Clara CA 95054
+ US
+
+48-18-FA (hex) Nocsys
+4818FA (base 16) Nocsys
+ 1F, No. 63 Building, No. 421 Hong Cao Road, Xuhui District
+ Shanghai Shanghai 200233
+ CN
+
+78-0F-77 (hex) HangZhou Gubei Electronics Technology Co.,Ltd
+780F77 (base 16) HangZhou Gubei Electronics Technology Co.,Ltd
+ HangZhou City, Zhejiang province Binjiang District Jiang Hong Road 611 Building 1 room 106
+ Hangzhou ZheJiang 310052
+ CN
+
+0C-08-B4 (hex) HUMAX Co., Ltd.
+0C08B4 (base 16) HUMAX Co., Ltd.
+ HUMAX Village, 216, Hwangsaeul-ro, Bu
+ Seongnam-si Gyeonggi-do 463-875
+ KR
+
+00-BF-77 (hex) Cisco Systems, Inc
+00BF77 (base 16) Cisco Systems, Inc
+ 80 West Tasman Drive
+ San Jose CA 94568
+ US
+
+00-3D-E8 (hex) LG Electronics (Mobile Communications)
+003DE8 (base 16) LG Electronics (Mobile Communications)
+ 60-39, Gasan-dong, Geumcheon-gu
+ Seoul 153-801
+ KR
+
+00-2F-D9 (hex) Fiberhome Telecommunication Technologies Co.,LTD
+002FD9 (base 16) Fiberhome Telecommunication Technologies Co.,LTD
+ No.5 DongXin Road
+ Wuhan Hubei 430074
+ CN
+
+88-5F-E8 (hex) IEEE Registration Authority
+885FE8 (base 16) IEEE Registration Authority
+ 445 Hoes Lane
+ Piscataway NJ 08554
+ US
+
+A0-67-BE (hex) Sicon srl
+A067BE (base 16) Sicon srl
+ Via Sila 1/3
+ Isola Vicentina Vicenza 36033
+ IT
+
54-C5-7A (hex) Sunnovo International Limited
54C57A (base 16) Sunnovo International Limited
1717 Haitai Building
@@ -114533,6 +115079,888 @@ B42D56 (base 16) Extreme Networks, Inc.
Seongnam-si Gyeonggi-do 463-875
KR
+48-74-6E (hex) Apple, Inc.
+48746E (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+54-72-4F (hex) Apple, Inc.
+54724F (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+04-F1-3E (hex) Apple, Inc.
+04F13E (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+60-03-08 (hex) Apple, Inc.
+600308 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+80-EA-96 (hex) Apple, Inc.
+80EA96 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+24-A2-E1 (hex) Apple, Inc.
+24A2E1 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+90-B9-31 (hex) Apple, Inc.
+90B931 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+28-0B-5C (hex) Apple, Inc.
+280B5C (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+A8-96-8A (hex) Apple, Inc.
+A8968A (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+9C-04-EB (hex) Apple, Inc.
+9C04EB (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+88-53-95 (hex) Apple, Inc.
+885395 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+80-92-9F (hex) Apple, Inc.
+80929F (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+98-B8-E3 (hex) Apple, Inc.
+98B8E3 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+D8-00-4D (hex) Apple, Inc.
+D8004D (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+98-FE-94 (hex) Apple, Inc.
+98FE94 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+68-64-4B (hex) Apple, Inc.
+68644B (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+F0-99-BF (hex) Apple, Inc.
+F099BF (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+FC-E9-98 (hex) Apple, Inc.
+FCE998 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+48-E9-F1 (hex) Apple, Inc.
+48E9F1 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+4C-7C-5F (hex) Apple, Inc.
+4C7C5F (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+60-F8-1D (hex) Apple, Inc.
+60F81D (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+68-9C-70 (hex) Apple, Inc.
+689C70 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+2C-B4-3A (hex) Apple, Inc.
+2CB43A (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+04-26-65 (hex) Apple, Inc.
+042665 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+F4-F1-5A (hex) Apple, Inc.
+F4F15A (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+20-7D-74 (hex) Apple, Inc.
+207D74 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+4C-8D-79 (hex) Apple, Inc.
+4C8D79 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+FC-FC-48 (hex) Apple, Inc.
+FCFC48 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+38-C9-86 (hex) Apple, Inc.
+38C986 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+70-EC-E4 (hex) Apple, Inc.
+70ECE4 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+D8-1D-72 (hex) Apple, Inc.
+D81D72 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+94-F6-A3 (hex) Apple, Inc.
+94F6A3 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+78-FD-94 (hex) Apple, Inc.
+78FD94 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+48-D7-05 (hex) Apple, Inc.
+48D705 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+7C-6D-F8 (hex) Apple, Inc.
+7C6DF8 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+3C-AB-8E (hex) Apple, Inc.
+3CAB8E (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+78-7E-61 (hex) Apple, Inc.
+787E61 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+D4-F4-6F (hex) Apple, Inc.
+D4F46F (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+C8-85-50 (hex) Apple, Inc.
+C88550 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+AC-7F-3E (hex) Apple, Inc.
+AC7F3E (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+A4-C3-61 (hex) Apple, Inc.
+A4C361 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+08-70-45 (hex) Apple, Inc.
+087045 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+40-33-1A (hex) Apple, Inc.
+40331A (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+DC-37-14 (hex) Apple, Inc.
+DC3714 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+78-9F-70 (hex) Apple, Inc.
+789F70 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+64-B0-A6 (hex) Apple, Inc.
+64B0A6 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+84-FC-AC (hex) Apple, Inc.
+84FCAC (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+6C-19-C0 (hex) Apple, Inc.
+6C19C0 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+20-AB-37 (hex) Apple, Inc.
+20AB37 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+C0-D0-12 (hex) Apple, Inc.
+C0D012 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+D4-DC-CD (hex) Apple, Inc.
+D4DCCD (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+48-4B-AA (hex) Apple, Inc.
+484BAA (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+F8-03-77 (hex) Apple, Inc.
+F80377 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+14-BD-61 (hex) Apple, Inc.
+14BD61 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+78-88-6D (hex) Apple, Inc.
+78886D (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+A8-5C-2C (hex) Apple, Inc.
+A85C2C (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+00-DB-70 (hex) Apple, Inc.
+00DB70 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+BC-EC-5D (hex) Apple, Inc.
+BCEC5D (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+DC-41-5F (hex) Apple, Inc.
+DC415F (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+30-63-6B (hex) Apple, Inc.
+30636B (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+0C-51-01 (hex) Apple, Inc.
+0C5101 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+08-6D-41 (hex) Apple, Inc.
+086D41 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+04-D3-CF (hex) Apple, Inc.
+04D3CF (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+20-3C-AE (hex) Apple, Inc.
+203CAE (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+74-8D-08 (hex) Apple, Inc.
+748D08 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+A0-3B-E3 (hex) Apple, Inc.
+A03BE3 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+18-65-90 (hex) Apple, Inc.
+186590 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+00-10-FA (hex) Apple, Inc.
+0010FA (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+00-05-02 (hex) Apple, Inc.
+000502 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+B8-78-2E (hex) Apple, Inc.
+B8782E (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+A4-D1-8C (hex) Apple, Inc.
+A4D18C (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+CC-25-EF (hex) Apple, Inc.
+CC25EF (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+68-DB-CA (hex) Apple, Inc.
+68DBCA (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+04-4B-ED (hex) Apple, Inc.
+044BED (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+6C-8D-C1 (hex) Apple, Inc.
+6C8DC1 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+38-CA-DA (hex) Apple, Inc.
+38CADA (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+F4-5C-89 (hex) Apple, Inc.
+F45C89 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+58-1F-AA (hex) Apple, Inc.
+581FAA (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+24-AB-81 (hex) Apple, Inc.
+24AB81 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+70-CD-60 (hex) Apple, Inc.
+70CD60 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+7C-C5-37 (hex) Apple, Inc.
+7CC537 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+C4-2C-03 (hex) Apple, Inc.
+C42C03 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+D8-30-62 (hex) Apple, Inc.
+D83062 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+40-D3-2D (hex) Apple, Inc.
+40D32D (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+7C-6D-62 (hex) Apple, Inc.
+7C6D62 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+28-6A-B8 (hex) Apple, Inc.
+286AB8 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+40-3C-FC (hex) Apple, Inc.
+403CFC (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+B8-C7-5D (hex) Apple, Inc.
+B8C75D (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+E8-04-0B (hex) Apple, Inc.
+E8040B (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+E4-CE-8F (hex) Apple, Inc.
+E4CE8F (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+3C-07-54 (hex) Apple, Inc.
+3C0754 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+A4-67-06 (hex) Apple, Inc.
+A46706 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+80-B0-3D (hex) Apple, Inc.
+80B03D (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+C8-3C-85 (hex) Apple, Inc.
+C83C85 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+A0-4E-A7 (hex) Apple, Inc.
+A04EA7 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+40-9C-28 (hex) Apple, Inc.
+409C28 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+08-E6-89 (hex) Apple, Inc.
+08E689 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+4C-B1-99 (hex) Apple, Inc.
+4CB199 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+98-D6-BB (hex) Apple, Inc.
+98D6BB (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+3C-D0-F8 (hex) Apple, Inc.
+3CD0F8 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+7C-C3-A1 (hex) Apple, Inc.
+7CC3A1 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+00-26-08 (hex) Apple, Inc.
+002608 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+00-1E-C2 (hex) Apple, Inc.
+001EC2 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+00-1B-63 (hex) Apple, Inc.
+001B63 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+00-17-F2 (hex) Apple, Inc.
+0017F2 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+00-16-CB (hex) Apple, Inc.
+0016CB (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+00-03-93 (hex) Apple, Inc.
+000393 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+80-49-71 (hex) Apple, Inc.
+804971 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+64-E6-82 (hex) Apple, Inc.
+64E682 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+B4-F7-A1 (hex) LG Electronics (Mobile Communications)
+B4F7A1 (base 16) LG Electronics (Mobile Communications)
+ 60-39, Gasan-dong, Geumcheon-gu
+ Seoul 153-801
+ KR
+
+C0-A8-F0 (hex) Adamson Systems Engineering
+C0A8F0 (base 16) Adamson Systems Engineering
+ 1401 Scugog Line 6
+ Port Perry Ontario L9L 1B2
+ CA
+
+38-C9-A9 (hex) SMART High Reliability Solutions, Inc.
+38C9A9 (base 16) SMART High Reliability Solutions, Inc.
+ 1325 N Fiesta Blvd., #101
+ Gilbert AZ 85233
+ US
+
+28-3B-82 (hex) D-Link International
+283B82 (base 16) D-Link International
+ 1 Internal Business Park, #03-12,The Synergy, Singapore
+ Singapore Singapore 609917
+ SG
+
+C4-00-AD (hex) Advantech Technology (CHINA) Co., Ltd.
+C400AD (base 16) Advantech Technology (CHINA) Co., Ltd.
+ No.666, Han-Pu Rd. Yu-Shan
+ Kun-Shan Jiang Su 215316
+ CN
+
+34-5A-06 (hex) SHARP Corporation
+345A06 (base 16) SHARP Corporation
+ 1 Takumi-cho, Sakai-ku
+ Sakai City Osaka 590-8522
+ JP
+
+0C-8B-D3 (hex) ITEL MOBILE LIMITED
+0C8BD3 (base 16) ITEL MOBILE LIMITED
+ RM B3 & B4 BLOCK B, KO FAI INDUSTRIAL BUILDING NO.7 KO FAI ROAD, YAU TONG, KLN, H.K
+ Hong Kong KOWLOON 999077
+ HK
+
+04-AC-44 (hex) Holtek Semiconductor Inc.
+04AC44 (base 16) Holtek Semiconductor Inc.
+ No.3, Creation Rd. II, Science Park
+ Hsinchu 300
+ TW
+
+F4-DC-A5 (hex) DAWON DNS
+F4DCA5 (base 16) DAWON DNS
+ 217ho, Sauphwajiwon-dong, KETI, 226, Cheomdangwagi-ro, Buk-gu
+ Gwangju 61011
+ KR
+
+50-1C-B0 (hex) Cisco Systems, Inc
+501CB0 (base 16) Cisco Systems, Inc
+ 80 West Tasman Drive
+ San Jose CA 94568
+ US
+
+C4-FF-BC (hex) IEEE Registration Authority
+C4FFBC (base 16) IEEE Registration Authority
+ 445 Hoes Lane
+ Piscataway NJ 08554
+ US
+
+78-58-60 (hex) HUAWEI TECHNOLOGIES CO.,LTD
+785860 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
+ CN
+
+F8-90-66 (hex) Nain Inc.
+F89066 (base 16) Nain Inc.
+ Aoyamadai building 902, Shibuya 2-9-10, Shibuya-ku
+ Tokyo 150-0002
+ JP
+
+B4-FB-F9 (hex) HUAWEI TECHNOLOGIES CO.,LTD
+B4FBF9 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
+ CN
+
+B4-2E-F8 (hex) Eline Technology co.Ltd
+B42EF8 (base 16) Eline Technology co.Ltd
+ kangcheng Road, Pharmaceutical Industrical Park, Yuanzhou District
+ Yichun Jiangxi 336000
+ CN
+
+D8-44-5C (hex) DEV Tecnologia Ind Com Man Eq LTDA
+D8445C (base 16) DEV Tecnologia Ind Com Man Eq LTDA
+ Av Prof Lineu Prestes 2242 SL 23
+ Sao Paulo SP 05508000
+ BR
+
+78-5D-C8 (hex) LG Electronics
+785DC8 (base 16) LG Electronics
+ 222 LG-ro, JINWI-MYEON
+ Pyeongtaek-si Gyeonggi-do 451-713
+ KR
+
+7C-39-53 (hex) zte corporation
+7C3953 (base 16) zte corporation
+ 12/F.,zte R&D building ,kejinan Road,Shenzhen,P.R.China
+ shenzhen guangdong 518057
+ CN
+
+48-C7-96 (hex) Samsung Electronics Co.,Ltd
+48C796 (base 16) Samsung Electronics Co.,Ltd
+ #94-1, Imsoo-Dong
+ Gumi Gyeongbuk 730-350
+ KR
+
+80-4E-70 (hex) Samsung Electronics Co.,Ltd
+804E70 (base 16) Samsung Electronics Co.,Ltd
+ #94-1, Imsoo-Dong
+ Gumi Gyeongbuk 730-350
+ KR
+
+4C-EF-C0 (hex) Amazon Technologies Inc.
+4CEFC0 (base 16) Amazon Technologies Inc.
+ P.O Box 8102
+ Reno NV 89507
+ US
+
+D4-6D-6D (hex) Intel Corporate
+D46D6D (base 16) Intel Corporate
+ Lot 8, Jalan Hi-Tech 2/3
+ Kulim Kedah 09000
+ MY
+
+CC-8E-71 (hex) Cisco Systems, Inc
+CC8E71 (base 16) Cisco Systems, Inc
+ 80 West Tasman Drive
+ San Jose CA 94568
+ US
+
+CC-3B-58 (hex) Curiouser Products Inc
+CC3B58 (base 16) Curiouser Products Inc
+ 712 Broadway #4
+ New York NY 10003
+ US
+
+38-F5-54 (hex) HISENSE ELECTRIC CO.,LTD
+38F554 (base 16) HISENSE ELECTRIC CO.,LTD
+ No. 218, Qianwangang Rd
+ Qingdao Shandong 266555
+ CN
+
+18-94-C6 (hex) ShenZhen Chenyee Technology Co., Ltd.
+1894C6 (base 16) ShenZhen Chenyee Technology Co., Ltd.
+ 32F, Tower A, East Pacific International Center, No.7888, Shennan Avenue, Futian District
+ Shenzhen 518040
+ CN
+
+14-A7-2B (hex) currentoptronics Pvt.Ltd
+14A72B (base 16) currentoptronics Pvt.Ltd
+ CRT Building, Jupitor Jn , Near Time kids Koothattukulam - Piravom Rd
+ ERNAKULAM Time Kids day care 686662
+ IN
+
+AC-07-5F (hex) HUAWEI TECHNOLOGIES CO.,LTD
+AC075F (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
+ CN
+
+88-17-A3 (hex) Integrated Device Technology (Malaysia) Sdn. Bhd.
+8817A3 (base 16) Integrated Device Technology (Malaysia) Sdn. Bhd.
+ Phase 3, Bayan Lepas FIZ
+ Bayan Lepas Penang 11900
+ MY
+
+00-71-47 (hex) Amazon Technologies Inc.
+007147 (base 16) Amazon Technologies Inc.
+ P.O Box 8102
+ Reno NV 89507
+ US
+
+78-8C-54 (hex) Ping Communication
+788C54 (base 16) Ping Communication
+ Brenden 18
+ Appenzell Meistersrüte AI 9050
+ CH
+
+D4-66-A8 (hex) Riedo Networks Ltd
+D466A8 (base 16) Riedo Networks Ltd
+ Route de la Fonderie 6
+ Fribourg 1700
+ CH
+
+30-B7-D4 (hex) Hitron Technologies. Inc
+30B7D4 (base 16) Hitron Technologies. Inc
+ No. 1-8, Lising 1st Rd. Hsinchu Science Park, Hsinchu, 300, Taiwan, R.O.C
+ Hsin-chu Taiwan 300
+ TW
+
+38-80-DF (hex) Motorola Mobility LLC, a Lenovo Company
+3880DF (base 16) Motorola Mobility LLC, a Lenovo Company
+ 222 West Merchandise Mart Plaza
+ Chicago IL 60654
+ US
+
+7C-B2-32 (hex) Hui Zhou Gaoshengda Technology Co.,LTD
+7CB232 (base 16) Hui Zhou Gaoshengda Technology Co.,LTD
+ No.75,Zhongkai High-Tech Development District,Huizhou
+ Hui Zhou Guangdong 516006
+ CN
+
+2C-D9-74 (hex) Hui Zhou Gaoshengda Technology Co.,LTD
+2CD974 (base 16) Hui Zhou Gaoshengda Technology Co.,LTD
+ No.75,Zhongkai High-Tech Development District,Huizhou
+ Hui Zhou Guangdong 516006
+ CN
+
+58-B3-FC (hex) SHENZHEN RF-LINK TECHNOLOGY CO.,LTD.
+58B3FC (base 16) SHENZHEN RF-LINK TECHNOLOGY CO.,LTD.
+ Bldg56A,6/F,Baotian Rd3,Xixiang Town,Baoan District,
+ Shenzhen Guangdong 518000
+ CN
+
+BC-AB-7C (hex) TRnP KOREA Co Ltd
+BCAB7C (base 16) TRnP KOREA Co Ltd
+ room1308,239 SoHyungRo,WonMiGu,
+ BuChunCity KyungKiDo 1135
+ KR
+
2C-39-96 (hex) Sagemcom Broadband SAS
2C3996 (base 16) Sagemcom Broadband SAS
250 route de l'Empereur
@@ -114575,42 +116003,6 @@ A0F895 (base 16) Shenzhen TINNO Mobile Technology Corp.
San Jose 95110
US
-28-ED-6A (hex) Apple, Inc.
-28ED6A (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-34-AB-37 (hex) Apple, Inc.
-34AB37 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-60-A3-7D (hex) Apple, Inc.
-60A37D (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-00-56-CD (hex) Apple, Inc.
-0056CD (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-70-81-EB (hex) Apple, Inc.
-7081EB (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-08-66-98 (hex) Apple, Inc.
-086698 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
2C-FD-37 (hex) Blue Calypso, Inc.
2CFD37 (base 16) Blue Calypso, Inc.
101 West Renner RD Suite 280
@@ -115055,12 +116447,6 @@ A4516F (base 16) Microsoft Mobile Oy
Shanghai Shanghai 201616
CN
-90-60-F1 (hex) Apple, Inc.
-9060F1 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
EC-26-CA (hex) TP-LINK TECHNOLOGIES CO.,LTD.
EC26CA (base 16) TP-LINK TECHNOLOGIES CO.,LTD.
Building 24 (floors 1,3,4,5) and 28 (floors1-4) 
@@ -115283,12 +116669,6 @@ A49947 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
Shenzhen Guangdong 518108
CN
-74-1B-B2 (hex) Apple, Inc.
-741BB2 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
00-25-86 (hex) TP-LINK TECHNOLOGIES CO.,LTD.
002586 (base 16) TP-LINK TECHNOLOGIES CO.,LTD.
Building 7, Second Part, Honghualing Industrial Zone
@@ -115355,12 +116735,6 @@ AC7E8A (base 16) Cisco Systems, Inc
San Jose CA 95134
US
-28-CF-E9 (hex) Apple, Inc.
-28CFE9 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
00-50-2A (hex) Cisco Systems, Inc
00502A (base 16) Cisco Systems, Inc
170 W. TASMAN DR.
@@ -115751,480 +117125,12 @@ E8EDF3 (base 16) Cisco Systems, Inc
San Jose CA 95134
US
-E4-25-E7 (hex) Apple, Inc.
-E425E7 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-08-00-07 (hex) Apple, Inc.
-080007 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-00-0A-95 (hex) Apple, Inc.
-000A95 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-00-22-41 (hex) Apple, Inc.
-002241 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-00-23-DF (hex) Apple, Inc.
-0023DF (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-00-25-BC (hex) Apple, Inc.
-0025BC (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-00-26-4A (hex) Apple, Inc.
-00264A (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-00-26-B0 (hex) Apple, Inc.
-0026B0 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-04-1E-64 (hex) Apple, Inc.
-041E64 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-D4-9A-20 (hex) Apple, Inc.
-D49A20 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-90-27-E4 (hex) Apple, Inc.
-9027E4 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-60-33-4B (hex) Apple, Inc.
-60334B (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-A4-31-35 (hex) Apple, Inc.
-A43135 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-9C-35-EB (hex) Apple, Inc.
-9C35EB (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-50-7A-55 (hex) Apple, Inc.
-507A55 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-A0-99-9B (hex) Apple, Inc.
-A0999B (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-24-24-0E (hex) Apple, Inc.
-24240E (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-90-3C-92 (hex) Apple, Inc.
-903C92 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-34-12-98 (hex) Apple, Inc.
-341298 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-9C-29-3F (hex) Apple, Inc.
-9C293F (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
48-8A-D2 (hex) SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD.
488AD2 (base 16) SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD.
Mid-Fourth Flr.,Building 28,Cui Xi Fourth Road,Ke Yuan West,Nanshan
Shenzhen Guangdong 518057
CN
-A8-8E-24 (hex) Apple, Inc.
-A88E24 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-E8-80-2E (hex) Apple, Inc.
-E8802E (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-68-AE-20 (hex) Apple, Inc.
-68AE20 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-E0-B5-2D (hex) Apple, Inc.
-E0B52D (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-80-BE-05 (hex) Apple, Inc.
-80BE05 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-D8-BB-2C (hex) Apple, Inc.
-D8BB2C (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-D0-4F-7E (hex) Apple, Inc.
-D04F7E (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-2C-1F-23 (hex) Apple, Inc.
-2C1F23 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-54-9F-13 (hex) Apple, Inc.
-549F13 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-B8-09-8A (hex) Apple, Inc.
-B8098A (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-F0-DB-E2 (hex) Apple, Inc.
-F0DBE2 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-18-EE-69 (hex) Apple, Inc.
-18EE69 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-74-81-14 (hex) Apple, Inc.
-748114 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-18-F6-43 (hex) Apple, Inc.
-18F643 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-D0-A6-37 (hex) Apple, Inc.
-D0A637 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-A0-18-28 (hex) Apple, Inc.
-A01828 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-D0-03-4B (hex) Apple, Inc.
-D0034B (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-5C-59-48 (hex) Apple, Inc.
-5C5948 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-78-CA-39 (hex) Apple, Inc.
-78CA39 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-18-E7-F4 (hex) Apple, Inc.
-18E7F4 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-B8-FF-61 (hex) Apple, Inc.
-B8FF61 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-DC-2B-61 (hex) Apple, Inc.
-DC2B61 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-10-93-E9 (hex) Apple, Inc.
-1093E9 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-44-2A-60 (hex) Apple, Inc.
-442A60 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-E0-F8-47 (hex) Apple, Inc.
-E0F847 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-14-5A-05 (hex) Apple, Inc.
-145A05 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-28-CF-DA (hex) Apple, Inc.
-28CFDA (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-14-8F-C6 (hex) Apple, Inc.
-148FC6 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-28-37-37 (hex) Apple, Inc.
-283737 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-04-54-53 (hex) Apple, Inc.
-045453 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-F0-CB-A1 (hex) Apple, Inc.
-F0CBA1 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-C0-63-94 (hex) Apple, Inc.
-C06394 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-8C-00-6D (hex) Apple, Inc.
-8C006D (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-B0-9F-BA (hex) Apple, Inc.
-B09FBA (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-DC-86-D8 (hex) Apple, Inc.
-DC86D8 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-8C-29-37 (hex) Apple, Inc.
-8C2937 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-DC-9B-9C (hex) Apple, Inc.
-DC9B9C (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-98-F0-AB (hex) Apple, Inc.
-98F0AB (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-F0-DB-F8 (hex) Apple, Inc.
-F0DBF8 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-AC-CF-5C (hex) Apple, Inc.
-ACCF5C (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-3C-15-C2 (hex) Apple, Inc.
-3C15C2 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-04-48-9A (hex) Apple, Inc.
-04489A (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-D8-CF-9C (hex) Apple, Inc.
-D8CF9C (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-30-F7-C5 (hex) Apple, Inc.
-30F7C5 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-00-88-65 (hex) Apple, Inc.
-008865 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-40-B3-95 (hex) Apple, Inc.
-40B395 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-30-90-AB (hex) Apple, Inc.
-3090AB (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-1C-E6-2B (hex) Apple, Inc.
-1CE62B (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-A0-ED-CD (hex) Apple, Inc.
-A0EDCD (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-A8-86-DD (hex) Apple, Inc.
-A886DD (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-54-EA-A8 (hex) Apple, Inc.
-54EAA8 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-E4-C6-3D (hex) Apple, Inc.
-E4C63D (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-84-38-35 (hex) Apple, Inc.
-843835 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-70-73-CB (hex) Apple, Inc.
-7073CB (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-9C-20-7B (hex) Apple, Inc.
-9C207B (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-84-29-99 (hex) Apple, Inc.
-842999 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-74-E2-F5 (hex) Apple, Inc.
-74E2F5 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
-20-C9-D0 (hex) Apple, Inc.
-20C9D0 (base 16) Apple, Inc.
- 1 Infinite Loop
- CUPERTINO CA 95014
- US
-
14-02-EC (hex) Hewlett Packard Enterprise
1402EC (base 16) Hewlett Packard Enterprise
8000 Foothills Blvd.
@@ -116351,36 +117257,6 @@ B813E9 (base 16) Trace Live Network
Wuxi Jiangsu 214131
CN
-7C-01-91 (hex) Apple, Inc.
-7C0191 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-70-48-0F (hex) Apple, Inc.
-70480F (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-A4-B8-05 (hex) Apple, Inc.
-A4B805 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-58-7F-57 (hex) Apple, Inc.
-587F57 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-80-D6-05 (hex) Apple, Inc.
-80D605 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
68-A8-28 (hex) HUAWEI TECHNOLOGIES CO.,LTD
68A828 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
@@ -116393,18 +117269,6 @@ A4B805 (base 16) Apple, Inc.
WUXI Jiangsu 214128
CN
-C8-69-CD (hex) Apple, Inc.
-C869CD (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-BC-6C-21 (hex) Apple, Inc.
-BC6C21 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
9C-8D-D3 (hex) Leonton Technologies
9C8DD3 (base 16) Leonton Technologies
3F, No.501-16, Zhongzheng Rd., Xindian Dist.
@@ -116489,12 +117353,6 @@ A4DEC9 (base 16) QLove Mobile Intelligence Information Technology (W.H.) Co
A4-A6-A9 (hex) Private
A4A6A9 (base 16) Private
-04-69-F8 (hex) Apple, Inc.
-0469F8 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
9C-7A-03 (hex) Ciena Corporation
9C7A03 (base 16) Ciena Corporation
7035 Ridge Road
@@ -116621,12 +117479,6 @@ D47BB0 (base 16) ASKEY COMPUTER CORP
London Greater London W1F 7NT
GB
-94-9F-3E (hex) Sonos, Inc.
-949F3E (base 16) Sonos, Inc.
- 223 E. De La Guerra Street
- Santa Barbara CA 93101
- US
-
78-8E-33 (hex) Jiangsu SEUIC Technology Co.,Ltd
788E33 (base 16) Jiangsu SEUIC Technology Co.,Ltd
NO23.Wenzhu Road.Yuhuatai Distrct.
@@ -138113,12 +138965,6 @@ C4E510 (base 16) Mechatro, Inc.
Sunnyvale CA 94085
US
-20-76-8F (hex) Apple, Inc.
-20768F (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
9C-5C-F9 (hex) Sony Mobile Communications AB
9C5CF9 (base 16) Sony Mobile Communications AB
Nya Vattentornet
@@ -138167,36 +139013,12 @@ BC44B0 (base 16) Elastifile
shanghai shanghai 20233
CN
-C0-CC-F8 (hex) Apple, Inc.
-C0CCF8 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-80-ED-2C (hex) Apple, Inc.
-80ED2C (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-E8-B2-AC (hex) Apple, Inc.
-E8B2AC (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
00-80-B8 (hex) DMG MORI B.U.G. CO., LTD.
0080B8 (base 16) DMG MORI B.U.G. CO., LTD.
1-1-14 Techno park,
Shimonopporo, Atsubetsuku, Sapporo Hokkaido 004-0015
JP
-84-89-AD (hex) Apple, Inc.
-8489AD (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
40-B6-88 (hex) LEGIC Identsystems AG
40B688 (base 16) LEGIC Identsystems AG
Binzackerstrasse 41
@@ -138755,18 +139577,6 @@ D09DAB (base 16) TCT mobile ltd
Hui Zhou Guang Dong 516006
CN
-8C-8E-F2 (hex) Apple, Inc.
-8C8EF2 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-F4-0F-24 (hex) Apple, Inc.
-F40F24 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
A0-D3-85 (hex) AUMA Riester GmbH & Co. KG
A0D385 (base 16) AUMA Riester GmbH & Co. KG
Aumastr. 1
@@ -138779,18 +139589,6 @@ A0D385 (base 16) AUMA Riester GmbH & Co. KG
ningbo zhejiang 315048
CN
-84-A1-34 (hex) Apple, Inc.
-84A134 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-1C-91-48 (hex) Apple, Inc.
-1C9148 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
CC-16-7E (hex) Cisco Systems, Inc
CC167E (base 16) Cisco Systems, Inc
80 West Tasman Drive
@@ -139871,18 +140669,6 @@ B4D135 (base 16) Cloudistics
Mianyang City Sichuan Province 621000
CN
-78-28-CA (hex) Sonos, Inc.
-7828CA (base 16) Sonos, Inc.
- 614 Chapala Street
- Santa Barbara CA 93101
- US
-
-B8-E9-37 (hex) Sonos, Inc.
-B8E937 (base 16) Sonos, Inc.
- 223 East De La Guerra Street
- Santa Barbara CA 93101
- US
-
B0-52-16 (hex) Hon Hai Precision Ind. Co.,Ltd.
B05216 (base 16) Hon Hai Precision Ind. Co.,Ltd.
Building D21,No.1, East Zone 1st Road
@@ -140651,24 +141437,6 @@ C8028F (base 16) Nova Electronics (Shanghai) Co., Ltd.
Gumi Gyeongbuk 730-350
KR
-5C-F7-E6 (hex) Apple, Inc.
-5CF7E6 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-A0-D7-95 (hex) Apple, Inc.
-A0D795 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-CC-08-8D (hex) Apple, Inc.
-CC088D (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
00-80-FB (hex) BVM LIMITED
0080FB (base 16) BVM LIMITED
Lakeside House, Brickyard Road,
@@ -140867,36 +141635,6 @@ E8EADA (base 16) Denkovi Assembly Electronics LTD
Maebashi-shi Gunma 379-2105
JP
-B0-70-2D (hex) Apple, Inc.
-B0702D (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-D0-C5-F3 (hex) Apple, Inc.
-D0C5F3 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-60-F4-45 (hex) Apple, Inc.
-60F445 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-00-B3-62 (hex) Apple, Inc.
-00B362 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-F8-62-14 (hex) Apple, Inc.
-F86214 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
C0-E5-4E (hex) ARIES Embedded GmbH
C0E54E (base 16) ARIES Embedded GmbH
Schöngeisinger Str. 84
@@ -141071,18 +141809,6 @@ CC82EB (base 16) KYOCERA CORPORATION
Yokohama-shi Kanagawa 224-8502
JP
-50-82-D5 (hex) Apple, Inc.
-5082D5 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-9C-84-BF (hex) Apple, Inc.
-9C84BF (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
78-94-B4 (hex) Sercomm Corporation.
7894B4 (base 16) Sercomm Corporation.
violet_liu@sercomm.com
@@ -141161,24 +141887,6 @@ E0C0D1 (base 16) CK Telecom (Shenzhen) Limited
shenzhen guangdong 518057
CN
-48-BF-6B (hex) Apple, Inc.
-48BF6B (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-24-5B-A7 (hex) Apple, Inc.
-245BA7 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-BC-A9-20 (hex) Apple, Inc.
-BCA920 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
D0-55-B2 (hex) Integrated Device Technology (Malaysia) Sdn. Bhd.
D055B2 (base 16) Integrated Device Technology (Malaysia) Sdn. Bhd.
Phase 3, Bayan Lepas FIZ
@@ -142466,24 +143174,6 @@ E470B8 (base 16) Intel Corporate
Kulim Kedah 09000
MY
-B0-19-C6 (hex) Apple, Inc.
-B019C6 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-58-E2-8F (hex) Apple, Inc.
-58E28F (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-AC-1F-74 (hex) Apple, Inc.
-AC1F74 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
30-38-55 (hex) Nokia Corporation
303855 (base 16) Nokia Corporation
Elektroniikkatie 10
@@ -142907,42 +143597,6 @@ F8F21E (base 16) Intel Corporate
Swindon SN5 7XP
GB
-24-F6-77 (hex) Apple, Inc.
-24F677 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-78-67-D7 (hex) Apple, Inc.
-7867D7 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-54-33-CB (hex) Apple, Inc.
-5433CB (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-D0-D2-B0 (hex) Apple, Inc.
-D0D2B0 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-D8-8F-76 (hex) Apple, Inc.
-D88F76 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-3C-2E-F9 (hex) Apple, Inc.
-3C2EF9 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
8C-83-9D (hex) SHENZHEN XINYUPENG ELECTRONIC TECHNOLOGY CO., LTD
8C839D (base 16) SHENZHEN XINYUPENG ELECTRONIC TECHNOLOGY CO., LTD
ROOM 1505,BIT INNOVATION BUILDING,SCIENCE AND TECHNOLOGY PARK,NANSHAN DISTRICT
@@ -143473,3 +144127,1119 @@ BCC00F (base 16) Fiberhome Telecommunication Technologies Co.,LTD
Via Aosta 23
Venaria Reale Torino 10078
IT
+
+04-69-F8 (hex) Apple, Inc.
+0469F8 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+BC-6C-21 (hex) Apple, Inc.
+BC6C21 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+C8-69-CD (hex) Apple, Inc.
+C869CD (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+80-D6-05 (hex) Apple, Inc.
+80D605 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+58-7F-57 (hex) Apple, Inc.
+587F57 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+A4-B8-05 (hex) Apple, Inc.
+A4B805 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+70-48-0F (hex) Apple, Inc.
+70480F (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+7C-01-91 (hex) Apple, Inc.
+7C0191 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+9C-29-3F (hex) Apple, Inc.
+9C293F (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+34-12-98 (hex) Apple, Inc.
+341298 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+90-3C-92 (hex) Apple, Inc.
+903C92 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+24-24-0E (hex) Apple, Inc.
+24240E (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+A0-99-9B (hex) Apple, Inc.
+A0999B (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+D0-A6-37 (hex) Apple, Inc.
+D0A637 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+18-F6-43 (hex) Apple, Inc.
+18F643 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+74-81-14 (hex) Apple, Inc.
+748114 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+18-EE-69 (hex) Apple, Inc.
+18EE69 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+F0-DB-E2 (hex) Apple, Inc.
+F0DBE2 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+B8-09-8A (hex) Apple, Inc.
+B8098A (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+54-9F-13 (hex) Apple, Inc.
+549F13 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+2C-1F-23 (hex) Apple, Inc.
+2C1F23 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+E4-CB-59 (hex) Beijing Loveair Science and Technology Co. Ltd.
+E4CB59 (base 16) Beijing Loveair Science and Technology Co. Ltd.
+ 103,Block B, Kelin Building, No.107, Dongsi North Street, Dongcheng District,
+ Beijing 100000
+ CN
+
+C8-77-65 (hex) Tiesse SpA
+C87765 (base 16) Tiesse SpA
+ Via Asti
+ Ivrea TO 10015
+ IT
+
+50-7A-55 (hex) Apple, Inc.
+507A55 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+9C-35-EB (hex) Apple, Inc.
+9C35EB (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+A4-31-35 (hex) Apple, Inc.
+A43135 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+D0-03-4B (hex) Apple, Inc.
+D0034B (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+A0-18-28 (hex) Apple, Inc.
+A01828 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+3C-15-C2 (hex) Apple, Inc.
+3C15C2 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+AC-CF-5C (hex) Apple, Inc.
+ACCF5C (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+F0-DB-F8 (hex) Apple, Inc.
+F0DBF8 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+98-F0-AB (hex) Apple, Inc.
+98F0AB (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+DC-9B-9C (hex) Apple, Inc.
+DC9B9C (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+8C-29-37 (hex) Apple, Inc.
+8C2937 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+DC-86-D8 (hex) Apple, Inc.
+DC86D8 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+E4-C6-3D (hex) Apple, Inc.
+E4C63D (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+54-EA-A8 (hex) Apple, Inc.
+54EAA8 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+A8-86-DD (hex) Apple, Inc.
+A886DD (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+A0-ED-CD (hex) Apple, Inc.
+A0EDCD (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+1C-E6-2B (hex) Apple, Inc.
+1CE62B (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+30-90-AB (hex) Apple, Inc.
+3090AB (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+F0-CB-A1 (hex) Apple, Inc.
+F0CBA1 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+04-54-53 (hex) Apple, Inc.
+045453 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+28-37-37 (hex) Apple, Inc.
+283737 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+14-8F-C6 (hex) Apple, Inc.
+148FC6 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+28-CF-DA (hex) Apple, Inc.
+28CFDA (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+14-5A-05 (hex) Apple, Inc.
+145A05 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+D0-4F-7E (hex) Apple, Inc.
+D04F7E (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+D8-BB-2C (hex) Apple, Inc.
+D8BB2C (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+80-BE-05 (hex) Apple, Inc.
+80BE05 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+E0-B5-2D (hex) Apple, Inc.
+E0B52D (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+68-AE-20 (hex) Apple, Inc.
+68AE20 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+E8-80-2E (hex) Apple, Inc.
+E8802E (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+A8-8E-24 (hex) Apple, Inc.
+A88E24 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+D8-CF-9C (hex) Apple, Inc.
+D8CF9C (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+04-48-9A (hex) Apple, Inc.
+04489A (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+B0-9F-BA (hex) Apple, Inc.
+B09FBA (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+8C-00-6D (hex) Apple, Inc.
+8C006D (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+C0-63-94 (hex) Apple, Inc.
+C06394 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+84-38-35 (hex) Apple, Inc.
+843835 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+20-C9-D0 (hex) Apple, Inc.
+20C9D0 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+74-E2-F5 (hex) Apple, Inc.
+74E2F5 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+84-29-99 (hex) Apple, Inc.
+842999 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+9C-20-7B (hex) Apple, Inc.
+9C207B (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+40-B3-95 (hex) Apple, Inc.
+40B395 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+00-88-65 (hex) Apple, Inc.
+008865 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+30-F7-C5 (hex) Apple, Inc.
+30F7C5 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+70-73-CB (hex) Apple, Inc.
+7073CB (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+00-B3-62 (hex) Apple, Inc.
+00B362 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+F8-62-14 (hex) Apple, Inc.
+F86214 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+B0-70-2D (hex) Apple, Inc.
+B0702D (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+D0-C5-F3 (hex) Apple, Inc.
+D0C5F3 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+60-F4-45 (hex) Apple, Inc.
+60F445 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+50-82-D5 (hex) Apple, Inc.
+5082D5 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+9C-84-BF (hex) Apple, Inc.
+9C84BF (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+48-BF-6B (hex) Apple, Inc.
+48BF6B (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+24-5B-A7 (hex) Apple, Inc.
+245BA7 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+BC-A9-20 (hex) Apple, Inc.
+BCA920 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+B0-19-C6 (hex) Apple, Inc.
+B019C6 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+58-E2-8F (hex) Apple, Inc.
+58E28F (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+AC-1F-74 (hex) Apple, Inc.
+AC1F74 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+20-76-8F (hex) Apple, Inc.
+20768F (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+C0-CC-F8 (hex) Apple, Inc.
+C0CCF8 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+80-ED-2C (hex) Apple, Inc.
+80ED2C (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+E8-B2-AC (hex) Apple, Inc.
+E8B2AC (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+84-89-AD (hex) Apple, Inc.
+8489AD (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+8C-8E-F2 (hex) Apple, Inc.
+8C8EF2 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+F4-0F-24 (hex) Apple, Inc.
+F40F24 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+84-A1-34 (hex) Apple, Inc.
+84A134 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+1C-91-48 (hex) Apple, Inc.
+1C9148 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+5C-F7-E6 (hex) Apple, Inc.
+5CF7E6 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+A0-D7-95 (hex) Apple, Inc.
+A0D795 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+CC-08-8D (hex) Apple, Inc.
+CC088D (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+08-00-07 (hex) Apple, Inc.
+080007 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+E4-25-E7 (hex) Apple, Inc.
+E425E7 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+28-CF-E9 (hex) Apple, Inc.
+28CFE9 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+90-60-F1 (hex) Apple, Inc.
+9060F1 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+74-1B-B2 (hex) Apple, Inc.
+741BB2 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+28-ED-6A (hex) Apple, Inc.
+28ED6A (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+34-AB-37 (hex) Apple, Inc.
+34AB37 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+60-A3-7D (hex) Apple, Inc.
+60A37D (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+00-56-CD (hex) Apple, Inc.
+0056CD (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+70-81-EB (hex) Apple, Inc.
+7081EB (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+08-66-98 (hex) Apple, Inc.
+086698 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+E0-F8-47 (hex) Apple, Inc.
+E0F847 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+44-2A-60 (hex) Apple, Inc.
+442A60 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+10-93-E9 (hex) Apple, Inc.
+1093E9 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+DC-2B-61 (hex) Apple, Inc.
+DC2B61 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+B8-FF-61 (hex) Apple, Inc.
+B8FF61 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+18-E7-F4 (hex) Apple, Inc.
+18E7F4 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+78-CA-39 (hex) Apple, Inc.
+78CA39 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+5C-59-48 (hex) Apple, Inc.
+5C5948 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+60-33-4B (hex) Apple, Inc.
+60334B (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+90-27-E4 (hex) Apple, Inc.
+9027E4 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+24-F6-77 (hex) Apple, Inc.
+24F677 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+78-67-D7 (hex) Apple, Inc.
+7867D7 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+54-33-CB (hex) Apple, Inc.
+5433CB (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+D0-D2-B0 (hex) Apple, Inc.
+D0D2B0 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+D8-8F-76 (hex) Apple, Inc.
+D88F76 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+3C-2E-F9 (hex) Apple, Inc.
+3C2EF9 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+DC-56-E7 (hex) Apple, Inc.
+DC56E7 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+34-7C-25 (hex) Apple, Inc.
+347C25 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+D4-90-9C (hex) Apple, Inc.
+D4909C (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+D4-9A-20 (hex) Apple, Inc.
+D49A20 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+04-1E-64 (hex) Apple, Inc.
+041E64 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+00-26-B0 (hex) Apple, Inc.
+0026B0 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+00-26-4A (hex) Apple, Inc.
+00264A (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+00-25-BC (hex) Apple, Inc.
+0025BC (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+00-23-DF (hex) Apple, Inc.
+0023DF (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+00-22-41 (hex) Apple, Inc.
+002241 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+00-0A-95 (hex) Apple, Inc.
+000A95 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+60-5F-8D (hex) eero inc.
+605F8D (base 16) eero inc.
+ 500 Howard Street, Suite 900
+ SAN FRANCISCO CA 94105
+ US
+
+B4-DE-DF (hex) zte corporation
+B4DEDF (base 16) zte corporation
+ 12/F.,zte R&D building ,kejinan Road,Shenzhen,P.R.China
+ shenzhen guangdong 518057
+ CN
+
+84-74-60 (hex) zte corporation
+847460 (base 16) zte corporation
+ 12/F.,zte R&D building ,kejinan Road,Shenzhen,P.R.China
+ shenzhen guangdong 518057
+ CN
+
+B4-A8-B9 (hex) Cisco Systems, Inc
+B4A8B9 (base 16) Cisco Systems, Inc
+ 80 West Tasman Drive
+ San Jose CA 94568
+ US
+
+88-B6-EE (hex) Dish Technologies Corp
+88B6EE (base 16) Dish Technologies Corp
+ 94 Inverness Terrace E
+ Englewood CO 80112
+ US
+
+38-E6-0A (hex) Xiaomi Communications Co Ltd
+38E60A (base 16) Xiaomi Communications Co Ltd
+ The Rainbow City of China Resources
+ NO.68, Qinghe Middle Street Haidian District, Beijing 100085
+ CN
+
+C0-42-D0 (hex) Juniper Networks
+C042D0 (base 16) Juniper Networks
+ 1133 Innovation Way
+ Sunnyvale CA 94089
+ US
+
+E8-33-0D (hex) Xaptec GmbH
+E8330D (base 16) Xaptec GmbH
+ Neidenburger Str. 10
+ Gelsenkirchen 45897
+ DE
+
+D8-D7-75 (hex) Sagemcom Broadband SAS
+D8D775 (base 16) Sagemcom Broadband SAS
+ 250, route de l'Empereur
+ Rueil Malmaison Cedex hauts de seine 92848
+ FR
+
+78-53-64 (hex) SHIFT GmbH
+785364 (base 16) SHIFT GmbH
+ Am Gänsemarkt 6
+ Wabern Falkenberg Hessen 34590
+ DE
+
+24-18-1D (hex) SAMSUNG ELECTRO-MECHANICS(THAILAND)
+24181D (base 16) SAMSUNG ELECTRO-MECHANICS(THAILAND)
+ 93Moo5T. Bangsamak SEMTHAI, WELLGROW INDUSTRIAL ESTATE
+ Bangpakong Chachoengsao 24180
+ TH
+
+54-B7-E5 (hex) Rayson Technology Co., Ltd.
+54B7E5 (base 16) Rayson Technology Co., Ltd.
+ 1F No.9 R&D Rd.II, Science-Based Industrial Park
+ Hsin-Chu 300
+ TW
+
+BC-0F-A7 (hex) Ouster
+BC0FA7 (base 16) Ouster
+ 350 Treat Ave
+ San Francisco CA 94110
+ US
+
+AC-F9-70 (hex) HUAWEI TECHNOLOGIES CO.,LTD
+ACF970 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
+ CN
+
+0C-41-E9 (hex) HUAWEI TECHNOLOGIES CO.,LTD
+0C41E9 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
+ CN
+
+58-D7-59 (hex) HUAWEI TECHNOLOGIES CO.,LTD
+58D759 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
+ CN
+
+B4-1C-30 (hex) zte corporation
+B41C30 (base 16) zte corporation
+ 12/F.,zte R&D building ,kejinan Road,Shenzhen,P.R.China
+ shenzhen guangdong 518057
+ CN
+
+F4-C2-48 (hex) Samsung Electronics Co.,Ltd
+F4C248 (base 16) Samsung Electronics Co.,Ltd
+ #94-1, Imsoo-Dong
+ Gumi Gyeongbuk 730-350
+ KR
+
+A8-51-5B (hex) Samsung Electronics Co.,Ltd
+A8515B (base 16) Samsung Electronics Co.,Ltd
+ #94-1, Imsoo-Dong
+ Gumi Gyeongbuk 730-350
+ KR
+
+60-6B-FF (hex) Nintendo Co.,Ltd
+606BFF (base 16) Nintendo Co.,Ltd
+ 11-1 HOKOTATE-CHO KAMITOBA,MINAMI-KU
+ KYOTO KYOTO 601-8501
+ JP
+
+AC-17-C8 (hex) Cisco Meraki
+AC17C8 (base 16) Cisco Meraki
+ 500 Terry A. Francois Blvd
+ San Francisco 94158
+ US
+
+EC-9B-8B (hex) Hewlett Packard Enterprise
+EC9B8B (base 16) Hewlett Packard Enterprise
+ 8000 Foothills Blvd.
+ Roseville CA 95747
+ US
+
+70-C9-4E (hex) Liteon Technology Corporation
+70C94E (base 16) Liteon Technology Corporation
+ 4F, 90, Chien 1 Road
+ New Taipei City Taiwan 23585
+ TW
+
+70-D0-81 (hex) Beijing Netpower Technologies Inc.
+70D081 (base 16) Beijing Netpower Technologies Inc.
+ Room 201, Block B, NO. 15 Building, EastZone
+ Courtyard10, Xibeiwang East Road Haidian District, Beijing 100094
+ CN
+
+70-3A-73 (hex) Shenzhen Sundray Technologies Company Limited
+703A73 (base 16) Shenzhen Sundray Technologies Company Limited
+ 6th Floor,Block A1, Nanshan iPark, No.1001 XueYuan Road, Nanshan District
+ Shenzhen Guangdong 518057
+ CN
+
+18-0F-76 (hex) D-Link International
+180F76 (base 16) D-Link International
+ 1 Internal Business Park, #03-12,The Synergy, Singapore
+ Singapore Singapore 609917
+ SG
+
+18-4C-08 (hex) Rockwell Automation
+184C08 (base 16) Rockwell Automation
+ 1 Allen-Bradley Dr.
+ Mayfield Heights OH 44124-6118
+ US
+
+88-E9-0F (hex) innomdlelab
+88E90F (base 16) innomdlelab
+ Unnam 1 gil, 3
+ Seocho-gu Seoul 06778
+ KR
+
+C0-98-DA (hex) China Mobile IOT Company Limited
+C098DA (base 16) China Mobile IOT Company Limited
+ NO.8 Yu Ma Road, NanAn Area Chongqing,China
+ Chongqing Chongqing 401336
+ CN
+
+98-D8-63 (hex) Shanghai High-Flying Electronics Technology Co., Ltd
+98D863 (base 16) Shanghai High-Flying Electronics Technology Co., Ltd
+ Room 1002 ,#1Building,No.3000 Longdong Avenue,Pudong District,Shanghai,China
+ shanghai shanghai 201203
+ CN
+
+F0-0F-EC (hex) HUAWEI TECHNOLOGIES CO.,LTD
+F00FEC (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
+ CN
+
+0C-70-4A (hex) HUAWEI TECHNOLOGIES CO.,LTD
+0C704A (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
+ CN
+
+54-A6-5C (hex) Technicolor CH USA Inc.
+54A65C (base 16) Technicolor CH USA Inc.
+ 101 West 103rd St.
+ Indianapolis IN 46290
+ US
+
+94-9F-3E (hex) Sonos, Inc.
+949F3E (base 16) Sonos, Inc.
+ 614 Chapala St
+ Santa Barbara CA 93101
+ US
+
+B8-E9-37 (hex) Sonos, Inc.
+B8E937 (base 16) Sonos, Inc.
+ 614 Chapala St
+ Santa Barbara CA 93101
+ US
+
+78-28-CA (hex) Sonos, Inc.
+7828CA (base 16) Sonos, Inc.
+ 614 Chapala St
+ Santa Barbara CA 93101
+ US
+
+34-7E-5C (hex) Sonos, Inc.
+347E5C (base 16) Sonos, Inc.
+ 614 Chapala St
+ Santa Barbara CA 93101
+ US
+
+C0-48-E6 (hex) Samsung Electronics Co.,Ltd
+C048E6 (base 16) Samsung Electronics Co.,Ltd
+ 129, Samsung-ro, Youngtongl-Gu
+ Suwon Gyeonggi-Do 16677
+ KR
+
+6C-E4-DA (hex) NEC Platforms, Ltd.
+6CE4DA (base 16) NEC Platforms, Ltd.
+ 2-3 Kandatsukasamachi
+ Chiyodaku Tokyo 101-8532
+ JP
+
+C8-8F-26 (hex) Skyworth Digital Technology(Shenzhen) Co.,Ltd
+C88F26 (base 16) Skyworth Digital Technology(Shenzhen) Co.,Ltd
+ 7F,Block A,Skyworth Building,
+ Shenzhen Guangdong 518057
+ CN
+
+B0-26-80 (hex) Cisco Systems, Inc
+B02680 (base 16) Cisco Systems, Inc
+ 80 West Tasman Drive
+ San Jose CA 94568
+ US
+
+00-3C-10 (hex) Cisco Systems, Inc
+003C10 (base 16) Cisco Systems, Inc
+ 80 West Tasman Drive
+ San Jose CA 94568
+ US
+
+90-83-4B (hex) BEIJING YUNYI TIMES TECHNOLOGY CO,.LTD
+90834B (base 16) BEIJING YUNYI TIMES TECHNOLOGY CO,.LTD
+ 1-411Room 19#Building No.26 Xihuan South Rd. BDA Daxing District,
+ BEIJING 100176
+ CN
+
+48-BD-3D (hex) New H3C Technologies Co., Ltd
+48BD3D (base 16) New H3C Technologies Co., Ltd
+ 466 Changhe Road, Binjiang District
+ Hangzhou Zhejiang 310052
+ CN
+
+4C-AB-FC (hex) zte corporation
+4CABFC (base 16) zte corporation
+ 12/F.,zte R&D building ,kejinan Road,Shenzhen,P.R.China
+ shenzhen guangdong 518057
+ CN
+
+20-0F-70 (hex) FOXTECH
+200F70 (base 16) FOXTECH
+ 152-160 City Road
+ LONDON KEMP HOUSE EC1V 2NX
+ GB
+
+E8-1A-AC (hex) ORFEO SOUNDWORKS Inc.
+E81AAC (base 16) ORFEO SOUNDWORKS Inc.
+ 612, 11-41, Simin-daero 327beon-gil, Dongan-gu
+ Anyang 14055
+ KR
+
+A0-38-F8 (hex) OURA Health Oy
+A038F8 (base 16) OURA Health Oy
+ Elektroniikkatie 3
+ Oulu 90590
+ FI
+
+14-6B-9C (hex) SHENZHEN BILIAN ELECTRONIC CO.,LTD
+146B9C (base 16) SHENZHEN BILIAN ELECTRONIC CO.,LTD
+ NO.268, Fuqian Rd, Jutang community, Guanlan Town, Longhua New district
+ shenzhen guangdong 518000
+ CN
+
+D0-77-14 (hex) Motorola Mobility LLC, a Lenovo Company
+D07714 (base 16) Motorola Mobility LLC, a Lenovo Company
+ 222 West Merchandise Mart Plaza
+ Chicago IL 60654
+ US
+
+34-D7-12 (hex) Smartisan Digital Co., Ltd
+34D712 (base 16) Smartisan Digital Co., Ltd
+ 4F, China Digital Kingdom, No.1 Wangjing North Road, Chaoyang District
+ Beijing Beijing 100012
+ CN
+
+98-45-62 (hex) Shanghai Baud Data Communication Co.,Ltd.
+984562 (base 16) Shanghai Baud Data Communication Co.,Ltd.
+ NO.123 JULI RD
+ PUDONG ZHANGJIANG HIGH-TECH PARK SHANGHAI 201203
+ CN
+
+E8-98-6D (hex) Palo Alto Networks
+E8986D (base 16) Palo Alto Networks
+ 3000 Tannery Way
+ Santa Clara CA 95054
+ US
+
+F0-81-73 (hex) Amazon Technologies Inc.
+F08173 (base 16) Amazon Technologies Inc.
+ P.O Box 8102
+ Reno 89507
+ US
+
+24-29-FE (hex) KYOCERA Corporation
+2429FE (base 16) KYOCERA Corporation
+ 30 Hoji
+ Kitami, Hokkaido 099-1595
+ JP
diff --git a/hwdb/ma-medium.txt b/hwdb/ma-medium.txt
index 30505fadcd..89577b9cf8 100644
--- a/hwdb/ma-medium.txt
+++ b/hwdb/ma-medium.txt
@@ -1718,9 +1718,6 @@ F00000-FFFFFF (base 16) Private
90-C6-82 (hex) Private
F00000-FFFFFF (base 16) Private
-98-02-D8 (hex) Private
-F00000-FFFFFF (base 16) Private
-
D0-76-50 (hex) Private
F00000-FFFFFF (base 16) Private
@@ -2003,6 +2000,105 @@ F00000-FFFFFF (base 16) Private
NishiTokyo-city Tokyo 202-0022
JP
+9C-43-1E (hex) HK ELEPHONE Communication Tech Co.,Limited
+D00000-DFFFFF (base 16) HK ELEPHONE Communication Tech Co.,Limited
+ Unit 04, 7/F Bright Way Tower No.33 Mong Kok Rd KL
+ Hong Kong 999077
+ HK
+
+9C-43-1E (hex) Wireless Environment, LLC
+400000-4FFFFF (base 16) Wireless Environment, LLC
+ 600 Beta Drive Unit 100 Mayfield Village, OH 44143,US
+ Mayfield Village OH 44143
+ US
+
+28-2C-02 (hex) ThirdReality, Inc
+B00000-BFFFFF (base 16) ThirdReality, Inc
+ 647 East Longhua Road, Huangpu District
+ Shanghai Shanghai 200023
+ CN
+
+9C-43-1E (hex) HAESUNG DS
+200000-2FFFFF (base 16) HAESUNG DS
+ 8F, Haesung 2 Building, 508, Teheran-ro, Gangnam-gu
+ Seoul 06178
+ KR
+
+28-2C-02 (hex) Tokin Limited
+A00000-AFFFFF (base 16) Tokin Limited
+ Unit 513-4, Block A, Focal Industrial Centre, 21 Man Lok Street, Hung Hom
+ Kowloon 0000
+ HK
+
+F0-41-C8 (hex) Shenzhen Medica Technology Development Co., Ltd.
+200000-2FFFFF (base 16) Shenzhen Medica Technology Development Co., Ltd.
+ 2F Building A, Tongfang Information Harbor, No.11, East Langshan Road, Nanshan District
+ Shenzhen 518000
+ CN
+
+C4-FF-BC (hex) Danego BV
+000000-0FFFFF (base 16) Danego BV
+ Protonenlaan 24
+ Uden NB 5405 NE
+ NL
+
+C4-FF-BC (hex) Critical Link
+700000-7FFFFF (base 16) Critical Link
+ 6712 Brooklawn Parkway
+ Syracuse 13211
+ US
+
+A4-DA-22 (hex) Klashwerks Inc.
+B00000-BFFFFF (base 16) Klashwerks Inc.
+ 441 Maclaren Street, Suite 408
+ Ottawa ON K2P2H3
+ CA
+
+88-A9-A7 (hex) Sieper Lüdenscheid GmbH & Co. KG
+600000-6FFFFF (base 16) Sieper Lüdenscheid GmbH & Co. KG
+ Schlittenbacher Straße 60
+ Lüdenscheid 58511
+ DE
+
+98-02-D8 (hex) Private
+F00000-FFFFFF (base 16) Private
+
+C4-FF-BC (hex) KyongBo Electric Co., Ltd.
+C00000-CFFFFF (base 16) KyongBo Electric Co., Ltd.
+ 5, Seongsuil-ro 12-gagil Seongdong-gu
+ Seoul 04792
+ KR
+
+C4-FF-BC (hex) ShenZhen ZYT Technology co., Ltd
+800000-8FFFFF (base 16) ShenZhen ZYT Technology co., Ltd
+ Floor four,Build C,FuSen Industrial park, HangCheng Avenue,Baoan District
+ Shenzhen GuangDong 518000
+ CN
+
+DC-E5-33 (hex) SAN Engineering
+700000-7FFFFF (base 16) SAN Engineering
+ 434-31 UTO Korea BD. 4F
+ Seongnam-si Jungwon-gu Gyunggi-do 13230
+ KR
+
+DC-E5-33 (hex) Suzhou ATES electronic technology co.LTD
+D00000-DFFFFF (base 16) Suzhou ATES electronic technology co.LTD
+ NO.2 aimin road,Xiangcheng district
+ Suzhou city Jiangsu Province 215002
+ CN
+
+88-A9-A7 (hex) Zhejiang Haoteng Electronic Technology Co.,Ltd.
+A00000-AFFFFF (base 16) Zhejiang Haoteng Electronic Technology Co.,Ltd.
+ Zhejiang Lishui city streets Nanming mountain Shek road Liandu District No. 268 Building 2 block B
+ Lishui Zhejiang 323000
+ CN
+
+F0-41-C8 (hex) LINPA ACOUSTIC TECHNOLOGY CO.,LTD
+000000-0FFFFF (base 16) LINPA ACOUSTIC TECHNOLOGY CO.,LTD
+ 2A,No60 , Lizhong Road,DaliQingxi Town
+ Dongguan Guandong 523648
+ CN
+
1C-87-76 (hex) Strone Technology
C00000-CFFFFF (base 16) Strone Technology
13 Ellis Street
@@ -3944,6 +4040,123 @@ F8-B5-68 (hex) CloudMinds (Shenzhen) Holdings Co., Ltd
10-07-23 (hex) Private
F00000-FFFFFF (base 16) Private
+28-2C-02 (hex) LLC MICROTEH
+500000-5FFFFF (base 16) LLC MICROTEH
+ pl.5 bldg.2/3 Akademika Anokhina str.
+ Moscow 119602
+ RU
+
+9C-43-1E (hex) Wunda Group plc
+800000-8FFFFF (base 16) Wunda Group plc
+ Unit 1-5, Hawthorn, Crick
+ Caldicot Monmouthshire NP26 5UT
+ GB
+
+9C-43-1E (hex) Advanced Logic Technology (ALT) sa
+300000-3FFFFF (base 16) Advanced Logic Technology (ALT) sa
+ Route de Niederpallen, 30H
+ Redange-sur-Attert Luxembourg 8506
+ LU
+
+C4-FF-BC (hex) GSM Innovations Pty Ltd
+900000-9FFFFF (base 16) GSM Innovations Pty Ltd
+ 142-144 Fullarton Road
+ Rose Park SA 5067
+ AU
+
+C4-FF-BC (hex) SHENZHEN KALIF ELECTRONICS CO.,LTD
+300000-3FFFFF (base 16) SHENZHEN KALIF ELECTRONICS CO.,LTD
+ 1ã€2 and 3 Floor, No.114, Haochong No.2 Industry Area, Hongxing Community, Songgang, Baoan, Shenzhen
+ SHENZHEN GuangDong 518105
+ CN
+
+C4-FF-BC (hex) Beijing KDF information technology co. LTD.
+D00000-DFFFFF (base 16) Beijing KDF information technology co. LTD.
+ Room14C,TowerA,,LindaBuilding,No.8,Dongtucheng Road,Chaoyang District, Beijing.
+ Beijing 100013
+ CN
+
+9C-43-1E (hex) Optris GmbH
+700000-7FFFFF (base 16) Optris GmbH
+ Ferdinand-Buisson-Str. 14
+ Berlin 13127
+ DE
+
+C4-FF-BC (hex) viRaTec GmbH
+E00000-EFFFFF (base 16) viRaTec GmbH
+ Phorusgasse 8/1
+ Wien 1040
+ AT
+
+DC-E5-33 (hex) Controls Inc
+500000-5FFFFF (base 16) Controls Inc
+ 5204 Portside Drive
+ Medina OH 44256
+ US
+
+C4-FF-BC (hex) Shenzhen C & D Electronics Co., Ltd.
+600000-6FFFFF (base 16) Shenzhen C & D Electronics Co., Ltd.
+ 9th FIoor, Building 9, No.1 Qingxiang road, BaoNeng Science and TechnoIogy Industrial Park, Longhua New District
+ ShenZhen GuangDong 518000
+ CN
+
+DC-E5-33 (hex) FLYHT Aerospace
+000000-0FFFFF (base 16) FLYHT Aerospace
+ 300E 1144 - 29th St. N.E.
+ Calgary AB T2E7P1
+ CA
+
+DC-E5-33 (hex) Private
+A00000-AFFFFF (base 16) Private
+
+A4-DA-22 (hex) Shen Zhen City YaKun Electronics Co., Ltd
+D00000-DFFFFF (base 16) Shen Zhen City YaKun Electronics Co., Ltd
+ SOUTHERN BUILDING 5388 Shang Bu Industrial Zone Huaqiang North Road Futian District
+ shen zhen city Guang Dong Province 518000
+ CN
+
+A4-DA-22 (hex) Abetechs GmbH
+A00000-AFFFFF (base 16) Abetechs GmbH
+ Niermannsweg 11
+ Erkrath North Rhine-Westphalia 40699
+ DE
+
+A4-DA-22 (hex) T2T System
+100000-1FFFFF (base 16) T2T System
+ #316, HYUNDAI Knowledge Industry Center, 70, Dusan-ro
+ Geumcheon-gu Seoul 08584
+ KR
+
+A4-DA-22 (hex) Quuppa Oy
+E00000-EFFFFF (base 16) Quuppa Oy
+ Keilaranta 1
+ Espoo 02150
+ FI
+
+88-A9-A7 (hex) AndroVideo Inc.
+C00000-CFFFFF (base 16) AndroVideo Inc.
+ 2f-4, 17, Lane 91, Nei Hu Rd., Sec. 1
+ Taipei 11441
+ TW
+
+F0-41-C8 (hex) Shenzhen Nufilo Electronic Technology Co., Ltd.
+900000-9FFFFF (base 16) Shenzhen Nufilo Electronic Technology Co., Ltd.
+ Tianliao Building West Unit F1315, (New Materials Industrial Park), Xueyuan Road, Nanshan District
+ Shenzhen Guangdong 518055
+ CN
+
+F0-41-C8 (hex) SHENZHEN WISEWING INTERNET TECHNOLOGY CO.,LTD
+300000-3FFFFF (base 16) SHENZHEN WISEWING INTERNET TECHNOLOGY CO.,LTD
+ No.826,Zone 1,Block B,Famous industrial product display purchasing center,Baoyuan Road,Xixiang,Bao'an Dis., Shenzhen,P.R.China
+ shenzhen China 518102
+ CN
+
+F0-41-C8 (hex) Shanghai Think-Force Electronic Technology Co. Ltd
+C00000-CFFFFF (base 16) Shanghai Think-Force Electronic Technology Co. Ltd
+ North ZhongShan Road, No. 3000, Room 2608
+ Shanghai 200000
+ CN
+
1C-87-76 (hex) Zhuhai MYZR Technology Co.,Ltd
500000-5FFFFF (base 16) Zhuhai MYZR Technology Co.,Ltd
Room 302,Area D2,National Hi-tech Zone,NO.1,Software Park Road
@@ -6005,6 +6218,156 @@ F8-B5-68 (hex) Combiwins Technology Co.,Limited
Chennai Tamilnadu 600035
IN
+28-2C-02 (hex) SHENZHEN DOMENOR TECHNOLOGY LLC
+D00000-DFFFFF (base 16) SHENZHEN DOMENOR TECHNOLOGY LLC
+ F4, BUILDING A3, SILICON VALLEY POWER TECHNOLOGY PARK, SILI ROAD, KUKENG COMMUNITY, GUANLAN TOWN,LONGHUA DISTRICT
+ SHENZHEN GUANGDONG 518110
+ CN
+
+9C-43-1E (hex) Symfun Telecom Ltd
+100000-1FFFFF (base 16) Symfun Telecom Ltd
+ Floor 4 Building 11 Xi Qi Dian Jia Yuan
+ Beijing 100083
+ CN
+
+9C-43-1E (hex) Antailiye Technology Co.,Ltd
+000000-0FFFFF (base 16) Antailiye Technology Co.,Ltd
+ 7/F,Zhengjiyuan Buiding,2 Road,Qianjing, Xixiang, Baoan District,Shenzhen
+ SHEN ZHEN GUANGDONG 518000
+ CN
+
+9C-43-1E (hex) ST Access Control System Corp.
+A00000-AFFFFF (base 16) ST Access Control System Corp.
+ 3F., No. 111 Zhongzheng Rd., Banciao Dist., New Taipei City
+ New Taipei City 22054
+ TW
+
+C4-FF-BC (hex) Mobiletron Electronics Co., Ltd
+200000-2FFFFF (base 16) Mobiletron Electronics Co., Ltd
+ 85, Sec.4, Chung-Ching Rd., Ta-Ya District
+ Taichung 428
+ TW
+
+C4-FF-BC (hex) iMageTech CO.,LTD.
+400000-4FFFFF (base 16) iMageTech CO.,LTD.
+ 5F., No.16, Lane 15, Sec. 6, Mincyuan E. Rd., Neihu District,
+ TAIPEI 114
+ TW
+
+C4-FF-BC (hex) KAGA ELECTRONICS CO.,LTD.
+B00000-BFFFFF (base 16) KAGA ELECTRONICS CO.,LTD.
+ 20 Kandamatsunaga-cho
+ Chiyoda-ku TOKYO 101-8627
+ JP
+
+C4-FF-BC (hex) comtime GmbH
+500000-5FFFFF (base 16) comtime GmbH
+ Gutenbergring 22
+ Norderstedt 22848
+ US
+
+DC-E5-33 (hex) Tintel Hongkong Co.Ltd
+B00000-BFFFFF (base 16) Tintel Hongkong Co.Ltd
+ FLAT C,23/F,LUCKY PLAZA,315-321 LOCKHART ROAD,WANCHAI,HONGKONG
+ HONGKONG GUANG DONG PROVINCE 999077
+ HK
+
+DC-E5-33 (hex) JB-Lighting Lichtanlagen GmbH
+800000-8FFFFF (base 16) JB-Lighting Lichtanlagen GmbH
+ Sallersteig 15
+ 89134 89134
+ DE
+
+DC-E5-33 (hex) Giant Power Technology Biomedical Corporation
+E00000-EFFFFF (base 16) Giant Power Technology Biomedical Corporation
+ Rm201, 2nd Educational Building, No. 84, Gongzhuan Rd, Taishan Dist
+ New Taipei City 24301
+ TW
+
+DC-E5-33 (hex) shenzhen bangying electronics co,.ltd
+400000-4FFFFF (base 16) shenzhen bangying electronics co,.ltd
+ 3/F Building 16,Hongfa industrialPark,Tangtou Shiyan Town
+ shenzhen guangdong 518000
+ CN
+
+A4-DA-22 (hex) AURANEXT
+600000-6FFFFF (base 16) AURANEXT
+ 202 quai de clichy
+ CLICHY 92110
+ FR
+
+A4-DA-22 (hex) Wyze Labs Inc
+200000-2FFFFF (base 16) Wyze Labs Inc
+ 22522 29TH DR SE L101
+ BOTHELL WA 98021
+ US
+
+A4-DA-22 (hex) LORIOT AG
+400000-4FFFFF (base 16) LORIOT AG
+ Zuercherstrasse 68
+ Thalwil Zürich 8800
+ CH
+
+A4-DA-22 (hex) DURATECH Enterprise,LLC
+300000-3FFFFF (base 16) DURATECH Enterprise,LLC
+ NO.1013,184,Gasan digital 2-ro,Geumcheon-gu,Seoul
+ Seoul 08501
+ KR
+
+A4-DA-22 (hex) EHO.LINK
+C00000-CFFFFF (base 16) EHO.LINK
+ 5 Avenue de Saint Menet, Imm. Axiome, Bat. B
+ Marseille 13011
+ FR
+
+A4-DA-22 (hex) General Electric Company
+000000-0FFFFF (base 16) General Electric Company
+ Valle del Cedro #1551
+ Ciudad Juarez Chih 32575
+ MX
+
+88-A9-A7 (hex) Mikroelektronika
+300000-3FFFFF (base 16) Mikroelektronika
+ Batajnicki drum 23
+ Belgrade 11186
+ RS
+
+88-A9-A7 (hex) kimura giken corporation
+700000-7FFFFF (base 16) kimura giken corporation
+ 4-9-19 kamiyoga
+ Setagaya-ku Tokyo 158-0098
+ JP
+
+88-A9-A7 (hex) FlashForge Corporation
+900000-9FFFFF (base 16) FlashForge Corporation
+ No.518, Xianyuan Road
+ Jinhua Zhejiang 321000
+ CN
+
+88-A9-A7 (hex) Thomas & Darden, Inc
+400000-4FFFFF (base 16) Thomas & Darden, Inc
+ 916 Springdale Rd Bldg 4 #104
+ Austin 78702
+ US
+
+88-A9-A7 (hex) Impact Distribution
+E00000-EFFFFF (base 16) Impact Distribution
+ Ter Heidelaan 50a
+ Aarschot 3200
+ BE
+
+88-A9-A7 (hex) Honeywell spol. s.r.o. HTS CZ o.z.
+200000-2FFFFF (base 16) Honeywell spol. s.r.o. HTS CZ o.z.
+ Turanka 100/1387
+ Brno 62700
+ CZ
+
+88-A9-A7 (hex) Solaredge LTD.
+100000-1FFFFF (base 16) Solaredge LTD.
+ Hamada 1
+ Herzelia 4673335
+ IL
+
1C-87-76 (hex) Hekatron Vertriebs GmbH
B00000-BFFFFF (base 16) Hekatron Vertriebs GmbH
Brühlmatten 9
@@ -7889,21 +8252,12 @@ F00000-FFFFFF (base 16) Private
58-FC-DB (hex) Private
F00000-FFFFFF (base 16) Private
-2C-26-5F (hex) Private
-F00000-FFFFFF (base 16) Private
-
-28-FD-80 (hex) Private
-F00000-FFFFFF (base 16) Private
-
2C-D1-41 (hex) Private
F00000-FFFFFF (base 16) Private
2C-6A-6F (hex) Private
F00000-FFFFFF (base 16) Private
-A0-BB-3E (hex) Private
-F00000-FFFFFF (base 16) Private
-
BC-66-41 (hex) Private
F00000-FFFFFF (base 16) Private
@@ -8075,6 +8429,57 @@ D00000-DFFFFF (base 16) NOX Systems AG
Moscow 107258
RU
+28-2C-02 (hex) Shenzhen Neoway Technology Co.,Ltd.
+800000-8FFFFF (base 16) Shenzhen Neoway Technology Co.,Ltd.
+ 4F-2#,Lian Jian Science & Industry Park,Huarong Road,Dalang Street,Longhua District
+ Shenzhen Guangdong 518000
+ CN
+
+C4-FF-BC (hex) VISATECH C0., LTD.
+100000-1FFFFF (base 16) VISATECH C0., LTD.
+ C-312 168, Gasan digital 1-ro
+ Geumcheon-gu Seoul 08507
+ KR
+
+DC-E5-33 (hex) Tiertime Corporation
+900000-9FFFFF (base 16) Tiertime Corporation
+ 2398 Walsh Avenue
+ Santa Clara CA 95051
+ US
+
+A4-DA-22 (hex) Hydro Electronic Devices, Inc.
+700000-7FFFFF (base 16) Hydro Electronic Devices, Inc.
+ 2120 Constitution Ave
+ Hartford WI 53027
+ US
+
+2C-26-5F (hex) Private
+F00000-FFFFFF (base 16) Private
+
+28-FD-80 (hex) Private
+F00000-FFFFFF (base 16) Private
+
+A0-BB-3E (hex) Private
+F00000-FFFFFF (base 16) Private
+
+F0-41-C8 (hex) ATN Media Group FZ LLC
+D00000-DFFFFF (base 16) ATN Media Group FZ LLC
+ Business Bay-alabrj st Business Towar By Damac.office-807
+ Dubai 25051
+ AE
+
+F0-41-C8 (hex) XI'AN MEI SHANG MEI WIRELESS TECHNOLOGY.Co., Ltd.
+500000-5FFFFF (base 16) XI'AN MEI SHANG MEI WIRELESS TECHNOLOGY.Co., Ltd.
+ Xi'an Beilin District Yanta Middle Road No. 17A XIN QING YA YUAN 2-5C
+ XI'AN shanxi 710000
+ CN
+
+F0-41-C8 (hex) AED Engineering GmbH
+600000-6FFFFF (base 16) AED Engineering GmbH
+ Taunusstr. 51
+ Munich Bavaria 80807
+ DE
+
34-D0-B8 (hex) Kongqiguanjia (Beijing)Technology co.,ltd
E00000-EFFFFF (base 16) Kongqiguanjia (Beijing)Technology co.,ltd
Room 1201,Block A,Building of Fesco,Xidawang Road,Chaoyang district
@@ -8147,6 +8552,66 @@ F8-B5-68 (hex) Beijing Wanji Techonology Co., Ltd.
beijing beijing 100193
CN
+28-2C-02 (hex) Dexin Digital Technology Corp. Ltd.
+300000-3FFFFF (base 16) Dexin Digital Technology Corp. Ltd.
+ No.10 and 12, Wuxing Fourth Road,Wuhou District Chengdu 610045 Sichuan, PR China
+ chengdu Sichuan 610045
+ CN
+
+9C-43-1E (hex) ProMOS Technologies Inc.
+500000-5FFFFF (base 16) ProMOS Technologies Inc.
+ 3A3, No.1, Lixing 1st Rd., East Dist.,
+ Hsinchu City Taiwan 300
+ TW
+
+DC-E5-33 (hex) Ambi Labs Limited
+100000-1FFFFF (base 16) Ambi Labs Limited
+ 1903, 19/F, Loon Lee Building, 267-275 Des Voeux Road Central., Sheung Wan, Hong Kong
+ Hong Kong Hong Kong 00000
+ HK
+
+DC-E5-33 (hex) Remko GmbH & Co. KG
+200000-2FFFFF (base 16) Remko GmbH & Co. KG
+ Im Seelenkamp 12
+ Lage 32791
+ DE
+
+A4-DA-22 (hex) SolidPro Technology Corporation
+800000-8FFFFF (base 16) SolidPro Technology Corporation
+ 10F.-1, No.150, Jian 1st Rd.
+ Zhonghe Dist. New Taipei City 23511
+ TW
+
+A4-DA-22 (hex) Original Products Pvt. Ltd.
+500000-5FFFFF (base 16) Original Products Pvt. Ltd.
+ B-19, Shiv Park, School Road, Khanpur
+ New Delhi New Delhi 110062
+ IN
+
+88-A9-A7 (hex) Shenzhenshi kechuangzhixian technology Co.LTD
+000000-0FFFFF (base 16) Shenzhenshi kechuangzhixian technology Co.LTD
+ Room 14G,14th Floor, Langshi Building , keji South Road 12 , High-tech Industrial Park , Nanshan District
+ Shenzhen 518000
+ CN
+
+88-A9-A7 (hex) TWK-ELEKTRONIK
+B00000-BFFFFF (base 16) TWK-ELEKTRONIK
+ Heinrichstr. 85
+ Duesseldorf 40239
+ DE
+
+88-A9-A7 (hex) psb intralogistics GmbH
+800000-8FFFFF (base 16) psb intralogistics GmbH
+ Blocksbergstrasse 145
+ Pirmasens 66955
+ DE
+
+F0-41-C8 (hex) Nanchang BlackShark Co.,Ltd.
+700000-7FFFFF (base 16) Nanchang BlackShark Co.,Ltd.
+ Room 319, Jiaoqiao Town Office Building, Economic and Technical development zone, Nanchang City, Jiangxi Province.
+ Nanchang 330013
+ CN
+
1C-87-74 (hex) Philips Personal Health Solutions
000000-0FFFFF (base 16) Philips Personal Health Solutions
High Tech Campus, HTC37 floor 0
@@ -10150,3 +10615,93 @@ F00000-FFFFFF (base 16) Private
0C-EF-AF (hex) Private
F00000-FFFFFF (base 16) Private
+
+28-2C-02 (hex) EFENTO T P SZYDÅOWSKI K ZARĘBA SPÓÅKA JAWNA
+400000-4FFFFF (base 16) EFENTO T P SZYDÅOWSKI K ZARĘBA SPÓÅKA JAWNA
+ Dietla 93/6
+ Kraków 31-031
+ PL
+
+28-2C-02 (hex) Capintec, Inc.
+E00000-EFFFFF (base 16) Capintec, Inc.
+ 7 Vreeland Road
+ Florham Park NJ 07932
+ US
+
+9C-43-1E (hex) R-S-I Elektrotechnik GmbH CO KG
+600000-6FFFFF (base 16) R-S-I Elektrotechnik GmbH CO KG
+ Woelkestrasse 11
+ Schweitenkirchen 85276
+ DE
+
+9C-43-1E (hex) CONTINENT Co. Ltd
+900000-9FFFFF (base 16) CONTINENT Co. Ltd
+ Bumazhnaya st., 16/3 lit B, of. 414
+ Saint-Petersburg 190020
+ RU
+
+9C-43-1E (hex) SuZhou Jinruiyang Information Technology CO.,LTD
+C00000-CFFFFF (base 16) SuZhou Jinruiyang Information Technology CO.,LTD
+ NO.1003 Room A1 Buliding Tengfei Business Park in Suzhou Industrial Park.
+ Suzhou Jiangsu 215123
+ CN
+
+9C-43-1E (hex) JNL Technologies Inc
+B00000-BFFFFF (base 16) JNL Technologies Inc
+ W1205 Industrial Dr
+ Ixonia WI 53036
+ US
+
+9C-43-1E (hex) Midas Technology DBA Phoenix Audio Technologies
+E00000-EFFFFF (base 16) Midas Technology DBA Phoenix Audio Technologies
+ 16 Goodyear #120
+ Irvine CA 92618
+ US
+
+C4-FF-BC (hex) Advanced Navigation
+A00000-AFFFFF (base 16) Advanced Navigation
+ Level 8, 37 Pitt Street
+ Sydney NSW 2000
+ AU
+
+DC-E5-33 (hex) ShenZhen C&D Electronics CO.Ltd.
+300000-3FFFFF (base 16) ShenZhen C&D Electronics CO.Ltd.
+ 9th FIoor, Building 9, No.1 Qingxiang road, BaoNeng Science and TechnoIogy Industrial Park, Longhua New District
+ ShenZhen GuangDong 518000
+ CN
+
+DC-E5-33 (hex) WECAN Solution Inc.
+600000-6FFFFF (base 16) WECAN Solution Inc.
+ 71, Yulhadong-ro 8-gil, Dong-gu, Daegu, Republic of Korea
+ Daegu 41102
+ KR
+
+DC-E5-33 (hex) BRCK
+C00000-CFFFFF (base 16) BRCK
+ PO Box 58275-00200, 2nd Floor Bishop Magua Center, George Padmore Lane, 2nd Floor Bishop Magua Center, George Padmore Lane
+ Nairobi Nairobi 00200
+ KE
+
+A4-DA-22 (hex) Malldon Technology Limited
+900000-9FFFFF (base 16) Malldon Technology Limited
+ 607 Longsheng Technology Building, Longhua Dist
+ Shenzhen Guangdong 518000
+ CN
+
+88-A9-A7 (hex) AVLINK INDUSTRIAL CO., LTD
+D00000-DFFFFF (base 16) AVLINK INDUSTRIAL CO., LTD
+ 7/F, A1 Bldg, 1st Shuichanjingwan Industrial Park, Nanchang Village, Gushu, Bao'an Dist
+ Shenzhen Guangdong 518126
+ CN
+
+88-A9-A7 (hex) Volterman Inc.
+500000-5FFFFF (base 16) Volterman Inc.
+ Suite B2, Sunset Lake Road
+ Newark DE 19702
+ US
+
+F0-41-C8 (hex) Powervault Ltd
+B00000-BFFFFF (base 16) Powervault Ltd
+ 29 Shand Street, London Bridge
+ London SE1 2ES
+ GB
diff --git a/hwdb/ma-small.txt b/hwdb/ma-small.txt
index 5a7b6e7ffc..79b2cc672b 100644
--- a/hwdb/ma-small.txt
+++ b/hwdb/ma-small.txt
@@ -620,12 +620,6 @@ F78000-F78FFF (base 16) Manvish eTech Pvt. Ltd.
SUMIDA-KU TOKYO 1300026
JP
-70-B3-D5 (hex) Vtron Pty Ltd
-341000-341FFF (base 16) Vtron Pty Ltd
- Unit 6, 59 Township Drive
- West Burleigh Queensland 4219
- AU
-
70-B3-D5 (hex) Peek Traffic
875000-875FFF (base 16) Peek Traffic
2906 Corporate Way
@@ -2777,6 +2771,150 @@ B6C000-B6CFFF (base 16) GHM-Messtechnik GmbH (Standort IMTRON)
Kraków 31-031
PL
+70-B3-D5 (hex) KST technology
+351000-351FFF (base 16) KST technology
+ KST B/D 4-5, Wiryeseong-daero 12-gil
+ Songpa-gu Seoul 05636
+ KR
+
+70-B3-D5 (hex) Vtron Pty Ltd
+15D000-15DFFF (base 16) Vtron Pty Ltd
+ Unit 2, 62 Township Drive West
+ West Burleigh Queensland 4219
+ AU
+
+70-B3-D5 (hex) Vtron Pty Ltd
+341000-341FFF (base 16) Vtron Pty Ltd
+ Unit 2, 62 Township Drive West
+ West Burleigh Queensland 4219
+ AU
+
+70-B3-D5 (hex) Kunshan excellent Intelligent Technology Co., Ltd.
+BE4000-BE4FFF (base 16) Kunshan excellent Intelligent Technology Co., Ltd.
+ Room 2002 Site B Modern Square No 8 Wei yi Road
+ kunshan Jiangsu Province 215301
+ CN
+
+70-B3-D5 (hex) YUYAMA MFG Co.,Ltd
+E86000-E86FFF (base 16) YUYAMA MFG Co.,Ltd
+ 3-3-1
+ TOYONAKASHI OSAKA 561-0841
+ JP
+
+70-B3-D5 (hex) QUANTAFLOW
+6EB000-6EBFFF (base 16) QUANTAFLOW
+ AVENUE DU CANADA
+ HONFLEUR 14600
+ FR
+
+70-B3-D5 (hex) FLUDIA
+4A0000-4A0FFF (base 16) FLUDIA
+ 4T rue honoré d'estienne d'orves
+ Suresnes 92150
+ FR
+
+70-B3-D5 (hex) OLEDCOMM
+A43000-A43FFF (base 16) OLEDCOMM
+ 10-12 avenue de l'Europe
+ Vélizy Villacoublay Ile de France 78140
+ FR
+
+70-B3-D5 (hex) Peter Huber Kaeltemaschinenbau AG
+D7B000-D7BFFF (base 16) Peter Huber Kaeltemaschinenbau AG
+ Werner-von-Siemens-Str. 1
+ Offenburg Ba-Wue 77656
+ DE
+
+70-B3-D5 (hex) TORGOVYY DOM TEHNOLOGIY LLC
+7C0000-7C0FFF (base 16) TORGOVYY DOM TEHNOLOGIY LLC
+ The village of Rumyantsevo, Build.1
+ Moscow Moscow 142784
+ RU
+
+70-B3-D5 (hex) Cardinal Health
+75E000-75EFFF (base 16) Cardinal Health
+ 444 McDonnell Blvd.
+ Hazelwood MO 63042
+ US
+
+70-B3-D5 (hex) Matrix Orbital Corporation
+2B7000-2B7FFF (base 16) Matrix Orbital Corporation
+ Suite 602, 4774 Westwinds Dr NE
+ Calgary Alberta T3J 0L7
+ CA
+
+70-B3-D5 (hex) Stone Three
+7BF000-7BFFFF (base 16) Stone Three
+ 24 Gardner Williams Ave
+ Somerset West Western Cape 7130
+ ZA
+
+70-B3-D5 (hex) Transas Marine Limited
+304000-304FFF (base 16) Transas Marine Limited
+ 10 Eastgate Avenue, Eastgate Business Park
+ Little Island, Cork 0
+ IE
+
+70-B3-D5 (hex) MonsoonRF, Inc.
+0F3000-0F3FFF (base 16) MonsoonRF, Inc.
+ 7740 Garvey Ave, Unit D
+ Rosemead CA 91770
+ US
+
+70-B3-D5 (hex) SHINWA INDUSTRIES, INC.
+F87000-F87FFF (base 16) SHINWA INDUSTRIES, INC.
+ Daisan Nishi-Aoyama Bldg. 6F 1-8-1 Shibuya
+ Shibuya-ku Tokyo 150-0002
+ JP
+
+70-B3-D5 (hex) AmTote Australasia
+DAA000-DAAFFF (base 16) AmTote Australasia
+ Unit3, 28 LeightonPlace.
+ HORNSBY NSW 2077
+ AU
+
+70-B3-D5 (hex) EA Elektroautomatik GmbH & Co. KG
+743000-743FFF (base 16) EA Elektroautomatik GmbH & Co. KG
+ Helmholtzstraße 31-33
+ Viersen NRW 41747
+ DE
+
+70-B3-D5 (hex) MB connect line GmbH Fernwartungssysteme
+08A000-08AFFF (base 16) MB connect line GmbH Fernwartungssysteme
+ Winnettener Straße 6
+ Dinkelsbuehl Bavaria 91550
+ DE
+
+70-B3-D5 (hex) Prisma Telecom Testing Srl
+689000-689FFF (base 16) Prisma Telecom Testing Srl
+ Via Petrocchi, 4
+ Milano MI 20127
+ IT
+
+70-B3-D5 (hex) Plantiga Technologies Inc
+525000-525FFF (base 16) Plantiga Technologies Inc
+ 324-611 Alexander Street
+ Vancouver British Columbia V6A 1E1
+ CA
+
+70-B3-D5 (hex) Krontech
+6E9000-6E9FFF (base 16) Krontech
+ I.T.U ARI 3 Teknokent Kron Telekomunikasyon, Maslak
+ Istanbul 34467
+ TR
+
+70-B3-D5 (hex) TRIDENT INFOSOL PVT LTD
+C8F000-C8FFFF (base 16) TRIDENT INFOSOL PVT LTD
+ NO1A , KUSHAL GARDEN , PEENYA INDUSTRIAL AREA
+ BANGALORE 560058
+ IN
+
+70-B3-D5 (hex) Zamir Recognition Systems Ltd.
+981000-981FFF (base 16) Zamir Recognition Systems Ltd.
+ Manachat Tech Park 1/22
+ Jerusalem 96951
+ IL
+
70-B3-D5 (hex) Flintab AB
D60000-D60FFF (base 16) Flintab AB
Kabelvägen 4
@@ -5582,6 +5720,171 @@ FF9000-FF9FFF (base 16) InOut Communication Systems
Udiner UD 33100
IT
+70-B3-D5 (hex) Neuron GmbH
+E1B000-E1BFFF (base 16) Neuron GmbH
+ Badenerstrasse 9
+ Brugg 5200
+ CH
+
+70-B3-D5 (hex) HAVELSAN A.Åž.
+096000-096FFF (base 16) HAVELSAN A.Åž.
+ Mustafa Kemal Mah. 2120.Cad. No.39
+ ANKARA 06510
+ TR
+
+70-B3-D5 (hex) YG COMPANY CO., LTD
+63F000-63FFFF (base 16) YG COMPANY CO., LTD
+ 65, Techno 3-ro
+ Daejeon Yuseong-gu 34016
+ KR
+
+70-B3-D5 (hex) Selex ES Inc.
+F5E000-F5EFFF (base 16) Selex ES Inc.
+ 4221 Tudor Lane
+ Greensboro NC 27410
+ US
+
+70-B3-D5 (hex) DIMASTEC GESTAO DE PONTO E ACESSO EIRELI-ME
+F8F000-F8FFFF (base 16) DIMASTEC GESTAO DE PONTO E ACESSO EIRELI-ME
+ Praça Rotary Club, 355
+ Ribeirão Preto São Paulo 14021-355
+ BR
+
+70-B3-D5 (hex) Savari Inc
+207000-207FFF (base 16) Savari Inc
+ 2005 De la cruz blvd, st 111,
+ santa clara CA 95050
+ US
+
+70-B3-D5 (hex) QIAGEN Instruments AG
+A29000-A29FFF (base 16) QIAGEN Instruments AG
+ Garstligweg 8
+ Hombrechtikon Zurich 8634
+ CH
+
+70-B3-D5 (hex) ONDEMAND LABORATORY Co., Ltd.
+069000-069FFF (base 16) ONDEMAND LABORATORY Co., Ltd.
+ Daiba 449 Space 369 Building 2F
+ Mishima Shizuoka 411-0803
+ JP
+
+70-B3-D5 (hex) EPSOFT Co., Ltd
+A3A000-A3AFFF (base 16) EPSOFT Co., Ltd
+ 301, Bupyeong-daero, Bupyeong-gu
+ Incheon 21315
+ KR
+
+70-B3-D5 (hex) Emergency Lighting Products Limited
+480000-480FFF (base 16) Emergency Lighting Products Limited
+ Gillmans Industrial Estate, Natts Lane
+ Billingshurst RH14 9EZ
+ GB
+
+70-B3-D5 (hex) CSM MACHINERY srl
+FE3000-FE3FFF (base 16) CSM MACHINERY srl
+ Via Cadore Mare, 25
+ Cimetta di Codognè Treviso 31013
+ IT
+
+70-B3-D5 (hex) X-Laser LLC
+711000-711FFF (base 16) X-Laser LLC
+ 9125 Whiskey Bottom Rd Ste A
+ Laurel MD 20723
+ US
+
+70-B3-D5 (hex) GS Elektromedizinsiche Geräte G. Stemple GmbH
+144000-144FFF (base 16) GS Elektromedizinsiche Geräte G. Stemple GmbH
+ Hauswiesenstr. 26
+ Kaufering Bayern 86916
+ DE
+
+70-B3-D5 (hex) NESA SRL
+BFA000-BFAFFF (base 16) NESA SRL
+ Via Sartori, 6/8
+ Vidor Treviso 31020
+ IT
+
+70-B3-D5 (hex) Renesas Electronics
+340000-340FFF (base 16) Renesas Electronics
+ 2801 Scott Blvd
+ Santa Clara CA 95050
+ US
+
+70-B3-D5 (hex) AEM Singapore Pte. Ltd.
+AC1000-AC1FFF (base 16) AEM Singapore Pte. Ltd.
+ 52 Serangoon North Ave 4
+ Singapore Singapore 555853
+ SG
+
+70-B3-D5 (hex) Planewave Instruments
+CB4000-CB4FFF (base 16) Planewave Instruments
+ 1819 Kona Dr.
+ Compton CA 90220
+ US
+
+70-B3-D5 (hex) Avionica
+611000-611FFF (base 16) Avionica
+ 9941 West Jessamine St
+ Miami FL 33157
+ US
+
+70-B3-D5 (hex) ELDES
+9A0000-9A0FFF (base 16) ELDES
+ Ukmerges 283B
+ Vilnius 06313
+ LT
+
+70-B3-D5 (hex) Intesens
+B17000-B17FFF (base 16) Intesens
+ 425 rue Jean Rostand
+ labege 31670
+ FR
+
+70-B3-D5 (hex) Avant Technologies, Inc
+410000-410FFF (base 16) Avant Technologies, Inc
+ Road 156 Caguas West Ind. Park bldg 39
+ Caguas PR 00726
+ US
+
+70-B3-D5 (hex) Lab241 Co.,Ltd.
+21B000-21BFFF (base 16) Lab241 Co.,Ltd.
+ 25Dong 241Ho, 97, Siheung-daero, Geumcheon-gu
+ Seoul Seoul 08639
+ KR
+
+70-B3-D5 (hex) HEITEC AG
+228000-228FFF (base 16) HEITEC AG
+ Dr.-Otto-Leich-Str. 16
+ Eckental Bavaria 90542
+ DE
+
+70-B3-D5 (hex) Alere Technologies AS
+2AE000-2AEFFF (base 16) Alere Technologies AS
+ Kjelsaasveien 161
+ Oslo Oslo 0382
+ NO
+
+70-B3-D5 (hex) Insitu, Inc
+B3B000-B3BFFF (base 16) Insitu, Inc
+ 118 E Columbia River Way
+ Bingen WA 98605
+ US
+
+70-B3-D5 (hex) MatchX GmbH
+1CB000-1CBFFF (base 16) MatchX GmbH
+ Adalbert Str.8
+ Berlin 10999
+ DE
+
+70-B3-D5 (hex) Metrum Sweden AB
+F98000-F98FFF (base 16) Metrum Sweden AB
+ Anders Personsgatan 16
+ Goteborg 41664
+ SE
+
+70-B3-D5 (hex) Private
+DE9000-DE9FFF (base 16) Private
+
70-B3-D5 (hex) Schildknecht AG
494000-494FFF (base 16) Schildknecht AG
Haugweg 26
@@ -7328,18 +7631,6 @@ AE7000-AE7FFF (base 16) E-T-A Elektrotechnische Apparate GmbH
Altdorf 90518
DE
-70-B3-D5 (hex) Vtron Pty Ltd
-400000-400FFF (base 16) Vtron Pty Ltd
- Unit 2, 62 Township Drive
- Australia Queensland 4219
- AU
-
-70-B3-D5 (hex) Vtron Pty Ltd
-E0F000-E0FFFF (base 16) Vtron Pty Ltd
- Unit 6, 59 Township Drive
- West Burleigh Queensland 4219
- AU
-
70-B3-D5 (hex) DSP4YOU LTd
12F000-12FFFF (base 16) DSP4YOU LTd
Unit 1204, 106 How Ming Street
@@ -7784,12 +8075,6 @@ FFC000-FFCFFF (base 16) Symetrics Industries d.b.a. Extant Aerospace
Montoire sur le Loir Loir et Cher 41800
FR
-70-B3-D5 (hex) Vtron Pty Ltd
-B2B000-B2BFFF (base 16) Vtron Pty Ltd
- Unit 2, 62 Township Drive
- West Burleigh Queensland 4219
- AU
-
70-B3-D5 (hex) RJ45 Technologies
9D0000-9D0FFF (base 16) RJ45 Technologies
7, rue Roland Martin
@@ -8039,12 +8324,6 @@ C14000-C14FFF (base 16) Grupo Epelsa S.L.
Alcala de Henares Madrid 28805
ES
-70-B3-D5 (hex) SENSO2ME bvba
-631000-631FFF (base 16) SENSO2ME bvba
- Zandhoef 16
- KASTERLEE België 2460
- BE
-
70-B3-D5 (hex) S Labs sp. z o.o.
C53000-C53FFF (base 16) S Labs sp. z o.o.
Jasnogórska, 44
@@ -8294,6 +8573,120 @@ CFE000-CFEFFF (base 16) Secturion Systems
Centerville UT 84014
US
+70-B3-D5 (hex) Shenzhen INVT Electric Co.,Ltd
+1D0000-1D0FFF (base 16) Shenzhen INVT Electric Co.,Ltd
+ INVT Bldg., GaoFa Scientific Park, Longjing, Nanshan, Shenzhen.
+ Shenzhen Guangdong 518055
+ CN
+
+70-B3-D5 (hex) Vtron Pty Ltd
+400000-400FFF (base 16) Vtron Pty Ltd
+ Unit 2, 62 Township Drive West
+ West Burleigh Queensland 4219
+ AU
+
+70-B3-D5 (hex) Vtron Pty Ltd
+B2B000-B2BFFF (base 16) Vtron Pty Ltd
+ Unit 2, 62 Township Drive West
+ West Burleigh Queensland 4219
+ AU
+
+70-B3-D5 (hex) Vtron Pty Ltd
+E0F000-E0FFFF (base 16) Vtron Pty Ltd
+ Unit 2, 62 Township Drive West
+ West Burleigh Queensland 4219
+ AU
+
+70-B3-D5 (hex) KRONOTECH SRL
+8C8000-8C8FFF (base 16) KRONOTECH SRL
+ VIALE UNGHERIA 125
+ UDINE ITALY/UDINE 33100
+ IT
+
+70-B3-D5 (hex) Particle sizing systems
+670000-670FFF (base 16) Particle sizing systems
+ 8203 Kristel Cir
+ New Port Richey FL 34652
+ US
+
+70-B3-D5 (hex) Grupo Epelsa S.L.
+4E1000-4E1FFF (base 16) Grupo Epelsa S.L.
+ C/ Punto Net,3
+ Alcala de Henares Madrid 28805
+ ES
+
+70-B3-D5 (hex) Waterkotte GmbH
+7EA000-7EAFFF (base 16) Waterkotte GmbH
+ Gewerkenstr. 15
+ Herne 44628
+ DE
+
+70-B3-D5 (hex) Imecon Engineering SrL
+5E3000-5E3FFF (base 16) Imecon Engineering SrL
+ via Gerola 13/15
+ Fiesco CR 26010
+ IT
+
+70-B3-D5 (hex) ELBIT SYSTEMS BMD AND LAND EW - ELISRA LTD
+24F000-24FFFF (base 16) ELBIT SYSTEMS BMD AND LAND EW - ELISRA LTD
+ Hamerchava 29
+ holon 58101
+ IL
+
+70-B3-D5 (hex) HiDes, Inc.
+837000-837FFF (base 16) HiDes, Inc.
+ 6F, No.86, Baozhong Rd., Xindian Dist.,
+ New Taipei City New Taipei City 23144
+ TW
+
+70-B3-D5 (hex) OptoPrecision GmbH
+4F9000-4F9FFF (base 16) OptoPrecision GmbH
+ Auf der Höhe 15
+ Bremen Bremen 28357
+ DE
+
+70-B3-D5 (hex) OSUNG LST CO.,LTD.
+B64000-B64FFF (base 16) OSUNG LST CO.,LTD.
+ #433-31, Sandong-ro, Eumbong-myeon
+ Asan-si Chungcheongnam-do 31418
+ KR
+
+70-B3-D5 (hex) Impulse Automation
+7A3000-7A3FFF (base 16) Impulse Automation
+ Obuhovskoy Oborony 120-B
+ Saint Petersburg Saint Petersburg 192012
+ RU
+
+70-B3-D5 (hex) SENSO2ME
+631000-631FFF (base 16) SENSO2ME
+ Zandhoef 16
+ KASTERLEE België 2460
+ BE
+
+70-B3-D5 (hex) Infodev Electronic Designers Intl.
+DBF000-DBFFFF (base 16) Infodev Electronic Designers Intl.
+ 1995 rue Frank-Carrel Suite 202
+ Quebec Quebec G1N4H9
+ CA
+
+70-B3-D5 (hex) SENSO2ME
+F7A000-F7AFFF (base 16) SENSO2ME
+ Zandhoef 16
+ KASTERLEE België 2460
+ BE
+
+70-B3-D5 (hex) KOSMEK.Ltd
+BB9000-BB9FFF (base 16) KOSMEK.Ltd
+ Murodani 2-1-5, Nishi-ku
+ Kobe-City Hyogo Pref. 6512241
+ JP
+
+70-B3-D5 (hex) Quantum Opus, LLC
+602000-602FFF (base 16) Quantum Opus, LLC
+ 45211 Helm St
+ Plymouth MI 48170
+ US
+
70-B3-D5 (hex) Innitive B.V.
66B000-66BFFF (base 16) Innitive B.V.
Brouwerijstraat 20
@@ -9902,12 +10295,6 @@ B44000-B44FFF (base 16) ENTEC Electric & Electronic Co., LTD.
London NW1 5QP
GB
-70-B3-D5 (hex) Vtron Pty Ltd
-3EF000-3EFFFF (base 16) Vtron Pty Ltd
- Unit 6, 59 Township Drive
- West Burleigh Queensland 4219
- AU
-
70-B3-D5 (hex) Morgan Schaffer Inc.
7C2000-7C2FFF (base 16) Morgan Schaffer Inc.
8300 rue St-Patrick bureau 150
@@ -10925,6 +11312,54 @@ BA2000-BA2FFF (base 16) MAMAC Systems, Inc.
Chanhassen 55317-8002
US
+70-B3-D5 (hex) Vtron Pty Ltd
+3EF000-3EFFFF (base 16) Vtron Pty Ltd
+ Unit 2, 62 Township Drive West
+ West Burleigh Queensland 4219
+ AU
+
+70-B3-D5 (hex) ELVA-1 MICROWAVE HANDELSBOLAG
+FA3000-FA3FFF (base 16) ELVA-1 MICROWAVE HANDELSBOLAG
+ c/o Hornlund, Kungsgatan 54
+ Furulund 244 62
+ SE
+
+70-B3-D5 (hex) Collini Dienstleistungs GmbH
+C67000-C67FFF (base 16) Collini Dienstleistungs GmbH
+ Schweizerstr. 59
+ Hohenems A 6845
+ AT
+
+70-B3-D5 (hex) Richard Paul Russell Ltd
+98B000-98BFFF (base 16) Richard Paul Russell Ltd
+ The Lodge, Unit 1 Barnes Farm Business Park
+ Milford on Sea Hampshire SO41 0AP
+ GB
+
+70-B3-D5 (hex) Association Romandix
+AEB000-AEBFFF (base 16) Association Romandix
+ rue de Sebeillon 9b
+ Lausanne Vaud 1004
+ CH
+
+70-B3-D5 (hex) Special Services Group, LLC
+0F8000-0F8FFF (base 16) Special Services Group, LLC
+ PO Box 825
+ Denair CA 95316
+ US
+
+70-B3-D5 (hex) Divigraph (Pty) LTD
+A86000-A86FFF (base 16) Divigraph (Pty) LTD
+ Postnet Suite 72, Private Bag X7
+ Chempet 7442
+ ZA
+
+70-B3-D5 (hex) Tunstall A/S
+A17000-A17FFF (base 16) Tunstall A/S
+ Niels Bohrs vej 42
+ Stilling Skanderborg 8660
+ DK
+
70-B3-D5 (hex) Saline Lectronics, Inc.
246000-246FFF (base 16) Saline Lectronics, Inc.
710 N Maple Rd
@@ -11009,6 +11444,84 @@ FD6000-FD6FFF (base 16) Visual Fan
Anyang-si Gyeonggi-do 14067
KR
+70-B3-D5 (hex) FactoryLab B.V.
+5DC000-5DCFFF (base 16) FactoryLab B.V.
+ Lindtsedijk 54
+ Zwijndrecht Zuid Holland 3336LE
+ NL
+
+70-B3-D5 (hex) True Networks Ltd.
+AF2000-AF2FFF (base 16) True Networks Ltd.
+ #401 51 Seongnam-Daero Bundang-gu
+ SEONGNAM-si GYEONGGI-do 13636
+ KR
+
+70-B3-D5 (hex) Storbyte, Inc.
+63D000-63DFFF (base 16) Storbyte, Inc.
+ 1800 Washington Blvd Suite 412
+ Baltimore MD 21230
+ US
+
+70-B3-D5 (hex) HGH SYSTEMES INFRAROUGES
+853000-853FFF (base 16) HGH SYSTEMES INFRAROUGES
+ 10 Rue Maryse Bastié
+ Igny IDF 91430
+ FR
+
+70-B3-D5 (hex) Shenzhen bayue software co. LTD
+784000-784FFF (base 16) Shenzhen bayue software co. LTD
+ B301, second phase of China merchants street technology building, nanshan district
+ ShenZhen 518000
+ CN
+
+70-B3-D5 (hex) Preston Industries dba PolyScience
+3B5000-3B5FFF (base 16) Preston Industries dba PolyScience
+ 6600 W. Touhy Ave
+ Niles IL 60714-4588
+ US
+
+70-B3-D5 (hex) KMtronic ltd
+0AF000-0AFFFF (base 16) KMtronic ltd
+ Dobri Czintulov 28A str.
+ Gorna Oryahovica VT 5100
+ BG
+
+70-B3-D5 (hex) BLOCKSI LLC
+9E6000-9E6FFF (base 16) BLOCKSI LLC
+ 228 Hamilton avenue 3rd floor
+ Palo Alto 94301
+ US
+
+70-B3-D5 (hex) Fire4 Systems UK Ltd
+E69000-E69FFF (base 16) Fire4 Systems UK Ltd
+ 8 Regent Street
+ Leeds West Yorkshire LS7 4PE
+ GB
+
+70-B3-D5 (hex) RealD
+CCB000-CCBFFF (base 16) RealD
+ 5700 Flatiron Parkway
+ Boulder CO 80301
+ US
+
+70-B3-D5 (hex) Melecs EWS GmbH
+704000-704FFF (base 16) Melecs EWS GmbH
+ GZO-Technologiestrasse 1
+ Siegendorf 7011
+ AT
+
+70-B3-D5 (hex) Raft Technologies
+8D0000-8D0FFF (base 16) Raft Technologies
+ Habarzel 25
+ Tel aviv 6971035
+ IL
+
+70-B3-D5 (hex) Jacarta Ltd
+09B000-09BFFF (base 16) Jacarta Ltd
+ Wagon Yard, London Road
+ Marlborough SN8 1LH
+ GB
+
70-B3-D5 (hex) EMAC, Inc.
8AB000-8ABFFF (base 16) EMAC, Inc.
2390 EMAC Way
@@ -11378,12 +11891,6 @@ A27000-A27FFF (base 16) HDL da Amazônia Industria Eletrônica Ltda
Manaus MN 69075-010
BR
-70-B3-D5 (hex) Insitu Inc
-7AD000-7ADFFF (base 16) Insitu Inc
- 118 E. Columbia River Way
- Bingen Washington 98605
- US
-
70-B3-D5 (hex) LLVISION TECHNOLOGY CO.,LTD
E21000-E21FFF (base 16) LLVISION TECHNOLOGY CO.,LTD
Room302,Building A Fuxing,No.30 He Tao Yuan,Guan Dong Dian Bei Jie
@@ -13699,3 +14206,123 @@ EF9000-EF9FFF (base 16) Critical Link LLC
Av. Onze de Setembre 19
Reus Tarragona 43203
ES
+
+70-B3-D5 (hex) Triax A/S
+963000-963FFF (base 16) Triax A/S
+ Bjornkaervej 3
+ Hornsyld Denmark 8783
+ DK
+
+70-B3-D5 (hex) White Matter LLC
+368000-368FFF (base 16) White Matter LLC
+ 999 3rd Ave 700
+ Seattle 98104
+ US
+
+70-B3-D5 (hex) iFreecomm Technology Co., Ltd
+032000-032FFF (base 16) iFreecomm Technology Co., Ltd
+ D401, NO.16 Langshan Road, Nanshan District
+ Shenzhen Guangdong 518057
+ CN
+
+70-B3-D5 (hex) RELISTE Ges.m.b.H.
+1B9000-1B9FFF (base 16) RELISTE Ges.m.b.H.
+ Enzersdorfer Strasse 8-10
+ Brunn am Gebirge 2345
+ AT
+
+70-B3-D5 (hex) JUSTEK INC
+EB5000-EB5FFF (base 16) JUSTEK INC
+ 613-9, DONGCHUN-RI, JINWI-MYEON
+ PYEONGTAEK-SI GYEONGGI-DO 17711
+ KR
+
+70-B3-D5 (hex) SHENZHEN WISEWING INTERNET TECHNOLOGY CO.,LTD
+94A000-94AFFF (base 16) SHENZHEN WISEWING INTERNET TECHNOLOGY CO.,LTD
+ No.826,Zone 1,Block B,Famous industrial product display purchasing center,Baoyuan Road,Xixiang,Bao'an Dis., Shenzhen,P.R.China
+ shenzhen China 518102
+ CN
+
+70-B3-D5 (hex) Mo-Sys Engineering Ltd
+075000-075FFF (base 16) Mo-Sys Engineering Ltd
+ Thames Bank House, Tunnel Avenue
+ London SE100PA
+ GB
+
+70-B3-D5 (hex) Abbas, a.s.
+B18000-B18FFF (base 16) Abbas, a.s.
+ Edisonova 5
+ Brno CZ 61200
+ CZ
+
+70-B3-D5 (hex) Shanghai Holystar Information Technology Co.,Ltd
+6E1000-6E1FFF (base 16) Shanghai Holystar Information Technology Co.,Ltd
+ 8F Building A3 NO.1528 Gumei Rd Shanghai China PR
+ shanghai 200233
+ CN
+
+70-B3-D5 (hex) Mimo Networks
+25D000-25DFFF (base 16) Mimo Networks
+ 701 E Middlefield Road Mountain View,
+ Mountain View CA 94043
+ US
+
+70-B3-D5 (hex) ATBiS Co.,Ltd
+C2F000-C2FFFF (base 16) ATBiS Co.,Ltd
+ #1603 5th. Ace High-end Tower, 226 Gasan Digital 1-ro, Geumcheon-gu
+ Seoul 08502
+ KR
+
+70-B3-D5 (hex) Cyanview
+E3A000-E3AFFF (base 16) Cyanview
+ 26, Rue de la Foire
+ Papignies 7861
+ BE
+
+70-B3-D5 (hex) AdInte, inc.
+BAC000-BACFFF (base 16) AdInte, inc.
+ 347-1, Shijo-cho, Shimogyo-ku, 7F CUBE Nishikarasuma BLDG.
+ Kyoto-shi Kyoto 6008441
+ JP
+
+70-B3-D5 (hex) Valk Welding B.V.
+5DA000-5DAFFF (base 16) Valk Welding B.V.
+ Staalindustrieweg 15
+ Alblasserdam Zuid Holland 2952 AT
+ NL
+
+70-B3-D5 (hex) VITEC
+CDA000-CDAFFF (base 16) VITEC
+ 99 rue pierre sémard
+ Chatillon France 92320
+ FR
+
+70-B3-D5 (hex) Nortek Global HVAC
+4D4000-4D4FFF (base 16) Nortek Global HVAC
+ Fens Pool Ave
+ Brierley Hill West Midlands DY5 1QA
+ GB
+
+70-B3-D5 (hex) Insitu, Inc
+7AD000-7ADFFF (base 16) Insitu, Inc
+ 118 E Columbia River Way
+ Bingen WA 98605
+ US
+
+70-B3-D5 (hex) KWS-Electronic GmbH
+EB3000-EB3FFF (base 16) KWS-Electronic GmbH
+ Sportplatzstrasse 1
+ Grosskarolinenfeld D-83109
+ DE
+
+70-B3-D5 (hex) University Of Groningen
+700000-700FFF (base 16) University Of Groningen
+ Broerstraat 5
+ Groningen Groningen 9712 CP
+ NL
+
+70-B3-D5 (hex) Globalcom Engineering SPA
+A0D000-A0DFFF (base 16) Globalcom Engineering SPA
+ Via Volta 39
+ CARDANO AL CAMPO VA 21010
+ IT
diff --git a/hwdb/meson.build b/hwdb/meson.build
index a5175039cd..d333ee68a3 100644
--- a/hwdb/meson.build
+++ b/hwdb/meson.build
@@ -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
diff --git a/hwdb/parse_hwdb.py b/hwdb/parse_hwdb.py
index a25ac8d904..f4cc9c6974 100755
--- a/hwdb/parse_hwdb.py
+++ b/hwdb/parse_hwdb.py
@@ -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')),
diff --git a/hwdb/pci.ids b/hwdb/pci.ids
index be21887b09..f749ba4010 100644
--- a/hwdb/pci.ids
+++ b/hwdb/pci.ids
@@ -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/.
@@ -77,18 +77,18 @@
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
@@ -249,6 +249,9 @@
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
@@ -258,9 +261,15 @@
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
@@ -584,9 +593,12 @@
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
@@ -737,6 +749,7 @@
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]
@@ -905,6 +918,7 @@
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
@@ -915,6 +929,7 @@
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
@@ -966,14 +981,17 @@
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]
@@ -982,6 +1000,7 @@
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
@@ -989,25 +1008,30 @@
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)
@@ -1575,6 +1599,7 @@
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]
@@ -1603,6 +1628,7 @@
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]
@@ -2344,7 +2370,8 @@
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]
@@ -2478,6 +2505,7 @@
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]
@@ -3129,8 +3157,9 @@
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)
@@ -3155,6 +3184,7 @@
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
@@ -3372,6 +3402,7 @@
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]
@@ -4008,16 +4039,21 @@
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
@@ -4111,7 +4147,9 @@
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
@@ -4607,7 +4645,7 @@
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
@@ -4615,7 +4653,7 @@
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
@@ -4629,7 +4667,7 @@
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
@@ -4637,23 +4675,23 @@
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
@@ -5168,11 +5206,9 @@
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.
@@ -5185,11 +5221,11 @@
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
@@ -6145,6 +6181,7 @@
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
@@ -6154,6 +6191,7 @@
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
@@ -6195,6 +6233,10 @@
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
@@ -6215,6 +6257,8 @@
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)
@@ -9256,19 +9300,19 @@
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
@@ -10690,10 +10734,10 @@
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
@@ -10717,11 +10761,12 @@
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]
@@ -10801,7 +10846,7 @@
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]
@@ -10811,7 +10856,7 @@
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]
@@ -10820,6 +10865,8 @@
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]
@@ -10835,7 +10882,7 @@
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]
@@ -10845,10 +10892,12 @@
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
@@ -10863,7 +10912,7 @@
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]
@@ -10889,6 +10938,8 @@
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
@@ -10896,6 +10947,7 @@
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
@@ -10946,6 +10998,9 @@
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
@@ -11084,8 +11139,8 @@
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
@@ -11145,6 +11200,7 @@
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
@@ -11222,6 +11278,7 @@
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
@@ -12524,6 +12581,8 @@
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
@@ -12980,7 +13039,7 @@
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
@@ -14922,6 +14981,7 @@
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
@@ -15276,7 +15336,7 @@
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
@@ -15438,9 +15498,9 @@
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)
@@ -15467,7 +15527,7 @@
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
@@ -15745,6 +15805,7 @@
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
@@ -16239,6 +16300,8 @@
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
@@ -16299,6 +16362,8 @@
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
@@ -16419,6 +16484,8 @@
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
@@ -16518,6 +16585,8 @@
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
@@ -16536,6 +16605,8 @@
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
@@ -16554,6 +16625,8 @@
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
@@ -16572,6 +16645,8 @@
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
@@ -16590,6 +16665,8 @@
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]
@@ -16608,6 +16685,8 @@
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
@@ -17247,6 +17326,7 @@
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
@@ -17371,7 +17451,8 @@
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
@@ -19125,12 +19206,14 @@
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
@@ -19539,6 +19622,7 @@
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
@@ -19985,6 +20069,7 @@
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)
@@ -20170,6 +20255,7 @@
# 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
@@ -20730,6 +20816,8 @@
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
@@ -20863,6 +20951,9 @@
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
@@ -20897,6 +20988,7 @@
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
@@ -21705,6 +21797,7 @@
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
@@ -21916,6 +22009,7 @@
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
@@ -22114,6 +22208,12 @@
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]
@@ -22123,6 +22223,7 @@
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
@@ -22209,9 +22310,11 @@
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
@@ -22225,7 +22328,16 @@
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
@@ -22999,6 +23111,8 @@
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
@@ -23314,6 +23428,7 @@
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
@@ -23434,6 +23549,7 @@
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+
@@ -23544,6 +23660,7 @@
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
@@ -23626,7 +23743,7 @@
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
@@ -24758,7 +24875,7 @@
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
@@ -25755,7 +25872,7 @@
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
@@ -25930,7 +26047,7 @@
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
@@ -25985,14 +26102,14 @@
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]
@@ -26004,7 +26121,7 @@
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]
@@ -26018,7 +26135,7 @@
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
@@ -26038,7 +26155,7 @@
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
@@ -26055,7 +26172,7 @@
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
@@ -26070,7 +26187,7 @@
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
@@ -26085,7 +26202,7 @@
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
@@ -26101,7 +26218,7 @@
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
@@ -26112,7 +26229,7 @@
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
@@ -26129,7 +26246,7 @@
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
@@ -26143,7 +26260,7 @@
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
@@ -26154,7 +26271,7 @@
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
@@ -26164,8 +26281,7 @@
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
@@ -26176,12 +26292,10 @@
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
@@ -26235,16 +26349,14 @@
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
@@ -28906,6 +29018,34 @@
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)
diff --git a/hwdb/pnp_id_registry.html b/hwdb/pnp_id_registry.html
index 3b00f5bf04..a2752e252e 100644
--- a/hwdb/pnp_id_registry.html
+++ b/hwdb/pnp_id_registry.html
@@ -579,7 +579,7 @@
<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>
@@ -2408,6 +2408,21 @@
<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>
diff --git a/hwdb/usb.ids b/hwdb/usb.ids
index dae1bf350c..ec20b2fa22 100644
--- a/hwdb/usb.ids
+++ b/hwdb/usb.ids
@@ -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]
@@ -109,6 +111,7 @@
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
@@ -202,6 +205,7 @@
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
@@ -236,6 +240,7 @@
0611 OfficeJet K60xi
0612 business inkjet 3000
0624 Bluetooth Dongle
+ 0641 X1200 Optical Mouse
0701 ScanJet 5300c/5370c
0704 DeskJet 825c
0705 ScanJet 4400c
@@ -314,6 +319,7 @@
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
@@ -528,6 +534,7 @@
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
@@ -648,6 +655,7 @@
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
@@ -781,6 +789,8 @@
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)
@@ -1114,6 +1124,7 @@
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
@@ -1431,6 +1442,10 @@
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)
@@ -2318,6 +2333,7 @@
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
@@ -2327,11 +2343,13 @@
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
@@ -2387,7 +2405,7 @@
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
@@ -2405,6 +2423,7 @@
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
@@ -2586,6 +2605,7 @@
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
@@ -2758,6 +2778,7 @@
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
@@ -3121,6 +3142,7 @@
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)
@@ -3251,6 +3273,7 @@
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
@@ -3673,12 +3696,12 @@
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
@@ -3733,9 +3756,9 @@
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
@@ -3746,6 +3769,7 @@
2686 MF6500 series
2687 iR4530
2688 LBP3460
+ 2689 FAX-L180/L380S/L398S
268c iR C6870
268d iR 6870C EUR
268e iR C5870
@@ -3757,6 +3781,7 @@
26b5 MF4200 series
26da LBP3010B printer
26e6 iR1024
+ 271a LBP6000
2736 I-SENSYS MF4550d
2737 MF4410
3041 PowerShot S10
@@ -4067,6 +4092,7 @@
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
@@ -4528,6 +4554,8 @@
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
@@ -4633,6 +4661,7 @@
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)
@@ -4646,6 +4675,8 @@
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)
@@ -4745,9 +4776,11 @@
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
@@ -5234,6 +5267,7 @@
b104 CNF7069 Webcam
b107 CNF7070 Webcam
b14c CNF8050 Webcam
+ b159 CNF8243 Webcam
b15c Sony Vaio Integrated Camera
b175 4-Port Hub
b1aa Webcam-101
@@ -5265,6 +5299,7 @@
04f3 Elan Microelectronics Corp.
000a Touchscreen
0103 ActiveJet K-2024 Multimedia Keyboard
+ 016f Touchscreen
01a4 Wireless Keyboard
0201 Touchscreen
0210 Optical Mouse
@@ -5320,6 +5355,7 @@
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
@@ -5507,6 +5543,7 @@
021c MFC-9320CW
021d MFC-9120CN
021e DCP-9010CN
+ 021f DCP-8085DN
0220 MFC-9010CN
0222 DCP-195C
0223 DCP-365CN
@@ -5531,6 +5568,7 @@
023f MFC-8680DN
0240 MFC-J950DN
0248 DCP-7055 scanner/printer
+ 024e MFC-7460DN
0253 DCP-J125
0254 DCP-J315W
0255 DCP-J515W
@@ -5550,6 +5588,7 @@
026d MFC-J805D
026e MFC-J855DN
026f MFC-J270W
+ 0270 MFC-7360N
0273 DCP-7057 scanner/printer
0276 MFC-5895CW
0278 MFC-J410W
@@ -5781,6 +5820,7 @@
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
@@ -6162,6 +6202,7 @@
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
@@ -6358,6 +6399,7 @@
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
@@ -6664,6 +6706,8 @@
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
@@ -6684,6 +6728,7 @@
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]
@@ -8334,6 +8379,7 @@
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)
diff --git a/man/binfmt.d.xml b/man/binfmt.d.xml
index 5b63cfb4c3..5f55cb4db2 100644
--- a/man/binfmt.d.xml
+++ b/man/binfmt.d.xml
@@ -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
diff --git a/man/bootctl.xml b/man/bootctl.xml
index 675e0174e9..7662593a70 100644
--- a/man/bootctl.xml
+++ b/man/bootctl.xml
@@ -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
@@ -103,6 +111,14 @@
</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>
@@ -119,7 +135,7 @@
<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>
diff --git a/man/bootup.xml b/man/bootup.xml
index b92c60f43a..56f4f57097 100644
--- a/man/bootup.xml
+++ b/man/bootup.xml
@@ -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
diff --git a/man/busctl.xml b/man/busctl.xml
index 28b36f09d0..0c0d28b5d3 100644
--- a/man/busctl.xml
+++ b/man/busctl.xml
@@ -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
@@ -145,6 +147,7 @@
</varlistentry>
<varlistentry>
+ <term><option>-q</option></term>
<term><option>--quiet</option></term>
<listitem>
diff --git a/man/coredump.conf.xml b/man/coredump.conf.xml
index 5f61e05f40..097296059f 100644
--- a/man/coredump.conf.xml
+++ b/man/coredump.conf.xml
@@ -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
diff --git a/man/coredumpctl.xml b/man/coredumpctl.xml
index 5bbd5222af..72191d1dc2 100644
--- a/man/coredumpctl.xml
+++ b/man/coredumpctl.xml
@@ -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
@@ -142,7 +144,7 @@
<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>
diff --git a/man/crypttab.xml b/man/crypttab.xml
index ac7d55271c..474d3d83e0 100644
--- a/man/crypttab.xml
+++ b/man/crypttab.xml
@@ -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
@@ -198,10 +200,19 @@
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>
diff --git a/man/custom-entities.ent.in b/man/custom-entities.ent.in
index 0257c2a94f..9ea92384aa 100644
--- a/man/custom-entities.ent.in
+++ b/man/custom-entities.ent.in
@@ -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@>
diff --git a/man/custom-html.xsl b/man/custom-html.xsl
index e89d73e7f1..47ce6abfee 100644
--- a/man/custom-html.xsl
+++ b/man/custom-html.xsl
@@ -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
diff --git a/man/custom-man.xsl b/man/custom-man.xsl
index e1b8d3618a..3307fd3c0d 100644
--- a/man/custom-man.xsl
+++ b/man/custom-man.xsl
@@ -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
diff --git a/man/daemon.xml b/man/daemon.xml
index 485c66225e..18337daad8 100644
--- a/man/daemon.xml
+++ b/man/daemon.xml
@@ -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
@@ -505,10 +507,10 @@
</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>
@@ -560,7 +562,7 @@
</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
diff --git a/man/dnssec-trust-anchors.d.xml b/man/dnssec-trust-anchors.d.xml
index 6e90e6aef9..d6e488065b 100644
--- a/man/dnssec-trust-anchors.d.xml
+++ b/man/dnssec-trust-anchors.d.xml
@@ -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
diff --git a/man/environment.d.xml b/man/environment.d.xml
index ad9db1666f..7dedfa4891 100644
--- a/man/environment.d.xml
+++ b/man/environment.d.xml
@@ -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>
diff --git a/man/file-hierarchy.xml b/man/file-hierarchy.xml
index ab52ccfe0c..b1442dd82c 100644
--- a/man/file-hierarchy.xml
+++ b/man/file-hierarchy.xml
@@ -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
diff --git a/man/glib-event-glue.c b/man/glib-event-glue.c
index 8f3168d0ea..32d8e921b8 100644
--- a/man/glib-event-glue.c
+++ b/man/glib-event-glue.c
@@ -1,4 +1,6 @@
/***
+ SPDX-License-Identifier: MIT
+
Copyright 2014 Tom Gundersen
Permission is hereby granted, free of charge, to any person
diff --git a/man/halt.xml b/man/halt.xml
index e3fa60a915..0abcdb475c 100644
--- a/man/halt.xml
+++ b/man/halt.xml
@@ -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
@@ -112,8 +114,13 @@
<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>
diff --git a/man/hostname.xml b/man/hostname.xml
index 8a4c0d5ac0..7b0fd29237 100644
--- a/man/hostname.xml
+++ b/man/hostname.xml
@@ -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
diff --git a/man/hostnamectl.xml b/man/hostnamectl.xml
index 81bce2da6a..fa70d5cc6c 100644
--- a/man/hostnamectl.xml
+++ b/man/hostnamectl.xml
@@ -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
diff --git a/man/hwdb.xml b/man/hwdb.xml
index ae5ddb1a4d..bf89819949 100644
--- a/man/hwdb.xml
+++ b/man/hwdb.xml
@@ -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>
diff --git a/man/journal-remote.conf.xml b/man/journal-remote.conf.xml
index f7ac8c46e0..ed49c39f35 100644
--- a/man/journal-remote.conf.xml
+++ b/man/journal-remote.conf.xml
@@ -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
diff --git a/man/journal-upload.conf.xml b/man/journal-upload.conf.xml
index e3be62dfd1..bbb6df503b 100644
--- a/man/journal-upload.conf.xml
+++ b/man/journal-upload.conf.xml
@@ -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
diff --git a/man/journalctl.xml b/man/journalctl.xml
index 444b916073..257ff5a816 100644
--- a/man/journalctl.xml
+++ b/man/journalctl.xml
@@ -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
@@ -385,6 +387,20 @@
</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
@@ -423,7 +439,7 @@
<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
diff --git a/man/journald.conf.xml b/man/journald.conf.xml
index 8974f8f8d5..844228e324 100644
--- a/man/journald.conf.xml
+++ b/man/journald.conf.xml
@@ -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
@@ -379,7 +381,7 @@
<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
diff --git a/man/kernel-command-line.xml b/man/kernel-command-line.xml
index 4ab76487df..422c0607da 100644
--- a/man/kernel-command-line.xml
+++ b/man/kernel-command-line.xml
@@ -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
@@ -381,6 +383,15 @@
</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>
diff --git a/man/kernel-install.xml b/man/kernel-install.xml
index 94b6b1110d..fa86a3aaa0 100644
--- a/man/kernel-install.xml
+++ b/man/kernel-install.xml
@@ -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
diff --git a/man/less-variables.xml b/man/less-variables.xml
index 396481c937..750815e7ce 100644
--- a/man/less-variables.xml
+++ b/man/less-variables.xml
@@ -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>
diff --git a/man/libsystemd-pkgconfig.xml b/man/libsystemd-pkgconfig.xml
index 272da64cd7..b98f60922a 100644
--- a/man/libsystemd-pkgconfig.xml
+++ b/man/libsystemd-pkgconfig.xml
@@ -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>
diff --git a/man/libudev.xml b/man/libudev.xml
index 53b68dcc89..e92db55759 100644
--- a/man/libudev.xml
+++ b/man/libudev.xml
@@ -6,6 +6,8 @@
]>
<!--
+ SPDX-License-Identifier: LGPL-2.1+
+
This file is part of systemd.
Copyright 2015 David Herrmann <dh.herrmann@gmail.com>
diff --git a/man/locale.conf.xml b/man/locale.conf.xml
index 1405dda3fd..cd349acdcd 100644
--- a/man/locale.conf.xml
+++ b/man/locale.conf.xml
@@ -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
diff --git a/man/localectl.xml b/man/localectl.xml
index 7da12c29de..89a7ab2855 100644
--- a/man/localectl.xml
+++ b/man/localectl.xml
@@ -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
@@ -110,6 +112,7 @@
</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" />
diff --git a/man/localtime.xml b/man/localtime.xml
index 2827da6e93..0341c61614 100644
--- a/man/localtime.xml
+++ b/man/localtime.xml
@@ -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
diff --git a/man/loginctl.xml b/man/loginctl.xml
index 534a0d961e..65c5227ed3 100644
--- a/man/loginctl.xml
+++ b/man/loginctl.xml
@@ -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
@@ -280,11 +282,10 @@
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>
diff --git a/man/logind.conf.xml b/man/logind.conf.xml
index 16f51af72c..8d2bfc5d5b 100644
--- a/man/logind.conf.xml
+++ b/man/logind.conf.xml
@@ -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
diff --git a/man/machine-id.xml b/man/machine-id.xml
index 3c261bffcc..3d82a3edaf 100644
--- a/man/machine-id.xml
+++ b/man/machine-id.xml
@@ -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
@@ -53,18 +55,26 @@
<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>
@@ -79,19 +89,59 @@
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>
diff --git a/man/machine-info.xml b/man/machine-info.xml
index cd5997d4e2..b9f4fa821e 100644
--- a/man/machine-info.xml
+++ b/man/machine-info.xml
@@ -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
diff --git a/man/machinectl.xml b/man/machinectl.xml
index cf46fe8024..43f4d127b8 100644
--- a/man/machinectl.xml
+++ b/man/machinectl.xml
@@ -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
@@ -208,16 +210,16 @@
<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>
@@ -299,6 +301,13 @@
<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>
@@ -528,14 +537,16 @@
<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>
diff --git a/man/meson.build b/man/meson.build
index 7d28e6ba1a..3a684101d2 100644
--- a/man/meson.build
+++ b/man/meson.build
@@ -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')
@@ -32,7 +49,7 @@ custom_entities_ent = configure_file(
man_pages = []
html_pages = []
source_xml_files = []
-foreach tuple : manpages
+foreach tuple : xsltproc.found() ? manpages : []
stem = tuple[0]
section = tuple[1]
aliases = tuple[2]
@@ -115,8 +132,8 @@ systemd_index_xml = custom_target(
output : 'systemd.index.xml',
command : [make_man_index_py, '@OUTPUT@'] + nonindex_xml_files)
-foreach tuple : [['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]
diff --git a/man/modules-load.d.xml b/man/modules-load.d.xml
index 4b722aa128..0dd0c3c161 100644
--- a/man/modules-load.d.xml
+++ b/man/modules-load.d.xml
@@ -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
diff --git a/man/networkctl.xml b/man/networkctl.xml
index d4fa5e9029..33e0629d80 100644
--- a/man/networkctl.xml
+++ b/man/networkctl.xml
@@ -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
diff --git a/man/networkd.conf.xml b/man/networkd.conf.xml
index 57e647a31b..8a16058161 100644
--- a/man/networkd.conf.xml
+++ b/man/networkd.conf.xml
@@ -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
diff --git a/man/nss-myhostname.xml b/man/nss-myhostname.xml
index 6e05cb1897..bf3ea405a1 100644
--- a/man/nss-myhostname.xml
+++ b/man/nss-myhostname.xml
@@ -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
diff --git a/man/nss-mymachines.xml b/man/nss-mymachines.xml
index 00bcc53ec0..dc3076ab0d 100644
--- a/man/nss-mymachines.xml
+++ b/man/nss-mymachines.xml
@@ -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
diff --git a/man/nss-resolve.xml b/man/nss-resolve.xml
index f88c25c453..edd4e9d32e 100644
--- a/man/nss-resolve.xml
+++ b/man/nss-resolve.xml
@@ -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
diff --git a/man/nss-systemd.xml b/man/nss-systemd.xml
index 34811f0a2e..0114a6f936 100644
--- a/man/nss-systemd.xml
+++ b/man/nss-systemd.xml
@@ -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
diff --git a/man/os-release.xml b/man/os-release.xml
index 99bbb61004..b0468c16a0 100644
--- a/man/os-release.xml
+++ b/man/os-release.xml
@@ -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
diff --git a/man/pam_systemd.xml b/man/pam_systemd.xml
index cef5445c1c..f45631688c 100644
--- a/man/pam_systemd.xml
+++ b/man/pam_systemd.xml
@@ -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
diff --git a/man/resolved.conf.xml b/man/resolved.conf.xml
index 1846df7502..451b9cdd01 100644
--- a/man/resolved.conf.xml
+++ b/man/resolved.conf.xml
@@ -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
diff --git a/man/rules/meson.build b/man/rules/meson.build
index ae0556058e..499fe6d19e 100644
--- a/man/rules/meson.build
+++ b/man/rules/meson.build
@@ -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', [], ''],
diff --git a/man/runlevel.xml b/man/runlevel.xml
index 50fdacde00..b3d90d8ff4 100644
--- a/man/runlevel.xml
+++ b/man/runlevel.xml
@@ -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
diff --git a/man/sd-bus-errors.xml b/man/sd-bus-errors.xml
index 055af7a682..a655ab1d97 100644
--- a/man/sd-bus-errors.xml
+++ b/man/sd-bus-errors.xml
@@ -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
diff --git a/man/sd-bus.xml b/man/sd-bus.xml
index 6439395549..48d62d466f 100644
--- a/man/sd-bus.xml
+++ b/man/sd-bus.xml
@@ -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
diff --git a/man/sd-daemon.xml b/man/sd-daemon.xml
index b06d99f346..151d89e698 100644
--- a/man/sd-daemon.xml
+++ b/man/sd-daemon.xml
@@ -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
diff --git a/man/sd-event.xml b/man/sd-event.xml
index 24a69bb645..2518050570 100644
--- a/man/sd-event.xml
+++ b/man/sd-event.xml
@@ -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
diff --git a/man/sd-id128.xml b/man/sd-id128.xml
index bc74e3f481..bd27237978 100644
--- a/man/sd-id128.xml
+++ b/man/sd-id128.xml
@@ -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
diff --git a/man/sd-journal.xml b/man/sd-journal.xml
index 0f4b3e8eea..52f99c7f4c 100644
--- a/man/sd-journal.xml
+++ b/man/sd-journal.xml
@@ -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
diff --git a/man/sd-login.xml b/man/sd-login.xml
index b2131a9af9..148dd19cea 100644
--- a/man/sd-login.xml
+++ b/man/sd-login.xml
@@ -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
diff --git a/man/sd_booted.xml b/man/sd_booted.xml
index 4dd674b8ea..54a9de894b 100644
--- a/man/sd_booted.xml
+++ b/man/sd_booted.xml
@@ -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
diff --git a/man/sd_bus_add_match.xml b/man/sd_bus_add_match.xml
index 2014141ae3..4772c738ac 100644
--- a/man/sd_bus_add_match.xml
+++ b/man/sd_bus_add_match.xml
@@ -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
diff --git a/man/sd_bus_creds_get_pid.xml b/man/sd_bus_creds_get_pid.xml
index 9e68d5e8c7..6bc78edf07 100644
--- a/man/sd_bus_creds_get_pid.xml
+++ b/man/sd_bus_creds_get_pid.xml
@@ -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
@@ -394,16 +396,19 @@
<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 check whether the capability specified by
@@ -500,15 +505,16 @@
<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
diff --git a/man/sd_bus_creds_new_from_pid.xml b/man/sd_bus_creds_new_from_pid.xml
index b4d7d61d0f..5cdff073ea 100644
--- a/man/sd_bus_creds_new_from_pid.xml
+++ b/man/sd_bus_creds_new_from_pid.xml
@@ -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
diff --git a/man/sd_bus_default.xml b/man/sd_bus_default.xml
index d9102a36ce..62520ff4dd 100644
--- a/man/sd_bus_default.xml
+++ b/man/sd_bus_default.xml
@@ -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
diff --git a/man/sd_bus_error.xml b/man/sd_bus_error.xml
index 4970ce3c08..ef40178f1f 100644
--- a/man/sd_bus_error.xml
+++ b/man/sd_bus_error.xml
@@ -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
diff --git a/man/sd_bus_error_add_map.xml b/man/sd_bus_error_add_map.xml
index a1eda21ed5..b79381fefd 100644
--- a/man/sd_bus_error_add_map.xml
+++ b/man/sd_bus_error_add_map.xml
@@ -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
diff --git a/man/sd_bus_get_fd.xml b/man/sd_bus_get_fd.xml
index 9f7019069f..2e867b0bf7 100644
--- a/man/sd_bus_get_fd.xml
+++ b/man/sd_bus_get_fd.xml
@@ -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
diff --git a/man/sd_bus_message_append.xml b/man/sd_bus_message_append.xml
index 2c28ee7154..3fba212014 100644
--- a/man/sd_bus_message_append.xml
+++ b/man/sd_bus_message_append.xml
@@ -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
diff --git a/man/sd_bus_message_append_array.xml b/man/sd_bus_message_append_array.xml
index 27db2a96c3..2b9f3d1832 100644
--- a/man/sd_bus_message_append_array.xml
+++ b/man/sd_bus_message_append_array.xml
@@ -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
diff --git a/man/sd_bus_message_append_basic.xml b/man/sd_bus_message_append_basic.xml
index 276953af69..bec126836e 100644
--- a/man/sd_bus_message_append_basic.xml
+++ b/man/sd_bus_message_append_basic.xml
@@ -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
diff --git a/man/sd_bus_message_append_string_memfd.xml b/man/sd_bus_message_append_string_memfd.xml
index 9e99999bf3..470c62d4e1 100644
--- a/man/sd_bus_message_append_string_memfd.xml
+++ b/man/sd_bus_message_append_string_memfd.xml
@@ -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
diff --git a/man/sd_bus_message_append_strv.xml b/man/sd_bus_message_append_strv.xml
index 0f77adcc8b..21feafd501 100644
--- a/man/sd_bus_message_append_strv.xml
+++ b/man/sd_bus_message_append_strv.xml
@@ -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
diff --git a/man/sd_bus_message_get_cookie.xml b/man/sd_bus_message_get_cookie.xml
index 3328eead3d..d87d361501 100644
--- a/man/sd_bus_message_get_cookie.xml
+++ b/man/sd_bus_message_get_cookie.xml
@@ -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
diff --git a/man/sd_bus_message_get_monotonic_usec.xml b/man/sd_bus_message_get_monotonic_usec.xml
index 2c0a8a5d54..9d619e5f68 100644
--- a/man/sd_bus_message_get_monotonic_usec.xml
+++ b/man/sd_bus_message_get_monotonic_usec.xml
@@ -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
diff --git a/man/sd_bus_message_read_basic.xml b/man/sd_bus_message_read_basic.xml
index 6a46403159..eb1750b2db 100644
--- a/man/sd_bus_message_read_basic.xml
+++ b/man/sd_bus_message_read_basic.xml
@@ -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
diff --git a/man/sd_bus_negotiate_fds.xml b/man/sd_bus_negotiate_fds.xml
index e91269ba31..5841c2dad6 100644
--- a/man/sd_bus_negotiate_fds.xml
+++ b/man/sd_bus_negotiate_fds.xml
@@ -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
diff --git a/man/sd_bus_new.xml b/man/sd_bus_new.xml
index d281b5dd44..57e9f4a9cf 100644
--- a/man/sd_bus_new.xml
+++ b/man/sd_bus_new.xml
@@ -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
diff --git a/man/sd_bus_path_encode.xml b/man/sd_bus_path_encode.xml
index 986eccc6a8..1c898b4fab 100644
--- a/man/sd_bus_path_encode.xml
+++ b/man/sd_bus_path_encode.xml
@@ -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
diff --git a/man/sd_bus_process.xml b/man/sd_bus_process.xml
index 4b9f52e52f..d9731f332c 100644
--- a/man/sd_bus_process.xml
+++ b/man/sd_bus_process.xml
@@ -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
diff --git a/man/sd_bus_request_name.xml b/man/sd_bus_request_name.xml
index f07ae09555..f44cfdb1ac 100644
--- a/man/sd_bus_request_name.xml
+++ b/man/sd_bus_request_name.xml
@@ -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
diff --git a/man/sd_bus_track_add_name.xml b/man/sd_bus_track_add_name.xml
index 6a5e344cb1..19d0115bc9 100644
--- a/man/sd_bus_track_add_name.xml
+++ b/man/sd_bus_track_add_name.xml
@@ -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
diff --git a/man/sd_bus_track_new.xml b/man/sd_bus_track_new.xml
index 60e2e77f75..4f92a5513d 100644
--- a/man/sd_bus_track_new.xml
+++ b/man/sd_bus_track_new.xml
@@ -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
diff --git a/man/sd_event_add_child.xml b/man/sd_event_add_child.xml
index bc732db7fa..15ea5de327 100644
--- a/man/sd_event_add_child.xml
+++ b/man/sd_event_add_child.xml
@@ -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
diff --git a/man/sd_event_add_defer.xml b/man/sd_event_add_defer.xml
index ab28b330fe..9064e63365 100644
--- a/man/sd_event_add_defer.xml
+++ b/man/sd_event_add_defer.xml
@@ -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
diff --git a/man/sd_event_add_io.xml b/man/sd_event_add_io.xml
index c3749164cd..d7b26f7887 100644
--- a/man/sd_event_add_io.xml
+++ b/man/sd_event_add_io.xml
@@ -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
diff --git a/man/sd_event_add_signal.xml b/man/sd_event_add_signal.xml
index e98f1d2682..192ba95ffa 100644
--- a/man/sd_event_add_signal.xml
+++ b/man/sd_event_add_signal.xml
@@ -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
diff --git a/man/sd_event_add_time.xml b/man/sd_event_add_time.xml
index 5496b71529..56abac18cd 100644
--- a/man/sd_event_add_time.xml
+++ b/man/sd_event_add_time.xml
@@ -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
diff --git a/man/sd_event_exit.xml b/man/sd_event_exit.xml
index 9846a3eaf4..a798a1c482 100644
--- a/man/sd_event_exit.xml
+++ b/man/sd_event_exit.xml
@@ -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
diff --git a/man/sd_event_get_fd.xml b/man/sd_event_get_fd.xml
index f68752dd0e..ed648c2347 100644
--- a/man/sd_event_get_fd.xml
+++ b/man/sd_event_get_fd.xml
@@ -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
diff --git a/man/sd_event_new.xml b/man/sd_event_new.xml
index c0a5e98177..35f91cd303 100644
--- a/man/sd_event_new.xml
+++ b/man/sd_event_new.xml
@@ -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
diff --git a/man/sd_event_now.xml b/man/sd_event_now.xml
index 2c83b0bcb5..a17e208934 100644
--- a/man/sd_event_now.xml
+++ b/man/sd_event_now.xml
@@ -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
diff --git a/man/sd_event_run.xml b/man/sd_event_run.xml
index 5b68959165..fb2687f3a4 100644
--- a/man/sd_event_run.xml
+++ b/man/sd_event_run.xml
@@ -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
diff --git a/man/sd_event_set_watchdog.xml b/man/sd_event_set_watchdog.xml
index cbc5bc0836..ee28caf235 100644
--- a/man/sd_event_set_watchdog.xml
+++ b/man/sd_event_set_watchdog.xml
@@ -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
diff --git a/man/sd_event_source_get_event.xml b/man/sd_event_source_get_event.xml
index 2fdbd411bd..219956dcee 100644
--- a/man/sd_event_source_get_event.xml
+++ b/man/sd_event_source_get_event.xml
@@ -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
diff --git a/man/sd_event_source_get_pending.xml b/man/sd_event_source_get_pending.xml
index 7f88bd1b87..dff6952a5a 100644
--- a/man/sd_event_source_get_pending.xml
+++ b/man/sd_event_source_get_pending.xml
@@ -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
diff --git a/man/sd_event_source_set_description.xml b/man/sd_event_source_set_description.xml
index b9488a622f..ad855e6f89 100644
--- a/man/sd_event_source_set_description.xml
+++ b/man/sd_event_source_set_description.xml
@@ -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
diff --git a/man/sd_event_source_set_enabled.xml b/man/sd_event_source_set_enabled.xml
index 6844f29a49..0628c3e8e9 100644
--- a/man/sd_event_source_set_enabled.xml
+++ b/man/sd_event_source_set_enabled.xml
@@ -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
diff --git a/man/sd_event_source_set_prepare.xml b/man/sd_event_source_set_prepare.xml
index ee61d23983..148cab16b1 100644
--- a/man/sd_event_source_set_prepare.xml
+++ b/man/sd_event_source_set_prepare.xml
@@ -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
diff --git a/man/sd_event_source_set_priority.xml b/man/sd_event_source_set_priority.xml
index b6bab6d316..43edd76a7e 100644
--- a/man/sd_event_source_set_priority.xml
+++ b/man/sd_event_source_set_priority.xml
@@ -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
diff --git a/man/sd_event_source_set_userdata.xml b/man/sd_event_source_set_userdata.xml
index 533d491b13..cb317ad1d7 100644
--- a/man/sd_event_source_set_userdata.xml
+++ b/man/sd_event_source_set_userdata.xml
@@ -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
diff --git a/man/sd_event_source_unref.xml b/man/sd_event_source_unref.xml
index 2c4d450763..ec9e7c01fc 100644
--- a/man/sd_event_source_unref.xml
+++ b/man/sd_event_source_unref.xml
@@ -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
diff --git a/man/sd_event_wait.xml b/man/sd_event_wait.xml
index 26327dc688..89de31d22f 100644
--- a/man/sd_event_wait.xml
+++ b/man/sd_event_wait.xml
@@ -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
diff --git a/man/sd_get_seats.xml b/man/sd_get_seats.xml
index c053144483..b4b133ff0f 100644
--- a/man/sd_get_seats.xml
+++ b/man/sd_get_seats.xml
@@ -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
diff --git a/man/sd_id128_get_machine.xml b/man/sd_id128_get_machine.xml
index 3938c6d836..a97beebbd5 100644
--- a/man/sd_id128_get_machine.xml
+++ b/man/sd_id128_get_machine.xml
@@ -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
diff --git a/man/sd_id128_randomize.xml b/man/sd_id128_randomize.xml
index 852a9fd7eb..bdce3b18b7 100644
--- a/man/sd_id128_randomize.xml
+++ b/man/sd_id128_randomize.xml
@@ -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
diff --git a/man/sd_id128_to_string.xml b/man/sd_id128_to_string.xml
index 927d1ad5f2..b82b141a3a 100644
--- a/man/sd_id128_to_string.xml
+++ b/man/sd_id128_to_string.xml
@@ -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
diff --git a/man/sd_is_fifo.xml b/man/sd_is_fifo.xml
index 3bd388d80e..2af17df650 100644
--- a/man/sd_is_fifo.xml
+++ b/man/sd_is_fifo.xml
@@ -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
diff --git a/man/sd_journal_add_match.xml b/man/sd_journal_add_match.xml
index 2294b43643..b41d6189d9 100644
--- a/man/sd_journal_add_match.xml
+++ b/man/sd_journal_add_match.xml
@@ -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
diff --git a/man/sd_journal_enumerate_fields.xml b/man/sd_journal_enumerate_fields.xml
index bc2c21ed4b..20005564b0 100644
--- a/man/sd_journal_enumerate_fields.xml
+++ b/man/sd_journal_enumerate_fields.xml
@@ -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
diff --git a/man/sd_journal_get_catalog.xml b/man/sd_journal_get_catalog.xml
index 92ed0dea06..95f3e3b007 100644
--- a/man/sd_journal_get_catalog.xml
+++ b/man/sd_journal_get_catalog.xml
@@ -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
diff --git a/man/sd_journal_get_cursor.xml b/man/sd_journal_get_cursor.xml
index b7aa05f8b2..ead150ec53 100644
--- a/man/sd_journal_get_cursor.xml
+++ b/man/sd_journal_get_cursor.xml
@@ -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
diff --git a/man/sd_journal_get_cutoff_realtime_usec.xml b/man/sd_journal_get_cutoff_realtime_usec.xml
index 0950e11b44..8fd9674111 100644
--- a/man/sd_journal_get_cutoff_realtime_usec.xml
+++ b/man/sd_journal_get_cutoff_realtime_usec.xml
@@ -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
diff --git a/man/sd_journal_get_data.xml b/man/sd_journal_get_data.xml
index 01e436e70d..831ed0bc6e 100644
--- a/man/sd_journal_get_data.xml
+++ b/man/sd_journal_get_data.xml
@@ -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
diff --git a/man/sd_journal_get_fd.xml b/man/sd_journal_get_fd.xml
index 2e686caccb..b162b2bf11 100644
--- a/man/sd_journal_get_fd.xml
+++ b/man/sd_journal_get_fd.xml
@@ -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
diff --git a/man/sd_journal_get_realtime_usec.xml b/man/sd_journal_get_realtime_usec.xml
index 607d74666b..49800c34a3 100644
--- a/man/sd_journal_get_realtime_usec.xml
+++ b/man/sd_journal_get_realtime_usec.xml
@@ -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
diff --git a/man/sd_journal_get_usage.xml b/man/sd_journal_get_usage.xml
index 06b0ff534d..63d073e119 100644
--- a/man/sd_journal_get_usage.xml
+++ b/man/sd_journal_get_usage.xml
@@ -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
diff --git a/man/sd_journal_has_runtime_files.xml b/man/sd_journal_has_runtime_files.xml
index 3f6d56ca77..7431190496 100644
--- a/man/sd_journal_has_runtime_files.xml
+++ b/man/sd_journal_has_runtime_files.xml
@@ -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
diff --git a/man/sd_journal_next.xml b/man/sd_journal_next.xml
index 7c385de260..18b0da048d 100644
--- a/man/sd_journal_next.xml
+++ b/man/sd_journal_next.xml
@@ -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
diff --git a/man/sd_journal_open.xml b/man/sd_journal_open.xml
index 25b3048f2e..5e7ae45688 100644
--- a/man/sd_journal_open.xml
+++ b/man/sd_journal_open.xml
@@ -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
diff --git a/man/sd_journal_print.xml b/man/sd_journal_print.xml
index a741abe32d..f771ba307f 100644
--- a/man/sd_journal_print.xml
+++ b/man/sd_journal_print.xml
@@ -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
diff --git a/man/sd_journal_query_unique.xml b/man/sd_journal_query_unique.xml
index d7a41a039c..fb08400f20 100644
--- a/man/sd_journal_query_unique.xml
+++ b/man/sd_journal_query_unique.xml
@@ -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
diff --git a/man/sd_journal_seek_head.xml b/man/sd_journal_seek_head.xml
index 985073496c..7e866e8e82 100644
--- a/man/sd_journal_seek_head.xml
+++ b/man/sd_journal_seek_head.xml
@@ -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
diff --git a/man/sd_journal_stream_fd.xml b/man/sd_journal_stream_fd.xml
index db88eba1bc..29d64f91d7 100644
--- a/man/sd_journal_stream_fd.xml
+++ b/man/sd_journal_stream_fd.xml
@@ -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
diff --git a/man/sd_listen_fds.xml b/man/sd_listen_fds.xml
index c1c2423884..8563a06997 100644
--- a/man/sd_listen_fds.xml
+++ b/man/sd_listen_fds.xml
@@ -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
diff --git a/man/sd_login_monitor_new.xml b/man/sd_login_monitor_new.xml
index 129c99f97d..935fca5697 100644
--- a/man/sd_login_monitor_new.xml
+++ b/man/sd_login_monitor_new.xml
@@ -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
diff --git a/man/sd_machine_get_class.xml b/man/sd_machine_get_class.xml
index ef604139da..989fa2db0f 100644
--- a/man/sd_machine_get_class.xml
+++ b/man/sd_machine_get_class.xml
@@ -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
diff --git a/man/sd_notify.xml b/man/sd_notify.xml
index 7d7b0077be..c28f303c7e 100644
--- a/man/sd_notify.xml
+++ b/man/sd_notify.xml
@@ -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
@@ -122,12 +124,10 @@
<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>
@@ -202,6 +202,26 @@
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>
@@ -227,33 +247,25 @@
</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>
diff --git a/man/sd_pid_get_session.xml b/man/sd_pid_get_owner_uid.xml
index 14ebd53e36..fcedcfcd1f 100644
--- a/man/sd_pid_get_session.xml
+++ b/man/sd_pid_get_owner_uid.xml
@@ -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
@@ -21,10 +23,10 @@
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>
@@ -38,30 +40,30 @@
</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>
@@ -69,15 +71,15 @@
<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>
@@ -117,15 +119,15 @@
</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>
@@ -135,9 +137,9 @@
</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>
@@ -169,16 +171,34 @@
<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>
@@ -186,37 +206,21 @@
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
@@ -246,10 +250,10 @@
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
diff --git a/man/sd_seat_get_active.xml b/man/sd_seat_get_active.xml
index 3dd461f83f..57a6b526f2 100644
--- a/man/sd_seat_get_active.xml
+++ b/man/sd_seat_get_active.xml
@@ -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
diff --git a/man/sd_session_is_active.xml b/man/sd_session_is_active.xml
index f95e74ead6..14993bcd67 100644
--- a/man/sd_session_is_active.xml
+++ b/man/sd_session_is_active.xml
@@ -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
diff --git a/man/sd_uid_get_state.xml b/man/sd_uid_get_state.xml
index 130af761da..1183d9079a 100644
--- a/man/sd_uid_get_state.xml
+++ b/man/sd_uid_get_state.xml
@@ -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
diff --git a/man/sd_watchdog_enabled.xml b/man/sd_watchdog_enabled.xml
index 759d9303c6..e85998c216 100644
--- a/man/sd_watchdog_enabled.xml
+++ b/man/sd_watchdog_enabled.xml
@@ -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
diff --git a/man/shutdown.xml b/man/shutdown.xml
index a8af387c67..41fe71f4da 100644
--- a/man/shutdown.xml
+++ b/man/shutdown.xml
@@ -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
diff --git a/man/standard-conf.xml b/man/standard-conf.xml
index 2836afccd0..673ca44edc 100644
--- a/man/standard-conf.xml
+++ b/man/standard-conf.xml
@@ -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>
diff --git a/man/standard-options.xml b/man/standard-options.xml
index f718451a1b..dcc6bb89ae 100644
--- a/man/standard-options.xml
+++ b/man/standard-options.xml
@@ -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>
diff --git a/man/sysctl.d.xml b/man/sysctl.d.xml
index ccf6c8e39f..ec69b4c5bb 100644
--- a/man/sysctl.d.xml
+++ b/man/sysctl.d.xml
@@ -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
diff --git a/man/systemctl.xml b/man/systemctl.xml
index 4abee60790..60882e5aa3 100644
--- a/man/systemctl.xml
+++ b/man/systemctl.xml
@@ -6,6 +6,8 @@
]>
<!--
+ SPDX-License-Identifier: LGPL-2.1+
+
This file is part of systemd.
Copyright 2010 Lennart Poettering
@@ -354,6 +356,19 @@
</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>
diff --git a/man/systemd-analyze.xml b/man/systemd-analyze.xml
index e74739498c..876f96d559 100644
--- a/man/systemd-analyze.xml
+++ b/man/systemd-analyze.xml
@@ -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
@@ -123,6 +125,12 @@
<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>
@@ -218,6 +226,12 @@
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>
diff --git a/man/systemd-ask-password-console.service.xml b/man/systemd-ask-password-console.service.xml
index 3c1537d942..db318de8c2 100644
--- a/man/systemd-ask-password-console.service.xml
+++ b/man/systemd-ask-password-console.service.xml
@@ -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
diff --git a/man/systemd-ask-password.xml b/man/systemd-ask-password.xml
index 16ec257014..686fa89468 100644
--- a/man/systemd-ask-password.xml
+++ b/man/systemd-ask-password.xml
@@ -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
diff --git a/man/systemd-backlight@.service.xml b/man/systemd-backlight@.service.xml
index 3459ed8851..e047884c50 100644
--- a/man/systemd-backlight@.service.xml
+++ b/man/systemd-backlight@.service.xml
@@ -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
diff --git a/man/systemd-binfmt.service.xml b/man/systemd-binfmt.service.xml
index cccfb49ca9..0c33348ba8 100644
--- a/man/systemd-binfmt.service.xml
+++ b/man/systemd-binfmt.service.xml
@@ -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
diff --git a/man/systemd-cat.xml b/man/systemd-cat.xml
index 160db9fb5c..2c394f2ceb 100644
--- a/man/systemd-cat.xml
+++ b/man/systemd-cat.xml
@@ -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
diff --git a/man/systemd-cgls.xml b/man/systemd-cgls.xml
index 219514b183..128324e616 100644
--- a/man/systemd-cgls.xml
+++ b/man/systemd-cgls.xml
@@ -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
diff --git a/man/systemd-cgtop.xml b/man/systemd-cgtop.xml
index be13631239..d7ad08ec37 100644
--- a/man/systemd-cgtop.xml
+++ b/man/systemd-cgtop.xml
@@ -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
diff --git a/man/systemd-coredump.xml b/man/systemd-coredump.xml
index d71fdc644f..1ae9ffb89e 100644
--- a/man/systemd-coredump.xml
+++ b/man/systemd-coredump.xml
@@ -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
@@ -110,7 +112,7 @@
<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>
diff --git a/man/systemd-cryptsetup-generator.xml b/man/systemd-cryptsetup-generator.xml
index f036ab9744..645e2ee178 100644
--- a/man/systemd-cryptsetup-generator.xml
+++ b/man/systemd-cryptsetup-generator.xml
@@ -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
diff --git a/man/systemd-cryptsetup@.service.xml b/man/systemd-cryptsetup@.service.xml
index 73bd5b78ab..efcbf247f4 100644
--- a/man/systemd-cryptsetup@.service.xml
+++ b/man/systemd-cryptsetup@.service.xml
@@ -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
diff --git a/man/systemd-debug-generator.xml b/man/systemd-debug-generator.xml
index 0a66b9bbf9..e8656a36ab 100644
--- a/man/systemd-debug-generator.xml
+++ b/man/systemd-debug-generator.xml
@@ -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
diff --git a/man/systemd-delta.xml b/man/systemd-delta.xml
index be241f6950..94f6b093db 100644
--- a/man/systemd-delta.xml
+++ b/man/systemd-delta.xml
@@ -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
diff --git a/man/systemd-detect-virt.xml b/man/systemd-detect-virt.xml
index 72ea35892f..4426827e57 100644
--- a/man/systemd-detect-virt.xml
+++ b/man/systemd-detect-virt.xml
@@ -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
diff --git a/man/systemd-environment-d-generator.xml b/man/systemd-environment-d-generator.xml
index 7950aa98a5..7bc1dd0ef1 100644
--- a/man/systemd-environment-d-generator.xml
+++ b/man/systemd-environment-d-generator.xml
@@ -6,6 +6,8 @@
]>
<!--
+ SPDX-License-Identifier: LGPL-2.1+
+
This file is part of systemd.
Copyright 2017 Zbigniew Jędrzejewski-Szmek
diff --git a/man/systemd-escape.xml b/man/systemd-escape.xml
index fb20d2d94f..513e9a6a97 100644
--- a/man/systemd-escape.xml
+++ b/man/systemd-escape.xml
@@ -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>
@@ -107,11 +112,12 @@
<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>
diff --git a/man/systemd-firstboot.xml b/man/systemd-firstboot.xml
index 539422ab98..0ac5f3bd85 100644
--- a/man/systemd-firstboot.xml
+++ b/man/systemd-firstboot.xml
@@ -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>
@@ -136,6 +140,15 @@
</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
@@ -182,6 +195,7 @@
<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>
@@ -195,9 +209,10 @@
<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>
@@ -206,6 +221,7 @@
<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>
@@ -217,9 +233,10 @@
<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>
@@ -265,6 +282,7 @@
<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>,
diff --git a/man/systemd-fsck@.service.xml b/man/systemd-fsck@.service.xml
index 711e269016..f4d2dc1341 100644
--- a/man/systemd-fsck@.service.xml
+++ b/man/systemd-fsck@.service.xml
@@ -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
diff --git a/man/systemd-fstab-generator.xml b/man/systemd-fstab-generator.xml
index b898d719f2..51e390a364 100644
--- a/man/systemd-fstab-generator.xml
+++ b/man/systemd-fstab-generator.xml
@@ -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
diff --git a/man/systemd-getty-generator.xml b/man/systemd-getty-generator.xml
index 3058444467..adb48a7fd6 100644
--- a/man/systemd-getty-generator.xml
+++ b/man/systemd-getty-generator.xml
@@ -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
diff --git a/man/systemd-gpt-auto-generator.xml b/man/systemd-gpt-auto-generator.xml
index 2927fcd291..3fbe215c41 100644
--- a/man/systemd-gpt-auto-generator.xml
+++ b/man/systemd-gpt-auto-generator.xml
@@ -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
diff --git a/man/systemd-halt.service.xml b/man/systemd-halt.service.xml
index d16e5d628f..b58279d828 100644
--- a/man/systemd-halt.service.xml
+++ b/man/systemd-halt.service.xml
@@ -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
diff --git a/man/systemd-hibernate-resume-generator.xml b/man/systemd-hibernate-resume-generator.xml
index 3bbb6ab989..188bdb6e57 100644
--- a/man/systemd-hibernate-resume-generator.xml
+++ b/man/systemd-hibernate-resume-generator.xml
@@ -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
diff --git a/man/systemd-hibernate-resume@.service.xml b/man/systemd-hibernate-resume@.service.xml
index a968adf0a9..cbda08961c 100644
--- a/man/systemd-hibernate-resume@.service.xml
+++ b/man/systemd-hibernate-resume@.service.xml
@@ -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
diff --git a/man/systemd-hostnamed.service.xml b/man/systemd-hostnamed.service.xml
index 17755aa69e..e905e461be 100644
--- a/man/systemd-hostnamed.service.xml
+++ b/man/systemd-hostnamed.service.xml
@@ -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
diff --git a/man/systemd-hwdb.xml b/man/systemd-hwdb.xml
index 2b363c77f2..58b151653b 100644
--- a/man/systemd-hwdb.xml
+++ b/man/systemd-hwdb.xml
@@ -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>
@@ -48,13 +71,6 @@
<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
diff --git a/man/systemd-importd.service.xml b/man/systemd-importd.service.xml
index 70a618ce46..9fd36bb3b3 100644
--- a/man/systemd-importd.service.xml
+++ b/man/systemd-importd.service.xml
@@ -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
diff --git a/man/systemd-inhibit.xml b/man/systemd-inhibit.xml
index 09b82b82c1..ce34cc8c50 100644
--- a/man/systemd-inhibit.xml
+++ b/man/systemd-inhibit.xml
@@ -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
diff --git a/man/systemd-initctl.service.xml b/man/systemd-initctl.service.xml
index 5c7f9a4a16..64211e27f7 100644
--- a/man/systemd-initctl.service.xml
+++ b/man/systemd-initctl.service.xml
@@ -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
diff --git a/man/systemd-journal-gatewayd.service.xml b/man/systemd-journal-gatewayd.service.xml
index 3ee344e50b..4d461d9be4 100644
--- a/man/systemd-journal-gatewayd.service.xml
+++ b/man/systemd-journal-gatewayd.service.xml
@@ -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
@@ -101,6 +103,13 @@
</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>
diff --git a/man/systemd-journal-remote.xml b/man/systemd-journal-remote.xml
index 1f1c305267..658c7e07f4 100644
--- a/man/systemd-journal-remote.xml
+++ b/man/systemd-journal-remote.xml
@@ -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
@@ -196,6 +201,48 @@
</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>
diff --git a/man/systemd-journal-upload.xml b/man/systemd-journal-upload.xml
index f9723dea89..a43062a6d5 100644
--- a/man/systemd-journal-upload.xml
+++ b/man/systemd-journal-upload.xml
@@ -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
@@ -169,6 +174,43 @@
</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>
diff --git a/man/systemd-journald.service.xml b/man/systemd-journald.service.xml
index fec0e1fe88..8ca0e896ab 100644
--- a/man/systemd-journald.service.xml
+++ b/man/systemd-journald.service.xml
@@ -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
@@ -90,17 +92,19 @@
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>
diff --git a/man/systemd-localed.service.xml b/man/systemd-localed.service.xml
index 2a796c9045..308a848c08 100644
--- a/man/systemd-localed.service.xml
+++ b/man/systemd-localed.service.xml
@@ -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
diff --git a/man/systemd-logind.service.xml b/man/systemd-logind.service.xml
index 47089fd8c7..b51158b7cd 100644
--- a/man/systemd-logind.service.xml
+++ b/man/systemd-logind.service.xml
@@ -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
diff --git a/man/systemd-machine-id-commit.service.xml b/man/systemd-machine-id-commit.service.xml
index 39da1922cc..acb4ffb626 100644
--- a/man/systemd-machine-id-commit.service.xml
+++ b/man/systemd-machine-id-commit.service.xml
@@ -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
diff --git a/man/systemd-machine-id-setup.xml b/man/systemd-machine-id-setup.xml
index 714317c945..527cb7bff5 100644
--- a/man/systemd-machine-id-setup.xml
+++ b/man/systemd-machine-id-setup.xml
@@ -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
diff --git a/man/systemd-machined.service.xml b/man/systemd-machined.service.xml
index c4f173f79b..8bf4e75550 100644
--- a/man/systemd-machined.service.xml
+++ b/man/systemd-machined.service.xml
@@ -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
index 0000000000..073c52fafe
--- /dev/null
+++ b/man/systemd-makefs@.service.xml
@@ -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>
diff --git a/man/systemd-modules-load.service.xml b/man/systemd-modules-load.service.xml
index ee097d7f5c..6f370190f2 100644
--- a/man/systemd-modules-load.service.xml
+++ b/man/systemd-modules-load.service.xml
@@ -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
diff --git a/man/systemd-mount.xml b/man/systemd-mount.xml
index 40dc70fe70..87bc2b36eb 100644
--- a/man/systemd-mount.xml
+++ b/man/systemd-mount.xml
@@ -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
@@ -264,6 +266,21 @@
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" />
diff --git a/man/systemd-networkd-wait-online.service.xml b/man/systemd-networkd-wait-online.service.xml
index e21c805342..96715cad2f 100644
--- a/man/systemd-networkd-wait-online.service.xml
+++ b/man/systemd-networkd-wait-online.service.xml
@@ -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
diff --git a/man/systemd-networkd.service.xml b/man/systemd-networkd.service.xml
index a6e079c887..8bc5f5e869 100644
--- a/man/systemd-networkd.service.xml
+++ b/man/systemd-networkd.service.xml
@@ -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
diff --git a/man/systemd-notify.xml b/man/systemd-notify.xml
index 8c56a6b8ed..acd4ee41fc 100644
--- a/man/systemd-notify.xml
+++ b/man/systemd-notify.xml
@@ -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
diff --git a/man/systemd-nspawn.xml b/man/systemd-nspawn.xml
index 3951e32e8f..3dbdf376d3 100644
--- a/man/systemd-nspawn.xml
+++ b/man/systemd-nspawn.xml
@@ -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
@@ -521,6 +523,23 @@
</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
@@ -806,7 +825,13 @@
<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>
@@ -915,20 +940,17 @@
<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>
@@ -1061,7 +1083,8 @@
<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
@@ -1075,14 +1098,17 @@
<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>
@@ -1094,10 +1120,20 @@
<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>
@@ -1108,7 +1144,9 @@
</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
diff --git a/man/systemd-path.xml b/man/systemd-path.xml
index e2b23eec51..7144569d59 100644
--- a/man/systemd-path.xml
+++ b/man/systemd-path.xml
@@ -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
diff --git a/man/systemd-quotacheck.service.xml b/man/systemd-quotacheck.service.xml
index 9d4976274e..c3a5e69d40 100644
--- a/man/systemd-quotacheck.service.xml
+++ b/man/systemd-quotacheck.service.xml
@@ -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
diff --git a/man/systemd-random-seed.service.xml b/man/systemd-random-seed.service.xml
index 9ec01b6c34..658bdf3638 100644
--- a/man/systemd-random-seed.service.xml
+++ b/man/systemd-random-seed.service.xml
@@ -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
diff --git a/man/systemd-remount-fs.service.xml b/man/systemd-remount-fs.service.xml
index 6a5f0e6e38..8e68b99fe5 100644
--- a/man/systemd-remount-fs.service.xml
+++ b/man/systemd-remount-fs.service.xml
@@ -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
diff --git a/man/systemd-resolve.xml b/man/systemd-resolve.xml
index 53f843ff93..f924090553 100644
--- a/man/systemd-resolve.xml
+++ b/man/systemd-resolve.xml
@@ -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
@@ -319,6 +321,48 @@
<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>
diff --git a/man/systemd-resolved.service.xml b/man/systemd-resolved.service.xml
index d07d1968b4..da6e8c4441 100644
--- a/man/systemd-resolved.service.xml
+++ b/man/systemd-resolved.service.xml
@@ -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>
@@ -110,7 +113,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
@@ -134,7 +137,7 @@
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
@@ -164,15 +167,26 @@
<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
diff --git a/man/systemd-rfkill.service.xml b/man/systemd-rfkill.service.xml
index f464842700..cb6fae4c2d 100644
--- a/man/systemd-rfkill.service.xml
+++ b/man/systemd-rfkill.service.xml
@@ -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
diff --git a/man/systemd-run.xml b/man/systemd-run.xml
index 7477195dab..9db6a26dfd 100644
--- a/man/systemd-run.xml
+++ b/man/systemd-run.xml
@@ -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
@@ -244,7 +246,15 @@
<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>
@@ -316,6 +326,21 @@
<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" />
diff --git a/man/systemd-sleep.conf.xml b/man/systemd-sleep.conf.xml
index 9a379ecb94..7fecd667de 100644
--- a/man/systemd-sleep.conf.xml
+++ b/man/systemd-sleep.conf.xml
@@ -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-socket-activate.xml b/man/systemd-socket-activate.xml
index 356bc10359..79e35dd30e 100644
--- a/man/systemd-socket-activate.xml
+++ b/man/systemd-socket-activate.xml
@@ -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-socket-proxyd.xml b/man/systemd-socket-proxyd.xml
index 96702a8939..1705374826 100644
--- a/man/systemd-socket-proxyd.xml
+++ b/man/systemd-socket-proxyd.xml
@@ -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]
diff --git a/man/systemd-suspend.service.xml b/man/systemd-suspend.service.xml
index 2aa172e990..24c213eb74 100644
--- a/man/systemd-suspend.service.xml
+++ b/man/systemd-suspend.service.xml
@@ -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
diff --git a/man/systemd-sysctl.service.xml b/man/systemd-sysctl.service.xml
index ee00e8d262..3251bc6321 100644
--- a/man/systemd-sysctl.service.xml
+++ b/man/systemd-sysctl.service.xml
@@ -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
diff --git a/man/systemd-system-update-generator.xml b/man/systemd-system-update-generator.xml
index 833ed79646..c57dc781db 100644
--- a/man/systemd-system-update-generator.xml
+++ b/man/systemd-system-update-generator.xml
@@ -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
diff --git a/man/systemd-system.conf.xml b/man/systemd-system.conf.xml
index 81f1b1ef8d..08f6c91901 100644
--- a/man/systemd-system.conf.xml
+++ b/man/systemd-system.conf.xml
@@ -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
@@ -159,8 +161,10 @@
<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
@@ -178,6 +182,15 @@
</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
diff --git a/man/systemd-sysusers.xml b/man/systemd-sysusers.xml
index 990b935cf2..73ba4e4a84 100644
--- a/man/systemd-sysusers.xml
+++ b/man/systemd-sysusers.xml
@@ -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
diff --git a/man/systemd-sysv-generator.xml b/man/systemd-sysv-generator.xml
index 2353eb3efe..3eceb51381 100644
--- a/man/systemd-sysv-generator.xml
+++ b/man/systemd-sysv-generator.xml
@@ -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
diff --git a/man/systemd-timedated.service.xml b/man/systemd-timedated.service.xml
index fee860204d..2dfde3c1b8 100644
--- a/man/systemd-timedated.service.xml
+++ b/man/systemd-timedated.service.xml
@@ -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
diff --git a/man/systemd-timesyncd.service.xml b/man/systemd-timesyncd.service.xml
index 7860c0d4e4..e9b5c25780 100644
--- a/man/systemd-timesyncd.service.xml
+++ b/man/systemd-timesyncd.service.xml
@@ -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
diff --git a/man/systemd-tmpfiles.xml b/man/systemd-tmpfiles.xml
index c1aab51551..24a08b0354 100644
--- a/man/systemd-tmpfiles.xml
+++ b/man/systemd-tmpfiles.xml
@@ -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
@@ -60,10 +62,16 @@
<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>
@@ -113,7 +121,7 @@
<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>
@@ -131,11 +139,19 @@
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
@@ -148,12 +164,16 @@
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" />
@@ -185,8 +205,12 @@
<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>
diff --git a/man/systemd-tty-ask-password-agent.xml b/man/systemd-tty-ask-password-agent.xml
index 2c114f4631..e934649ed9 100644
--- a/man/systemd-tty-ask-password-agent.xml
+++ b/man/systemd-tty-ask-password-agent.xml
@@ -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
diff --git a/man/systemd-udevd.service.xml b/man/systemd-udevd.service.xml
index 81b957b0c8..ee18dae6eb 100644
--- a/man/systemd-udevd.service.xml
+++ b/man/systemd-udevd.service.xml
@@ -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>
@@ -82,6 +105,7 @@
</varlistentry>
<varlistentry>
+ <term><option>-c=</option></term>
<term><option>--children-max=</option></term>
<listitem>
<para>Limit the number of events executed in parallel.</para>
@@ -89,6 +113,7 @@
</varlistentry>
<varlistentry>
+ <term><option>-e=</option></term>
<term><option>--exec-delay=</option></term>
<listitem>
<para>Delay the execution of <varname>RUN</varname>
@@ -100,6 +125,7 @@
</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
@@ -108,6 +134,7 @@
</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.
@@ -119,11 +146,7 @@
</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>
diff --git a/man/systemd-update-done.service.xml b/man/systemd-update-done.service.xml
index a2dad39f01..b0dd56fdff 100644
--- a/man/systemd-update-done.service.xml
+++ b/man/systemd-update-done.service.xml
@@ -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
diff --git a/man/systemd-update-utmp.service.xml b/man/systemd-update-utmp.service.xml
index be7cec236c..286c18ed4c 100644
--- a/man/systemd-update-utmp.service.xml
+++ b/man/systemd-update-utmp.service.xml
@@ -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
diff --git a/man/systemd-user-sessions.service.xml b/man/systemd-user-sessions.service.xml
index 67aba54119..c3eaffa242 100644
--- a/man/systemd-user-sessions.service.xml
+++ b/man/systemd-user-sessions.service.xml
@@ -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
diff --git a/man/systemd-vconsole-setup.service.xml b/man/systemd-vconsole-setup.service.xml
index 6df82aed32..3b72234b0f 100644
--- a/man/systemd-vconsole-setup.service.xml
+++ b/man/systemd-vconsole-setup.service.xml
@@ -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
@@ -57,25 +59,21 @@
<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>
diff --git a/man/systemd-veritysetup-generator.xml b/man/systemd-veritysetup-generator.xml
index 87d66e9ee5..b6b5b3bc51 100644
--- a/man/systemd-veritysetup-generator.xml
+++ b/man/systemd-veritysetup-generator.xml
@@ -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
diff --git a/man/systemd-veritysetup@.service.xml b/man/systemd-veritysetup@.service.xml
index 173e5358e0..55600e9ad5 100644
--- a/man/systemd-veritysetup@.service.xml
+++ b/man/systemd-veritysetup@.service.xml
@@ -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
diff --git a/man/systemd-volatile-root.service.xml b/man/systemd-volatile-root.service.xml
index b90a3261fa..ee7c8b3762 100644
--- a/man/systemd-volatile-root.service.xml
+++ b/man/systemd-volatile-root.service.xml
@@ -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
diff --git a/man/systemd.automount.xml b/man/systemd.automount.xml
index 49ea7e510c..b0f5b19372 100644
--- a/man/systemd.automount.xml
+++ b/man/systemd.automount.xml
@@ -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
diff --git a/man/systemd.device.xml b/man/systemd.device.xml
index c60b9c035e..a275a880e4 100644
--- a/man/systemd.device.xml
+++ b/man/systemd.device.xml
@@ -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
@@ -83,6 +85,12 @@
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>
@@ -106,35 +114,36 @@
<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>
@@ -146,20 +155,14 @@
<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
index 0000000000..1270e08cd2
--- /dev/null
+++ b/man/systemd.dnssd.xml
@@ -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>
diff --git a/man/systemd.environment-generator.xml b/man/systemd.environment-generator.xml
index ff8be92833..d5e773e5e3 100644
--- a/man/systemd.environment-generator.xml
+++ b/man/systemd.environment-generator.xml
@@ -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>
diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml
index dfae0572d8..3d81e45732 100644
--- a/man/systemd.exec.xml
+++ b/man/systemd.exec.xml
@@ -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
@@ -56,24 +58,18 @@
<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>.
@@ -86,27 +82,30 @@
<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'>
@@ -141,6 +140,7 @@
<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
@@ -165,12 +165,45 @@
</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
@@ -206,7 +239,10 @@
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
@@ -232,540 +268,186 @@
<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>
+ <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>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>
- </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>
@@ -784,14 +466,15 @@
<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
@@ -802,19 +485,14 @@
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
@@ -928,97 +606,284 @@
</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>
@@ -1064,31 +929,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
@@ -1108,8 +948,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>
@@ -1118,53 +958,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>
@@ -1189,45 +1022,12 @@ 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>
<listitem><para>Takes a boolean argument. If true, kernel variables accessible through
@@ -1251,25 +1051,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>
@@ -1281,152 +1076,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>
@@ -1435,16 +1240,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
@@ -1459,23 +1268,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>
@@ -1594,13 +1395,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
@@ -1614,15 +1413,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>
@@ -1655,247 +1450,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>
@@ -1925,7 +1942,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>
@@ -1942,7 +1959,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>
@@ -2392,7 +2409,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>
@@ -2497,7 +2514,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>
@@ -2512,7 +2529,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>
@@ -2547,22 +2564,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>
diff --git a/man/systemd.generator.xml b/man/systemd.generator.xml
index fb0f0c4da8..55bb2b4a90 100644
--- a/man/systemd.generator.xml
+++ b/man/systemd.generator.xml
@@ -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>
@@ -74,17 +76,14 @@
<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
@@ -122,7 +121,8 @@
<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>
@@ -131,7 +131,7 @@
<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>
@@ -188,13 +188,10 @@
<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>
diff --git a/man/systemd.journal-fields.xml b/man/systemd.journal-fields.xml
index e488affe3e..b08ef1777e 100644
--- a/man/systemd.journal-fields.xml
+++ b/man/systemd.journal-fields.xml
@@ -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
@@ -193,18 +195,19 @@
<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>
diff --git a/man/systemd.kill.xml b/man/systemd.kill.xml
index 13b7ab14df..1abcd6d8e7 100644
--- a/man/systemd.kill.xml
+++ b/man/systemd.kill.xml
@@ -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
diff --git a/man/systemd.link.xml b/man/systemd.link.xml
index 99bb6a19fb..162674f769 100644
--- a/man/systemd.link.xml
+++ b/man/systemd.link.xml
@@ -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
diff --git a/man/systemd.mount.xml b/man/systemd.mount.xml
index 58cdb547ea..663e7fa3ac 100644
--- a/man/systemd.mount.xml
+++ b/man/systemd.mount.xml
@@ -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
@@ -317,6 +319,44 @@
</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
@@ -336,13 +376,12 @@
<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>
diff --git a/man/systemd.netdev.xml b/man/systemd.netdev.xml
index 6f8991b81c..c92792341b 100644
--- a/man/systemd.netdev.xml
+++ b/man/systemd.netdev.xml
@@ -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
@@ -178,6 +180,10 @@
<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>
@@ -893,6 +899,22 @@
</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
diff --git a/man/systemd.network.xml b/man/systemd.network.xml
index b1759677f9..3466f3a3cf 100644
--- a/man/systemd.network.xml
+++ b/man/systemd.network.xml
@@ -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
@@ -250,6 +252,21 @@
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>
@@ -924,6 +941,18 @@
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>
@@ -1452,19 +1481,36 @@
</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>
@@ -1610,7 +1656,7 @@
<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>
diff --git a/man/systemd.nspawn.xml b/man/systemd.nspawn.xml
index 58024a071d..9a6a2351f8 100644
--- a/man/systemd.nspawn.xml
+++ b/man/systemd.nspawn.xml
@@ -6,6 +6,8 @@
]>
<!--
+ SPDX-License-Identifier: LGPL-2.1+
+
This file is part of systemd.
Copyright 2015 Lennart Poettering
@@ -275,7 +277,7 @@
<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>
diff --git a/man/systemd.offline-updates.xml b/man/systemd.offline-updates.xml
index b4dce3e92d..01dd6c55e4 100644
--- a/man/systemd.offline-updates.xml
+++ b/man/systemd.offline-updates.xml
@@ -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
@@ -170,7 +172,6 @@
<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>,
diff --git a/man/systemd.path.xml b/man/systemd.path.xml
index 9e8f2c66c1..30f295d2d7 100644
--- a/man/systemd.path.xml
+++ b/man/systemd.path.xml
@@ -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
diff --git a/man/systemd.preset.xml b/man/systemd.preset.xml
index 92eb4e8280..482856221c 100644
--- a/man/systemd.preset.xml
+++ b/man/systemd.preset.xml
@@ -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
diff --git a/man/systemd.resource-control.xml b/man/systemd.resource-control.xml
index 0c0c91608a..18b7bf8f6a 100644
--- a/man/systemd.resource-control.xml
+++ b/man/systemd.resource-control.xml
@@ -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
@@ -120,10 +122,6 @@
<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>
@@ -142,7 +140,7 @@
<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 a superset of and replace <varname>BlockIO</varname>
prefixed ones. On unified hierarchy, IO resource control also applies to buffered writes.</para>
</listitem>
</varlistentry>
@@ -500,7 +498,7 @@
</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>
@@ -711,13 +709,32 @@
<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>
diff --git a/man/systemd.scope.xml b/man/systemd.scope.xml
index e41493cdd3..092361c6b0 100644
--- a/man/systemd.scope.xml
+++ b/man/systemd.scope.xml
@@ -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.service.xml b/man/systemd.service.xml
index 2b183a9cef..76dfe60be4 100644
--- a/man/systemd.service.xml
+++ b/man/systemd.service.xml
@@ -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
@@ -342,7 +344,7 @@
<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>
@@ -352,7 +354,7 @@
<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
@@ -461,7 +463,9 @@
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
@@ -513,6 +517,15 @@
<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>
@@ -531,6 +544,14 @@
<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>
@@ -549,7 +570,16 @@
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>
@@ -890,14 +920,6 @@
</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
diff --git a/man/systemd.slice.xml b/man/systemd.slice.xml
index c46ba7a2e1..d67cce102a 100644
--- a/man/systemd.slice.xml
+++ b/man/systemd.slice.xml
@@ -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
diff --git a/man/systemd.socket.xml b/man/systemd.socket.xml
index 68d01cccc5..a1943f65ab 100644
--- a/man/systemd.socket.xml
+++ b/man/systemd.socket.xml
@@ -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
diff --git a/man/systemd.special.xml b/man/systemd.special.xml
index 4beef07dd5..18689a0a9e 100644
--- a/man/systemd.special.xml
+++ b/man/systemd.special.xml
@@ -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>,
@@ -444,6 +445,10 @@
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>
@@ -495,18 +500,6 @@
</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
@@ -534,7 +527,8 @@
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>
@@ -906,9 +900,10 @@
<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>
diff --git a/man/systemd.swap.xml b/man/systemd.swap.xml
index 254389e774..707b04b208 100644
--- a/man/systemd.swap.xml
+++ b/man/systemd.swap.xml
@@ -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
diff --git a/man/systemd.target.xml b/man/systemd.target.xml
index 281f5d4d6c..4daa9f52fd 100644
--- a/man/systemd.target.xml
+++ b/man/systemd.target.xml
@@ -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>
diff --git a/man/systemd.time.xml b/man/systemd.time.xml
index a4f6a785d5..6cb32f13b7 100644
--- a/man/systemd.time.xml
+++ b/man/systemd.time.xml
@@ -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>
diff --git a/man/systemd.timer.xml b/man/systemd.timer.xml
index b8f921f3af..5b1bc8b521 100644
--- a/man/systemd.timer.xml
+++ b/man/systemd.timer.xml
@@ -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
diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml
index bec6356270..5cd8be310d 100644
--- a/man/systemd.unit.xml
+++ b/man/systemd.unit.xml
@@ -6,6 +6,8 @@
]>
<!--
+ SPDX-License-Identifier: LGPL-2.1+
+
This file is part of systemd.
Copyright 2010 Lennart Poettering
@@ -194,9 +196,7 @@
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
@@ -215,23 +215,6 @@
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
@@ -268,6 +251,32 @@
</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,
@@ -295,9 +304,10 @@
<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>
@@ -327,22 +337,22 @@
<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>
@@ -358,42 +368,42 @@
<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>
@@ -409,6 +419,45 @@
</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
@@ -455,8 +504,9 @@
<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
@@ -487,7 +537,14 @@
<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>
@@ -525,7 +582,14 @@
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>
@@ -536,7 +600,14 @@
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>
@@ -739,6 +810,23 @@
</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>
@@ -763,28 +851,32 @@
</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>
@@ -807,10 +899,20 @@
</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>
@@ -950,6 +1052,7 @@
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
@@ -1117,9 +1220,115 @@
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>
@@ -1130,8 +1339,7 @@
<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>
@@ -1216,7 +1424,8 @@
<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>
@@ -1227,101 +1436,115 @@
<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>
diff --git a/man/systemd.xml b/man/systemd.xml
index b455b605cb..62ececb6e9 100644
--- a/man/systemd.xml
+++ b/man/systemd.xml
@@ -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>
@@ -441,7 +443,7 @@
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
diff --git a/man/sysusers.d.xml b/man/sysusers.d.xml
index fbe97544d7..38b749cf15 100644
--- a/man/sysusers.d.xml
+++ b/man/sysusers.d.xml
@@ -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
diff --git a/man/telinit.xml b/man/telinit.xml
index bdd22a6ce8..70044cc1da 100644
--- a/man/telinit.xml
+++ b/man/telinit.xml
@@ -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
diff --git a/man/timedatectl.xml b/man/timedatectl.xml
index 80f63e8918..dba94d8831 100644
--- a/man/timedatectl.xml
+++ b/man/timedatectl.xml
@@ -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
diff --git a/man/timesyncd.conf.xml b/man/timesyncd.conf.xml
index 7c84e80d4d..812b16e1b9 100644
--- a/man/timesyncd.conf.xml
+++ b/man/timesyncd.conf.xml
@@ -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
@@ -101,6 +103,23 @@
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>
diff --git a/man/tmpfiles.d.xml b/man/tmpfiles.d.xml
index 68ae43eb90..f5d97aa38f 100644
--- a/man/tmpfiles.d.xml
+++ b/man/tmpfiles.d.xml
@@ -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
@@ -46,9 +48,17 @@
</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>
diff --git a/man/udev.conf.xml b/man/udev.conf.xml
index e104e53f5d..2339e8b9d3 100644
--- a/man/udev.conf.xml
+++ b/man/udev.conf.xml
@@ -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
diff --git a/man/udev.xml b/man/udev.xml
index 3359fb0865..7b42d2326b 100644
--- a/man/udev.xml
+++ b/man/udev.xml
@@ -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>
diff --git a/man/udev_device_get_syspath.xml b/man/udev_device_get_syspath.xml
index 014f43b21c..1eb029f8f9 100644
--- a/man/udev_device_get_syspath.xml
+++ b/man/udev_device_get_syspath.xml
@@ -6,6 +6,8 @@
]>
<!--
+ SPDX-License-Identifier: LGPL-2.1+
+
This file is part of systemd.
Copyright 2015 David Herrmann <dh.herrmann@gmail.com>
diff --git a/man/udev_device_has_tag.xml b/man/udev_device_has_tag.xml
index 480257343c..cdfcd7b727 100644
--- a/man/udev_device_has_tag.xml
+++ b/man/udev_device_has_tag.xml
@@ -6,6 +6,8 @@
]>
<!--
+ SPDX-License-Identifier: LGPL-2.1+
+
This file is part of systemd.
Copyright 2015 David Herrmann <dh.herrmann@gmail.com>
diff --git a/man/udev_device_new_from_syspath.xml b/man/udev_device_new_from_syspath.xml
index 0bb71c8e91..13f1b4ccef 100644
--- a/man/udev_device_new_from_syspath.xml
+++ b/man/udev_device_new_from_syspath.xml
@@ -6,6 +6,8 @@
]>
<!--
+ SPDX-License-Identifier: LGPL-2.1+
+
This file is part of systemd.
Copyright 2015 David Herrmann <dh.herrmann@gmail.com>
diff --git a/man/udev_enumerate_add_match_subsystem.xml b/man/udev_enumerate_add_match_subsystem.xml
index 5acce00bb0..fee861c65d 100644
--- a/man/udev_enumerate_add_match_subsystem.xml
+++ b/man/udev_enumerate_add_match_subsystem.xml
@@ -6,6 +6,8 @@
]>
<!--
+ SPDX-License-Identifier: LGPL-2.1+
+
This file is part of systemd.
Copyright 2015 David Herrmann <dh.herrmann@gmail.com>
diff --git a/man/udev_enumerate_new.xml b/man/udev_enumerate_new.xml
index b5856c5577..e195ad5105 100644
--- a/man/udev_enumerate_new.xml
+++ b/man/udev_enumerate_new.xml
@@ -6,6 +6,8 @@
]>
<!--
+ SPDX-License-Identifier: LGPL-2.1+
+
This file is part of systemd.
Copyright 2015 David Herrmann <dh.herrmann@gmail.com>
diff --git a/man/udev_enumerate_scan_devices.xml b/man/udev_enumerate_scan_devices.xml
index e0b6bfba32..3abfcef84e 100644
--- a/man/udev_enumerate_scan_devices.xml
+++ b/man/udev_enumerate_scan_devices.xml
@@ -6,6 +6,8 @@
]>
<!--
+ SPDX-License-Identifier: LGPL-2.1+
+
This file is part of systemd.
Copyright 2015 David Herrmann <dh.herrmann@gmail.com>
diff --git a/man/udev_list_entry.xml b/man/udev_list_entry.xml
index a1b531d52a..12b48357ff 100644
--- a/man/udev_list_entry.xml
+++ b/man/udev_list_entry.xml
@@ -6,6 +6,8 @@
]>
<!--
+ SPDX-License-Identifier: LGPL-2.1+
+
This file is part of systemd.
Copyright 2015 David Herrmann <dh.herrmann@gmail.com>
diff --git a/man/udev_monitor_filter_update.xml b/man/udev_monitor_filter_update.xml
index f129595618..3590a3ccd6 100644
--- a/man/udev_monitor_filter_update.xml
+++ b/man/udev_monitor_filter_update.xml
@@ -6,6 +6,8 @@
]>
<!--
+ SPDX-License-Identifier: LGPL-2.1+
+
This file is part of systemd.
Copyright 2015 David Herrmann <dh.herrmann@gmail.com>
diff --git a/man/udev_monitor_new_from_netlink.xml b/man/udev_monitor_new_from_netlink.xml
index d73a4acaec..90ce121611 100644
--- a/man/udev_monitor_new_from_netlink.xml
+++ b/man/udev_monitor_new_from_netlink.xml
@@ -6,6 +6,8 @@
]>
<!--
+ SPDX-License-Identifier: LGPL-2.1+
+
This file is part of systemd.
Copyright 2015 David Herrmann <dh.herrmann@gmail.com>
diff --git a/man/udev_monitor_receive_device.xml b/man/udev_monitor_receive_device.xml
index 7e842f88df..abc9615eb5 100644
--- a/man/udev_monitor_receive_device.xml
+++ b/man/udev_monitor_receive_device.xml
@@ -6,6 +6,8 @@
]>
<!--
+ SPDX-License-Identifier: LGPL-2.1+
+
This file is part of systemd.
Copyright 2015 David Herrmann <dh.herrmann@gmail.com>
diff --git a/man/udev_new.xml b/man/udev_new.xml
index 587835a3ca..b4520d7e36 100644
--- a/man/udev_new.xml
+++ b/man/udev_new.xml
@@ -6,6 +6,8 @@
]>
<!--
+ SPDX-License-Identifier: LGPL-2.1+
+
This file is part of systemd.
Copyright 2015 David Herrmann <dh.herrmann@gmail.com>
diff --git a/man/udevadm.xml b/man/udevadm.xml
index 7ace4f9826..753ddf98da 100644
--- a/man/udevadm.xml
+++ b/man/udevadm.xml
@@ -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>
@@ -33,16 +56,16 @@
<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>
@@ -65,24 +88,15 @@
<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
@@ -187,19 +201,9 @@
<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
@@ -331,13 +335,9 @@
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
@@ -368,17 +368,13 @@
<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>
@@ -442,18 +438,15 @@
</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>
@@ -500,13 +493,9 @@
<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>
@@ -536,13 +525,9 @@
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>
@@ -555,13 +540,8 @@
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>
diff --git a/man/user-system-options.xml b/man/user-system-options.xml
index 8616c54249..d6a5eeffb7 100644
--- a/man/user-system-options.xml
+++ b/man/user-system-options.xml
@@ -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>
diff --git a/man/vconsole.conf.xml b/man/vconsole.conf.xml
index 4a6672cbae..fecbfd82bc 100644
--- a/man/vconsole.conf.xml
+++ b/man/vconsole.conf.xml
@@ -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
diff --git a/meson.build b/meson.build
index f7a610af3b..ddc061c126 100644
--- a/meson.build
+++ b/meson.build
@@ -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
diff --git a/meson_options.txt b/meson_options.txt
index 3de72acf95..f0c0506ff1 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -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',
diff --git a/mkosi.build b/mkosi.build
index 92eb55b130..0781f0d9c4 100755
--- a/mkosi.build
+++ b/mkosi.build
@@ -24,9 +24,45 @@
# 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
diff --git a/modprobe.d/systemd.conf b/modprobe.d/systemd.conf
index d32f3ce3ea..0c4a3eaa3a 100644
--- a/modprobe.d/systemd.conf
+++ b/modprobe.d/systemd.conf
@@ -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
diff --git a/network/80-container-host0.network b/network/80-container-host0.network
index b012cf98cb..44c59b7dde 100644
--- a/network/80-container-host0.network
+++ b/network/80-container-host0.network
@@ -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/network/80-container-ve.network b/network/80-container-ve.network
index ac796bfb07..8a8df2fcd3 100644
--- a/network/80-container-ve.network
+++ b/network/80-container-ve.network
@@ -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/network/80-container-vz.network b/network/80-container-vz.network
index 3d532d6f60..4d4482b33a 100644
--- a/network/80-container-vz.network
+++ b/network/80-container-vz.network
@@ -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/network/99-default.link b/network/99-default.link
index 79538f9b29..561bf329e4 100644
--- a/network/99-default.link
+++ b/network/99-default.link
@@ -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
diff --git a/network/meson.build b/network/meson.build
index 4c33e45a16..fb17e1632e 100644
--- a/network/meson.build
+++ b/network/meson.build
@@ -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',
diff --git a/po/be.po b/po/be.po
index 2f60eb2eba..ce8f1223cd 100644
--- 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.
diff --git a/po/be@latin.po b/po/be@latin.po
index 121696a316..36eb347ae1 100644
--- a/po/be@latin.po
+++ b/po/be@latin.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.
diff --git a/po/bg.po b/po/bg.po
index 5f92f8e2e7..b395cc2ca7 100644
--- 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.
diff --git a/po/ca.po b/po/ca.po
index 30fdea0cf6..a625dd6404 100644
--- 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.
diff --git a/po/cs.po b/po/cs.po
index 9622c71054..332dc3cef6 100644
--- 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í."
diff --git a/po/da.po b/po/da.po
index a5be57940f..187103ce9e 100644
--- 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.
diff --git a/po/de.po b/po/de.po
index 72075e81fd..bb431fe4a7 100644
--- 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.
diff --git a/po/el.po b/po/el.po
index 94c9986d60..0e7db7fb15 100644
--- 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.
diff --git a/po/es.po b/po/es.po
index 6642351f68..705a47e354 100644
--- 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.
diff --git a/po/fr.po b/po/fr.po
index 17550c755e..c300774035 100644
--- 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) »."
diff --git a/po/gl.po b/po/gl.po
index 59d92e1f7d..92000f5956 100644
--- 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.
diff --git a/po/hr.po b/po/hr.po
index e98e88aeb7..2f282cdfca 100644
--- 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.
diff --git a/po/hu.po b/po/hu.po
index b92921707f..77b7a00a69 100644
--- 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.
diff --git a/po/id.po b/po/id.po
index 72eb94c7ec..f7860e6a3c 100644
--- 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.
diff --git a/po/it.po b/po/it.po
index 7afa5c3b9c..0ce48591c3 100644
--- 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
index 0000000000..1c37e6bee7
--- /dev/null
+++ b/po/its/polkit.its
@@ -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
index 0000000000..c7427ec672
--- /dev/null
+++ b/po/its/polkit.loc
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<locatingRules>
+ <locatingRule name="polkit policy" pattern="*.policy">
+ <documentRule localName="policyconfig" target="polkit.its"/>
+ </locatingRule>
+</locatingRules>
diff --git a/po/ko.po b/po/ko.po
index e78ad2ef87..7a1e9e1c68 100644
--- 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.
diff --git a/po/meson.build b/po/meson.build
index f89291bfc4..7ba08fba18 100644
--- a/po/meson.build
+++ b/po/meson.build
@@ -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@']
diff --git a/po/pl.po b/po/pl.po
index c289a2cd4c..2e9d134f20 100644
--- 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)â€."
diff --git a/po/pt_BR.po b/po/pt_BR.po
index a087a4786b..acc03af910 100644
--- a/po/pt_BR.po
+++ b/po/pt_BR.po
@@ -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.
diff --git a/po/ro.po b/po/ro.po
index c5b6758b90..d9109fc040 100644
--- 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.
diff --git a/po/ru.po b/po/ru.po
index 0c0fab780e..3cbf13dab1 100644
--- 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)», необходимо пройти "
"аутентификацию."
diff --git a/po/sk.po b/po/sk.po
index 84dd7326fe..e1747d8caa 100644
--- 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.
diff --git a/po/sr.po b/po/sr.po
index 7f9b2b31cd..c20bec8834 100644
--- 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.
diff --git a/po/sv.po b/po/sv.po
index 1de9b4650d..4a7f3d8987 100644
--- 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"
diff --git a/po/tr.po b/po/tr.po
index b71f30b835..71b65eaf7e 100644
--- 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ı "
diff --git a/po/uk.po b/po/uk.po
index 66044b8686..31e5f55beb 100644
--- 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.
diff --git a/po/zh_CN.po b/po/zh_CN.po
index 10c53d4538..7fbbcb1925 100644
--- a/po/zh_CN.po
+++ b/po/zh_CN.po
@@ -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.
diff --git a/po/zh_TW.po b/po/zh_TW.po
index affea9126e..c2b3b08914 100644
--- a/po/zh_TW.po
+++ b/po/zh_TW.po
@@ -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.
diff --git a/system-preset/90-systemd.preset b/presets/90-systemd.preset
index 3ba4bb760d..11960e5423 100644
--- a/system-preset/90-systemd.preset
+++ b/presets/90-systemd.preset
@@ -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
index 0000000000..48aa8c9796
--- /dev/null
+++ b/presets/meson.build
@@ -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)
diff --git a/units/remote-cryptsetup-pre.target b/presets/user/90-systemd.preset
index a375e61889..22fe41fc33 100644
--- a/units/remote-cryptsetup-pre.target
+++ b/presets/user/90-systemd.preset
@@ -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
diff --git a/rules/50-udev-default.rules.in b/rules/50-udev-default.rules.in
index 898148c064..71e716913c 100644
--- a/rules/50-udev-default.rules.in
+++ b/rules/50-udev-default.rules.in
@@ -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"
diff --git a/rules/60-input-id.rules b/rules/60-input-id.rules
index dee42199b6..bb8a812d1b 100644
--- a/rules/60-input-id.rules
+++ b/rules/60-input-id.rules
@@ -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"
diff --git a/rules/60-persistent-input.rules b/rules/60-persistent-input.rules
index 91efbe7294..255547d906 100644
--- a/rules/60-persistent-input.rules
+++ b/rules/60-persistent-input.rules
@@ -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"
diff --git a/rules/60-persistent-storage.rules b/rules/60-persistent-storage.rules
index 72fec5c884..0de8cf3a1a 100644
--- a/rules/60-persistent-storage.rules
+++ b/rules/60-persistent-storage.rules
@@ -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}"
diff --git a/rules/99-systemd.rules.in b/rules/99-systemd.rules.in
index 62f0b98cd3..419ca4ed87 100644
--- a/rules/99-systemd.rules.in
+++ b/rules/99-systemd.rules.in
@@ -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/rules/meson.build b/rules/meson.build
index 1bb43147e3..e253b9f591 100644
--- a/rules/meson.build
+++ b/rules/meson.build
@@ -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('''
60-block.rules
60-cdrom_id.rules
@@ -24,6 +41,8 @@ rules = files('''
install_data(rules,
install_dir : udevrulesdir)
+all_rules = rules
+
rules_in = '''
50-udev-default.rules
64-btrfs.rules
@@ -37,4 +56,5 @@ foreach file : rules_in
configuration : substs)
install_data(gen,
install_dir : udevrulesdir)
+ all_rules += gen
endforeach
diff --git a/shell-completion/bash/bootctl b/shell-completion/bash/bootctl
index c86ec7edc9..34b1b552d9 100644
--- a/shell-completion/bash/bootctl
+++ b/shell-completion/bash/bootctl
@@ -1,4 +1,5 @@
# bootctl(1) completion -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1+
#
# This file is part of systemd.
#
diff --git a/shell-completion/bash/busctl b/shell-completion/bash/busctl
index 6a770b1b84..aa4c1d74d9 100644
--- a/shell-completion/bash/busctl
+++ b/shell-completion/bash/busctl
@@ -1,4 +1,5 @@
# busctl(1) completion -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1+
#
# This file is part of systemd.
#
diff --git a/shell-completion/bash/coredumpctl b/shell-completion/bash/coredumpctl
index 87fe473e09..842e4943ff 100644
--- a/shell-completion/bash/coredumpctl
+++ b/shell-completion/bash/coredumpctl
@@ -1,4 +1,5 @@
# coredumpctl(1) completion -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1+
#
# This file is part of systemd.
#
diff --git a/shell-completion/bash/hostnamectl b/shell-completion/bash/hostnamectl
index 7cf8b6f631..a35ac7f9a0 100644
--- a/shell-completion/bash/hostnamectl
+++ b/shell-completion/bash/hostnamectl
@@ -1,4 +1,5 @@
# hostnamectl(1) completion -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1+
#
# This file is part of systemd.
#
diff --git a/shell-completion/bash/journalctl b/shell-completion/bash/journalctl
index c90a114497..03ee733d7e 100644
--- a/shell-completion/bash/journalctl
+++ b/shell-completion/bash/journalctl
@@ -1,4 +1,5 @@
# journalctl(1) completion -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1+
#
# This file is part of systemd.
#
diff --git a/shell-completion/bash/kernel-install b/shell-completion/bash/kernel-install
index 7cd2494cf7..5a78528d36 100644
--- a/shell-completion/bash/kernel-install
+++ b/shell-completion/bash/kernel-install
@@ -1,4 +1,5 @@
# kernel-install(8) completion -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1+
#
# This file is part of systemd.
#
diff --git a/shell-completion/bash/localectl b/shell-completion/bash/localectl
index e0c06a794e..97c91a4ce2 100644
--- a/shell-completion/bash/localectl
+++ b/shell-completion/bash/localectl
@@ -1,4 +1,5 @@
# localectl(1) completion -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1+
#
# This file is part of systemd.
#
diff --git a/shell-completion/bash/loginctl b/shell-completion/bash/loginctl
index 776eca4e62..d8d14f889a 100644
--- a/shell-completion/bash/loginctl
+++ b/shell-completion/bash/loginctl
@@ -1,4 +1,5 @@
# loginctl(1) completion -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1+
#
# This file is part of systemd.
#
diff --git a/shell-completion/bash/machinectl b/shell-completion/bash/machinectl
index aebe48304d..7865a99882 100644
--- a/shell-completion/bash/machinectl
+++ b/shell-completion/bash/machinectl
@@ -1,4 +1,5 @@
# machinectl(1) completion -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1+
#
# This file is part of systemd.
#
diff --git a/shell-completion/bash/meson.build b/shell-completion/bash/meson.build
index 11238781c6..347518cd46 100644
--- a/shell-completion/bash/meson.build
+++ b/shell-completion/bash/meson.build
@@ -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)
diff --git a/shell-completion/bash/networkctl b/shell-completion/bash/networkctl
index 68e3338471..0c36aaf464 100644
--- a/shell-completion/bash/networkctl
+++ b/shell-completion/bash/networkctl
@@ -1,4 +1,5 @@
# networkctl(1) completion -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1+
#
# This file is part of systemd.
#
diff --git a/shell-completion/bash/systemctl.in b/shell-completion/bash/systemctl.in
index bde28efc3e..5a353f7107 100644
--- a/shell-completion/bash/systemctl.in
+++ b/shell-completion/bash/systemctl.in
@@ -1,4 +1,5 @@
# systemctl(1) completion -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1+
#
# This file is part of systemd.
#
diff --git a/shell-completion/bash/systemd-analyze b/shell-completion/bash/systemd-analyze
index 8c56a1cf9a..45ff7a1f3e 100644
--- a/shell-completion/bash/systemd-analyze
+++ b/shell-completion/bash/systemd-analyze
@@ -1,4 +1,5 @@
# systemd-analyze(1) completion -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1+
#
# This file is part of systemd.
#
diff --git a/shell-completion/bash/systemd-cat b/shell-completion/bash/systemd-cat
index 8d84042af1..20ff672059 100644
--- a/shell-completion/bash/systemd-cat
+++ b/shell-completion/bash/systemd-cat
@@ -1,4 +1,5 @@
# systemd-cat(1) completion -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1+
#
# This file is part of systemd.
#
diff --git a/shell-completion/bash/systemd-cgls b/shell-completion/bash/systemd-cgls
index 0570438660..0f579a6e67 100644
--- a/shell-completion/bash/systemd-cgls
+++ b/shell-completion/bash/systemd-cgls
@@ -1,4 +1,5 @@
# systemd-cgls(1) completion -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1+
#
# This file is part of systemd.
#
diff --git a/shell-completion/bash/systemd-cgtop b/shell-completion/bash/systemd-cgtop
index f1ed22fd55..7a1b4acc7c 100644
--- a/shell-completion/bash/systemd-cgtop
+++ b/shell-completion/bash/systemd-cgtop
@@ -1,4 +1,5 @@
# systemd-cgtop(1) completion -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1+
#
# This file is part of systemd.
#
diff --git a/shell-completion/bash/systemd-delta b/shell-completion/bash/systemd-delta
index cb1732895f..d3933437b3 100644
--- a/shell-completion/bash/systemd-delta
+++ b/shell-completion/bash/systemd-delta
@@ -1,4 +1,5 @@
# systemd-delta(1) completion -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1+
#
# This file is part of systemd.
#
diff --git a/shell-completion/bash/systemd-detect-virt b/shell-completion/bash/systemd-detect-virt
index df06c29841..21dca2b966 100644
--- a/shell-completion/bash/systemd-detect-virt
+++ b/shell-completion/bash/systemd-detect-virt
@@ -1,4 +1,5 @@
# systemd-detect-virt(1) completion -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1+
#
# This file is part of systemd.
#
diff --git a/shell-completion/bash/systemd-nspawn b/shell-completion/bash/systemd-nspawn
index ea4a5e1f43..4f2fbef84f 100644
--- a/shell-completion/bash/systemd-nspawn
+++ b/shell-completion/bash/systemd-nspawn
@@ -1,4 +1,5 @@
# systemd-nspawn(1) completion -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1+
#
# This file is part of systemd.
#
diff --git a/shell-completion/bash/systemd-path b/shell-completion/bash/systemd-path
index 2f0c5f5bd7..5d99775c2d 100644
--- a/shell-completion/bash/systemd-path
+++ b/shell-completion/bash/systemd-path
@@ -1,4 +1,5 @@
# systemd-path(1) completion -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1+
#
# This file is part of systemd.
#
diff --git a/shell-completion/bash/systemd-resolve b/shell-completion/bash/systemd-resolve
index f59482fe23..3f789e80d0 100644
--- a/shell-completion/bash/systemd-resolve
+++ b/shell-completion/bash/systemd-resolve
@@ -1,4 +1,5 @@
# systemd-resolve(1) completion -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1+
#
# This file is part of systemd.
#
diff --git a/shell-completion/bash/systemd-run b/shell-completion/bash/systemd-run
index 4116ba7eca..125cd306f0 100644
--- a/shell-completion/bash/systemd-run
+++ b/shell-completion/bash/systemd-run
@@ -1,4 +1,5 @@
# systemd-run(1) completion -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1+
#
# This file is part of systemd.
#
diff --git a/shell-completion/bash/timedatectl b/shell-completion/bash/timedatectl
index a57fbd2546..b9d00811e3 100644
--- a/shell-completion/bash/timedatectl
+++ b/shell-completion/bash/timedatectl
@@ -1,4 +1,5 @@
# timedatectl(1) completion -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1+
#
# This file is part of systemd.
#
diff --git a/shell-completion/bash/udevadm b/shell-completion/bash/udevadm
index b828b8dd7c..744a38826b 100644
--- a/shell-completion/bash/udevadm
+++ b/shell-completion/bash/udevadm
@@ -1,4 +1,5 @@
# udevadm(8) completion -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1+
#
# This file is part of systemd.
#
diff --git a/shell-completion/zsh/_bootctl b/shell-completion/zsh/_bootctl
index 0e1b0a5562..f107005814 100644
--- a/shell-completion/zsh/_bootctl
+++ b/shell-completion/zsh/_bootctl
@@ -1,4 +1,5 @@
#compdef bootctl
+# SPDX-License-Identifier: LGPL-2.1+
(( $+functions[_bootctl_command] )) || _bootctl_command()
{
diff --git a/shell-completion/zsh/_busctl b/shell-completion/zsh/_busctl
index a425b8c700..883ace47af 100644
--- a/shell-completion/zsh/_busctl
+++ b/shell-completion/zsh/_busctl
@@ -1,4 +1,5 @@
#compdef busctl
+# SPDX-License-Identifier: LGPL-2.1+
# busctl(1) completion -*- shell-script -*-
#
diff --git a/shell-completion/zsh/_coredumpctl b/shell-completion/zsh/_coredumpctl
index e469bca958..ea8cfb2dec 100644
--- a/shell-completion/zsh/_coredumpctl
+++ b/shell-completion/zsh/_coredumpctl
@@ -1,4 +1,5 @@
#compdef coredumpctl
+# SPDX-License-Identifier: LGPL-2.1+
_coredumpctl_command(){
local -a _coredumpctl_cmds
diff --git a/shell-completion/zsh/_hostnamectl b/shell-completion/zsh/_hostnamectl
index 8c4a354af2..ea86863e5a 100644
--- a/shell-completion/zsh/_hostnamectl
+++ b/shell-completion/zsh/_hostnamectl
@@ -1,4 +1,5 @@
#compdef hostnamectl
+# SPDX-License-Identifier: LGPL-2.1+
_hostnamectl_set-hostname() {
if (( CURRENT <= 3 )); then
diff --git a/shell-completion/zsh/_journalctl b/shell-completion/zsh/_journalctl
index 4a78a2e946..4bffabba96 100644
--- a/shell-completion/zsh/_journalctl
+++ b/shell-completion/zsh/_journalctl
@@ -1,4 +1,5 @@
#compdef journalctl
+# SPDX-License-Identifier: LGPL-2.1+
_list_fields() {
local -a journal_fields
diff --git a/shell-completion/zsh/_kernel-install b/shell-completion/zsh/_kernel-install
index 4fdd3a4ae7..6358a64589 100644
--- a/shell-completion/zsh/_kernel-install
+++ b/shell-completion/zsh/_kernel-install
@@ -1,4 +1,5 @@
#compdef kernel-install
+# SPDX-License-Identifier: LGPL-2.1+
_images(){
if [[ "$words[2]" == "remove" ]]; then
diff --git a/shell-completion/zsh/_localectl b/shell-completion/zsh/_localectl
index 54c2d456e4..e5ec65b53b 100644
--- a/shell-completion/zsh/_localectl
+++ b/shell-completion/zsh/_localectl
@@ -1,4 +1,5 @@
#compdef localectl
+# SPDX-License-Identifier: LGPL-2.1+
_localectl_set-locale() {
local -a _locales locale_fields
diff --git a/shell-completion/zsh/_loginctl b/shell-completion/zsh/_loginctl
index 6f6ff6e314..03dde9a891 100644
--- a/shell-completion/zsh/_loginctl
+++ b/shell-completion/zsh/_loginctl
@@ -1,4 +1,5 @@
#compdef loginctl
+# SPDX-License-Identifier: LGPL-2.1+
_loginctl_all_sessions() {
local session description
diff --git a/shell-completion/zsh/_machinectl b/shell-completion/zsh/_machinectl
index 92d77109a5..933f4d2e6a 100644
--- a/shell-completion/zsh/_machinectl
+++ b/shell-completion/zsh/_machinectl
@@ -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;}
diff --git a/shell-completion/zsh/_networkctl b/shell-completion/zsh/_networkctl
index acf7463edb..ea485d653c 100644
--- a/shell-completion/zsh/_networkctl
+++ b/shell-completion/zsh/_networkctl
@@ -1,4 +1,5 @@
#compdef networkctl
+# SPDX-License-Identifier: LGPL-2.1+
_networkctl_command(){
local -a _networkctl_cmds
diff --git a/shell-completion/zsh/_sd_hosts_or_user_at_host b/shell-completion/zsh/_sd_hosts_or_user_at_host
index 282f7328e4..11f94f1976 100644
--- a/shell-completion/zsh/_sd_hosts_or_user_at_host
+++ b/shell-completion/zsh/_sd_hosts_or_user_at_host
@@ -1,4 +1,5 @@
#autoload
+# SPDX-License-Identifier: LGPL-2.1+
_alternative \
'users-hosts:: _user_at_host' \
diff --git a/shell-completion/zsh/_sd_machines b/shell-completion/zsh/_sd_machines
index a0039ee0f8..ab35cf84b3 100644
--- a/shell-completion/zsh/_sd_machines
+++ b/shell-completion/zsh/_sd_machines
@@ -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;};
}
diff --git a/shell-completion/zsh/_sd_outputmodes b/shell-completion/zsh/_sd_outputmodes
index 2948f40130..3b8850b3f0 100644
--- a/shell-completion/zsh/_sd_outputmodes
+++ b/shell-completion/zsh/_sd_outputmodes
@@ -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)
diff --git a/shell-completion/zsh/_sd_unit_files b/shell-completion/zsh/_sd_unit_files
index 5e90ea23c5..cce44423e9 100644
--- a/shell-completion/zsh/_sd_unit_files
+++ b/shell-completion/zsh/_sd_unit_files
@@ -1,4 +1,5 @@
#autoload
+# SPDX-License-Identifier: LGPL-2.1+
_sd_unit_files() {
local files expl
diff --git a/shell-completion/zsh/_systemctl.in b/shell-completion/zsh/_systemctl.in
index d35c900f10..47ec9970e1 100644
--- a/shell-completion/zsh/_systemctl.in
+++ b/shell-completion/zsh/_systemctl.in
@@ -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' \
diff --git a/shell-completion/zsh/_systemd b/shell-completion/zsh/_systemd
index 62114ff095..ccac889244 100644
--- a/shell-completion/zsh/_systemd
+++ b/shell-completion/zsh/_systemd
@@ -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
diff --git a/shell-completion/zsh/_systemd-analyze b/shell-completion/zsh/_systemd-analyze
index 22b4c181a1..ce22217fbc 100644
--- a/shell-completion/zsh/_systemd-analyze
+++ b/shell-completion/zsh/_systemd-analyze
@@ -1,4 +1,5 @@
#compdef systemd-analyze
+# SPDX-License-Identifier: LGPL-2.1+
_systemd_analyze_set-log-level() {
local -a _levels
diff --git a/shell-completion/zsh/_systemd-delta b/shell-completion/zsh/_systemd-delta
index 757f1b66fb..44e4cb3791 100644
--- a/shell-completion/zsh/_systemd-delta
+++ b/shell-completion/zsh/_systemd-delta
@@ -1,4 +1,5 @@
#compdef systemd-delta
+# SPDX-License-Identifier: LGPL-2.1+
_delta_type() {
local -a _delta_types
diff --git a/shell-completion/zsh/_systemd-inhibit b/shell-completion/zsh/_systemd-inhibit
index 1b3247b2cd..764713e28a 100644
--- a/shell-completion/zsh/_systemd-inhibit
+++ b/shell-completion/zsh/_systemd-inhibit
@@ -1,4 +1,5 @@
#compdef systemd-inhibit
+# SPDX-License-Identifier: LGPL-2.1+
_systemd_inhibit_command(){
if (( CURRENT == 1 )); then
diff --git a/shell-completion/zsh/_systemd-nspawn b/shell-completion/zsh/_systemd-nspawn
index 77b2e7cd7c..e0bedee2aa 100644
--- a/shell-completion/zsh/_systemd-nspawn
+++ b/shell-completion/zsh/_systemd-nspawn
@@ -1,4 +1,5 @@
#compdef systemd-nspawn
+# SPDX-License-Identifier: LGPL-2.1+
_nspawn-caps(){
local -a _caps
diff --git a/shell-completion/zsh/_systemd-resolve b/shell-completion/zsh/_systemd-resolve
index c318ab50f1..eb7606af30 100644
--- a/shell-completion/zsh/_systemd-resolve
+++ b/shell-completion/zsh/_systemd-resolve
@@ -1,4 +1,5 @@
#compdef systemd-resolve
+# SPDX-License-Identifier: LGPL-2.1+
#
# This file is part of systemd.
diff --git a/shell-completion/zsh/_systemd-run b/shell-completion/zsh/_systemd-run
index 5c3e65c223..0ad4b27a6f 100644
--- a/shell-completion/zsh/_systemd-run
+++ b/shell-completion/zsh/_systemd-run
@@ -1,4 +1,5 @@
#compdef systemd-run
+# SPDX-License-Identifier: LGPL-2.1+
__systemctl() {
local -a _modes
diff --git a/shell-completion/zsh/_systemd-tmpfiles b/shell-completion/zsh/_systemd-tmpfiles
index 6ff02e5d98..0993bca5a4 100644
--- a/shell-completion/zsh/_systemd-tmpfiles
+++ b/shell-completion/zsh/_systemd-tmpfiles
@@ -1,4 +1,5 @@
#compdef systemd-tmpfiles
+# SPDX-License-Identifier: LGPL-2.1+
_arguments \
{-h,--help}'[Show help]' \
diff --git a/shell-completion/zsh/_timedatectl b/shell-completion/zsh/_timedatectl
index dfdcfebb3c..c1ed21e565 100644
--- a/shell-completion/zsh/_timedatectl
+++ b/shell-completion/zsh/_timedatectl
@@ -1,4 +1,5 @@
#compdef timedatectl
+# SPDX-License-Identifier: LGPL-2.1+
_timedatectl_set-timezone(){
local -a _timezones
diff --git a/shell-completion/zsh/_udevadm b/shell-completion/zsh/_udevadm
index bb23e64d24..c6bd685aee 100644
--- a/shell-completion/zsh/_udevadm
+++ b/shell-completion/zsh/_udevadm
@@ -1,4 +1,5 @@
#compdef udevadm
+# SPDX-License-Identifier: LGPL-2.1+
_udevadm_info(){
_arguments \
diff --git a/shell-completion/zsh/meson.build b/shell-completion/zsh/meson.build
index 4e7b33a8a7..cf3c556f13 100644
--- a/shell-completion/zsh/meson.build
+++ b/shell-completion/zsh/meson.build
@@ -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')
diff --git a/src/ac-power/ac-power.c b/src/ac-power/ac-power.c
index c5277884a8..6d3172d5c1 100644
--- a/src/ac-power/ac-power.c
+++ b/src/ac-power/ac-power.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/activate/activate.c b/src/activate/activate.c
index 4b82dca491..83807efdcf 100644
--- a/src/activate/activate.c
+++ b/src/activate/activate.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/analyze/analyze-verify.c b/src/analyze/analyze-verify.c
index f34c24c53a..461e7852ac 100644
--- a/src/analyze/analyze-verify.c
+++ b/src/analyze/analyze-verify.c
@@ -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)
diff --git a/src/analyze/analyze-verify.h b/src/analyze/analyze-verify.h
index d5466ecdf9..a895130508 100644
--- a/src/analyze/analyze-verify.h
+++ b/src/analyze/analyze-verify.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/analyze/analyze.c b/src/analyze/analyze.c
index 9fcc20dba3..d45c1dc496 100644
--- a/src/analyze/analyze.c
+++ b/src/analyze/analyze.c
@@ -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]);
}
diff --git a/src/analyze/meson.build b/src/analyze/meson.build
index fcbd814233..b32311413b 100644
--- a/src/analyze/meson.build
+++ b/src/analyze/meson.build
@@ -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
diff --git a/src/ask-password/ask-password.c b/src/ask-password/ask-password.c
index 6d53dd982c..48cfaa7acc 100644
--- a/src/ask-password/ask-password.c
+++ b/src/ask-password/ask-password.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/backlight/backlight.c b/src/backlight/backlight.c
index c909b5bb51..8fedf8ebbc 100644
--- a/src/backlight/backlight.c
+++ b/src/backlight/backlight.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/basic/MurmurHash2.c b/src/basic/MurmurHash2.c
index a282a21201..47adfb4d0a 100644
--- a/src/basic/MurmurHash2.c
+++ b/src/basic/MurmurHash2.c
@@ -15,6 +15,10 @@
#include "MurmurHash2.h"
+#if __GNUC__ >= 7
+_Pragma("GCC diagnostic ignored \"-Wimplicit-fallthrough\"")
+#endif
+
//-----------------------------------------------------------------------------
// Platform-specific functions and macros
diff --git a/src/basic/af-list.c b/src/basic/af-list.c
index 4b291d177b..fa81a69e0e 100644
--- a/src/basic/af-list.c
+++ b/src/basic/af-list.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/basic/af-list.h b/src/basic/af-list.h
index 6a4cc03839..65656022cc 100644
--- a/src/basic/af-list.h
+++ b/src/basic/af-list.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/alloc-util.c b/src/basic/alloc-util.c
index 948389f276..cdde4f2859 100644
--- a/src/basic/alloc-util.c
+++ b/src/basic/alloc-util.c
@@ -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);
diff --git a/src/basic/alloc-util.h b/src/basic/alloc-util.h
index 0a89691bae..02dee37d36 100644
--- a/src/basic/alloc-util.h
+++ b/src/basic/alloc-util.h
@@ -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);
diff --git a/src/basic/architecture.c b/src/basic/architecture.c
index 2518dd8112..46157061ed 100644
--- a/src/basic/architecture.c
+++ b/src/basic/architecture.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/basic/architecture.h b/src/basic/architecture.h
index 40a2ce6448..c81a1c2f44 100644
--- a/src/basic/architecture.h
+++ b/src/basic/architecture.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/arphrd-list.c b/src/basic/arphrd-list.c
index 2d598dc66f..5df93a59c1 100644
--- a/src/basic/arphrd-list.c
+++ b/src/basic/arphrd-list.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/basic/arphrd-list.h b/src/basic/arphrd-list.h
index c0f8758dbe..2222e92c8a 100644
--- a/src/basic/arphrd-list.h
+++ b/src/basic/arphrd-list.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/async.c b/src/basic/async.c
index a1f163f27b..d368b92522 100644
--- a/src/basic/async.c
+++ b/src/basic/async.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/basic/async.h b/src/basic/async.h
index 9bd13ff6e0..7eac54d8b2 100644
--- a/src/basic/async.h
+++ b/src/basic/async.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/audit-util.c b/src/basic/audit-util.c
index 24a6c8a936..6a93c9109c 100644
--- a/src/basic/audit-util.c
+++ b/src/basic/audit-util.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/basic/audit-util.h b/src/basic/audit-util.h
index 3088951326..dba15de8ee 100644
--- a/src/basic/audit-util.h
+++ b/src/basic/audit-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/barrier.c b/src/basic/barrier.c
index 0c44e47b12..cd3638b676 100644
--- a/src/basic/barrier.c
+++ b/src/basic/barrier.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/basic/barrier.h b/src/basic/barrier.h
index fbc2d9d98d..7260d751c4 100644
--- a/src/basic/barrier.h
+++ b/src/basic/barrier.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/bitmap.c b/src/basic/bitmap.c
index f6212e6151..f1aa7c5e51 100644
--- a/src/basic/bitmap.c
+++ b/src/basic/bitmap.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/basic/bitmap.h b/src/basic/bitmap.h
index 63fdbe8bea..f1d822c643 100644
--- a/src/basic/bitmap.h
+++ b/src/basic/bitmap.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/blkid-util.h b/src/basic/blkid-util.h
index 53340ec6f3..3aba76b79e 100644
--- a/src/basic/blkid-util.h
+++ b/src/basic/blkid-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/bpf-program.c b/src/basic/bpf-program.c
index ce6f9e4409..3690f812ae 100644
--- a/src/basic/bpf-program.c
+++ b/src/basic/bpf-program.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/basic/bpf-program.h b/src/basic/bpf-program.h
index 35a41ffc44..146350d18e 100644
--- a/src/basic/bpf-program.h
+++ b/src/basic/bpf-program.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/btrfs-util.c b/src/basic/btrfs-util.c
index c2061addd1..ac96e63531 100644
--- a/src/basic/btrfs-util.c
+++ b/src/basic/btrfs-util.c
@@ -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;
}
diff --git a/src/basic/btrfs-util.h b/src/basic/btrfs-util.h
index 04a2e1274b..2c78daa37b 100644
--- a/src/basic/btrfs-util.h
+++ b/src/basic/btrfs-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/build.h b/src/basic/build.h
index 9aaa6e3dae..ab2a838ce9 100644
--- a/src/basic/build.h
+++ b/src/basic/build.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/bus-label.c b/src/basic/bus-label.c
index d4531c7947..a072d0ad5d 100644
--- a/src/basic/bus-label.c
+++ b/src/basic/bus-label.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/basic/bus-label.h b/src/basic/bus-label.h
index 600268b767..5c6bc1f267 100644
--- a/src/basic/bus-label.h
+++ b/src/basic/bus-label.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/calendarspec.c b/src/basic/calendarspec.c
index 1fc9e9b154..e6add0c383 100644
--- a/src/basic/calendarspec.c
+++ b/src/basic/calendarspec.c
@@ -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);
}
}
diff --git a/src/basic/calendarspec.h b/src/basic/calendarspec.h
index 8888251705..124f7f5880 100644
--- a/src/basic/calendarspec.h
+++ b/src/basic/calendarspec.h
@@ -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);
diff --git a/src/basic/cap-list.c b/src/basic/cap-list.c
index 2e9b2d9a55..c4557666ef 100644
--- a/src/basic/cap-list.c
+++ b/src/basic/cap-list.c
@@ -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));
diff --git a/src/basic/cap-list.h b/src/basic/cap-list.h
index f9f6b70d80..ca9f4aa970 100644
--- a/src/basic/cap-list.h
+++ b/src/basic/cap-list.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/capability-util.c b/src/basic/capability-util.c
index 96c2e992bd..97778c55ab 100644
--- a/src/basic/capability-util.c
+++ b/src/basic/capability-util.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/basic/capability-util.h b/src/basic/capability-util.h
index 3dc9429153..fd9370ecb7 100644
--- a/src/basic/capability-util.h
+++ b/src/basic/capability-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c
index d51c3efd22..f599d0f0f1 100644
--- a/src/basic/cgroup-util.c
+++ b/src/basic/cgroup-util.c
@@ -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);
@@ -1493,7 +1474,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) {
@@ -1577,7 +1558,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) {
@@ -1614,7 +1595,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) {
@@ -2086,8 +2067,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;
}
@@ -2244,10 +2224,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);
@@ -2257,19 +2237,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;
}
@@ -2355,24 +2348,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);
@@ -2407,6 +2410,9 @@ int cg_kernel_controllers(Set *controllers) {
return r;
}
+ *ret = controllers;
+ controllers = NULL;
+
return 0;
}
@@ -2436,28 +2442,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;
}
@@ -2505,6 +2522,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;
@@ -2538,7 +2556,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);
}
diff --git a/src/basic/cgroup-util.h b/src/basic/cgroup-util.h
index c16a33723c..05c9f84505 100644
--- a/src/basic/cgroup-util.h
+++ b/src/basic/cgroup-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
@@ -31,14 +32,18 @@
#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);
diff --git a/src/basic/chattr-util.c b/src/basic/chattr-util.c
index 2896a729af..3635deee4e 100644
--- a/src/basic/chattr-util.c
+++ b/src/basic/chattr-util.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/basic/chattr-util.h b/src/basic/chattr-util.h
index 960cf6d5b3..a4ddaeeb8c 100644
--- a/src/basic/chattr-util.h
+++ b/src/basic/chattr-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/clock-util.c b/src/basic/clock-util.c
index 7fe8d35ea5..e2499099b6 100644
--- a/src/basic/clock-util.c
+++ b/src/basic/clock-util.c
@@ -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";
/*
diff --git a/src/basic/clock-util.h b/src/basic/clock-util.h
index 8830cd2f38..b90c31fb78 100644
--- a/src/basic/clock-util.h
+++ b/src/basic/clock-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/conf-files.c b/src/basic/conf-files.c
index 907d1350fe..c0ac202f57 100644
--- a/src/basic/conf-files.c
+++ b/src/basic/conf-files.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/basic/conf-files.h b/src/basic/conf-files.h
index 20ecf6e5f1..75dfd05e7c 100644
--- a/src/basic/conf-files.h
+++ b/src/basic/conf-files.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/copy.c b/src/basic/copy.c
index e120b9eb4e..0673ecd4a2 100644
--- a/src/basic/copy.c
+++ b/src/basic/copy.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/basic/copy.h b/src/basic/copy.h
index 4f3e11423e..59da4c2425 100644
--- a/src/basic/copy.h
+++ b/src/basic/copy.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/cpu-set-util.c b/src/basic/cpu-set-util.c
index aec0edc3dc..9f0a61a18e 100644
--- a/src/basic/cpu-set-util.c
+++ b/src/basic/cpu-set-util.c
@@ -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. */
diff --git a/src/basic/cpu-set-util.h b/src/basic/cpu-set-util.h
index 9b08ba0a67..c98149eaeb 100644
--- a/src/basic/cpu-set-util.h
+++ b/src/basic/cpu-set-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
@@ -24,10 +25,31 @@
#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
index 0000000000..193cf65dfc
--- /dev/null
+++ b/src/basic/crypt-util.c
@@ -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
index 0000000000..537f785607
--- /dev/null
+++ b/src/basic/crypt-util.h
@@ -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
diff --git a/src/basic/def.h b/src/basic/def.h
index c04e58b57a..77ab735aed 100644
--- a/src/basic/def.h
+++ b/src/basic/def.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
@@ -36,10 +37,6 @@
/* 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
diff --git a/src/basic/device-nodes.c b/src/basic/device-nodes.c
index 38c0628a90..61dc49238c 100644
--- a/src/basic/device-nodes.c
+++ b/src/basic/device-nodes.c
@@ -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++) {
diff --git a/src/basic/device-nodes.h b/src/basic/device-nodes.h
index 94f385abcb..7dd8a772a5 100644
--- a/src/basic/device-nodes.h
+++ b/src/basic/device-nodes.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
@@ -22,5 +23,18 @@
#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))
diff --git a/src/basic/dirent-util.c b/src/basic/dirent-util.c
index 5bf58bcdc3..e2b093bad3 100644
--- a/src/basic/dirent-util.c
+++ b/src/basic/dirent-util.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/basic/dirent-util.h b/src/basic/dirent-util.h
index 18b9db9b28..94d5ee81a3 100644
--- a/src/basic/dirent-util.h
+++ b/src/basic/dirent-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/env-util.c b/src/basic/env-util.c
index fa42edfa96..e77f9d6d3f 100644
--- a/src/basic/env-util.c
+++ b/src/basic/env-util.c
@@ -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);
}
diff --git a/src/basic/env-util.h b/src/basic/env-util.h
index d5da8cd67b..956a2a8270 100644
--- a/src/basic/env-util.h
+++ b/src/basic/env-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/errno-list.c b/src/basic/errno-list.c
index c6a01eec8b..d8eedfc0ad 100644
--- a/src/basic/errno-list.c
+++ b/src/basic/errno-list.c
@@ -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);
-}
diff --git a/src/basic/errno-list.h b/src/basic/errno-list.h
index 4eec0cc786..4e9b75a7ea 100644
--- a/src/basic/errno-list.h
+++ b/src/basic/errno-list.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
@@ -19,7 +20,11 @@
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);
diff --git a/src/basic/escape.c b/src/basic/escape.c
index 0a6122c64a..7d77aef329 100644
--- a/src/basic/escape.c
+++ b/src/basic/escape.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/basic/escape.h b/src/basic/escape.h
index 6f5cc60bc8..de89f43a82 100644
--- a/src/basic/escape.h
+++ b/src/basic/escape.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/ether-addr-util.c b/src/basic/ether-addr-util.c
index 5697e8d132..bbe8bf0006 100644
--- a/src/basic/ether-addr-util.c
+++ b/src/basic/ether-addr-util.c
@@ -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 == '.') {
diff --git a/src/basic/ether-addr-util.h b/src/basic/ether-addr-util.h
index 74e125a95f..08d05a136f 100644
--- a/src/basic/ether-addr-util.h
+++ b/src/basic/ether-addr-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/exec-util.c b/src/basic/exec-util.c
index ade8511466..82ccbdf5ec 100644
--- a/src/basic/exec-util.c
+++ b/src/basic/exec-util.c
@@ -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
diff --git a/src/basic/exec-util.h b/src/basic/exec-util.h
index 72009799b2..d69bec7bc2 100644
--- a/src/basic/exec-util.h
+++ b/src/basic/exec-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/basic/exit-status.c b/src/basic/exit-status.c
index 7cfebbae72..c02681d4cc 100644
--- a/src/basic/exit-status.c
+++ b/src/basic/exit-status.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/basic/exit-status.h b/src/basic/exit-status.h
index 195b3bc486..1e10419f8b 100644
--- a/src/basic/exit-status.h
+++ b/src/basic/exit-status.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/extract-word.c b/src/basic/extract-word.c
index f4ac526eb1..5e42560487 100644
--- a/src/basic/extract-word.c
+++ b/src/basic/extract-word.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/basic/extract-word.h b/src/basic/extract-word.h
index 04746c6d08..300c51bb77 100644
--- a/src/basic/extract-word.h
+++ b/src/basic/extract-word.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/fd-util.c b/src/basic/fd-util.c
index 9d61044c89..a4a5c6b3f6 100644
--- a/src/basic/fd-util.c
+++ b/src/basic/fd-util.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
@@ -26,8 +27,10 @@
#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;
+}
diff --git a/src/basic/fd-util.h b/src/basic/fd-util.h
index 34b98d4aec..84a0816f03 100644
--- a/src/basic/fd-util.h
+++ b/src/basic/fd-util.h
@@ -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)
diff --git a/src/basic/fileio-label.c b/src/basic/fileio-label.c
index ef51c49395..bf5fec1faa 100644
--- a/src/basic/fileio-label.c
+++ b/src/basic/fileio-label.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/basic/fileio-label.h b/src/basic/fileio-label.h
index 9854ea50b9..0adb895236 100644
--- a/src/basic/fileio-label.h
+++ b/src/basic/fileio-label.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
@@ -24,6 +25,10 @@
#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);
diff --git a/src/basic/fileio.c b/src/basic/fileio.c
index 9ee7a4af38..4e02d5b344 100644
--- a/src/basic/fileio.c
+++ b/src/basic/fileio.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
@@ -22,8 +23,10 @@
#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 (;;) {
diff --git a/src/basic/fileio.h b/src/basic/fileio.h
index eba05be2a9..da5d5c66b5 100644
--- a/src/basic/fileio.h
+++ b/src/basic/fileio.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
@@ -29,11 +30,17 @@
#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);
diff --git a/src/basic/format-util.h b/src/basic/format-util.h
index ae42a8f89e..d9a78f7811 100644
--- a/src/basic/format-util.h
+++ b/src/basic/format-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/fs-util.c b/src/basic/fs-util.c
index b90f343ed3..4ca36faf09 100644
--- a/src/basic/fs-util.c
+++ b/src/basic/fs-util.c
@@ -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 */
@@ -621,10 +621,7 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags,
* Suggested usage: whenever you want to canonicalize a path, use this function. Pass the absolute path you got
* as-is: fully qualified and relative to your host's root. Optionally, specify the root parameter to tell this
* function what to do when encountering a symlink with an absolute path as directory: prefix it by the
- * specified path.
- *
- * Note: there's also chase_symlinks_prefix() (see below), which as first step prefixes the passed path by the
- * passed root. */
+ * specified path. */
if (original_root) {
r = path_make_absolute_cwd(original_root, &root);
@@ -661,9 +658,18 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags,
todo += m;
+ /* Empty? Then we reached the end. */
+ if (isempty(first))
+ break;
+
/* Just a single slash? Then we reached the end. */
- if (isempty(first) || path_equal(first, "/"))
+ if (path_equal(first, "/")) {
+ /* Preserve the trailing slash */
+ if (!strextend(&done, "/", NULL))
+ return -ENOMEM;
+
break;
+ }
/* Just a dot? Then let's eat this up. */
if (path_equal(first, "/."))
@@ -707,12 +713,16 @@ 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 "./"
* or something else weird. */
+ /* If done is "/", as first also contains slash at the head, then remove this redundant slash. */
+ if (streq_ptr(done, "/"))
+ *done = '\0';
+
if (!strextend(&done, first, todo, NULL))
return -ENOMEM;
@@ -726,7 +736,7 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags,
if (fstat(child, &st) < 0)
return -errno;
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)) {
@@ -766,12 +776,11 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags,
return -ENOMEM;
}
- }
-
- /* 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);
+ /* 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);
+ } else
+ joined = strjoin("/", destination, todo);
if (!joined)
return -ENOMEM;
@@ -786,6 +795,10 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags,
done = first;
first = NULL;
} else {
+ /* If done is "/", as first also contains slash at the head, then remove this redundant slash. */
+ if (streq(done, "/"))
+ *done = '\0';
+
if (!strextend(&done, first, NULL))
return -ENOMEM;
}
@@ -810,3 +823,18 @@ 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;
+}
diff --git a/src/basic/fs-util.h b/src/basic/fs-util.h
index d3342d5cda..a7ba61625d 100644
--- a/src/basic/fs-util.h
+++ b/src/basic/fs-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
@@ -98,3 +99,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);
diff --git a/src/basic/generate-gperfs.py b/src/basic/generate-gperfs.py
index d4cc9aa45c..aca9ab1fe9 100755
--- a/src/basic/generate-gperfs.py
+++ b/src/basic/generate-gperfs.py
@@ -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))
diff --git a/src/basic/glob-util.c b/src/basic/glob-util.c
index f611c42e4c..6e80a1e23b 100644
--- a/src/basic/glob-util.c
+++ b/src/basic/glob-util.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/basic/glob-util.h b/src/basic/glob-util.h
index e1f6083afa..911e6d2c1a 100644
--- a/src/basic/glob-util.h
+++ b/src/basic/glob-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/hash-funcs.c b/src/basic/hash-funcs.c
index c3a4a011b5..e69f81558d 100644
--- a/src/basic/hash-funcs.c
+++ b/src/basic/hash-funcs.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/basic/hash-funcs.h b/src/basic/hash-funcs.h
index 299189d143..959e2c101d 100644
--- a/src/basic/hash-funcs.h
+++ b/src/basic/hash-funcs.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/hashmap.c b/src/basic/hashmap.c
index 4bfaa864b4..cc4423b2af 100644
--- a/src/basic/hashmap.c
+++ b/src/basic/hashmap.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
@@ -25,12 +26,14 @@
#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;
diff --git a/src/basic/hashmap.h b/src/basic/hashmap.h
index c1089652d3..0eb763944c 100644
--- a/src/basic/hashmap.h
+++ b/src/basic/hashmap.h
@@ -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);
diff --git a/src/basic/hexdecoct.c b/src/basic/hexdecoct.c
index 766770389c..fe7e4954ef 100644
--- a/src/basic/hexdecoct.c
+++ b/src/basic/hexdecoct.c
@@ -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;
diff --git a/src/basic/hexdecoct.h b/src/basic/hexdecoct.h
index 1ba2f69ebd..08d0a52276 100644
--- a/src/basic/hexdecoct.h
+++ b/src/basic/hexdecoct.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/hostname-util.c b/src/basic/hostname-util.c
index ea9e77087f..b59e5425a5 100644
--- a/src/basic/hostname-util.c
+++ b/src/basic/hostname-util.c
@@ -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;
}
diff --git a/src/basic/hostname-util.h b/src/basic/hostname-util.h
index 7af4e6c7ec..d837d6f28c 100644
--- a/src/basic/hostname-util.h
+++ b/src/basic/hostname-util.h
@@ -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);
diff --git a/src/basic/in-addr-util.c b/src/basic/in-addr-util.c
index e27faba75f..572e172b33 100644
--- a/src/basic/in-addr-util.c
+++ b/src/basic/in-addr-util.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/basic/in-addr-util.h b/src/basic/in-addr-util.h
index 59f8eb7edf..acaae6d287 100644
--- a/src/basic/in-addr-util.h
+++ b/src/basic/in-addr-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/io-util.c b/src/basic/io-util.c
index cc6dfa8c1b..77c9bdc739 100644
--- a/src/basic/io-util.c
+++ b/src/basic/io-util.c
@@ -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;
diff --git a/src/basic/io-util.h b/src/basic/io-util.h
index d9b69adde9..d81610ad21 100644
--- a/src/basic/io-util.h
+++ b/src/basic/io-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/journal-importer.c b/src/basic/journal-importer.c
index e750101165..6942c370cb 100644
--- a/src/basic/journal-importer.c
+++ b/src/basic/journal-importer.c
@@ -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);
diff --git a/src/basic/journal-importer.h b/src/basic/journal-importer.h
index b3e308dd6d..d11caa2396 100644
--- a/src/basic/journal-importer.h
+++ b/src/basic/journal-importer.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/basic/khash.c b/src/basic/khash.c
index 84648dc1c9..694210512c 100644
--- a/src/basic/khash.c
+++ b/src/basic/khash.c
@@ -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) {
diff --git a/src/basic/khash.h b/src/basic/khash.h
index 410f3020e0..7041d39993 100644
--- a/src/basic/khash.h
+++ b/src/basic/khash.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/label.c b/src/basic/label.c
index f5ab855d32..ce81d286ab 100644
--- a/src/basic/label.c
+++ b/src/basic/label.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/basic/label.h b/src/basic/label.h
index 3e9251aa71..86447c2e98 100644
--- a/src/basic/label.h
+++ b/src/basic/label.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/list.h b/src/basic/list.h
index c3771a177f..7006c3e273 100644
--- a/src/basic/list.h
+++ b/src/basic/list.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
@@ -182,3 +183,6 @@
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))
diff --git a/src/basic/locale-util.c b/src/basic/locale-util.c
index ada0a28cd8..266cb29936 100644
--- a/src/basic/locale-util.c
+++ b/src/basic/locale-util.c
@@ -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) {
diff --git a/src/basic/locale-util.h b/src/basic/locale-util.h
index 0630a034ab..60ce017a15 100644
--- a/src/basic/locale-util.h
+++ b/src/basic/locale-util.h
@@ -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);
diff --git a/src/basic/lockfile-util.c b/src/basic/lockfile-util.c
index 3ee4191e4d..f4761a9d55 100644
--- a/src/basic/lockfile-util.c
+++ b/src/basic/lockfile-util.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/basic/lockfile-util.h b/src/basic/lockfile-util.h
index 22491ee8e1..1e86ad7442 100644
--- a/src/basic/lockfile-util.h
+++ b/src/basic/lockfile-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/log.c b/src/basic/log.c
index 4f0fe54579..20d9588e2f 100644
--- a/src/basic/log.c
+++ b/src/basic/log.c
@@ -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);
}
diff --git a/src/basic/log.h b/src/basic/log.h
index 10a6032788..aa5976c3c0 100644
--- a/src/basic/log.h
+++ b/src/basic/log.h
@@ -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,
diff --git a/src/basic/login-util.c b/src/basic/login-util.c
index 339e94f12d..af4539453a 100644
--- a/src/basic/login-util.c
+++ b/src/basic/login-util.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/basic/login-util.h b/src/basic/login-util.h
index b01ee25c88..1c558bfe20 100644
--- a/src/basic/login-util.h
+++ b/src/basic/login-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/macro.h b/src/basic/macro.h
index a51562db35..02d22de833 100644
--- a/src/basic/macro.h
+++ b/src/basic/macro.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
@@ -47,6 +48,11 @@
#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.
diff --git a/src/basic/memfd-util.c b/src/basic/memfd-util.c
index 8f4f0e3a24..e7eb895462 100644
--- a/src/basic/memfd-util.c
+++ b/src/basic/memfd-util.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/basic/memfd-util.h b/src/basic/memfd-util.h
index 46d4989e4c..1d66c98cce 100644
--- a/src/basic/memfd-util.h
+++ b/src/basic/memfd-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/mempool.c b/src/basic/mempool.c
index f95e2beb0f..0da8e1f775 100644
--- a/src/basic/mempool.c
+++ b/src/basic/mempool.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/basic/mempool.h b/src/basic/mempool.h
index 0618b8dd22..c9235c8361 100644
--- a/src/basic/mempool.h
+++ b/src/basic/mempool.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/meson.build b/src/basic/meson.build
index 1ddefb7fbb..a37e279e57 100644
--- a/src/basic/meson.build
+++ b/src/basic/meson.build
@@ -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
diff --git a/src/basic/missing.h b/src/basic/missing.h
index 352d2b024b..790f9f55a5 100644
--- a/src/basic/missing.h
+++ b/src/basic/missing.h
@@ -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"
diff --git a/src/basic/missing_syscall.h b/src/basic/missing_syscall.h
index 3322e4e4d6..fd82c11e94 100644
--- a/src/basic/missing_syscall.h
+++ b/src/basic/missing_syscall.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
@@ -319,6 +320,8 @@ static inline ssize_t copy_file_range(int fd_in, loff_t *off_in,
}
#endif
+/* ======================================================================= */
+
#if !HAVE_BPF
# ifndef __NR_bpf
# if defined __i386__
@@ -348,3 +351,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
diff --git a/src/basic/mkdir-label.c b/src/basic/mkdir-label.c
index aa6878cdf0..16eb7ce265 100644
--- a/src/basic/mkdir-label.c
+++ b/src/basic/mkdir-label.c
@@ -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) {
diff --git a/src/basic/mkdir.c b/src/basic/mkdir.c
index 7db09fc6a1..4386b38c4a 100644
--- a/src/basic/mkdir.c
+++ b/src/basic/mkdir.c
@@ -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) {
diff --git a/src/basic/mkdir.h b/src/basic/mkdir.h
index d564a3547f..04a537f8a8 100644
--- a/src/basic/mkdir.h
+++ b/src/basic/mkdir.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
@@ -22,17 +23,17 @@
#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
index 0000000000..07956dbffd
--- /dev/null
+++ b/src/basic/module-util.h
@@ -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);
diff --git a/src/basic/mount-util.c b/src/basic/mount-util.c
index c4d451db73..a8947cefc2 100644
--- a/src/basic/mount-util.c
+++ b/src/basic/mount-util.c
@@ -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>
@@ -39,8 +41,82 @@
#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;
diff --git a/src/basic/mount-util.h b/src/basic/mount-util.h
index 1e066d8886..a81d019277 100644
--- a/src/basic/mount-util.h
+++ b/src/basic/mount-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
@@ -29,6 +30,10 @@
#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,
diff --git a/src/basic/nss-util.h b/src/basic/nss-util.h
index 9d927a8227..4fc676395f 100644
--- a/src/basic/nss-util.h
+++ b/src/basic/nss-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/ordered-set.c b/src/basic/ordered-set.c
index 2e0bdf6488..afcf2dbd1d 100644
--- a/src/basic/ordered-set.c
+++ b/src/basic/ordered-set.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/basic/ordered-set.h b/src/basic/ordered-set.h
index e1dfc86380..c4dbd79249 100644
--- a/src/basic/ordered-set.h
+++ b/src/basic/ordered-set.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/parse-util.c b/src/basic/parse-util.c
index 4ae07b0a8e..d03f60e01a 100644
--- a/src/basic/parse-util.c
+++ b/src/basic/parse-util.c
@@ -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;
diff --git a/src/basic/parse-util.h b/src/basic/parse-util.h
index dc09782ca8..1eda1d7f9f 100644
--- a/src/basic/parse-util.h
+++ b/src/basic/parse-util.h
@@ -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);
diff --git a/src/basic/path-util.c b/src/basic/path-util.c
index 6c06bd2acb..ab4778d4ed 100644
--- a/src/basic/path-util.c
+++ b/src/basic/path-util.c
@@ -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;
diff --git a/src/basic/path-util.h b/src/basic/path-util.h
index 546246595c..f79cdf928e 100644
--- a/src/basic/path-util.h
+++ b/src/basic/path-util.h
@@ -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);
diff --git a/src/basic/prioq.c b/src/basic/prioq.c
index 4570b8e4ba..407b17e9bf 100644
--- a/src/basic/prioq.c
+++ b/src/basic/prioq.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/basic/prioq.h b/src/basic/prioq.h
index 113c73d040..a222955dfe 100644
--- a/src/basic/prioq.h
+++ b/src/basic/prioq.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/proc-cmdline.c b/src/basic/proc-cmdline.c
index 8592a428d5..c5d1fb1d41 100644
--- a/src/basic/proc-cmdline.c
+++ b/src/basic/proc-cmdline.c
@@ -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];
diff --git a/src/basic/proc-cmdline.h b/src/basic/proc-cmdline.h
index ebfed355e9..16ccfbc2cb 100644
--- a/src/basic/proc-cmdline.h
+++ b/src/basic/proc-cmdline.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/process-util.c b/src/basic/process-util.c
index 99b0946a03..17c94f44a0 100644
--- a/src/basic/process-util.c
+++ b/src/basic/process-util.c
@@ -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",
diff --git a/src/basic/process-util.h b/src/basic/process-util.h
index 82af2f9181..1b7e692060 100644
--- a/src/basic/process-util.h
+++ b/src/basic/process-util.h
@@ -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);
diff --git a/src/basic/random-util.c b/src/basic/random-util.c
index 146c8f55ed..1bc8000896 100644
--- a/src/basic/random-util.c
+++ b/src/basic/random-util.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/basic/random-util.h b/src/basic/random-util.h
index 804e225fc1..dd8701515e 100644
--- a/src/basic/random-util.h
+++ b/src/basic/random-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/ratelimit.c b/src/basic/ratelimit.c
index 3ca5625e4d..5b684e261a 100644
--- a/src/basic/ratelimit.c
+++ b/src/basic/ratelimit.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/basic/ratelimit.h b/src/basic/ratelimit.h
index 9c8dddf5ad..19acf9c854 100644
--- a/src/basic/ratelimit.h
+++ b/src/basic/ratelimit.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/raw-clone.h b/src/basic/raw-clone.h
index c6e531ada4..f01b73a8fe 100644
--- a/src/basic/raw-clone.h
+++ b/src/basic/raw-clone.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/refcnt.h b/src/basic/refcnt.h
index 1d77a6445a..ae2e446d6c 100644
--- a/src/basic/refcnt.h
+++ b/src/basic/refcnt.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/replace-var.c b/src/basic/replace-var.c
index d2642812e7..c73ed9777e 100644
--- a/src/basic/replace-var.c
+++ b/src/basic/replace-var.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/basic/replace-var.h b/src/basic/replace-var.h
index 31eb057803..3d5906198e 100644
--- a/src/basic/replace-var.h
+++ b/src/basic/replace-var.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/rlimit-util.c b/src/basic/rlimit-util.c
index 5c41429f01..00648211d3 100644
--- a/src/basic/rlimit-util.c
+++ b/src/basic/rlimit-util.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/basic/rlimit-util.h b/src/basic/rlimit-util.h
index d4594eccd6..4494b89c76 100644
--- a/src/basic/rlimit-util.h
+++ b/src/basic/rlimit-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/rm-rf.c b/src/basic/rm-rf.c
index 0bbafb4cd7..2839f37cd9 100644
--- a/src/basic/rm-rf.c
+++ b/src/basic/rm-rf.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/basic/rm-rf.h b/src/basic/rm-rf.h
index e13f7003e3..1127e326b2 100644
--- a/src/basic/rm-rf.h
+++ b/src/basic/rm-rf.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/securebits-util.c b/src/basic/securebits-util.c
index 011ec36af4..b5f6418a6c 100644
--- a/src/basic/securebits-util.c
+++ b/src/basic/securebits-util.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/basic/securebits-util.h b/src/basic/securebits-util.h
index b4d970c366..aaa192f0a5 100644
--- a/src/basic/securebits-util.h
+++ b/src/basic/securebits-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/selinux-util.c b/src/basic/selinux-util.c
index 93bcdb2160..0c6e99b1d7 100644
--- a/src/basic/selinux-util.c
+++ b/src/basic/selinux-util.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/basic/selinux-util.h b/src/basic/selinux-util.h
index 5bf72364b4..9780dca81e 100644
--- a/src/basic/selinux-util.h
+++ b/src/basic/selinux-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/set.c b/src/basic/set.c
index fd398b8212..e554e825eb 100644
--- a/src/basic/set.c
+++ b/src/basic/set.c
@@ -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)
diff --git a/src/basic/set.h b/src/basic/set.h
index 12d0fda1ca..156ab4b081 100644
--- a/src/basic/set.h
+++ b/src/basic/set.h
@@ -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 */
diff --git a/src/basic/sigbus.c b/src/basic/sigbus.c
index 0ce4f75684..2416929e36 100644
--- a/src/basic/sigbus.c
+++ b/src/basic/sigbus.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/basic/sigbus.h b/src/basic/sigbus.h
index 980243d9ce..90b0c9632e 100644
--- a/src/basic/sigbus.h
+++ b/src/basic/sigbus.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/signal-util.c b/src/basic/signal-util.c
index df6b742fde..27caabe471 100644
--- a/src/basic/signal-util.c
+++ b/src/basic/signal-util.c
@@ -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);
diff --git a/src/basic/signal-util.h b/src/basic/signal-util.h
index dfd6eb564d..76b239b1fc 100644
--- a/src/basic/signal-util.h
+++ b/src/basic/signal-util.h
@@ -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) {
diff --git a/src/basic/siphash24.c b/src/basic/siphash24.c
index 4bb41786c8..d3a81b7cc1 100644
--- a/src/basic/siphash24.c
+++ b/src/basic/siphash24.c
@@ -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;
}
diff --git a/src/basic/smack-util.c b/src/basic/smack-util.c
index 3dcf150c59..e0f1c9f1c7 100644
--- a/src/basic/smack-util.c
+++ b/src/basic/smack-util.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/basic/smack-util.h b/src/basic/smack-util.h
index f90ba0a027..e4d46d7736 100644
--- a/src/basic/smack-util.h
+++ b/src/basic/smack-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/socket-label.c b/src/basic/socket-label.c
index 6e7cdaac63..20be406371 100644
--- a/src/basic/socket-label.c
+++ b/src/basic/socket-label.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/basic/socket-util.c b/src/basic/socket-util.c
index 29c779552d..a458fc2902 100644
--- a/src/basic/socket-util.c
+++ b/src/basic/socket-util.c
@@ -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)
diff --git a/src/basic/socket-util.h b/src/basic/socket-util.h
index 43edc05c63..272e74b0cc 100644
--- a/src/basic/socket-util.h
+++ b/src/basic/socket-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/sparse-endian.h b/src/basic/sparse-endian.h
index a3573b84a9..5e59de5437 100644
--- a/src/basic/sparse-endian.h
+++ b/src/basic/sparse-endian.h
@@ -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
diff --git a/src/basic/special.h b/src/basic/special.h
index ddd4e84019..c058b1d852 100644
--- a/src/basic/special.h
+++ b/src/basic/special.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/stat-util.c b/src/basic/stat-util.c
index d87370e672..96fc8b3787 100644
--- a/src/basic/stat-util.c
+++ b/src/basic/stat-util.c
@@ -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;
diff --git a/src/basic/stat-util.h b/src/basic/stat-util.h
index cd204ac6cb..d8d3c20496 100644
--- a/src/basic/stat-util.h
+++ b/src/basic/stat-util.h
@@ -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
diff --git a/src/basic/stdio-util.h b/src/basic/stdio-util.h
index bd1144b4c9..dbfafba269 100644
--- a/src/basic/stdio-util.h
+++ b/src/basic/stdio-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/strbuf.c b/src/basic/strbuf.c
index 00aaf9e621..8befffa66f 100644
--- a/src/basic/strbuf.c
+++ b/src/basic/strbuf.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/basic/strbuf.h b/src/basic/strbuf.h
index a1632da0e8..d5888a06dc 100644
--- a/src/basic/strbuf.h
+++ b/src/basic/strbuf.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/string-table.c b/src/basic/string-table.c
index a1499ab126..d4b7c69bdc 100644
--- a/src/basic/string-table.c
+++ b/src/basic/string-table.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/basic/string-table.h b/src/basic/string-table.h
index 369610efc8..4306b90f46 100644
--- a/src/basic/string-table.h
+++ b/src/basic/string-table.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
diff --git a/src/basic/string-util.c b/src/basic/string-util.c
index 3179fba3ba..7e2f596edc 100644
--- a/src/basic/string-util.c
+++ b/src/basic/string-util.c
@@ -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;
diff --git a/src/basic/string-util.h b/src/basic/string-util.h
index 4c94b182c1..09a737ad37 100644
--- a/src/basic/string-util.h
+++ b/src/basic/string-util.h
@@ -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);
diff --git a/src/basic/strv.c b/src/basic/strv.c
index c63f11c6ad..54c701aee2 100644
--- a/src/basic/strv.c
+++ b/src/basic/strv.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/basic/strv.h b/src/basic/strv.h
index 385ad17779..0ed6b74330 100644
--- a/src/basic/strv.h
+++ b/src/basic/strv.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
@@ -180,3 +181,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; \
+ })
diff --git a/src/basic/strxcpyx.c b/src/basic/strxcpyx.c
index c6fbe79647..b440a9a725 100644
--- a/src/basic/strxcpyx.c
+++ b/src/basic/strxcpyx.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/basic/strxcpyx.h b/src/basic/strxcpyx.h
index 80ff58726b..0554454fd2 100644
--- a/src/basic/strxcpyx.h
+++ b/src/basic/strxcpyx.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/syslog-util.c b/src/basic/syslog-util.c
index db3405154e..4f4e2354b6 100644
--- a/src/basic/syslog-util.c
+++ b/src/basic/syslog-util.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/basic/syslog-util.h b/src/basic/syslog-util.h
index 5cb606a1bf..8f44e3f8ef 100644
--- a/src/basic/syslog-util.h
+++ b/src/basic/syslog-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/terminal-util.c b/src/basic/terminal-util.c
index 28c8c35fe0..48ee799ad4 100644
--- a/src/basic/terminal-util.c
+++ b/src/basic/terminal-util.c
@@ -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;
diff --git a/src/basic/terminal-util.h b/src/basic/terminal-util.h
index c3045eb09d..e82719b11b 100644
--- a/src/basic/terminal-util.h
+++ b/src/basic/terminal-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/time-util.c b/src/basic/time-util.c
index f7f5e614f2..d56576ddbe 100644
--- a/src/basic/time-util.c
+++ b/src/basic/time-util.c
@@ -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;
+}
diff --git a/src/basic/time-util.h b/src/basic/time-util.h
index 3b7f0e99c0..dc4a159310 100644
--- a/src/basic/time-util.h
+++ b/src/basic/time-util.h
@@ -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;
diff --git a/src/basic/umask-util.h b/src/basic/umask-util.h
index 359d87d27c..638b37d7de 100644
--- a/src/basic/umask-util.h
+++ b/src/basic/umask-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/unaligned.h b/src/basic/unaligned.h
index 7c847a3ccb..201b3d227e 100644
--- a/src/basic/unaligned.h
+++ b/src/basic/unaligned.h
@@ -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
index 0000000000..387533f597
--- /dev/null
+++ b/src/basic/unit-def.c
@@ -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
index 0000000000..c142e069a6
--- /dev/null
+++ b/src/basic/unit-def.h
@@ -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_;
diff --git a/src/basic/unit-name.c b/src/basic/unit-name.c
index f9c034c94b..403f288b57 100644
--- a/src/basic/unit-name.c
+++ b/src/basic/unit-name.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
@@ -24,12 +25,9 @@
#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);
diff --git a/src/basic/unit-name.h b/src/basic/unit-name.h
index 15558b4fbd..b47327dcaf 100644
--- a/src/basic/unit-name.h
+++ b/src/basic/unit-name.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
@@ -22,232 +23,10 @@
#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_;
diff --git a/src/basic/user-util.c b/src/basic/user-util.c
index a691a0d3fc..abb0b76866 100644
--- a/src/basic/user-util.c
+++ b/src/basic/user-util.c
@@ -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 */
diff --git a/src/basic/user-util.h b/src/basic/user-util.h
index dfea561bde..79adf91ee9 100644
--- a/src/basic/user-util.h
+++ b/src/basic/user-util.h
@@ -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))
diff --git a/src/basic/utf8.c b/src/basic/utf8.c
index 7a52fac621..4da9a405cb 100644
--- a/src/basic/utf8.c
+++ b/src/basic/utf8.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/basic/utf8.h b/src/basic/utf8.h
index f9b9c9468b..b0a7485aed 100644
--- a/src/basic/utf8.h
+++ b/src/basic/utf8.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/util.c b/src/basic/util.c
index 687de40993..8f9f2b902b 100644
--- a/src/basic/util.c
+++ b/src/basic/util.c
@@ -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)
diff --git a/src/basic/util.h b/src/basic/util.h
index b31dfd1c92..a79907de3e 100644
--- a/src/basic/util.h
+++ b/src/basic/util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/verbs.c b/src/basic/verbs.c
index d9cdb38d65..cb42e6dd08 100644
--- a/src/basic/verbs.c
+++ b/src/basic/verbs.c
@@ -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 {
diff --git a/src/basic/verbs.h b/src/basic/verbs.h
index 7b5e18510f..5f44a18f8e 100644
--- a/src/basic/verbs.h
+++ b/src/basic/verbs.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
@@ -20,13 +21,17 @@
***/
#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;
diff --git a/src/basic/virt.c b/src/basic/virt.c
index d8eeb54dbf..b0db28add6 100644
--- a/src/basic/virt.c
+++ b/src/basic/virt.c
@@ -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));
diff --git a/src/basic/virt.h b/src/basic/virt.h
index 7d15169112..d9badd8efe 100644
--- a/src/basic/virt.h
+++ b/src/basic/virt.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/web-util.c b/src/basic/web-util.c
index 595688ed93..d721b02653 100644
--- a/src/basic/web-util.c
+++ b/src/basic/web-util.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/basic/web-util.h b/src/basic/web-util.h
index e6bb6b53f5..ad8c850d1d 100644
--- a/src/basic/web-util.h
+++ b/src/basic/web-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/xattr-util.c b/src/basic/xattr-util.c
index e086376d7c..12d04eeffb 100644
--- a/src/basic/xattr-util.c
+++ b/src/basic/xattr-util.c
@@ -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;
diff --git a/src/basic/xattr-util.h b/src/basic/xattr-util.h
index 6fa097bf7e..1a78027aaa 100644
--- a/src/basic/xattr-util.h
+++ b/src/basic/xattr-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/basic/xml.c b/src/basic/xml.c
index a4337f4865..639c3438a0 100644
--- a/src/basic/xml.c
+++ b/src/basic/xml.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/basic/xml.h b/src/basic/xml.h
index 41cb69f0dc..d00b527232 100644
--- a/src/basic/xml.h
+++ b/src/basic/xml.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/binfmt/binfmt.c b/src/binfmt/binfmt.c
index 17af233ef8..eb888e88ea 100644
--- a/src/binfmt/binfmt.c
+++ b/src/binfmt/binfmt.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/boot/bootctl.c b/src/boot/bootctl.c
index 85f3b42c48..59c1af73de 100644
--- a/src/boot/bootctl.c
+++ b/src/boot/bootctl.c
@@ -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"
@@ -49,209 +51,46 @@
#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 },
{}
};
diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c
index 12176f1fe0..ea9f39a7e7 100644
--- a/src/boot/efi/boot.c
+++ b/src/boot/efi/boot.c
@@ -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 */
diff --git a/src/boot/efi/console.c b/src/boot/efi/console.c
index 2b797c9a5f..4487ed099f 100644
--- a/src/boot/efi/console.c
+++ b/src/boot/efi/console.c
@@ -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
diff --git a/src/boot/efi/console.h b/src/boot/efi/console.h
index 3fe0ce5ec4..5664a4e62f 100644
--- a/src/boot/efi/console.h
+++ b/src/boot/efi/console.h
@@ -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
diff --git a/src/boot/efi/disk.c b/src/boot/efi/disk.c
index 3e3b5b224a..af0f05c75d 100644
--- a/src/boot/efi/disk.c
+++ b/src/boot/efi/disk.c
@@ -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
diff --git a/src/boot/efi/disk.h b/src/boot/efi/disk.h
index af91a9c674..c5894f8e4e 100644
--- a/src/boot/efi/disk.h
+++ b/src/boot/efi/disk.h
@@ -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
diff --git a/src/boot/efi/graphics.c b/src/boot/efi/graphics.c
index 4854baf874..29577c837a 100644
--- a/src/boot/efi/graphics.c
+++ b/src/boot/efi/graphics.c
@@ -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
diff --git a/src/boot/efi/graphics.h b/src/boot/efi/graphics.h
index cf48e647e7..10e0c269ba 100644
--- a/src/boot/efi/graphics.h
+++ b/src/boot/efi/graphics.h
@@ -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
diff --git a/src/boot/efi/linux.c b/src/boot/efi/linux.c
index 0dc99a6c53..e8f7651324 100644
--- a/src/boot/efi/linux.c
+++ b/src/boot/efi/linux.c
@@ -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) {
diff --git a/src/boot/efi/linux.h b/src/boot/efi/linux.h
index d9e6ed7955..3c11423591 100644
--- a/src/boot/efi/linux.h
+++ b/src/boot/efi/linux.h
@@ -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
diff --git a/src/boot/efi/measure.c b/src/boot/efi/measure.c
index 324d1c8b9e..be4fea84a2 100644
--- a/src/boot/efi/measure.c
+++ b/src/boot/efi/measure.c
@@ -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)
diff --git a/src/boot/efi/measure.h b/src/boot/efi/measure.h
index 43aa8a0058..63e0a738ce 100644
--- a/src/boot/efi/measure.h
+++ b/src/boot/efi/measure.h
@@ -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
diff --git a/src/boot/efi/meson.build b/src/boot/efi/meson.build
index eb0be02977..992a3ba4c2 100644
--- a/src/boot/efi/meson.build
+++ b/src/boot/efi/meson.build
@@ -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
diff --git a/src/boot/efi/pe.c b/src/boot/efi/pe.c
index 054e8edbc6..3755a36a68 100644
--- a/src/boot/efi/pe.c
+++ b/src/boot/efi/pe.c
@@ -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
diff --git a/src/boot/efi/pe.h b/src/boot/efi/pe.h
index fa8feea758..4a411f5d76 100644
--- a/src/boot/efi/pe.h
+++ b/src/boot/efi/pe.h
@@ -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
diff --git a/src/boot/efi/shim.c b/src/boot/efi/shim.c
index 0f73be9549..6d7d814c5c 100644
--- a/src/boot/efi/shim.c
+++ b/src/boot/efi/shim.c
@@ -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;
}
diff --git a/src/boot/efi/shim.h b/src/boot/efi/shim.h
index 2dcf48dcd5..d9ab135ae0 100644
--- a/src/boot/efi/shim.h
+++ b/src/boot/efi/shim.h
@@ -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
diff --git a/src/boot/efi/splash.c b/src/boot/efi/splash.c
index c0ef7f64fe..32186d4e38 100644
--- a/src/boot/efi/splash.c
+++ b/src/boot/efi/splash.c
@@ -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
diff --git a/src/boot/efi/splash.h b/src/boot/efi/splash.h
index 09b543fb47..c7e9c7a78d 100644
--- a/src/boot/efi/splash.h
+++ b/src/boot/efi/splash.h
@@ -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
diff --git a/src/boot/efi/stub.c b/src/boot/efi/stub.c
index e85ebf2c3f..e917019c0c 100644
--- a/src/boot/efi/stub.c
+++ b/src/boot/efi/stub.c
@@ -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);
diff --git a/src/boot/efi/util.c b/src/boot/efi/util.c
index 98c5be74ce..b165f31005 100644
--- a/src/boot/efi/util.c
+++ b/src/boot/efi/util.c
@@ -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
diff --git a/src/boot/efi/util.h b/src/boot/efi/util.h
index e673cdf9a0..35150aea76 100644
--- a/src/boot/efi/util.h
+++ b/src/boot/efi/util.h
@@ -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
diff --git a/src/busctl/busctl-introspect.c b/src/busctl/busctl-introspect.c
index a05794941f..54d6e07d2c 100644
--- a/src/busctl/busctl-introspect.c
+++ b/src/busctl/busctl-introspect.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/busctl/busctl-introspect.h b/src/busctl/busctl-introspect.h
index d922e352db..a27a1c8f9d 100644
--- a/src/busctl/busctl-introspect.h
+++ b/src/busctl/busctl-introspect.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/busctl/busctl.c b/src/busctl/busctl.c
index b38d6c7267..7a8d6ba5ac 100644
--- a/src/busctl/busctl.c
+++ b/src/busctl/busctl.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
@@ -18,6 +19,7 @@
***/
#include <getopt.h>
+#include <stdio_ext.h>
#include "sd-bus.h"
@@ -691,12 +693,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);
@@ -863,7 +860,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;
@@ -889,13 +886,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);
@@ -906,6 +901,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;
@@ -917,10 +913,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)
@@ -952,22 +946,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)
@@ -985,10 +977,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));
@@ -1736,7 +1728,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"
@@ -2010,7 +2002,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();
@@ -2100,7 +2092,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);
diff --git a/src/cgls/cgls.c b/src/cgls/cgls.c
index 1b746a0e13..fb44b9f669 100644
--- a/src/cgls/cgls.c
+++ b/src/cgls/cgls.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/cgroups-agent/cgroups-agent.c b/src/cgroups-agent/cgroups-agent.c
index d7c722ac3d..05d12ebb41 100644
--- a/src/cgroups-agent/cgroups-agent.c
+++ b/src/cgroups-agent/cgroups-agent.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/cgtop/cgtop.c b/src/cgtop/cgtop.c
index 7ebb02fa8c..fe339eb493 100644
--- a/src/cgtop/cgtop.c
+++ b/src/cgtop/cgtop.c
@@ -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) {
diff --git a/src/core/audit-fd.c b/src/core/audit-fd.c
index 6207f8185e..60e79035af 100644
--- a/src/core/audit-fd.c
+++ b/src/core/audit-fd.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/core/audit-fd.h b/src/core/audit-fd.h
index 0eccb59210..43f4f193d8 100644
--- a/src/core/audit-fd.h
+++ b/src/core/audit-fd.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/core/automount.c b/src/core/automount.c
index 9b0d1ca429..28d5cc3917 100644
--- a/src/core/automount.c
+++ b/src/core/automount.c
@@ -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;
diff --git a/src/core/automount.h b/src/core/automount.h
index 76a201178e..b8be4d316e 100644
--- a/src/core/automount.h
+++ b/src/core/automount.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/core/bpf-firewall.c b/src/core/bpf-firewall.c
index 909c1c8253..f3f40fb0e8 100644
--- a/src/core/bpf-firewall.c
+++ b/src/core/bpf-firewall.c
@@ -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;
}
diff --git a/src/core/bpf-firewall.h b/src/core/bpf-firewall.h
index 870e314e0e..37a1f2e003 100644
--- a/src/core/bpf-firewall.h
+++ b/src/core/bpf-firewall.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/core/cgroup.c b/src/core/cgroup.c
index e9f9447118..78ef885b06 100644
--- a/src/core/cgroup.c
+++ b/src/core/cgroup.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
@@ -209,6 +210,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",
@@ -666,9 +677,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;
@@ -1020,7 +1033,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) {
@@ -1062,32 +1075,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;
@@ -1095,10 +1118,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;
@@ -1106,9 +1130,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 */
}
}
@@ -1126,7 +1148,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) {
@@ -1372,6 +1394,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,
@@ -1387,19 +1434,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);
@@ -1465,7 +1503,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(
@@ -1483,6 +1521,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.
@@ -1496,10 +1555,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);
@@ -1532,16 +1588,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;
@@ -1555,6 +1601,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);
@@ -1575,8 +1627,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;
@@ -1944,11 +1997,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);
@@ -1960,9 +2011,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);
@@ -2332,7 +2383,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;
@@ -2402,7 +2452,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;
@@ -2415,7 +2465,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;
@@ -2426,8 +2476,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;
diff --git a/src/core/cgroup.h b/src/core/cgroup.h
index 65245fbc43..0c5bb4a2c8 100644
--- a/src/core/cgroup.h
+++ b/src/core/cgroup.h
@@ -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);
diff --git a/src/core/chown-recursive.c b/src/core/chown-recursive.c
index 2a3a0704f5..f021f03a06 100644
--- a/src/core/chown-recursive.c
+++ b/src/core/chown-recursive.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/core/chown-recursive.h b/src/core/chown-recursive.h
index 653169885e..7540a8db59 100644
--- a/src/core/chown-recursive.h
+++ b/src/core/chown-recursive.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/core/dbus-automount.c b/src/core/dbus-automount.c
index 26212b3a95..4b1b86f7b9 100644
--- a/src/core/dbus-automount.c
+++ b/src/core/dbus-automount.c
@@ -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;
}
diff --git a/src/core/dbus-automount.h b/src/core/dbus-automount.h
index f41adda2a6..378119410c 100644
--- a/src/core/dbus-automount.h
+++ b/src/core/dbus-automount.h
@@ -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);
diff --git a/src/core/dbus-cgroup.c b/src/core/dbus-cgroup.c
index a99d727f4d..abca4e112d 100644
--- a/src/core/dbus-cgroup.c
+++ b/src/core/dbus-cgroup.c
@@ -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"
@@ -32,6 +34,42 @@
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;
diff --git a/src/core/dbus-cgroup.h b/src/core/dbus-cgroup.h
index b2212fe44e..0588370aa5 100644
--- a/src/core/dbus-cgroup.h
+++ b/src/core/dbus-cgroup.h
@@ -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);
diff --git a/src/core/dbus-device.c b/src/core/dbus-device.c
index e1a12224d3..fbb60d821e 100644
--- a/src/core/dbus-device.c
+++ b/src/core/dbus-device.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/core/dbus-device.h b/src/core/dbus-device.h
index eb1d8c3278..c8098708f4 100644
--- a/src/core/dbus-device.h
+++ b/src/core/dbus-device.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c
index e0aa9fdd82..be25b6e987 100644
--- a/src/core/dbus-execute.c
+++ b/src/core/dbus-execute.c
@@ -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>
@@ -26,15 +28,20 @@
#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"
@@ -378,7 +386,7 @@ static int property_get_syscall_filter(
#if HAVE_SECCOMP
Iterator i;
- void *id;
+ void *id, *val;
#endif
assert(bus);
@@ -394,14 +402,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;
}
@@ -662,7 +689,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,
@@ -672,19 +699,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,
@@ -694,19 +728,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(
@@ -752,6 +780,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),
@@ -805,11 +864,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),
@@ -819,6 +879,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),
@@ -979,7 +1041,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;
@@ -990,6 +1052,8 @@ int bus_exec_context_set_transient_property(
assert(name);
assert(message);
+ flags |= UNIT_PRIVATE;
+
if (streq(name, "User")) {
const char *uu;
@@ -1000,14 +1064,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;
@@ -1022,14 +1085,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;
@@ -1047,10 +1109,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;
@@ -1062,7 +1124,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);
}
}
@@ -1075,14 +1137,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;
@@ -1096,9 +1158,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;
@@ -1112,12 +1174,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;
@@ -1128,7 +1282,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;
@@ -1136,7 +1290,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;
@@ -1147,7 +1301,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"))
@@ -1159,7 +1313,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;
@@ -1176,11 +1330,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;
@@ -1189,7 +1341,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)
@@ -1207,27 +1359,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;
@@ -1238,7 +1397,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;
}
@@ -1246,11 +1405,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;
}
@@ -1261,7 +1420,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;
@@ -1273,10 +1432,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;
@@ -1303,34 +1462,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)
@@ -1348,10 +1505,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 {
@@ -1380,7 +1537,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;
@@ -1396,7 +1553,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;
@@ -1404,7 +1561,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;
@@ -1419,9 +1576,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;
@@ -1434,31 +1591,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), " ");
@@ -1468,7 +1625,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);
}
}
@@ -1483,9 +1659,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;
@@ -1500,7 +1676,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);
@@ -1510,7 +1686,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;
@@ -1525,11 +1701,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;
@@ -1544,7 +1720,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"))
@@ -1556,7 +1732,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;
@@ -1578,7 +1754,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;
@@ -1591,7 +1767,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;
@@ -1608,10 +1784,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;
@@ -1628,10 +1804,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;
@@ -1648,10 +1824,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;
@@ -1664,28 +1840,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);
}
}
@@ -1704,7 +1977,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"))
@@ -1748,7 +2021,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;
@@ -1760,13 +2033,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;
@@ -1783,10 +2056,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;
@@ -1798,53 +2071,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);
}
}
@@ -1852,40 +2120,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);
}
}
@@ -1899,9 +2162,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;
@@ -1916,10 +2179,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;
@@ -1940,8 +2203,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;
@@ -1958,14 +2232,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)
@@ -1983,16 +2264,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);
}
}
@@ -2000,36 +2281,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);
}
}
@@ -2058,9 +2335,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"))
@@ -2068,21 +2343,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;
@@ -2106,9 +2382,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;
@@ -2132,9 +2408,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;
@@ -2152,10 +2428,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;
@@ -2172,10 +2448,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;
@@ -2187,7 +2463,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"))
@@ -2199,7 +2475,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;
@@ -2213,12 +2489,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;
@@ -2232,17 +2507,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);
}
}
@@ -2254,13 +2531,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;
@@ -2277,7 +2554,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;
@@ -2298,45 +2575,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;
@@ -2367,7 +2644,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),
@@ -2379,8 +2656,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 ? "-" : "",
@@ -2402,6 +2679,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;
@@ -2438,7 +2717,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;
@@ -2468,7 +2747,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;
diff --git a/src/core/dbus-execute.h b/src/core/dbus-execute.h
index d0aa8e1dd5..f30f0774cd 100644
--- a/src/core/dbus-execute.h
+++ b/src/core/dbus-execute.h
@@ -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);
diff --git a/src/core/dbus-job.c b/src/core/dbus-job.c
index effc45db45..0802fc9773 100644
--- a/src/core/dbus-job.c
+++ b/src/core/dbus-job.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/core/dbus-job.h b/src/core/dbus-job.h
index a4366a0720..65d87814a6 100644
--- a/src/core/dbus-job.h
+++ b/src/core/dbus-job.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/core/dbus-kill.c b/src/core/dbus-kill.c
index 8c65be65fa..bf3bbb2047 100644
--- a/src/core/dbus-kill.c
+++ b/src/core/dbus-kill.c
@@ -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;
diff --git a/src/core/dbus-kill.h b/src/core/dbus-kill.h
index b9b18811e3..1df3b37c65 100644
--- a/src/core/dbus-kill.h
+++ b/src/core/dbus-kill.h
@@ -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);
diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c
index f87b52a266..ec9e65879f 100644
--- a/src/core/dbus-manager.c
+++ b/src/core/dbus-manager.c
@@ -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),
diff --git a/src/core/dbus-manager.h b/src/core/dbus-manager.h
index 9f3222da28..1a6090f0f5 100644
--- a/src/core/dbus-manager.h
+++ b/src/core/dbus-manager.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/core/dbus-mount.c b/src/core/dbus-mount.c
index 76a7a7ce97..628bce0b6a 100644
--- a/src/core/dbus-mount.c
+++ b/src/core/dbus-mount.c
@@ -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;
}
diff --git a/src/core/dbus-mount.h b/src/core/dbus-mount.h
index ec16166d36..5d5e1f679f 100644
--- a/src/core/dbus-mount.h
+++ b/src/core/dbus-mount.h
@@ -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);
diff --git a/src/core/dbus-path.c b/src/core/dbus-path.c
index 1e153e503f..0f54b04f76 100644
--- a/src/core/dbus-path.c
+++ b/src/core/dbus-path.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/core/dbus-path.h b/src/core/dbus-path.h
index d3c19e0c2b..5e7e859b56 100644
--- a/src/core/dbus-path.h
+++ b/src/core/dbus-path.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/core/dbus-scope.c b/src/core/dbus-scope.c
index 1abaf9f658..9195ad36d0 100644
--- a/src/core/dbus-scope.c
+++ b/src/core/dbus-scope.c
@@ -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;
+}
diff --git a/src/core/dbus-scope.h b/src/core/dbus-scope.h
index 270306f508..aa604897eb 100644
--- a/src/core/dbus-scope.h
+++ b/src/core/dbus-scope.h
@@ -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);
diff --git a/src/core/dbus-service.c b/src/core/dbus-service.c
index 05bdc0a748..0189952124 100644
--- a/src/core/dbus-service.c
+++ b/src/core/dbus-service.c
@@ -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;
}
diff --git a/src/core/dbus-service.h b/src/core/dbus-service.h
index 769a53769e..2da29ec601 100644
--- a/src/core/dbus-service.h
+++ b/src/core/dbus-service.h
@@ -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);
diff --git a/src/core/dbus-slice.c b/src/core/dbus-slice.c
index e37f50b283..fa2ff72151 100644
--- a/src/core/dbus-slice.c
+++ b/src/core/dbus-slice.c
@@ -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) {
diff --git a/src/core/dbus-slice.h b/src/core/dbus-slice.h
index 52ceebb135..0c21919ad1 100644
--- a/src/core/dbus-slice.h
+++ b/src/core/dbus-slice.h
@@ -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);
diff --git a/src/core/dbus-socket.c b/src/core/dbus-socket.c
index 21adb64e15..930b7fa87d 100644
--- a/src/core/dbus-socket.c
+++ b/src/core/dbus-socket.c
@@ -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) {
diff --git a/src/core/dbus-socket.h b/src/core/dbus-socket.h
index 7a792c7a89..e6db2d0772 100644
--- a/src/core/dbus-socket.h
+++ b/src/core/dbus-socket.h
@@ -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);
diff --git a/src/core/dbus-swap.c b/src/core/dbus-swap.c
index 85a2c26b98..795aaa94fe 100644
--- a/src/core/dbus-swap.c
+++ b/src/core/dbus-swap.c
@@ -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) {
diff --git a/src/core/dbus-swap.h b/src/core/dbus-swap.h
index 5238471f98..6cca7483d8 100644
--- a/src/core/dbus-swap.h
+++ b/src/core/dbus-swap.h
@@ -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);
diff --git a/src/core/dbus-target.c b/src/core/dbus-target.c
index 6858b1ce72..7060b65c6e 100644
--- a/src/core/dbus-target.c
+++ b/src/core/dbus-target.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/core/dbus-target.h b/src/core/dbus-target.h
index 9be5ce06b7..7852917962 100644
--- a/src/core/dbus-target.h
+++ b/src/core/dbus-target.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/core/dbus-timer.c b/src/core/dbus-timer.c
index c98282a5d4..3e64536b17 100644
--- a/src/core/dbus-timer.c
+++ b/src/core/dbus-timer.c
@@ -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;
}
diff --git a/src/core/dbus-timer.h b/src/core/dbus-timer.h
index 39053dc4a2..d810b048ee 100644
--- a/src/core/dbus-timer.h
+++ b/src/core/dbus-timer.h
@@ -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);
diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c
index a9a68826b4..cdab461d58 100644
--- a/src/core/dbus-unit.c
+++ b/src/core/dbus-unit.c
@@ -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);
diff --git a/src/core/dbus-unit.h b/src/core/dbus-unit.h
index b280de7a1d..d7066eefc8 100644
--- a/src/core/dbus-unit.h
+++ b/src/core/dbus-unit.h
@@ -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);
diff --git a/src/core/dbus.c b/src/core/dbus.c
index 210b344cd3..b7d8af9396 100644
--- a/src/core/dbus.c
+++ b/src/core/dbus.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/core/dbus.h b/src/core/dbus.h
index a092ed9d76..fe50fdd5f7 100644
--- a/src/core/dbus.h
+++ b/src/core/dbus.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/core/device.c b/src/core/device.c
index 87186f135b..dec6e74f95 100644
--- a/src/core/device.c
+++ b/src/core/device.c
@@ -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;
@@ -766,6 +795,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)
diff --git a/src/core/device.h b/src/core/device.h
index dd372fb695..a551e7748a 100644
--- a/src/core/device.h
+++ b/src/core/device.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/core/dynamic-user.c b/src/core/dynamic-user.c
index f1b5ee7ecb..3da31bf870 100644
--- a/src/core/dynamic-user.c
+++ b/src/core/dynamic-user.c
@@ -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;
}
diff --git a/src/core/dynamic-user.h b/src/core/dynamic-user.h
index e7de4f46ae..b073c65837 100644
--- a/src/core/dynamic-user.h
+++ b/src/core/dynamic-user.h
@@ -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);
diff --git a/src/core/emergency-action.c b/src/core/emergency-action.c
index 90232bc57a..308608e426 100644
--- a/src/core/emergency-action.c
+++ b/src/core/emergency-action.c
@@ -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);
}
diff --git a/src/core/emergency-action.h b/src/core/emergency-action.h
index 8804b59752..4079e8499a 100644
--- a/src/core/emergency-action.h
+++ b/src/core/emergency-action.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/core/execute.c b/src/core/execute.c
index c4dfac96d9..f20246796f 100644
--- a/src/core/execute.c
+++ b/src/core/execute.c
@@ -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;
@@ -1293,7 +1382,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) {
@@ -1708,7 +1797,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)
@@ -1728,13 +1822,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;
}
@@ -1944,7 +2031,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
@@ -1965,7 +2053,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) {
@@ -1974,7 +2064,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;
@@ -1989,10 +2079,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) {
@@ -2043,6 +2147,7 @@ fail:
return r;
}
+#if ENABLE_SMACK
static int setup_smack(
const ExecContext *context,
const ExecCommand *command) {
@@ -2073,55 +2178,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,
@@ -2161,7 +2218,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;
@@ -2196,7 +2253,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
@@ -2219,7 +2277,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);
@@ -2267,10 +2326,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,
@@ -2296,10 +2355,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;
@@ -2322,7 +2377,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,
@@ -2644,7 +2699,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;
@@ -2678,7 +2736,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;
@@ -2689,6 +2747,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
@@ -2798,6 +2857,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");
}
@@ -2965,17 +3028,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");
@@ -3070,11 +3128,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);
@@ -3093,7 +3154,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");
@@ -3158,6 +3219,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,
@@ -3218,7 +3291,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. */
@@ -3237,16 +3310,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);
@@ -3526,11 +3589,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);
@@ -3542,8 +3606,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);
@@ -3563,20 +3629,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) {
@@ -3597,18 +3669,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;
@@ -3663,18 +3723,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;
}
@@ -3787,7 +3854,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;
@@ -3851,9 +3918,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);
@@ -3984,6 +4051,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"
@@ -4021,6 +4102,26 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) {
fprintf(f, "%sSyslogLevel: %s\n", prefix, lvl_str);
}
+ 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;
@@ -4120,7 +4221,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
@@ -4132,8 +4233,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;
@@ -4142,6 +4245,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
@@ -4174,10 +4285,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,
@@ -4215,6 +4333,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);
@@ -4632,6 +4761,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);
@@ -4648,6 +4779,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);
diff --git a/src/core/execute.h b/src/core/execute.h
index 4d41990b36..d04dfcf6c9 100644
--- a/src/core/execute.h
+++ b/src/core/execute.h
@@ -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;
@@ -212,6 +222,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;
@@ -242,7 +257,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;
@@ -353,6 +368,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);
diff --git a/src/core/hostname-setup.c b/src/core/hostname-setup.c
index 845e31e1c5..19299918cc 100644
--- a/src/core/hostname-setup.c
+++ b/src/core/hostname-setup.c
@@ -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;
diff --git a/src/core/hostname-setup.h b/src/core/hostname-setup.h
index 73e8c75c71..8bf8769859 100644
--- a/src/core/hostname-setup.h
+++ b/src/core/hostname-setup.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/core/ima-setup.c b/src/core/ima-setup.c
index 6c7b209977..80319622ad 100644
--- a/src/core/ima-setup.c
+++ b/src/core/ima-setup.c
@@ -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 */
diff --git a/src/core/ima-setup.h b/src/core/ima-setup.h
index 472b58cb00..1eae74bceb 100644
--- a/src/core/ima-setup.h
+++ b/src/core/ima-setup.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/core/ip-address-access.c b/src/core/ip-address-access.c
index cfb7d51c4f..8d72fc03bf 100644
--- a/src/core/ip-address-access.c
+++ b/src/core/ip-address-access.c
@@ -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;
diff --git a/src/core/ip-address-access.h b/src/core/ip-address-access.h
index 9aeab1f4f8..536142e904 100644
--- a/src/core/ip-address-access.h
+++ b/src/core/ip-address-access.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/core/job.c b/src/core/job.c
index fb57f193fd..2ea7834dfd 100644
--- a/src/core/job.c
+++ b/src/core/job.c
@@ -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;
diff --git a/src/core/job.h b/src/core/job.h
index b17001889e..a2f3b7b5d2 100644
--- a/src/core/job.h
+++ b/src/core/job.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/core/kill.c b/src/core/kill.c
index 6854587d54..f438c4d8fa 100644
--- a/src/core/kill.c
+++ b/src/core/kill.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/core/kill.h b/src/core/kill.h
index b3d2056cb0..f0d6ec41e9 100644
--- a/src/core/kill.h
+++ b/src/core/kill.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/core/killall.c b/src/core/killall.c
index 5e914e478d..e77763e161 100644
--- a/src/core/killall.c
+++ b/src/core/killall.c
@@ -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)
diff --git a/src/core/killall.h b/src/core/killall.h
index acc2439f00..01bd6e52b3 100644
--- a/src/core/killall.h
+++ b/src/core/killall.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/core/kmod-setup.c b/src/core/kmod-setup.c
index 066b959770..a2809d03f6 100644
--- a/src/core/kmod-setup.c
+++ b/src/core/kmod-setup.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
@@ -21,10 +22,6 @@
#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;
}
diff --git a/src/core/kmod-setup.h b/src/core/kmod-setup.h
index 685f4df301..b5ea6b55a9 100644
--- a/src/core/kmod-setup.h
+++ b/src/core/kmod-setup.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/core/load-dropin.c b/src/core/load-dropin.c
index 00f09ce60a..57ed686d1f 100644
--- a/src/core/load-dropin.c
+++ b/src/core/load-dropin.c
@@ -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);
diff --git a/src/core/load-dropin.h b/src/core/load-dropin.h
index 5828a223ce..4c8ab487b3 100644
--- a/src/core/load-dropin.h
+++ b/src/core/load-dropin.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
index 5255932fbd..240f331778 100644
--- a/src/core/load-fragment-gperf.gperf.m4
+++ b/src/core/load-fragment-gperf.gperf.m4
@@ -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_warn_compat, DISABLED_LEGACY, 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)
diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
index a4e39a84ea..d6c616502b 100644
--- a/src/core/load-fragment.c
+++ b/src/core/load-fragment.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
@@ -45,7 +46,10 @@
#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;
}
@@ -1538,7 +1733,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;
}
@@ -1560,7 +1755,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;
@@ -1760,11 +1955,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);
}
@@ -2285,7 +2480,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)
@@ -2331,6 +2526,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,
@@ -2569,7 +2836,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;
@@ -2632,7 +2899,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] == '@') {
@@ -2642,12 +2910,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;
}
@@ -2662,16 +2930,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;
@@ -2702,7 +2970,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;
}
@@ -2713,7 +2981,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();
@@ -2725,7 +2993,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;
}
@@ -2733,7 +3001,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)
@@ -2745,7 +3014,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;
}
@@ -2831,8 +3106,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;
}
@@ -3194,6 +3469,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,
@@ -3221,7 +3563,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);
@@ -3715,7 +4057,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;
@@ -4442,7 +4784,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;
}
diff --git a/src/core/load-fragment.h b/src/core/load-fragment.h
index 1353b0a9d0..cb17bdd3c3 100644
--- a/src/core/load-fragment.h
+++ b/src/core/load-fragment.h
@@ -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);
@@ -85,6 +86,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);
@@ -120,6 +122,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);
diff --git a/src/core/locale-setup.c b/src/core/locale-setup.c
index fdd847ee8b..6240a83197 100644
--- a/src/core/locale-setup.c
+++ b/src/core/locale-setup.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/core/locale-setup.h b/src/core/locale-setup.h
index 3b97497afe..c1bee3812b 100644
--- a/src/core/locale-setup.h
+++ b/src/core/locale-setup.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/core/loopback-setup.c b/src/core/loopback-setup.c
index c167305ca9..9a75525894 100644
--- a/src/core/loopback-setup.c
+++ b/src/core/loopback-setup.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/core/loopback-setup.h b/src/core/loopback-setup.h
index e7547b8a26..9fac0189e4 100644
--- a/src/core/loopback-setup.h
+++ b/src/core/loopback-setup.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/core/machine-id-setup.c b/src/core/machine-id-setup.c
index df3cc74b98..767e97206c 100644
--- a/src/core/machine-id-setup.c
+++ b/src/core/machine-id-setup.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/core/machine-id-setup.h b/src/core/machine-id-setup.h
index 29f4620646..cbd83ba270 100644
--- a/src/core/machine-id-setup.h
+++ b/src/core/machine-id-setup.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/core/macros.systemd.in b/src/core/macros.systemd.in
index 03fb2a8389..940f1e895a 100644
--- a/src/core/macros.systemd.in
+++ b/src/core/macros.systemd.in
@@ -1,4 +1,5 @@
# -*- Mode: rpm-spec; indent-tabs-mode: nil -*- */
+# SPDX-License-Identifier: LGPL-2.1+
#
# This file is part of systemd.
#
diff --git a/src/core/main.c b/src/core/main.c
index b9bc2f6844..2ad5073368 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -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,6 +1444,615 @@ static int fixup_environment(void) {
return 0;
}
+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)
+ return;
+
+ if (!strstr(program_invocation_short_name, "init"))
+ return;
+
+ execv(SYSTEMCTL_BINARY_PATH, argv);
+ log_error_errno(errno, "Failed to exec " SYSTEMCTL_BINARY_PATH ": %m");
+ exit(1);
+#endif
+}
+
+static int become_shutdown(
+ const char *shutdown_verb,
+ int retval) {
+
+ char log_level[DECIMAL_STR_MAX(int) + 1],
+ 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",
+ };
+
+ _cleanup_strv_free_ char **env_block = NULL;
+ size_t pos = 5;
+ int r;
+
+ assert(shutdown_verb);
+ assert(!command_line[pos]);
+ 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 (streq(shutdown_verb, "reboot") &&
+ 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);
+
+ /* 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);
+
+ if (arg_watchdog_device &&
+ asprintf(&e, "WATCHDOG_DEVICE=%s", arg_watchdog_device) > 0)
+ (void) strv_consume(&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);
+ return -errno;
+}
+
+static void initialize_clock(void) {
+ int r;
+
+ 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.
+ */
+ (void) clock_reset_timewarp();
+ }
+
+ r = clock_apply_epoch();
+ if (r < 0)
+ log_error_errno(r, "Current system time is before build time, but cannot correct: %m");
+ else if (r > 0)
+ log_info("System time before build time, advancing clock.");
+}
+
+static void initialize_coredump(bool skip_setup) {
+
+ if (getpid_cached() != 1)
+ return;
+
+ /* Don't limit the core dump size, so that coredump handlers such as systemd-coredump (which honour the limit)
+ * will process core dumps for system services by default. */
+ if (setrlimit(RLIMIT_CORE, &RLIMIT_MAKE_CONST(RLIM_INFINITY)) < 0)
+ log_warning_errno(errno, "Failed to set RLIMIT_CORE: %m");
+
+ /* But at the same time, turn off the core_pattern logic by default, so that no coredumps are stored
+ * until the systemd-coredump tool is enabled via sysctl. */
+ if (!skip_setup)
+ (void) write_string_file("/proc/sys/kernel/core_pattern", "|/bin/false", 0);
+}
+
+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;
+
+ assert(saved_rlimit_nofile);
+ assert(saved_rlimit_memlock);
+ assert(ret_error_message);
+
+ /* Close and disarm the watchdog, so that the new instance can reinitialize it, but doesn't get rebooted while
+ * we do that */
+ 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);
+ 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;
@@ -1402,25 +2068,14 @@ int main(int argc, char *argv[]) {
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;
+ 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;
-#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. */
-
- execv(SYSTEMCTL_BINARY_PATH, argv);
- log_error_errno(errno, "Failed to exec " SYSTEMCTL_BINARY_PATH ": %m");
- return 1;
- }
-#endif
+ redirect_telinit(argc, argv);
dual_timestamp_from_monotonic(&kernel_timestamp, 0);
dual_timestamp_get(&userspace_timestamp);
@@ -1495,46 +2150,8 @@ int main(int argc, char *argv[]) {
goto finish;
}
- 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.
- */
- (void) clock_reset_timewarp();
- }
-
- r = clock_apply_epoch();
- if (r < 0)
- log_error_errno(r, "Current system time is before build time, but cannot correct: %m");
- else if (r > 0)
- log_info("System time before build time, advancing clock.");
- }
+ 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
@@ -1568,17 +2185,7 @@ int main(int argc, char *argv[]) {
kernel_timestamp = DUAL_TIMESTAMP_NULL;
}
- 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");
-
- /* 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);
- }
+ initialize_coredump(skip_setup);
if (arg_system) {
if (fixup_environment() < 0) {
@@ -1751,95 +2358,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,
@@ -1851,19 +2378,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;
@@ -1873,173 +2396,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;
+ 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));
- 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"
- };
-
- 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();
@@ -2048,126 +2455,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);
@@ -2177,85 +2475,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());
+ r = become_shutdown(shutdown_verb, retval);
- 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);
-
- /* 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,
diff --git a/src/core/manager.c b/src/core/manager.c
index d2be218b00..81c4d5289b 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -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"
@@ -53,14 +56,15 @@
#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 the notify fd here. We do that after deserialization,
+ * since they might have gotten serialized across the reexec. */
+
*_m = m;
return 0;
@@ -934,7 +961,7 @@ 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))) &&
+ (u && SERVICE(u)->deserialized_state == SERVICE_RUNNING) &&
(reexecuting ||
(MANAGER_IS_USER(m) && getenv("DBUS_SESSION_BUS_ADDRESS")));
@@ -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;
- } else if (!startswith(l, "kdbus-fd=")) /* ignore this one */
- log_notice("Unknown serialization item '%s'", l);
+ for (q = 0; q < _MANAGER_TIMESTAMP_MAX; q++) {
+ val = startswith(l, manager_timestamp_to_string(q));
+ if (!val)
+ continue;
+
+ val = startswith(val, "-timestamp=");
+ if (val)
+ break;
+ }
+
+ if (q < _MANAGER_TIMESTAMP_MAX) /* found it */
+ 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,
@@ -3062,9 +3129,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) {
@@ -3079,6 +3148,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 */
@@ -3101,10 +3183,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);
@@ -3459,7 +3541,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)))
@@ -3468,21 +3550,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)
@@ -3785,6 +3867,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",
@@ -3795,3 +3929,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);
diff --git a/src/core/manager.h b/src/core/manager.h
index 6fff7b2437..902af2609d 100644
--- a/src/core/manager.h
+++ b/src/core/manager.h
@@ -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_;
diff --git a/src/core/meson.build b/src/core/meson.build
index 4355f9ca6d..535ccde468 100644
--- a/src/core/meson.build
+++ b/src/core/meson.build
@@ -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)
diff --git a/src/core/mount-setup.c b/src/core/mount-setup.c
index 3d7831d032..7171d8fda4 100644
--- a/src/core/mount-setup.c
+++ b/src/core/mount-setup.c
@@ -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"
@@ -45,9 +47,10 @@
#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 {
@@ -96,15 +99,15 @@ static const MountPoint mount_table[] = {
{ "tmpfs", "/run", "tmpfs", "mode=755", MS_NOSUID|MS_NODEV|MS_STRICTATIME,
NULL, MNT_FATAL|MNT_IN_CONTAINER },
{ "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 },
{ "tmpfs", "/sys/fs/cgroup", "tmpfs", "mode=755", MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_STRICTATIME,
cg_is_legacy_wanted, MNT_FATAL|MNT_IN_CONTAINER },
{ "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,
@@ -201,6 +204,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;
}
@@ -236,11 +248,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");
@@ -382,9 +390,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
diff --git a/src/core/mount-setup.h b/src/core/mount-setup.h
index 647bd770ae..2c96e64e52 100644
--- a/src/core/mount-setup.h
+++ b/src/core/mount-setup.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/core/mount.c b/src/core/mount.c
index 903b3a9c1b..b25bb9cb40 100644
--- a/src/core/mount.c
+++ b/src/core/mount.c
@@ -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;
}
diff --git a/src/core/mount.h b/src/core/mount.h
index f81e4217df..44fe3b889e 100644
--- a/src/core/mount.h
+++ b/src/core/mount.h
@@ -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;
diff --git a/src/core/namespace.c b/src/core/namespace.c
index 6d74b8da67..a3262fcc4d 100644
--- a/src/core/namespace.c
+++ b/src/core/namespace.c
@@ -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);
diff --git a/src/core/namespace.h b/src/core/namespace.h
index da8d85dbc5..f0f198362c 100644
--- a/src/core/namespace.h
+++ b/src/core/namespace.h
@@ -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);
diff --git a/src/core/org.freedesktop.systemd1.conf b/src/core/org.freedesktop.systemd1.conf
index e824a2233c..97f6094b66 100644
--- a/src/core/org.freedesktop.systemd1.conf
+++ b/src/core/org.freedesktop.systemd1.conf
@@ -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
diff --git a/src/core/org.freedesktop.systemd1.policy.in.in b/src/core/org.freedesktop.systemd1.policy.in.in
index cc39a9e1c3..2c6ed749fd 100644
--- a/src/core/org.freedesktop.systemd1.policy.in.in
+++ b/src/core/org.freedesktop.systemd1.policy.in.in
@@ -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>
diff --git a/src/core/org.freedesktop.systemd1.service b/src/core/org.freedesktop.systemd1.service
index d4df3e93a2..8bd7302d6c 100644
--- a/src/core/org.freedesktop.systemd1.service
+++ b/src/core/org.freedesktop.systemd1.service
@@ -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/src/core/path.c b/src/core/path.c
index 44831f5803..6b22451a08 100644
--- a/src/core/path.c
+++ b/src/core/path.c
@@ -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;
diff --git a/src/core/path.h b/src/core/path.h
index 4230c8fb99..41e31986f2 100644
--- a/src/core/path.h
+++ b/src/core/path.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/core/scope.c b/src/core/scope.c
index 4cd5e3dd2a..10454d56b0 100644
--- a/src/core/scope.c
+++ b/src/core/scope.c
@@ -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,
diff --git a/src/core/scope.h b/src/core/scope.h
index eaf8e8b447..ca7c6c868f 100644
--- a/src/core/scope.h
+++ b/src/core/scope.h
@@ -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;
diff --git a/src/core/selinux-access.c b/src/core/selinux-access.c
index 2db4189401..475c3181c9 100644
--- a/src/core/selinux-access.c
+++ b/src/core/selinux-access.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/core/selinux-access.h b/src/core/selinux-access.h
index 1f6a518a61..c5f5fb975e 100644
--- a/src/core/selinux-access.h
+++ b/src/core/selinux-access.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/core/selinux-setup.c b/src/core/selinux-setup.c
index 60361a5638..7135542106 100644
--- a/src/core/selinux-setup.c
+++ b/src/core/selinux-setup.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/core/selinux-setup.h b/src/core/selinux-setup.h
index 7b613249b0..410991c49f 100644
--- a/src/core/selinux-setup.h
+++ b/src/core/selinux-setup.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/core/service.c b/src/core/service.c
index 915943aff3..ef1be33260 100644
--- a/src/core/service.c
+++ b/src/core/service.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
@@ -252,6 +253,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);
@@ -294,6 +334,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);
@@ -301,7 +344,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);
@@ -315,8 +358,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) {
@@ -360,7 +402,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) {
@@ -455,6 +497,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;
@@ -562,7 +619,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 {
@@ -570,7 +627,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;
}
@@ -578,21 +635,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 &&
@@ -602,6 +657,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) {
@@ -612,12 +671,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");
@@ -1103,11 +1162,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;
@@ -1217,24 +1277,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)
@@ -1243,21 +1305,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 ||
@@ -1294,17 +1341,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;
@@ -1353,11 +1397,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));
@@ -1493,9 +1532,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)
@@ -1521,16 +1564,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 ++;
- if (allow_restart && service_shall_restart(s)) {
+ service_set_state(s, s->result != SERVICE_SUCCESS ? SERVICE_FAILED : SERVICE_DEAD);
+
+ 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
@@ -1538,6 +1588,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;
@@ -1546,7 +1601,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]);
@@ -1791,39 +1846,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);
+ if (s->control_pid <= 0)
+ return;
- log_unit_debug_errno(UNIT(s), r, "Failed to kill control process " PID_FMT " (%s), ignoring: %m",
- s->control_pid, strna(comm));
- }
- }
+ r = kill_and_sigcont(s->control_pid, SIGKILL);
+ if (r < 0) {
+ _cleanup_free_ char *comm = NULL;
- if (UNIT(s)->cgroup_path) {
- _cleanup_set_free_ Set *pid_set = NULL;
- char *p;
+ (void) get_process_comm(s->control_pid, &comm);
- if (s->control_pid > 0) {
- r = set_make(&pid_set, PID_TO_PTR(s->control_pid), NULL);
- if (r < 0) {
- log_oom();
- return;
- }
- }
-
- 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));
}
}
@@ -1838,10 +1876,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;
@@ -1929,9 +1964,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;
@@ -2087,7 +2121,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);
@@ -2172,7 +2206,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;
@@ -2747,10 +2782,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;
@@ -2879,8 +2915,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 &&
@@ -3041,8 +3076,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;
@@ -3087,11 +3121,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) {
@@ -3254,7 +3283,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;
@@ -3343,38 +3372,57 @@ static int service_dispatch_watchdog(sd_event_source *source, usec_t usec, void
return 0;
}
-static void service_notify_message(Unit *u, pid_t pid, char **tags, FDSet *fds) {
- Service *s = SERVICE(u);
- _cleanup_free_ char *cc = NULL;
- bool notify_dbus = false;
- const char *e;
-
- assert(u);
-
- cc = strv_join(tags, ", ");
+static bool service_notify_message_authorized(Service *s, pid_t pid, char **tags, FDSet *fds) {
+ assert(s);
if (s->notify_access == NOTIFY_NONE) {
- log_unit_warning(u, "Got notification message from PID "PID_FMT", but reception is disabled.", pid);
- return;
- } else if (s->notify_access == NOTIFY_MAIN && pid != s->main_pid) {
+ log_unit_warning(UNIT(s), "Got notification message from PID "PID_FMT", but reception is disabled.", pid);
+ return false;
+ }
+
+ if (s->notify_access == NOTIFY_MAIN && pid != s->main_pid) {
if (s->main_pid != 0)
- log_unit_warning(u, "Got notification message from PID "PID_FMT", but reception only permitted for main PID "PID_FMT, pid, s->main_pid);
+ log_unit_warning(UNIT(s), "Got notification message from PID "PID_FMT", but reception only permitted for main PID "PID_FMT, pid, s->main_pid);
else
- log_unit_warning(u, "Got notification message from PID "PID_FMT", but reception only permitted for main PID which is currently not known", pid);
- return;
- } else if (s->notify_access == NOTIFY_EXEC && pid != s->main_pid && pid != s->control_pid) {
+ log_unit_warning(UNIT(s), "Got notification message from PID "PID_FMT", but reception only permitted for main PID which is currently not known", pid);
+
+ return false;
+ }
+
+ if (s->notify_access == NOTIFY_EXEC && pid != s->main_pid && pid != s->control_pid) {
if (s->main_pid != 0 && s->control_pid != 0)
- log_unit_warning(u, "Got notification message from PID "PID_FMT", but reception only permitted for main PID "PID_FMT" and control PID "PID_FMT,
+ log_unit_warning(UNIT(s), "Got notification message from PID "PID_FMT", but reception only permitted for main PID "PID_FMT" and control PID "PID_FMT,
pid, s->main_pid, s->control_pid);
else if (s->main_pid != 0)
- log_unit_warning(u, "Got notification message from PID "PID_FMT", but reception only permitted for main PID "PID_FMT, pid, s->main_pid);
+ log_unit_warning(UNIT(s), "Got notification message from PID "PID_FMT", but reception only permitted for main PID "PID_FMT, pid, s->main_pid);
else if (s->control_pid != 0)
- log_unit_warning(u, "Got notification message from PID "PID_FMT", but reception only permitted for control PID "PID_FMT, pid, s->control_pid);
+ log_unit_warning(UNIT(s), "Got notification message from PID "PID_FMT", but reception only permitted for control PID "PID_FMT, pid, s->control_pid);
else
- log_unit_warning(u, "Got notification message from PID "PID_FMT", but reception only permitted for main PID and control PID which are currently not known", pid);
+ log_unit_warning(UNIT(s), "Got notification message from PID "PID_FMT", but reception only permitted for main PID and control PID which are currently not known", pid);
+
+ return false;
+ }
+
+ return true;
+}
+
+static void service_notify_message(Unit *u, pid_t pid, char **tags, FDSet *fds) {
+ Service *s = SERVICE(u);
+ bool notify_dbus = false;
+ const char *e;
+ char **i;
+
+ assert(u);
+
+ if (!service_notify_message_authorized(SERVICE(u), pid, tags, fds))
return;
- } else
+
+ if (log_get_max_level() >= LOG_DEBUG) {
+ _cleanup_free_ char *cc = NULL;
+
+ cc = strv_join(tags, ", ");
log_unit_debug(u, "Got notification message from PID "PID_FMT" (%s)", pid, isempty(cc) ? "n/a" : cc);
+ }
/* Interpret MAINPID= */
e = strv_find_startswith(tags, "MAINPID=");
@@ -3385,51 +3433,50 @@ static void service_notify_message(Unit *u, pid_t pid, char **tags, FDSet *fds)
log_unit_warning(u, "A control process cannot also be the main process");
else if (pid == getpid_cached() || pid == 1)
log_unit_warning(u, "Service manager can't be main process, ignoring sd_notify() MAINPID= field");
- else {
+ else if (pid != s->main_pid) {
service_set_main_pid(s, pid);
unit_watch_pid(UNIT(s), pid);
notify_dbus = true;
}
}
- /* Interpret RELOADING= */
- if (strv_find(tags, "RELOADING=1")) {
-
- s->notify_state = NOTIFY_RELOADING;
-
- if (s->state == SERVICE_RUNNING)
- service_enter_reload_by_notify(s);
+ /* Interpret READY=/STOPPING=/RELOADING=. Last one wins. */
+ STRV_FOREACH_BACKWARDS(i, tags) {
- notify_dbus = true;
- }
+ if (streq(*i, "READY=1")) {
+ s->notify_state = NOTIFY_READY;
- /* 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= */
@@ -3458,21 +3505,52 @@ static void service_notify_message(Unit *u, pid_t pid, char **tags, FDSet *fds)
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=");
@@ -3481,16 +3559,7 @@ static void service_notify_message(Unit *u, pid_t pid, char **tags, FDSet *fds)
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 */
@@ -3617,7 +3686,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;
@@ -3760,6 +3829,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,
diff --git a/src/core/service.h b/src/core/service.h
index 16b700637c..5c5b24e3ef 100644
--- a/src/core/service.h
+++ b/src/core/service.h
@@ -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;
diff --git a/src/core/show-status.c b/src/core/show-status.c
index 8c94573844..40658a2e16 100644
--- a/src/core/show-status.c
+++ b/src/core/show-status.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/core/show-status.h b/src/core/show-status.h
index 9a29e72645..a13d52484c 100644
--- a/src/core/show-status.h
+++ b/src/core/show-status.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/core/shutdown.c b/src/core/shutdown.c
index 6d1cc3120a..aca89d13d1 100644
--- a/src/core/shutdown.c
+++ b/src/core/shutdown.c
@@ -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) {
diff --git a/src/core/slice.c b/src/core/slice.c
index b15f751c82..5ab1e6f898 100644
--- a/src/core/slice.c
+++ b/src/core/slice.c
@@ -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;
diff --git a/src/core/slice.h b/src/core/slice.h
index c9f3f61067..418327e933 100644
--- a/src/core/slice.h
+++ b/src/core/slice.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/core/smack-setup.c b/src/core/smack-setup.c
index 9cd539f3d3..b0d3612d69 100644
--- a/src/core/smack-setup.c
+++ b/src/core/smack-setup.c
@@ -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;
}
}
diff --git a/src/core/smack-setup.h b/src/core/smack-setup.h
index 78164c85e6..8c2de5fdc5 100644
--- a/src/core/smack-setup.h
+++ b/src/core/smack-setup.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/core/socket.c b/src/core/socket.c
index c0f4030302..7e3630ada7 100644
--- a/src/core/socket.c
+++ b/src/core/socket.c
@@ -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;
@@ -2762,7 +2758,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;
}
diff --git a/src/core/socket.h b/src/core/socket.h
index 8c263963c4..e9e560e57e 100644
--- a/src/core/socket.h
+++ b/src/core/socket.h
@@ -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;
diff --git a/src/core/swap.c b/src/core/swap.c
index f475755572..849ccbdd43 100644
--- a/src/core/swap.c
+++ b/src/core/swap.c
@@ -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;
diff --git a/src/core/swap.h b/src/core/swap.h
index 45da63c5e2..fa9d45ac0c 100644
--- a/src/core/swap.h
+++ b/src/core/swap.h
@@ -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;
diff --git a/src/core/systemd.pc.in b/src/core/systemd.pc.in
index ac52b30dd3..655773ea8a 100644
--- a/src/core/systemd.pc.in
+++ b/src/core/systemd.pc.in
@@ -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
diff --git a/src/core/target.c b/src/core/target.c
index 2a58dd394d..756cbbfb6c 100644
--- a/src/core/target.c
+++ b/src/core/target.c
@@ -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) {
diff --git a/src/core/target.h b/src/core/target.h
index 339aea154e..8d44a11545 100644
--- a/src/core/target.h
+++ b/src/core/target.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/core/timer.c b/src/core/timer.c
index 9ea5f322d8..03935eea94 100644
--- a/src/core/timer.c
+++ b/src/core/timer.c
@@ -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) {
/* 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:
diff --git a/src/core/timer.h b/src/core/timer.h
index 546c60d750..096d48bd34 100644
--- a/src/core/timer.h
+++ b/src/core/timer.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/core/transaction.c b/src/core/transaction.c
index 46c2fa452e..32ad660026 100644
--- a/src/core/transaction.c
+++ b/src/core/transaction.c
@@ -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);
diff --git a/src/core/transaction.h b/src/core/transaction.h
index ddfdbf9987..0d57b27f2e 100644
--- a/src/core/transaction.h
+++ b/src/core/transaction.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/core/triggers.systemd.in b/src/core/triggers.systemd.in
index f8c8cbc5f9..985c6d8b26 100644
--- a/src/core/triggers.systemd.in
+++ b/src/core/triggers.systemd.in
@@ -1,4 +1,5 @@
# -*- Mode: rpm-spec; indent-tabs-mode: nil -*- */
+# SPDX-License-Identifier: LGPL-2.1+
#
# This file is part of systemd.
#
diff --git a/src/core/umount.c b/src/core/umount.c
index 813d257139..7f8ddb99ee 100644
--- a/src/core/umount.c
+++ b/src/core/umount.c
@@ -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;
}
diff --git a/src/core/umount.h b/src/core/umount.h
index 4e2215a47d..7c029c384c 100644
--- a/src/core/umount.h
+++ b/src/core/umount.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/core/unit-printf.c b/src/core/unit-printf.c
index 0480ec6526..e61e0d1475 100644
--- a/src/core/unit-printf.c
+++ b/src/core/unit-printf.c
@@ -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 },
diff --git a/src/core/unit-printf.h b/src/core/unit-printf.h
index 4fc8531228..f1b620e162 100644
--- a/src/core/unit-printf.h
+++ b/src/core/unit-printf.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/core/unit.c b/src/core/unit.c
index 357306dce8..7af8425707 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -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"
@@ -51,9 +53,12 @@
#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);
diff --git a/src/core/unit.h b/src/core/unit.h
index 8c5c92ecd9..fdd82315ba 100644
--- a/src/core/unit.h
+++ b/src/core/unit.h
@@ -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_;
diff --git a/src/coredump/coredump-vacuum.c b/src/coredump/coredump-vacuum.c
index f02b6dbd87..aede180b43 100644
--- a/src/coredump/coredump-vacuum.c
+++ b/src/coredump/coredump-vacuum.c
@@ -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;
diff --git a/src/coredump/coredump-vacuum.h b/src/coredump/coredump-vacuum.h
index 4b7b9f2d98..c61d08f79c 100644
--- a/src/coredump/coredump-vacuum.h
+++ b/src/coredump/coredump-vacuum.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c
index 300d647903..e6063cc980 100644
--- a/src/coredump/coredump.c
+++ b/src/coredump/coredump.c
@@ -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);
diff --git a/src/coredump/coredumpctl.c b/src/coredump/coredumpctl.c
index 0380df10d1..0d420b2190 100644
--- a/src/coredump/coredumpctl.c
+++ b/src/coredump/coredumpctl.c
@@ -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)
diff --git a/src/coredump/meson.build b/src/coredump/meson.build
index 25a0409046..4e31e7c7c2 100644
--- a/src/coredump/meson.build
+++ b/src/coredump/meson.build
@@ -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
diff --git a/src/coredump/stacktrace.c b/src/coredump/stacktrace.c
index 1726613623..95fd27b79a 100644
--- a/src/coredump/stacktrace.c
+++ b/src/coredump/stacktrace.c
@@ -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);
diff --git a/src/coredump/stacktrace.h b/src/coredump/stacktrace.h
index 15e9c04465..d435878b44 100644
--- a/src/coredump/stacktrace.h
+++ b/src/coredump/stacktrace.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/coredump/test-coredump-vacuum.c b/src/coredump/test-coredump-vacuum.c
index 70a57f183f..0836825b07 100644
--- a/src/coredump/test-coredump-vacuum.c
+++ b/src/coredump/test-coredump-vacuum.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/cryptsetup/cryptsetup-generator.c b/src/cryptsetup/cryptsetup-generator.c
index 3752ca2ef2..7e61332e52 100644
--- a/src/cryptsetup/cryptsetup-generator.c
+++ b/src/cryptsetup/cryptsetup-generator.c
@@ -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);
diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c
index 8fc35ad999..21c51022ef 100644
--- a/src/cryptsetup/cryptsetup.c
+++ b/src/cryptsetup/cryptsetup.c
@@ -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"
@@ -38,7 +39,10 @@
#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);
diff --git a/src/debug-generator/debug-generator.c b/src/debug-generator/debug-generator.c
index 1d8bc71e57..604faa0d18 100644
--- a/src/debug-generator/debug-generator.c
+++ b/src/debug-generator/debug-generator.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/delta/delta.c b/src/delta/delta.c
index 605bea57bb..d286881698 100644
--- a/src/delta/delta.c
+++ b/src/delta/delta.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/detect-virt/detect-virt.c b/src/detect-virt/detect-virt.c
index 4b8956f0ad..00235742de 100644
--- a/src/detect-virt/detect-virt.c
+++ b/src/detect-virt/detect-virt.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/dissect/dissect.c b/src/dissect/dissect.c
index 06564e94b1..c8fb1c80d7 100644
--- a/src/dissect/dissect.c
+++ b/src/dissect/dissect.c
@@ -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;
diff --git a/src/environment-d-generator/environment-d-generator.c b/src/environment-d-generator/environment-d-generator.c
index 55de68550d..bb4d76da90 100644
--- a/src/environment-d-generator/environment-d-generator.c
+++ b/src/environment-d-generator/environment-d-generator.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/escape/escape.c b/src/escape/escape.c
index 5518c2a6fa..9c35b4663e 100644
--- a/src/escape/escape.c
+++ b/src/escape/escape.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/firstboot/firstboot.c b/src/firstboot/firstboot.c
index 586674d458..207ddeb70f 100644
--- a/src/firstboot/firstboot.c
+++ b/src/firstboot/firstboot.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
@@ -44,16 +45,19 @@
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);
diff --git a/src/fsck/fsck.c b/src/fsck/fsck.c
index cf5a9c59ff..0091e388dc 100644
--- a/src/fsck/fsck.c
+++ b/src/fsck/fsck.c
@@ -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;
diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c
index ec70a349fc..22c4ae9861 100644
--- a/src/fstab-generator/fstab-generator.c
+++ b/src/fstab-generator/fstab-generator.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
@@ -22,11 +23,12 @@
#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"
@@ -45,6 +48,14 @@
#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)
diff --git a/src/getty-generator/getty-generator.c b/src/getty-generator/getty-generator.c
index a143b5413b..3f62a81abc 100644
--- a/src/getty-generator/getty-generator.c
+++ b/src/getty-generator/getty-generator.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/gpt-auto-generator/gpt-auto-generator.c b/src/gpt-auto-generator/gpt-auto-generator.c
index ae0a8da63a..9e8b956d5c 100644
--- a/src/gpt-auto-generator/gpt-auto-generator.c
+++ b/src/gpt-auto-generator/gpt-auto-generator.c
@@ -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();
diff --git a/src/hibernate-resume/hibernate-resume-generator.c b/src/hibernate-resume/hibernate-resume-generator.c
index a97fe668d5..01222db516 100644
--- a/src/hibernate-resume/hibernate-resume-generator.c
+++ b/src/hibernate-resume/hibernate-resume-generator.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/hibernate-resume/hibernate-resume.c b/src/hibernate-resume/hibernate-resume.c
index 21df3c4461..2a427210cd 100644
--- a/src/hibernate-resume/hibernate-resume.c
+++ b/src/hibernate-resume/hibernate-resume.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/hostname/hostnamectl.c b/src/hostname/hostnamectl.c
index f5a9de94a6..e06b111b43 100644
--- a/src/hostname/hostnamectl.c
+++ b/src/hostname/hostnamectl.c
@@ -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,
diff --git a/src/hostname/hostnamed.c b/src/hostname/hostnamed.c
index fe0aa00efb..5feaa60c99 100644
--- a/src/hostname/hostnamed.c
+++ b/src/hostname/hostnamed.c
@@ -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;
diff --git a/src/hostname/meson.build b/src/hostname/meson.build
index 834300ae6e..75cc94874b 100644
--- a/src/hostname/meson.build
+++ b/src/hostname/meson.build
@@ -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
diff --git a/src/hostname/org.freedesktop.hostname1.conf b/src/hostname/org.freedesktop.hostname1.conf
index 46b4aadc83..e2658c6c95 100644
--- a/src/hostname/org.freedesktop.hostname1.conf
+++ b/src/hostname/org.freedesktop.hostname1.conf
@@ -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
diff --git a/src/hostname/org.freedesktop.hostname1.policy.in b/src/hostname/org.freedesktop.hostname1.policy.in
index c32c1d4fda..b10ca31ac5 100644
--- a/src/hostname/org.freedesktop.hostname1.policy.in
+++ b/src/hostname/org.freedesktop.hostname1.policy.in
@@ -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>
diff --git a/src/hostname/org.freedesktop.hostname1.service b/src/hostname/org.freedesktop.hostname1.service
index 6041ed60ca..421a8c607b 100644
--- a/src/hostname/org.freedesktop.hostname1.service
+++ b/src/hostname/org.freedesktop.hostname1.service
@@ -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/src/hwdb/hwdb.c b/src/hwdb/hwdb.c
index c964a28bce..4540260f9b 100644
--- a/src/hwdb/hwdb.c
+++ b/src/hwdb/hwdb.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/import/curl-util.c b/src/import/curl-util.c
index 0e8f3fb918..7069c95a9f 100644
--- a/src/import/curl-util.c
+++ b/src/import/curl-util.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/import/curl-util.h b/src/import/curl-util.h
index a758cc5640..c7c24c9f7e 100644
--- a/src/import/curl-util.h
+++ b/src/import/curl-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/import/export-raw.c b/src/import/export-raw.c
index a3dbce1954..8485027b2b 100644
--- a/src/import/export-raw.c
+++ b/src/import/export-raw.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/import/export-raw.h b/src/import/export-raw.h
index 8e723d4908..f932a37955 100644
--- a/src/import/export-raw.h
+++ b/src/import/export-raw.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/import/export-tar.c b/src/import/export-tar.c
index 3bb6027431..dafe3e1c88 100644
--- a/src/import/export-tar.c
+++ b/src/import/export-tar.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/import/export-tar.h b/src/import/export-tar.h
index 1e3c8bb80c..5739ade09a 100644
--- a/src/import/export-tar.h
+++ b/src/import/export-tar.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/import/export.c b/src/import/export.c
index cc98c33ef6..753d1399f5 100644
--- a/src/import/export.c
+++ b/src/import/export.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/import/import-common.c b/src/import/import-common.c
index ae71682988..2f989a171c 100644
--- a/src/import/import-common.c
+++ b/src/import/import-common.c
@@ -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)
diff --git a/src/import/import-common.h b/src/import/import-common.h
index 07d3250e71..55ec536406 100644
--- a/src/import/import-common.h
+++ b/src/import/import-common.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/import/import-compress.c b/src/import/import-compress.c
index 01b78fc9a6..cb5b9821c3 100644
--- a/src/import/import-compress.c
+++ b/src/import/import-compress.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/import/import-compress.h b/src/import/import-compress.h
index 6b59d0724b..1eac4d403a 100644
--- a/src/import/import-compress.h
+++ b/src/import/import-compress.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/import/import-raw.c b/src/import/import-raw.c
index 55cf8e8edd..f117c94da2 100644
--- a/src/import/import-raw.c
+++ b/src/import/import-raw.c
@@ -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;
diff --git a/src/import/import-raw.h b/src/import/import-raw.h
index 4f543e0883..1e0227ab55 100644
--- a/src/import/import-raw.h
+++ b/src/import/import-raw.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/import/import-tar.c b/src/import/import-tar.c
index ba140bccbd..c5014499ac 100644
--- a/src/import/import-tar.c
+++ b/src/import/import-tar.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/import/import-tar.h b/src/import/import-tar.h
index 24abe06c8f..44743c9cb3 100644
--- a/src/import/import-tar.h
+++ b/src/import/import-tar.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/import/import.c b/src/import/import.c
index 2b6ca24af8..cc454ee15b 100644
--- a/src/import/import.c
+++ b/src/import/import.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/import/importd.c b/src/import/importd.c
index 9b3fd06b52..9c7694c0ad 100644
--- a/src/import/importd.c
+++ b/src/import/importd.c
@@ -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);
diff --git a/src/import/meson.build b/src/import/meson.build
index e3a0da65d2..2dcc0bcc00 100644
--- a/src/import/meson.build
+++ b/src/import/meson.build
@@ -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)
diff --git a/src/import/org.freedesktop.import1.conf b/src/import/org.freedesktop.import1.conf
index ed2539a03b..9889cd6b10 100644
--- a/src/import/org.freedesktop.import1.conf
+++ b/src/import/org.freedesktop.import1.conf
@@ -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
diff --git a/src/import/org.freedesktop.import1.policy.in b/src/import/org.freedesktop.import1.policy.in
index 85924ed743..d96ca2d060 100644
--- a/src/import/org.freedesktop.import1.policy.in
+++ b/src/import/org.freedesktop.import1.policy.in
@@ -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>
diff --git a/src/import/org.freedesktop.import1.service b/src/import/org.freedesktop.import1.service
index 8fc4c47881..34d26d0732 100644
--- a/src/import/org.freedesktop.import1.service
+++ b/src/import/org.freedesktop.import1.service
@@ -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/src/import/pull-common.c b/src/import/pull-common.c
index 78840dd882..c2a3a6aa8b 100644
--- a/src/import/pull-common.c
+++ b/src/import/pull-common.c
@@ -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
diff --git a/src/import/pull-common.h b/src/import/pull-common.h
index f1f1a17fa9..14c81fb1f1 100644
--- a/src/import/pull-common.h
+++ b/src/import/pull-common.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/import/pull-job.c b/src/import/pull-job.c
index 995a652ec3..2b71766798 100644
--- a/src/import/pull-job.c
+++ b/src/import/pull-job.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/import/pull-job.h b/src/import/pull-job.h
index 412b66cf22..e8becdc002 100644
--- a/src/import/pull-job.h
+++ b/src/import/pull-job.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/import/pull-raw.c b/src/import/pull-raw.c
index b45ac814a9..880cb84ba8 100644
--- a/src/import/pull-raw.c
+++ b/src/import/pull-raw.c
@@ -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;
diff --git a/src/import/pull-raw.h b/src/import/pull-raw.h
index 6954d98994..c951fc25c1 100644
--- a/src/import/pull-raw.h
+++ b/src/import/pull-raw.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/import/pull-tar.c b/src/import/pull-tar.c
index 12211a6fc6..ed91511245 100644
--- a/src/import/pull-tar.c
+++ b/src/import/pull-tar.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/import/pull-tar.h b/src/import/pull-tar.h
index 7e63e496d8..9f004acdc6 100644
--- a/src/import/pull-tar.h
+++ b/src/import/pull-tar.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/import/pull.c b/src/import/pull.c
index 4af5d9c853..46e0fd5acb 100644
--- a/src/import/pull.c
+++ b/src/import/pull.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/import/qcow2-util.c b/src/import/qcow2-util.c
index 00734865b2..7e37bf4026 100644
--- a/src/import/qcow2-util.c
+++ b/src/import/qcow2-util.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/import/qcow2-util.h b/src/import/qcow2-util.h
index 6dddac8cdf..ae1fb8fd38 100644
--- a/src/import/qcow2-util.h
+++ b/src/import/qcow2-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/import/test-qcow2.c b/src/import/test-qcow2.c
index b820253d71..428191d18e 100644
--- a/src/import/test-qcow2.c
+++ b/src/import/test-qcow2.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/initctl/initctl.c b/src/initctl/initctl.c
index deb3f1b2a8..5488999727 100644
--- a/src/initctl/initctl.c
+++ b/src/initctl/initctl.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/journal-remote/journal-gatewayd.c b/src/journal-remote/journal-gatewayd.c
index a0f1f3e926..82c70cfbe3 100644
--- a/src/journal-remote/journal-gatewayd.c
+++ b/src/journal-remote/journal-gatewayd.c
@@ -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;
diff --git a/src/journal-remote/journal-remote-parse.c b/src/journal-remote/journal-remote-parse.c
index d61d1c18f6..2c4e28ad71 100644
--- a/src/journal-remote/journal-remote-parse.c
+++ b/src/journal-remote/journal-remote-parse.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/journal-remote/journal-remote-parse.h b/src/journal-remote/journal-remote-parse.h
index e3632528cf..7aa2f0663e 100644
--- a/src/journal-remote/journal-remote-parse.h
+++ b/src/journal-remote/journal-remote-parse.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/journal-remote/journal-remote-write.c b/src/journal-remote/journal-remote-write.c
index 734cad333f..c5c6abbd5c 100644
--- a/src/journal-remote/journal-remote-write.c
+++ b/src/journal-remote/journal-remote-write.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/journal-remote/journal-remote-write.h b/src/journal-remote/journal-remote-write.h
index e04af54e55..7fffc294ce 100644
--- a/src/journal-remote/journal-remote-write.h
+++ b/src/journal-remote/journal-remote-write.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/journal-remote/journal-remote.c b/src/journal-remote/journal-remote.c
index 9f51137645..e44989e1ba 100644
--- a/src/journal-remote/journal-remote.c
+++ b/src/journal-remote/journal-remote.c
@@ -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) {
diff --git a/src/journal-remote/journal-remote.h b/src/journal-remote/journal-remote.h
index 30ad7df996..30e5c4e995 100644
--- a/src/journal-remote/journal-remote.h
+++ b/src/journal-remote/journal-remote.h
@@ -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 {
diff --git a/src/journal-remote/journal-upload-journal.c b/src/journal-remote/journal-upload-journal.c
index 3a36e46ae0..6c214d27fc 100644
--- a/src/journal-remote/journal-upload-journal.c
+++ b/src/journal-remote/journal-upload-journal.c
@@ -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;
diff --git a/src/journal-remote/journal-upload.c b/src/journal-remote/journal-upload.c
index ea264989ab..69718aae87 100644
--- a/src/journal-remote/journal-upload.c
+++ b/src/journal-remote/journal-upload.c
@@ -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);
}
diff --git a/src/journal-remote/meson.build b/src/journal-remote/meson.build
index ed963d7930..5fdc4cccd7 100644
--- a/src/journal-remote/meson.build
+++ b/src/journal-remote/meson.build
@@ -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
diff --git a/src/journal-remote/microhttpd-util.c b/src/journal-remote/microhttpd-util.c
index 75c14ec996..2466c4f2b5 100644
--- a/src/journal-remote/microhttpd-util.c
+++ b/src/journal-remote/microhttpd-util.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/journal-remote/microhttpd-util.h b/src/journal-remote/microhttpd-util.h
index 4b2e9da30b..76a713068e 100644
--- a/src/journal-remote/microhttpd-util.h
+++ b/src/journal-remote/microhttpd-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/journal/audit-type.c b/src/journal/audit-type.c
index 373d3455ae..0af0364e95 100644
--- a/src/journal/audit-type.c
+++ b/src/journal/audit-type.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/journal/audit-type.h b/src/journal/audit-type.h
index 1dd2163707..603ad41cc7 100644
--- a/src/journal/audit-type.h
+++ b/src/journal/audit-type.h
@@ -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_; \
diff --git a/src/journal/cat.c b/src/journal/cat.c
index 08c844d44f..b2f9ed5010 100644
--- a/src/journal/cat.c
+++ b/src/journal/cat.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/journal/catalog.c b/src/journal/catalog.c
index bf92da9f90..6775535b17 100644
--- a/src/journal/catalog.c
+++ b/src/journal/catalog.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/journal/catalog.h b/src/journal/catalog.h
index 1b1014b335..ce4fa07555 100644
--- a/src/journal/catalog.h
+++ b/src/journal/catalog.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/journal/compress.c b/src/journal/compress.c
index 834859b23c..92eb3874fd 100644
--- a/src/journal/compress.c
+++ b/src/journal/compress.c
@@ -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;
diff --git a/src/journal/compress.h b/src/journal/compress.h
index fb71662a99..917bef0391 100644
--- a/src/journal/compress.h
+++ b/src/journal/compress.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/journal/fsprg.c b/src/journal/fsprg.c
index e7c22880be..281b48904a 100644
--- a/src/journal/fsprg.c
+++ b/src/journal/fsprg.c
@@ -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
diff --git a/src/journal/fsprg.h b/src/journal/fsprg.h
index 829b56e240..e0ec8884be 100644
--- a/src/journal/fsprg.h
+++ b/src/journal/fsprg.h
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+
#ifndef __fsprgh__
#define __fsprgh__
diff --git a/src/journal/journal-authenticate.c b/src/journal/journal-authenticate.c
index d8af113d3f..cff64749a8 100644
--- a/src/journal/journal-authenticate.c
+++ b/src/journal/journal-authenticate.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/journal/journal-authenticate.h b/src/journal/journal-authenticate.h
index 6c87319ede..e2866ea258 100644
--- a/src/journal/journal-authenticate.h
+++ b/src/journal/journal-authenticate.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/journal/journal-def.h b/src/journal/journal-def.h
index 1bd5de4c43..70ce1ab126 100644
--- a/src/journal/journal-def.h
+++ b/src/journal/journal-def.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c
index 3027801ab1..7fef403391 100644
--- a/src/journal/journal-file.c
+++ b/src/journal/journal-file.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
@@ -90,6 +91,10 @@
/* 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)
diff --git a/src/journal/journal-file.h b/src/journal/journal-file.h
index 008dba604b..c5cfa3d878 100644
--- a/src/journal/journal-file.h
+++ b/src/journal/journal-file.h
@@ -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,
diff --git a/src/journal/journal-internal.h b/src/journal/journal-internal.h
index 34a48141f5..5ec87e83d7 100644
--- a/src/journal/journal-internal.h
+++ b/src/journal/journal-internal.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/journal/journal-qrcode.c b/src/journal/journal-qrcode.c
index 4e194bd809..5a9dcaa525 100644
--- a/src/journal/journal-qrcode.c
+++ b/src/journal/journal-qrcode.c
@@ -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]);
}
diff --git a/src/journal/journal-qrcode.h b/src/journal/journal-qrcode.h
index ef39085561..cb26754ada 100644
--- a/src/journal/journal-qrcode.h
+++ b/src/journal/journal-qrcode.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/journal/journal-send.c b/src/journal/journal-send.c
index 4acef26394..a78aa07032 100644
--- a/src/journal/journal-send.c
+++ b/src/journal/journal-send.c
@@ -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;
diff --git a/src/journal/journal-vacuum.c b/src/journal/journal-vacuum.c
index 12ce2fd56c..c21e87858a 100644
--- a/src/journal/journal-vacuum.c
+++ b/src/journal/journal-vacuum.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/journal/journal-vacuum.h b/src/journal/journal-vacuum.h
index 1e750a2170..2aec412385 100644
--- a/src/journal/journal-vacuum.h
+++ b/src/journal/journal-vacuum.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/journal/journal-verify.c b/src/journal/journal-verify.c
index e756f51d0f..dc6b21b1e9 100644
--- a/src/journal/journal-verify.c
+++ b/src/journal/journal-verify.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/journal/journal-verify.h b/src/journal/journal-verify.h
index 8f0eaf6daa..4f999154f1 100644
--- a/src/journal/journal-verify.h
+++ b/src/journal/journal-verify.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c
index e826fa631e..956d85aff2 100644
--- a/src/journal/journalctl.c
+++ b/src/journal/journalctl.c
@@ -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);
diff --git a/src/journal/journald-audit.c b/src/journal/journald-audit.c
index 3334418f33..19f53751cb 100644
--- a/src/journal/journald-audit.c
+++ b/src/journal/journald-audit.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
@@ -29,10 +30,10 @@
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);
diff --git a/src/journal/journald-audit.h b/src/journal/journald-audit.h
index 8c7457778c..83dd4bca7a 100644
--- a/src/journal/journald-audit.h
+++ b/src/journal/journald-audit.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/journal/journald-console.c b/src/journal/journald-console.c
index 039f1a68ce..98fbb83a0c 100644
--- a/src/journal/journald-console.c
+++ b/src/journal/journald-console.c
@@ -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;
diff --git a/src/journal/journald-console.h b/src/journal/journald-console.h
index dda07e2c28..3b345507d9 100644
--- a/src/journal/journald-console.h
+++ b/src/journal/journald-console.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/journal/journald-context.c b/src/journal/journald-context.c
index eaa7f2544f..f5345e4cb2 100644
--- a/src/journal/journald-context.c
+++ b/src/journal/journald-context.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
@@ -24,9 +25,16 @@
#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;
diff --git a/src/journal/journald-context.h b/src/journal/journald-context.h
index eb1e21926a..e29f59ce5d 100644
--- a/src/journal/journald-context.h
+++ b/src/journal/journald-context.h
@@ -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;
+}
diff --git a/src/journal/journald-gperf.gperf b/src/journal/journald-gperf.gperf
index 6b05bda0ae..e8c1f2e2d5 100644
--- a/src/journal/journald-gperf.gperf
+++ b/src/journal/journald-gperf.gperf
@@ -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"
diff --git a/src/journal/journald-kmsg.c b/src/journal/journald-kmsg.c
index 36f16a1ec8..0fadc16fbd 100644
--- a/src/journal/journald-kmsg.c
+++ b/src/journal/journald-kmsg.c
@@ -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),
diff --git a/src/journal/journald-kmsg.h b/src/journal/journald-kmsg.h
index dab49f1e8c..af795eaf63 100644
--- a/src/journal/journald-kmsg.h
+++ b/src/journal/journald-kmsg.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/journal/journald-native.c b/src/journal/journald-native.c
index d45c9c2270..65fb6ab63a 100644
--- a/src/journal/journald-native.c
+++ b/src/journal/journald-native.c
@@ -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"
@@ -43,41 +45,6 @@
#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);
diff --git a/src/journal/journald-native.h b/src/journal/journald-native.h
index 1ab415ac85..7ca17ec609 100644
--- a/src/journal/journald-native.h
+++ b/src/journal/journald-native.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/journal/journald-rate-limit.c b/src/journal/journald-rate-limit.c
index a3404222e0..3517ce2e1c 100644
--- a/src/journal/journald-rate-limit.c
+++ b/src/journal/journald-rate-limit.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/journal/journald-rate-limit.h b/src/journal/journald-rate-limit.h
index bb0abb7ee9..af7bb495f2 100644
--- a/src/journal/journald-rate-limit.h
+++ b/src/journal/journald-rate-limit.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
index 00ad168286..48375f9c3e 100644
--- a/src/journal/journald-server.c
+++ b/src/journal/journald-server.c
@@ -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);
diff --git a/src/journal/journald-server.h b/src/journal/journald-server.h
index f4bdd588cb..bf4ba6897a 100644
--- a/src/journal/journald-server.h
+++ b/src/journal/journald-server.h
@@ -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);
diff --git a/src/journal/journald-stream.c b/src/journal/journald-stream.c
index 54dd096e45..671ada718c 100644
--- a/src/journal/journald-stream.c
+++ b/src/journal/journald-stream.c
@@ -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,
diff --git a/src/journal/journald-stream.h b/src/journal/journald-stream.h
index db4c67fae3..fd220b5864 100644
--- a/src/journal/journald-stream.h
+++ b/src/journal/journald-stream.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/journal/journald-syslog.c b/src/journal/journald-syslog.c
index 1fde0271a6..4018288b0c 100644
--- a/src/journal/journald-syslog.c
+++ b/src/journal/journald-syslog.c
@@ -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;
@@ -286,8 +287,7 @@ static void syslog_skip_date(char **buf) {
if (*p == ' ')
break;
- /* fall through */
-
+ _fallthrough_;
case NUMBER:
if (*p < '0' || *p > '9')
return;
@@ -324,18 +324,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);
@@ -351,6 +360,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);
@@ -375,13 +387,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) {
@@ -449,7 +455,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),
diff --git a/src/journal/journald-syslog.h b/src/journal/journald-syslog.h
index 46ad715314..3438107c5f 100644
--- a/src/journal/journald-syslog.h
+++ b/src/journal/journald-syslog.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/journal/journald-wall.c b/src/journal/journald-wall.c
index bfe53ce39d..431abfeb32 100644
--- a/src/journal/journald-wall.c
+++ b/src/journal/journald-wall.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/journal/journald-wall.h b/src/journal/journald-wall.h
index ebc2b89fa8..46ceac26bb 100644
--- a/src/journal/journald-wall.h
+++ b/src/journal/journald-wall.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/journal/journald.c b/src/journal/journald.c
index 318e067563..6d670e2f4f 100644
--- a/src/journal/journald.c
+++ b/src/journal/journald.c
@@ -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);
diff --git a/src/journal/meson.build b/src/journal/meson.build
index da42fd89d2..edb2a1a30e 100644
--- a/src/journal/meson.build
+++ b/src/journal/meson.build
@@ -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
diff --git a/src/journal/mmap-cache.c b/src/journal/mmap-cache.c
index ac7252093b..630ae6fbac 100644
--- a/src/journal/mmap-cache.c
+++ b/src/journal/mmap-cache.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/journal/mmap-cache.h b/src/journal/mmap-cache.h
index cf6af1906a..00bcafdfb1 100644
--- a/src/journal/mmap-cache.h
+++ b/src/journal/mmap-cache.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c
index fc86b99e70..8a1b161d8f 100644
--- a/src/journal/sd-journal.c
+++ b/src/journal/sd-journal.c
@@ -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);
diff --git a/src/journal/test-audit-type.c b/src/journal/test-audit-type.c
index 88a2e6d9d9..0f9780380d 100644
--- a/src/journal/test-audit-type.c
+++ b/src/journal/test-audit-type.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/journal/test-catalog.c b/src/journal/test-catalog.c
index b7d9e7bffa..2ad9909d1b 100644
--- a/src/journal/test-catalog.c
+++ b/src/journal/test-catalog.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/journal/test-compress-benchmark.c b/src/journal/test-compress-benchmark.c
index be5a6655a8..409a876054 100644
--- a/src/journal/test-compress-benchmark.c
+++ b/src/journal/test-compress-benchmark.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd
diff --git a/src/journal/test-compress.c b/src/journal/test-compress.c
index 893f2ab6eb..ea1ffcc4af 100644
--- a/src/journal/test-compress.c
+++ b/src/journal/test-compress.c
@@ -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));
diff --git a/src/journal/test-journal-enum.c b/src/journal/test-journal-enum.c
index 354c2c3c00..9733eec0e2 100644
--- a/src/journal/test-journal-enum.c
+++ b/src/journal/test-journal-enum.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/journal/test-journal-flush.c b/src/journal/test-journal-flush.c
index ba8b20b228..f9b7b75ef1 100644
--- a/src/journal/test-journal-flush.c
+++ b/src/journal/test-journal-flush.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/journal/test-journal-init.c b/src/journal/test-journal-init.c
index ef21e2d05f..074329138b 100644
--- a/src/journal/test-journal-init.c
+++ b/src/journal/test-journal-init.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/journal/test-journal-interleaving.c b/src/journal/test-journal-interleaving.c
index 35cae23bf8..5a88b2774f 100644
--- a/src/journal/test-journal-interleaving.c
+++ b/src/journal/test-journal-interleaving.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/journal/test-journal-match.c b/src/journal/test-journal-match.c
index 3ab554b9b0..018e965d67 100644
--- a/src/journal/test-journal-match.c
+++ b/src/journal/test-journal-match.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/journal/test-journal-send.c b/src/journal/test-journal-send.c
index d70f0b0bc8..8e69a52e29 100644
--- a/src/journal/test-journal-send.c
+++ b/src/journal/test-journal-send.c
@@ -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);
diff --git a/src/journal/test-journal-stream.c b/src/journal/test-journal-stream.c
index 7e5a980719..73ed6e5dcb 100644
--- a/src/journal/test-journal-stream.c
+++ b/src/journal/test-journal-stream.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/journal/test-journal-syslog.c b/src/journal/test-journal-syslog.c
index 4ff7f3ec2e..45ad1196aa 100644
--- a/src/journal/test-journal-syslog.c
+++ b/src/journal/test-journal-syslog.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/journal/test-journal-verify.c b/src/journal/test-journal-verify.c
index 3d2312fc55..fbb75e43e3 100644
--- a/src/journal/test-journal-verify.c
+++ b/src/journal/test-journal-verify.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/journal/test-journal.c b/src/journal/test-journal.c
index df685e90b6..517c9102a6 100644
--- a/src/journal/test-journal.c
+++ b/src/journal/test-journal.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/journal/test-mmap-cache.c b/src/journal/test-mmap-cache.c
index 702434efd2..39e7510128 100644
--- a/src/journal/test-mmap-cache.c
+++ b/src/journal/test-mmap-cache.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/kernel-install/kernel-install b/src/kernel-install/kernel-install
index 66bc4a6e8e..6eabb09e3c 100644
--- a/src/kernel-install/kernel-install
+++ b/src/kernel-install/kernel-install
@@ -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.
#
diff --git a/src/kernel-install/meson.build b/src/kernel-install/meson.build
index ede3323bab..65f483f229 100644
--- a/src/kernel-install/meson.build
+++ b/src/kernel-install/meson.build
@@ -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)
diff --git a/src/libsystemd-network/arp-util.c b/src/libsystemd-network/arp-util.c
index 2e02b3fa66..67409cc918 100644
--- a/src/libsystemd-network/arp-util.c
+++ b/src/libsystemd-network/arp-util.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd-network/arp-util.h b/src/libsystemd-network/arp-util.h
index 3ef56b002a..decfce3fd6 100644
--- a/src/libsystemd-network/arp-util.h
+++ b/src/libsystemd-network/arp-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/libsystemd-network/dhcp-identifier.c b/src/libsystemd-network/dhcp-identifier.c
index a21efc4d06..f33817ca7d 100644
--- a/src/libsystemd-network/dhcp-identifier.c
+++ b/src/libsystemd-network/dhcp-identifier.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd-network/dhcp-identifier.h b/src/libsystemd-network/dhcp-identifier.h
index 1cc0f9fb71..0ccee7a718 100644
--- a/src/libsystemd-network/dhcp-identifier.h
+++ b/src/libsystemd-network/dhcp-identifier.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/libsystemd-network/dhcp-internal.h b/src/libsystemd-network/dhcp-internal.h
index 3fdf02da3e..a53526956a 100644
--- a/src/libsystemd-network/dhcp-internal.h
+++ b/src/libsystemd-network/dhcp-internal.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/libsystemd-network/dhcp-lease-internal.h b/src/libsystemd-network/dhcp-lease-internal.h
index 7847ce0709..ac5cc47efd 100644
--- a/src/libsystemd-network/dhcp-lease-internal.h
+++ b/src/libsystemd-network/dhcp-lease-internal.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/libsystemd-network/dhcp-network.c b/src/libsystemd-network/dhcp-network.c
index a440a20f96..010090aef1 100644
--- a/src/libsystemd-network/dhcp-network.c
+++ b/src/libsystemd-network/dhcp-network.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd-network/dhcp-option.c b/src/libsystemd-network/dhcp-option.c
index c105196334..0489579e7f 100644
--- a/src/libsystemd-network/dhcp-option.c
+++ b/src/libsystemd-network/dhcp-option.c
@@ -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;
diff --git a/src/libsystemd-network/dhcp-packet.c b/src/libsystemd-network/dhcp-packet.c
index 475c5729a0..1c4ab5d52f 100644
--- a/src/libsystemd-network/dhcp-packet.c
+++ b/src/libsystemd-network/dhcp-packet.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd-network/dhcp-protocol.h b/src/libsystemd-network/dhcp-protocol.h
index 5cf7abbff9..73a9f75e75 100644
--- a/src/libsystemd-network/dhcp-protocol.h
+++ b/src/libsystemd-network/dhcp-protocol.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/libsystemd-network/dhcp-server-internal.h b/src/libsystemd-network/dhcp-server-internal.h
index 0c76956fad..8b5620e138 100644
--- a/src/libsystemd-network/dhcp-server-internal.h
+++ b/src/libsystemd-network/dhcp-server-internal.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/libsystemd-network/dhcp6-internal.h b/src/libsystemd-network/dhcp6-internal.h
index 945c3b9721..cb5b359cbe 100644
--- a/src/libsystemd-network/dhcp6-internal.h
+++ b/src/libsystemd-network/dhcp6-internal.h
@@ -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,
diff --git a/src/libsystemd-network/dhcp6-lease-internal.h b/src/libsystemd-network/dhcp6-lease-internal.h
index 14e708ef63..a3f00d4a5d 100644
--- a/src/libsystemd-network/dhcp6-lease-internal.h
+++ b/src/libsystemd-network/dhcp6-lease-internal.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/libsystemd-network/dhcp6-network.c b/src/libsystemd-network/dhcp6-network.c
index fd2d60c9d5..b3b8fddbcb 100644
--- a/src/libsystemd-network/dhcp6-network.c
+++ b/src/libsystemd-network/dhcp6-network.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd-network/dhcp6-option.c b/src/libsystemd-network/dhcp6-option.c
index f8056dbc4b..f346bda5fc 100644
--- a/src/libsystemd-network/dhcp6-option.c
+++ b/src/libsystemd-network/dhcp6-option.c
@@ -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;
diff --git a/src/libsystemd-network/dhcp6-protocol.h b/src/libsystemd-network/dhcp6-protocol.h
index 2487c470ab..7bbf183996 100644
--- a/src/libsystemd-network/dhcp6-protocol.h
+++ b/src/libsystemd-network/dhcp6-protocol.h
@@ -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),
+};
diff --git a/src/libsystemd-network/icmp6-util.c b/src/libsystemd-network/icmp6-util.c
index cf69044d6d..dd4e28bfd9 100644
--- a/src/libsystemd-network/icmp6-util.c
+++ b/src/libsystemd-network/icmp6-util.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd-network/icmp6-util.h b/src/libsystemd-network/icmp6-util.h
index 16b8be8298..ce14f41736 100644
--- a/src/libsystemd-network/icmp6-util.h
+++ b/src/libsystemd-network/icmp6-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/libsystemd-network/lldp-internal.h b/src/libsystemd-network/lldp-internal.h
index becc162fab..2673aa1c55 100644
--- a/src/libsystemd-network/lldp-internal.h
+++ b/src/libsystemd-network/lldp-internal.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/libsystemd-network/lldp-neighbor.c b/src/libsystemd-network/lldp-neighbor.c
index f1fecba6fa..1a6ea288aa 100644
--- a/src/libsystemd-network/lldp-neighbor.c
+++ b/src/libsystemd-network/lldp-neighbor.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd-network/lldp-neighbor.h b/src/libsystemd-network/lldp-neighbor.h
index c1a7606d06..76d4c0c724 100644
--- a/src/libsystemd-network/lldp-neighbor.h
+++ b/src/libsystemd-network/lldp-neighbor.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/libsystemd-network/lldp-network.c b/src/libsystemd-network/lldp-network.c
index ae2f6744d5..cb3841ef22 100644
--- a/src/libsystemd-network/lldp-network.c
+++ b/src/libsystemd-network/lldp-network.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd-network/lldp-network.h b/src/libsystemd-network/lldp-network.h
index c4cf8c79f1..c0f8cbe1c9 100644
--- a/src/libsystemd-network/lldp-network.h
+++ b/src/libsystemd-network/lldp-network.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/libsystemd-network/meson.build b/src/libsystemd-network/meson.build
index 78c74560b8..c710ab44a9 100644
--- a/src/libsystemd-network/meson.build
+++ b/src/libsystemd-network/meson.build
@@ -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
diff --git a/src/libsystemd-network/ndisc-internal.h b/src/libsystemd-network/ndisc-internal.h
index 82b896dba3..2743d85efc 100644
--- a/src/libsystemd-network/ndisc-internal.h
+++ b/src/libsystemd-network/ndisc-internal.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/libsystemd-network/ndisc-router.c b/src/libsystemd-network/ndisc-router.c
index 845a6b7c6c..2954928d00 100644
--- a/src/libsystemd-network/ndisc-router.c
+++ b/src/libsystemd-network/ndisc-router.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd-network/ndisc-router.h b/src/libsystemd-network/ndisc-router.h
index 1fe703da63..f3757f6dbb 100644
--- a/src/libsystemd-network/ndisc-router.h
+++ b/src/libsystemd-network/ndisc-router.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/libsystemd-network/network-internal.c b/src/libsystemd-network/network-internal.c
index 337241a815..e48b7d22dd 100644
--- a/src/libsystemd-network/network-internal.c
+++ b/src/libsystemd-network/network-internal.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd-network/network-internal.h b/src/libsystemd-network/network-internal.h
index 4666f174e9..a54adac602 100644
--- a/src/libsystemd-network/network-internal.h
+++ b/src/libsystemd-network/network-internal.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/libsystemd-network/radv-internal.h b/src/libsystemd-network/radv-internal.h
index 5601be844d..441939b717 100644
--- a/src/libsystemd-network/radv-internal.h
+++ b/src/libsystemd-network/radv-internal.h
@@ -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)
diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c
index 29b22eed45..228af69d88 100644
--- a/src/libsystemd-network/sd-dhcp-client.c
+++ b/src/libsystemd-network/sd-dhcp-client.c
@@ -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
diff --git a/src/libsystemd-network/sd-dhcp-lease.c b/src/libsystemd-network/sd-dhcp-lease.c
index 1ab569765d..78b8e058b4 100644
--- a/src/libsystemd-network/sd-dhcp-lease.c
+++ b/src/libsystemd-network/sd-dhcp-lease.c
@@ -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);
diff --git a/src/libsystemd-network/sd-dhcp-server.c b/src/libsystemd-network/sd-dhcp-server.c
index 663fd0e41d..63fb355e85 100644
--- a/src/libsystemd-network/sd-dhcp-server.c
+++ b/src/libsystemd-network/sd-dhcp-server.c
@@ -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;
diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c
index eba0c8bcbb..1c12e5430f 100644
--- a/src/libsystemd-network/sd-dhcp6-client.c
+++ b/src/libsystemd-network/sd-dhcp6-client.c
@@ -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);
}
diff --git a/src/libsystemd-network/sd-dhcp6-lease.c b/src/libsystemd-network/sd-dhcp6-lease.c
index 8396407e9f..6f604e072f 100644
--- a/src/libsystemd-network/sd-dhcp6-lease.c
+++ b/src/libsystemd-network/sd-dhcp6-lease.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd-network/sd-ipv4acd.c b/src/libsystemd-network/sd-ipv4acd.c
index 909b470251..7cf4f031de 100644
--- a/src/libsystemd-network/sd-ipv4acd.c
+++ b/src/libsystemd-network/sd-ipv4acd.c
@@ -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);
diff --git a/src/libsystemd-network/sd-ipv4ll.c b/src/libsystemd-network/sd-ipv4ll.c
index 88a90e593b..23e2f5211d 100644
--- a/src/libsystemd-network/sd-ipv4ll.c
+++ b/src/libsystemd-network/sd-ipv4ll.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd-network/sd-lldp.c b/src/libsystemd-network/sd-lldp.c
index 0f591a8011..2c05416184 100644
--- a/src/libsystemd-network/sd-lldp.c
+++ b/src/libsystemd-network/sd-lldp.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd-network/sd-ndisc.c b/src/libsystemd-network/sd-ndisc.c
index 4bf558b12b..b5c6d6e84d 100644
--- a/src/libsystemd-network/sd-ndisc.c
+++ b/src/libsystemd-network/sd-ndisc.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd-network/sd-radv.c b/src/libsystemd-network/sd-radv.c
index a3aa5c9c62..46704acdef 100644
--- a/src/libsystemd-network/sd-radv.c
+++ b/src/libsystemd-network/sd-radv.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
@@ -160,8 +161,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),
diff --git a/src/libsystemd-network/test-acd.c b/src/libsystemd-network/test-acd.c
index 27fcc332a3..7968c9056a 100644
--- a/src/libsystemd-network/test-acd.c
+++ b/src/libsystemd-network/test-acd.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd-network/test-dhcp-client.c b/src/libsystemd-network/test-dhcp-client.c
index 1942199294..0e25310e59 100644
--- a/src/libsystemd-network/test-dhcp-client.c
+++ b/src/libsystemd-network/test-dhcp-client.c
@@ -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);
diff --git a/src/libsystemd-network/test-dhcp-server.c b/src/libsystemd-network/test-dhcp-server.c
index 26f217835f..6632316b1e 100644
--- a/src/libsystemd-network/test-dhcp-server.c
+++ b/src/libsystemd-network/test-dhcp-server.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd-network/test-dhcp6-client.c b/src/libsystemd-network/test-dhcp6-client.c
index bd289fa802..a0418ecdb9 100644
--- a/src/libsystemd-network/test-dhcp6-client.c
+++ b/src/libsystemd-network/test-dhcp6-client.c
@@ -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);
diff --git a/src/libsystemd-network/test-ipv4ll-manual.c b/src/libsystemd-network/test-ipv4ll-manual.c
index 2b1387fa91..37092ea300 100644
--- a/src/libsystemd-network/test-ipv4ll-manual.c
+++ b/src/libsystemd-network/test-ipv4ll-manual.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd-network/test-ipv4ll.c b/src/libsystemd-network/test-ipv4ll.c
index 89864fd39c..d0620596e5 100644
--- a/src/libsystemd-network/test-ipv4ll.c
+++ b/src/libsystemd-network/test-ipv4ll.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd-network/test-lldp.c b/src/libsystemd-network/test-lldp.c
index 430c58ae60..c62689373f 100644
--- a/src/libsystemd-network/test-lldp.c
+++ b/src/libsystemd-network/test-lldp.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd-network/test-ndisc-ra.c b/src/libsystemd-network/test-ndisc-ra.c
index 18205ef2c9..c1a8d5a00d 100644
--- a/src/libsystemd-network/test-ndisc-ra.c
+++ b/src/libsystemd-network/test-ndisc-ra.c
@@ -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) {
diff --git a/src/libsystemd-network/test-ndisc-rs.c b/src/libsystemd-network/test-ndisc-rs.c
index c3e1a8e340..e1a2b9f7a2 100644
--- a/src/libsystemd-network/test-ndisc-rs.c
+++ b/src/libsystemd-network/test-ndisc-rs.c
@@ -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);
diff --git a/src/libsystemd/libsystemd.pc.in b/src/libsystemd/libsystemd.pc.in
index 7e6d4999cb..c861905b67 100644
--- a/src/libsystemd/libsystemd.pc.in
+++ b/src/libsystemd/libsystemd.pc.in
@@ -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/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym
index 92cb790d49..1a29b03e85 100644
--- a/src/libsystemd/libsystemd.sym
+++ b/src/libsystemd/libsystemd.sym
@@ -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;
diff --git a/src/libsystemd/meson.build b/src/libsystemd/meson.build
index 8807517a1a..4abf50b111 100644
--- a/src/libsystemd/meson.build
+++ b/src/libsystemd/meson.build
@@ -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('''
diff --git a/src/libsystemd/sd-bus/bus-bloom.c b/src/libsystemd/sd-bus/bus-bloom.c
index 112769fcb6..ebda6516e2 100644
--- a/src/libsystemd/sd-bus/bus-bloom.c
+++ b/src/libsystemd/sd-bus/bus-bloom.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd/sd-bus/bus-bloom.h b/src/libsystemd/sd-bus/bus-bloom.h
index c824622b95..2650762145 100644
--- a/src/libsystemd/sd-bus/bus-bloom.h
+++ b/src/libsystemd/sd-bus/bus-bloom.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/libsystemd/sd-bus/bus-common-errors.c b/src/libsystemd/sd-bus/bus-common-errors.c
index b40ba2520c..07a1f50047 100644
--- a/src/libsystemd/sd-bus/bus-common-errors.c
+++ b/src/libsystemd/sd-bus/bus-common-errors.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd/sd-bus/bus-common-errors.h b/src/libsystemd/sd-bus/bus-common-errors.h
index 4523be05ce..42c0f528f0 100644
--- a/src/libsystemd/sd-bus/bus-common-errors.h
+++ b/src/libsystemd/sd-bus/bus-common-errors.h
@@ -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"
diff --git a/src/libsystemd/sd-bus/bus-container.c b/src/libsystemd/sd-bus/bus-container.c
index 9827a42267..8f6d34838e 100644
--- a/src/libsystemd/sd-bus/bus-container.c
+++ b/src/libsystemd/sd-bus/bus-container.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd/sd-bus/bus-container.h b/src/libsystemd/sd-bus/bus-container.h
index 35952d9256..6921ffd52d 100644
--- a/src/libsystemd/sd-bus/bus-container.h
+++ b/src/libsystemd/sd-bus/bus-container.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/libsystemd/sd-bus/bus-control.c b/src/libsystemd/sd-bus/bus-control.c
index fcd4d27e07..12478e7cc6 100644
--- a/src/libsystemd/sd-bus/bus-control.c
+++ b/src/libsystemd/sd-bus/bus-control.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd/sd-bus/bus-control.h b/src/libsystemd/sd-bus/bus-control.h
index 01c71874db..c9d434c607 100644
--- a/src/libsystemd/sd-bus/bus-control.h
+++ b/src/libsystemd/sd-bus/bus-control.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/libsystemd/sd-bus/bus-convenience.c b/src/libsystemd/sd-bus/bus-convenience.c
index e171c53e21..9d3b596429 100644
--- a/src/libsystemd/sd-bus/bus-convenience.c
+++ b/src/libsystemd/sd-bus/bus-convenience.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd/sd-bus/bus-creds.c b/src/libsystemd/sd-bus/bus-creds.c
index 21a15c8d60..b6ef4a0fe5 100644
--- a/src/libsystemd/sd-bus/bus-creds.c
+++ b/src/libsystemd/sd-bus/bus-creds.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd/sd-bus/bus-creds.h b/src/libsystemd/sd-bus/bus-creds.h
index df8a1f1005..c4c60fa2d7 100644
--- a/src/libsystemd/sd-bus/bus-creds.h
+++ b/src/libsystemd/sd-bus/bus-creds.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/libsystemd/sd-bus/bus-dump.c b/src/libsystemd/sd-bus/bus-dump.c
index f117c98c11..2d93e1e437 100644
--- a/src/libsystemd/sd-bus/bus-dump.c
+++ b/src/libsystemd/sd-bus/bus-dump.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd/sd-bus/bus-dump.h b/src/libsystemd/sd-bus/bus-dump.h
index 874e86d09c..ab3b039203 100644
--- a/src/libsystemd/sd-bus/bus-dump.h
+++ b/src/libsystemd/sd-bus/bus-dump.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/libsystemd/sd-bus/bus-error.c b/src/libsystemd/sd-bus/bus-error.c
index 378f7a377a..c9517499d7 100644
--- a/src/libsystemd/sd-bus/bus-error.c
+++ b/src/libsystemd/sd-bus/bus-error.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd/sd-bus/bus-error.h b/src/libsystemd/sd-bus/bus-error.h
index e2c4cf4b3f..6181e37d81 100644
--- a/src/libsystemd/sd-bus/bus-error.h
+++ b/src/libsystemd/sd-bus/bus-error.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/libsystemd/sd-bus/bus-gvariant.c b/src/libsystemd/sd-bus/bus-gvariant.c
index 58782767fa..6a990a02c0 100644
--- a/src/libsystemd/sd-bus/bus-gvariant.c
+++ b/src/libsystemd/sd-bus/bus-gvariant.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd/sd-bus/bus-gvariant.h b/src/libsystemd/sd-bus/bus-gvariant.h
index 6da637fb05..474e131566 100644
--- a/src/libsystemd/sd-bus/bus-gvariant.h
+++ b/src/libsystemd/sd-bus/bus-gvariant.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/libsystemd/sd-bus/bus-internal.c b/src/libsystemd/sd-bus/bus-internal.c
index dacd243c3e..3c381b0ffe 100644
--- a/src/libsystemd/sd-bus/bus-internal.c
+++ b/src/libsystemd/sd-bus/bus-internal.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd/sd-bus/bus-internal.h b/src/libsystemd/sd-bus/bus-internal.h
index 3af383e18b..378c408ea3 100644
--- a/src/libsystemd/sd-bus/bus-internal.h
+++ b/src/libsystemd/sd-bus/bus-internal.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/libsystemd/sd-bus/bus-introspect.c b/src/libsystemd/sd-bus/bus-introspect.c
index 9fcb59631c..9bd2dadfde 100644
--- a/src/libsystemd/sd-bus/bus-introspect.c
+++ b/src/libsystemd/sd-bus/bus-introspect.c
@@ -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)
diff --git a/src/libsystemd/sd-bus/bus-introspect.h b/src/libsystemd/sd-bus/bus-introspect.h
index 8e2f3800ca..5d2d5a17dd 100644
--- a/src/libsystemd/sd-bus/bus-introspect.h
+++ b/src/libsystemd/sd-bus/bus-introspect.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/libsystemd/sd-bus/bus-kernel.c b/src/libsystemd/sd-bus/bus-kernel.c
index 5a3c4d6f50..c6179b4d95 100644
--- a/src/libsystemd/sd-bus/bus-kernel.c
+++ b/src/libsystemd/sd-bus/bus-kernel.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd/sd-bus/bus-kernel.h b/src/libsystemd/sd-bus/bus-kernel.h
index 49c0ab3a3c..d9f80935fe 100644
--- a/src/libsystemd/sd-bus/bus-kernel.h
+++ b/src/libsystemd/sd-bus/bus-kernel.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/libsystemd/sd-bus/bus-match.c b/src/libsystemd/sd-bus/bus-match.c
index a972c13054..8d798c0a58 100644
--- a/src/libsystemd/sd-bus/bus-match.c
+++ b/src/libsystemd/sd-bus/bus-match.c
@@ -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);
diff --git a/src/libsystemd/sd-bus/bus-match.h b/src/libsystemd/sd-bus/bus-match.h
index 8cbbb63b11..ac2e51a422 100644
--- a/src/libsystemd/sd-bus/bus-match.h
+++ b/src/libsystemd/sd-bus/bus-match.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c
index 3fc447df3f..219cff1f6e 100644
--- a/src/libsystemd/sd-bus/bus-message.c
+++ b/src/libsystemd/sd-bus/bus-message.c
@@ -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;
diff --git a/src/libsystemd/sd-bus/bus-message.h b/src/libsystemd/sd-bus/bus-message.h
index a84f908f75..1e4b20926d 100644
--- a/src/libsystemd/sd-bus/bus-message.h
+++ b/src/libsystemd/sd-bus/bus-message.h
@@ -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);
diff --git a/src/libsystemd/sd-bus/bus-objects.c b/src/libsystemd/sd-bus/bus-objects.c
index df2bdc806c..121197bbcb 100644
--- a/src/libsystemd/sd-bus/bus-objects.c
+++ b/src/libsystemd/sd-bus/bus-objects.c
@@ -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;
diff --git a/src/libsystemd/sd-bus/bus-objects.h b/src/libsystemd/sd-bus/bus-objects.h
index e0b8c534ed..6bffeda726 100644
--- a/src/libsystemd/sd-bus/bus-objects.h
+++ b/src/libsystemd/sd-bus/bus-objects.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/libsystemd/sd-bus/bus-protocol.h b/src/libsystemd/sd-bus/bus-protocol.h
index 9d180cb284..0d5dfd9474 100644
--- a/src/libsystemd/sd-bus/bus-protocol.h
+++ b/src/libsystemd/sd-bus/bus-protocol.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/libsystemd/sd-bus/bus-signature.c b/src/libsystemd/sd-bus/bus-signature.c
index 7bc243494a..d16461f4ae 100644
--- a/src/libsystemd/sd-bus/bus-signature.c
+++ b/src/libsystemd/sd-bus/bus-signature.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd/sd-bus/bus-signature.h b/src/libsystemd/sd-bus/bus-signature.h
index 1e0cd7f587..a6be1844e2 100644
--- a/src/libsystemd/sd-bus/bus-signature.h
+++ b/src/libsystemd/sd-bus/bus-signature.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/libsystemd/sd-bus/bus-slot.c b/src/libsystemd/sd-bus/bus-slot.c
index 725265b331..756761c3ed 100644
--- a/src/libsystemd/sd-bus/bus-slot.c
+++ b/src/libsystemd/sd-bus/bus-slot.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd/sd-bus/bus-slot.h b/src/libsystemd/sd-bus/bus-slot.h
index 3b8b94dc6b..beebaa1670 100644
--- a/src/libsystemd/sd-bus/bus-slot.h
+++ b/src/libsystemd/sd-bus/bus-slot.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/libsystemd/sd-bus/bus-socket.c b/src/libsystemd/sd-bus/bus-socket.c
index 235fe26393..07a9c8affd 100644
--- a/src/libsystemd/sd-bus/bus-socket.c
+++ b/src/libsystemd/sd-bus/bus-socket.c
@@ -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);
diff --git a/src/libsystemd/sd-bus/bus-socket.h b/src/libsystemd/sd-bus/bus-socket.h
index 684feead74..915a283f5a 100644
--- a/src/libsystemd/sd-bus/bus-socket.h
+++ b/src/libsystemd/sd-bus/bus-socket.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/libsystemd/sd-bus/bus-track.c b/src/libsystemd/sd-bus/bus-track.c
index 4acaf24793..ab22d6e4de 100644
--- a/src/libsystemd/sd-bus/bus-track.c
+++ b/src/libsystemd/sd-bus/bus-track.c
@@ -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)
diff --git a/src/libsystemd/sd-bus/bus-track.h b/src/libsystemd/sd-bus/bus-track.h
index 26bd05f5c7..0c5636b7e0 100644
--- a/src/libsystemd/sd-bus/bus-track.h
+++ b/src/libsystemd/sd-bus/bus-track.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/libsystemd/sd-bus/bus-type.c b/src/libsystemd/sd-bus/bus-type.c
index c692afc580..fe486f441d 100644
--- a/src/libsystemd/sd-bus/bus-type.c
+++ b/src/libsystemd/sd-bus/bus-type.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd/sd-bus/bus-type.h b/src/libsystemd/sd-bus/bus-type.h
index 5c87eb5f08..ae272b1e6a 100644
--- a/src/libsystemd/sd-bus/bus-type.h
+++ b/src/libsystemd/sd-bus/bus-type.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c
index 621fabb015..5fb15a7aaf 100644
--- a/src/libsystemd/sd-bus/sd-bus.c
+++ b/src/libsystemd/sd-bus/sd-bus.c
@@ -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) {
diff --git a/src/libsystemd/sd-bus/test-bus-benchmark.c b/src/libsystemd/sd-bus/test-bus-benchmark.c
index 6f0ca47df6..a466cddd75 100644
--- a/src/libsystemd/sd-bus/test-bus-benchmark.c
+++ b/src/libsystemd/sd-bus/test-bus-benchmark.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
@@ -228,7 +229,7 @@ int main(int argc, char *argv[]) {
} mode = MODE_BISECT;
Type type = TYPE_LEGACY;
int i, pair[2] = { -1, -1 };
- _cleanup_free_ char *name = NULL, *bus_name = NULL, *address = NULL, *server_name = NULL;
+ _cleanup_free_ char *address = NULL, *server_name = NULL;
_cleanup_close_ int bus_ref = -1;
const char *unique;
cpu_set_t cpuset;
diff --git a/src/libsystemd/sd-bus/test-bus-chat.c b/src/libsystemd/sd-bus/test-bus-chat.c
index 0fc6fc90ed..1b2efb9bb4 100644
--- a/src/libsystemd/sd-bus/test-bus-chat.c
+++ b/src/libsystemd/sd-bus/test-bus-chat.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd/sd-bus/test-bus-cleanup.c b/src/libsystemd/sd-bus/test-bus-cleanup.c
index 4d81e67a6b..d5601fc57b 100644
--- a/src/libsystemd/sd-bus/test-bus-cleanup.c
+++ b/src/libsystemd/sd-bus/test-bus-cleanup.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd/sd-bus/test-bus-creds.c b/src/libsystemd/sd-bus/test-bus-creds.c
index 64bd76a576..f654692bf6 100644
--- a/src/libsystemd/sd-bus/test-bus-creds.c
+++ b/src/libsystemd/sd-bus/test-bus-creds.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd/sd-bus/test-bus-error.c b/src/libsystemd/sd-bus/test-bus-error.c
index 66a3874f10..4e3f404e68 100644
--- a/src/libsystemd/sd-bus/test-bus-error.c
+++ b/src/libsystemd/sd-bus/test-bus-error.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd/sd-bus/test-bus-gvariant.c b/src/libsystemd/sd-bus/test-bus-gvariant.c
index 94fa964595..4c372fd05a 100644
--- a/src/libsystemd/sd-bus/test-bus-gvariant.c
+++ b/src/libsystemd/sd-bus/test-bus-gvariant.c
@@ -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);
}
diff --git a/src/libsystemd/sd-bus/test-bus-introspect.c b/src/libsystemd/sd-bus/test-bus-introspect.c
index 4425cfae26..8dee936768 100644
--- a/src/libsystemd/sd-bus/test-bus-introspect.c
+++ b/src/libsystemd/sd-bus/test-bus-introspect.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd/sd-bus/test-bus-marshal.c b/src/libsystemd/sd-bus/test-bus-marshal.c
index 221dbd35cc..ebf55e873c 100644
--- a/src/libsystemd/sd-bus/test-bus-marshal.c
+++ b/src/libsystemd/sd-bus/test-bus-marshal.c
@@ -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);
diff --git a/src/libsystemd/sd-bus/test-bus-match.c b/src/libsystemd/sd-bus/test-bus-match.c
index 8fd9d03ddf..47b45647c2 100644
--- a/src/libsystemd/sd-bus/test-bus-match.c
+++ b/src/libsystemd/sd-bus/test-bus-match.c
@@ -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);
diff --git a/src/libsystemd/sd-bus/test-bus-objects.c b/src/libsystemd/sd-bus/test-bus-objects.c
index 0b33ab7a3a..58ef8b6389 100644
--- a/src/libsystemd/sd-bus/test-bus-objects.c
+++ b/src/libsystemd/sd-bus/test-bus-objects.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd/sd-bus/test-bus-server.c b/src/libsystemd/sd-bus/test-bus-server.c
index b6272efc30..245f5707e1 100644
--- a/src/libsystemd/sd-bus/test-bus-server.c
+++ b/src/libsystemd/sd-bus/test-bus-server.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd/sd-bus/test-bus-signature.c b/src/libsystemd/sd-bus/test-bus-signature.c
index 4f4fd093bf..aa6160d1c9 100644
--- a/src/libsystemd/sd-bus/test-bus-signature.c
+++ b/src/libsystemd/sd-bus/test-bus-signature.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd/sd-bus/test-bus-track.c b/src/libsystemd/sd-bus/test-bus-track.c
index 5f5661cb33..320e8347f4 100644
--- a/src/libsystemd/sd-bus/test-bus-track.c
+++ b/src/libsystemd/sd-bus/test-bus-track.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd/sd-daemon/sd-daemon.c b/src/libsystemd/sd-daemon/sd-daemon.c
index c73647921c..64a74929bf 100644
--- a/src/libsystemd/sd-daemon/sd-daemon.c
+++ b/src/libsystemd/sd-daemon/sd-daemon.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd/sd-device/device-enumerator-private.h b/src/libsystemd/sd-device/device-enumerator-private.h
index eb06f9542d..5a46ec5f2b 100644
--- a/src/libsystemd/sd-device/device-enumerator-private.h
+++ b/src/libsystemd/sd-device/device-enumerator-private.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/libsystemd/sd-device/device-enumerator.c b/src/libsystemd/sd-device/device-enumerator.c
index ebb8b2d160..cd9ec042bf 100644
--- a/src/libsystemd/sd-device/device-enumerator.c
+++ b/src/libsystemd/sd-device/device-enumerator.c
@@ -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) {
diff --git a/src/libsystemd/sd-device/device-internal.h b/src/libsystemd/sd-device/device-internal.h
index 0505a27304..6be84f9575 100644
--- a/src/libsystemd/sd-device/device-internal.h
+++ b/src/libsystemd/sd-device/device-internal.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/libsystemd/sd-device/device-private.c b/src/libsystemd/sd-device/device-private.c
index 8839c3266c..77f0f4b2ee 100644
--- a/src/libsystemd/sd-device/device-private.c
+++ b/src/libsystemd/sd-device/device-private.c
@@ -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);
diff --git a/src/libsystemd/sd-device/device-private.h b/src/libsystemd/sd-device/device-private.h
index 29b3e155fb..02d93c98f9 100644
--- a/src/libsystemd/sd-device/device-private.h
+++ b/src/libsystemd/sd-device/device-private.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/libsystemd/sd-device/device-util.h b/src/libsystemd/sd-device/device-util.h
index 5b42e11de6..d55b810d2a 100644
--- a/src/libsystemd/sd-device/device-util.h
+++ b/src/libsystemd/sd-device/device-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/libsystemd/sd-device/sd-device.c b/src/libsystemd/sd-device/sd-device.c
index 3b5a04d1c3..a96d7445ce 100644
--- a/src/libsystemd/sd-device/sd-device.c
+++ b/src/libsystemd/sd-device/sd-device.c
@@ -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;
diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c
index 2c5c2ebb4d..a5f3e854b1 100644
--- a/src/libsystemd/sd-event/sd-event.c
+++ b/src/libsystemd/sd-event/sd-event.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd/sd-event/test-event.c b/src/libsystemd/sd-event/test-event.c
index 1a581ae23e..7f32838c6f 100644
--- a/src/libsystemd/sd-event/test-event.c
+++ b/src/libsystemd/sd-event/test-event.c
@@ -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);
diff --git a/src/libsystemd/sd-hwdb/hwdb-internal.h b/src/libsystemd/sd-hwdb/hwdb-internal.h
index 2f4934ae8b..36dae8c755 100644
--- a/src/libsystemd/sd-hwdb/hwdb-internal.h
+++ b/src/libsystemd/sd-hwdb/hwdb-internal.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/libsystemd/sd-hwdb/hwdb-util.h b/src/libsystemd/sd-hwdb/hwdb-util.h
index 5e21e5008b..b3053524e7 100644
--- a/src/libsystemd/sd-hwdb/hwdb-util.h
+++ b/src/libsystemd/sd-hwdb/hwdb-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/libsystemd/sd-hwdb/sd-hwdb.c b/src/libsystemd/sd-hwdb/sd-hwdb.c
index f8246eaa70..9418e8cf38 100644
--- a/src/libsystemd/sd-hwdb/sd-hwdb.c
+++ b/src/libsystemd/sd-hwdb/sd-hwdb.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd/sd-id128/id128-util.c b/src/libsystemd/sd-id128/id128-util.c
index f5c017ff8b..5541e8d47e 100644
--- a/src/libsystemd/sd-id128/id128-util.c
+++ b/src/libsystemd/sd-id128/id128-util.c
@@ -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;
diff --git a/src/libsystemd/sd-id128/id128-util.h b/src/libsystemd/sd-id128/id128-util.h
index 6b3855acbb..9f3340e581 100644
--- a/src/libsystemd/sd-id128/id128-util.h
+++ b/src/libsystemd/sd-id128/id128-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/libsystemd/sd-id128/sd-id128.c b/src/libsystemd/sd-id128/sd-id128.c
index d44d75ece8..561bcdf4f1 100644
--- a/src/libsystemd/sd-id128/sd-id128.c
+++ b/src/libsystemd/sd-id128/sd-id128.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd/sd-login/sd-login.c b/src/libsystemd/sd-login/sd-login.c
index 5fb7fd99d5..e8adaa6823 100644
--- a/src/libsystemd/sd-login/sd-login.c
+++ b/src/libsystemd/sd-login/sd-login.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd/sd-login/test-login.c b/src/libsystemd/sd-login/test-login.c
index 02a73f9189..559529ecf6 100644
--- a/src/libsystemd/sd-login/test-login.c
+++ b/src/libsystemd/sd-login/test-login.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd/sd-netlink/local-addresses.c b/src/libsystemd/sd-netlink/local-addresses.c
index d82ca806a4..23acec4061 100644
--- a/src/libsystemd/sd-netlink/local-addresses.c
+++ b/src/libsystemd/sd-netlink/local-addresses.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd/sd-netlink/local-addresses.h b/src/libsystemd/sd-netlink/local-addresses.h
index 18d71e797e..f722242821 100644
--- a/src/libsystemd/sd-netlink/local-addresses.h
+++ b/src/libsystemd/sd-netlink/local-addresses.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/libsystemd/sd-netlink/netlink-internal.h b/src/libsystemd/sd-netlink/netlink-internal.h
index dcfb080ad3..f045ff67ca 100644
--- a/src/libsystemd/sd-netlink/netlink-internal.h
+++ b/src/libsystemd/sd-netlink/netlink-internal.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/libsystemd/sd-netlink/netlink-message.c b/src/libsystemd/sd-netlink/netlink-message.c
index ac0427f949..c88754540e 100644
--- a/src/libsystemd/sd-netlink/netlink-message.c
+++ b/src/libsystemd/sd-netlink/netlink-message.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd/sd-netlink/netlink-socket.c b/src/libsystemd/sd-netlink/netlink-socket.c
index 129bfd2d80..22be94382a 100644
--- a/src/libsystemd/sd-netlink/netlink-socket.c
+++ b/src/libsystemd/sd-netlink/netlink-socket.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd/sd-netlink/netlink-types.c b/src/libsystemd/sd-netlink/netlink-types.c
index 979dc6824f..f8be296d37 100644
--- a/src/libsystemd/sd-netlink/netlink-types.c
+++ b/src/libsystemd/sd-netlink/netlink-types.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
@@ -36,6 +37,10 @@
#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 = {
diff --git a/src/libsystemd/sd-netlink/netlink-types.h b/src/libsystemd/sd-netlink/netlink-types.h
index ae65c1d8e4..57b46339f9 100644
--- a/src/libsystemd/sd-netlink/netlink-types.h
+++ b/src/libsystemd/sd-netlink/netlink-types.h
@@ -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;
diff --git a/src/libsystemd/sd-netlink/netlink-util.c b/src/libsystemd/sd-netlink/netlink-util.c
index 6b660b7dbf..b32fad271a 100644
--- a/src/libsystemd/sd-netlink/netlink-util.c
+++ b/src/libsystemd/sd-netlink/netlink-util.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd/sd-netlink/netlink-util.h b/src/libsystemd/sd-netlink/netlink-util.h
index d2fb651204..c804f5514c 100644
--- a/src/libsystemd/sd-netlink/netlink-util.h
+++ b/src/libsystemd/sd-netlink/netlink-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/libsystemd/sd-netlink/rtnl-message.c b/src/libsystemd/sd-netlink/rtnl-message.c
index d851ac228f..24345c4298 100644
--- a/src/libsystemd/sd-netlink/rtnl-message.c
+++ b/src/libsystemd/sd-netlink/rtnl-message.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd/sd-netlink/sd-netlink.c b/src/libsystemd/sd-netlink/sd-netlink.c
index 77f4d5b635..924b0c954f 100644
--- a/src/libsystemd/sd-netlink/sd-netlink.c
+++ b/src/libsystemd/sd-netlink/sd-netlink.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd/sd-netlink/test-local-addresses.c b/src/libsystemd/sd-netlink/test-local-addresses.c
index e0e28cc0cc..bb195b9de9 100644
--- a/src/libsystemd/sd-netlink/test-local-addresses.c
+++ b/src/libsystemd/sd-netlink/test-local-addresses.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd/sd-netlink/test-netlink.c b/src/libsystemd/sd-netlink/test-netlink.c
index 83f0395dfe..73e5af0060 100644
--- a/src/libsystemd/sd-netlink/test-netlink.c
+++ b/src/libsystemd/sd-netlink/test-netlink.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd/sd-network/network-util.c b/src/libsystemd/sd-network/network-util.c
index a0d9b5f1a4..0957d593e0 100644
--- a/src/libsystemd/sd-network/network-util.c
+++ b/src/libsystemd/sd-network/network-util.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd/sd-network/network-util.h b/src/libsystemd/sd-network/network-util.h
index 26780dce28..9c6b3fc0f0 100644
--- a/src/libsystemd/sd-network/network-util.h
+++ b/src/libsystemd/sd-network/network-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/libsystemd/sd-network/sd-network.c b/src/libsystemd/sd-network/sd-network.c
index 41b97ca1f3..8f4814019e 100644
--- a/src/libsystemd/sd-network/sd-network.c
+++ b/src/libsystemd/sd-network/sd-network.c
@@ -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;
diff --git a/src/libsystemd/sd-path/sd-path.c b/src/libsystemd/sd-path/sd-path.c
index 6570d01392..cd76e3507c 100644
--- a/src/libsystemd/sd-path/sd-path.c
+++ b/src/libsystemd/sd-path/sd-path.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libsystemd/sd-resolve/sd-resolve.c b/src/libsystemd/sd-resolve/sd-resolve.c
index 12fae65e6b..be3748e3ce 100644
--- a/src/libsystemd/sd-resolve/sd-resolve.c
+++ b/src/libsystemd/sd-resolve/sd-resolve.c
@@ -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);
}
diff --git a/src/libsystemd/sd-resolve/test-resolve.c b/src/libsystemd/sd-resolve/test-resolve.c
index 1be1a7f8a7..752eb15228 100644
--- a/src/libsystemd/sd-resolve/test-resolve.c
+++ b/src/libsystemd/sd-resolve/test-resolve.c
@@ -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");
diff --git a/src/libsystemd/sd-utf8/sd-utf8.c b/src/libsystemd/sd-utf8/sd-utf8.c
index 33a5a04ea1..b8db7eb093 100644
--- a/src/libsystemd/sd-utf8/sd-utf8.c
+++ b/src/libsystemd/sd-utf8/sd-utf8.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libudev/libudev-device-internal.h b/src/libudev/libudev-device-internal.h
index 0e9af8ec09..445acd91a7 100644
--- a/src/libudev/libudev-device-internal.h
+++ b/src/libudev/libudev-device-internal.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/libudev/libudev-device-private.c b/src/libudev/libudev-device-private.c
index 2aae0726c1..868926e72b 100644
--- a/src/libudev/libudev-device-private.c
+++ b/src/libudev/libudev-device-private.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libudev/libudev-device.c b/src/libudev/libudev-device.c
index c5f36725dc..82df426491 100644
--- a/src/libudev/libudev-device.c
+++ b/src/libudev/libudev-device.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libudev/libudev-enumerate.c b/src/libudev/libudev-enumerate.c
index ea80c750c9..271880075e 100644
--- a/src/libudev/libudev-enumerate.c
+++ b/src/libudev/libudev-enumerate.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libudev/libudev-hwdb.c b/src/libudev/libudev-hwdb.c
index 4bdc37d973..d2665278c1 100644
--- a/src/libudev/libudev-hwdb.c
+++ b/src/libudev/libudev-hwdb.c
@@ -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);
}
/**
diff --git a/src/libudev/libudev-list.c b/src/libudev/libudev-list.c
index 0d51322a15..29fbdbd450 100644
--- a/src/libudev/libudev-list.c
+++ b/src/libudev/libudev-list.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libudev/libudev-monitor.c b/src/libudev/libudev-monitor.c
index 32f2154b36..ca14373e19 100644
--- a/src/libudev/libudev-monitor.c
+++ b/src/libudev/libudev-monitor.c
@@ -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);
}
/**
diff --git a/src/libudev/libudev-private.h b/src/libudev/libudev-private.h
index 52c5075110..76730cc055 100644
--- a/src/libudev/libudev-private.h
+++ b/src/libudev/libudev-private.h
@@ -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);
diff --git a/src/libudev/libudev-queue.c b/src/libudev/libudev-queue.c
index f3143d4615..b941afb773 100644
--- a/src/libudev/libudev-queue.c
+++ b/src/libudev/libudev-queue.c
@@ -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);
}
/**
diff --git a/src/libudev/libudev-util.c b/src/libudev/libudev-util.c
index 1d73d8f090..977caad86d 100644
--- a/src/libudev/libudev-util.c
+++ b/src/libudev/libudev-util.c
@@ -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.
diff --git a/src/libudev/libudev.c b/src/libudev/libudev.c
index ce8d5b5760..64904c5ffa 100644
--- a/src/libudev/libudev.c
+++ b/src/libudev/libudev.c
@@ -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);
}
/**
diff --git a/src/libudev/libudev.h b/src/libudev/libudev.h
index 3f6d0ed16c..be465a0043 100644
--- a/src/libudev/libudev.h
+++ b/src/libudev/libudev.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/libudev/libudev.pc.in b/src/libudev/libudev.pc.in
index 1becae45fd..69f5c6463e 100644
--- a/src/libudev/libudev.pc.in
+++ b/src/libudev/libudev.pc.in
@@ -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/src/libudev/libudev.sym b/src/libudev/libudev.sym
index 76726fca77..1e8dbfa056 100644
--- a/src/libudev/libudev.sym
+++ b/src/libudev/libudev.sym
@@ -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/libudev/meson.build b/src/libudev/meson.build
index 57d678fa97..30d6721b60 100644
--- a/src/libudev/meson.build
+++ b/src/libudev/meson.build
@@ -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
diff --git a/src/locale/keymap-util.c b/src/locale/keymap-util.c
index b71091f706..2d788106bb 100644
--- a/src/locale/keymap-util.c
+++ b/src/locale/keymap-util.c
@@ -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)
diff --git a/src/locale/keymap-util.h b/src/locale/keymap-util.h
index 20ef2a4a34..371bbf2622 100644
--- a/src/locale/keymap-util.h
+++ b/src/locale/keymap-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/locale/localectl.c b/src/locale/localectl.c
index 0bd18a5c0b..f09fe42626 100644
--- a/src/locale/localectl.c
+++ b/src/locale/localectl.c
@@ -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;
diff --git a/src/locale/localed.c b/src/locale/localed.c
index 3c0c167dcf..3e3f03e046 100644
--- a/src/locale/localed.c
+++ b/src/locale/localed.c
@@ -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,
diff --git a/src/locale/meson.build b/src/locale/meson.build
index e9de6089f3..dca2c51d2f 100644
--- a/src/locale/meson.build
+++ b/src/locale/meson.build
@@ -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
diff --git a/src/locale/org.freedesktop.locale1.conf b/src/locale/org.freedesktop.locale1.conf
index 79d0ecd2bb..d74cbc11ab 100644
--- a/src/locale/org.freedesktop.locale1.conf
+++ b/src/locale/org.freedesktop.locale1.conf
@@ -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
diff --git a/src/locale/org.freedesktop.locale1.policy.in b/src/locale/org.freedesktop.locale1.policy.in
index df63845e9b..4c1c34da09 100644
--- a/src/locale/org.freedesktop.locale1.policy.in
+++ b/src/locale/org.freedesktop.locale1.policy.in
@@ -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>
diff --git a/src/locale/org.freedesktop.locale1.service b/src/locale/org.freedesktop.locale1.service
index 025f9a0fc2..b15d39540c 100644
--- a/src/locale/org.freedesktop.locale1.service
+++ b/src/locale/org.freedesktop.locale1.service
@@ -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/src/locale/test-keymap-util.c b/src/locale/test-keymap-util.c
index 2adda3da2b..fa26a0294e 100644
--- a/src/locale/test-keymap-util.c
+++ b/src/locale/test-keymap-util.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/login/70-power-switch.rules b/src/login/70-power-switch.rules
index 394a80f1f8..d69e65b3d5 100644
--- a/src/login/70-power-switch.rules
+++ b/src/login/70-power-switch.rules
@@ -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/src/login/70-uaccess.rules b/src/login/70-uaccess.rules
index 50dcd2e275..f2c838f353 100644
--- a/src/login/70-uaccess.rules
+++ b/src/login/70-uaccess.rules
@@ -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"
diff --git a/src/login/71-seat.rules.in b/src/login/71-seat.rules.in
index de55c9a4ec..0db46adc84 100644
--- a/src/login/71-seat.rules.in
+++ b/src/login/71-seat.rules.in
@@ -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/src/login/73-seat-late.rules.in b/src/login/73-seat-late.rules.in
index 901df750fd..d2546c8ee9 100644
--- a/src/login/73-seat-late.rules.in
+++ b/src/login/73-seat-late.rules.in
@@ -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/src/login/inhibit.c b/src/login/inhibit.c
index 7e5a093698..7b9e3f0f6e 100644
--- a/src/login/inhibit.c
+++ b/src/login/inhibit.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/login/loginctl.c b/src/login/loginctl.c
index a63174c093..dfcaff6195 100644
--- a/src/login/loginctl.c
+++ b/src/login/loginctl.c
@@ -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();
diff --git a/src/login/logind-acl.c b/src/login/logind-acl.c
index 1b69f4b9ca..d785f67ca3 100644
--- a/src/login/logind-acl.c
+++ b/src/login/logind-acl.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/login/logind-acl.h b/src/login/logind-acl.h
index 606005a6f1..36690dabd3 100644
--- a/src/login/logind-acl.h
+++ b/src/login/logind-acl.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/login/logind-action.c b/src/login/logind-action.c
index 91225a5363..852ea9f949 100644
--- a/src/login/logind-action.c
+++ b/src/login/logind-action.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/login/logind-action.h b/src/login/logind-action.h
index fb40ae48d2..8c31ec42be 100644
--- a/src/login/logind-action.h
+++ b/src/login/logind-action.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/login/logind-button.c b/src/login/logind-button.c
index e53dd63c29..94945f0bcb 100644
--- a/src/login/logind-button.c
+++ b/src/login/logind-button.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/login/logind-button.h b/src/login/logind-button.h
index f30cba2959..b47eb47571 100644
--- a/src/login/logind-button.h
+++ b/src/login/logind-button.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/login/logind-core.c b/src/login/logind-core.c
index ba538559f9..adeba746f5 100644
--- a/src/login/logind-core.c
+++ b/src/login/logind-core.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
index 2342375f20..ae36ececb5 100644
--- a/src/login/logind-dbus.c
+++ b/src/login/logind-dbus.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
@@ -50,27 +51,47 @@
#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;
diff --git a/src/login/logind-device.c b/src/login/logind-device.c
index 6537fa04bf..758ba73c2b 100644
--- a/src/login/logind-device.c
+++ b/src/login/logind-device.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/login/logind-device.h b/src/login/logind-device.h
index 927068e00a..d0911560dd 100644
--- a/src/login/logind-device.h
+++ b/src/login/logind-device.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/login/logind-gperf.gperf b/src/login/logind-gperf.gperf
index aca464427b..ee62db63a5 100644
--- a/src/login/logind-gperf.gperf
+++ b/src/login/logind-gperf.gperf
@@ -1,4 +1,7 @@
%{
+#if __GNUC__ >= 7
+_Pragma("GCC diagnostic ignored \"-Wimplicit-fallthrough\"")
+#endif
#include <stddef.h>
#include "conf-parser.h"
#include "logind.h"
diff --git a/src/login/logind-inhibit.c b/src/login/logind-inhibit.c
index 1e6f383738..8a6487ea45 100644
--- a/src/login/logind-inhibit.c
+++ b/src/login/logind-inhibit.c
@@ -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;
diff --git a/src/login/logind-inhibit.h b/src/login/logind-inhibit.h
index 70de199c60..cc6c62ab18 100644
--- a/src/login/logind-inhibit.h
+++ b/src/login/logind-inhibit.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/login/logind-seat-dbus.c b/src/login/logind-seat-dbus.c
index f934a5326a..8e4e4efc81 100644
--- a/src/login/logind-seat-dbus.c
+++ b/src/login/logind-seat-dbus.c
@@ -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;
}
diff --git a/src/login/logind-seat.c b/src/login/logind-seat.c
index 64a622307e..b99e7abf91 100644
--- a/src/login/logind-seat.c
+++ b/src/login/logind-seat.c
@@ -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",
diff --git a/src/login/logind-seat.h b/src/login/logind-seat.h
index 9a4fbc5bc5..5427ac21c8 100644
--- a/src/login/logind-seat.h
+++ b/src/login/logind-seat.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/login/logind-session-dbus.c b/src/login/logind-session-dbus.c
index 649f3c155e..8264a42fd4 100644
--- a/src/login/logind-session-dbus.c
+++ b/src/login/logind-session-dbus.c
@@ -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;
}
diff --git a/src/login/logind-session-device.c b/src/login/logind-session-device.c
index 05af2045d2..067e67a93d 100644
--- a/src/login/logind-session-device.c
+++ b/src/login/logind-session-device.c
@@ -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) {
diff --git a/src/login/logind-session-device.h b/src/login/logind-session-device.h
index 83aef1e18c..a1cf17af92 100644
--- a/src/login/logind-session-device.h
+++ b/src/login/logind-session-device.h
@@ -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);
};
diff --git a/src/login/logind-session.c b/src/login/logind-session.c
index 736f7d9fc1..c4bde80c0c 100644
--- a/src/login/logind-session.c
+++ b/src/login/logind-session.c
@@ -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,
diff --git a/src/login/logind-session.h b/src/login/logind-session.h
index 12b9d86f55..8491832402 100644
--- a/src/login/logind-session.h
+++ b/src/login/logind-session.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/login/logind-user-dbus.c b/src/login/logind-user-dbus.c
index 987c63014f..9fca5ce0cd 100644
--- a/src/login/logind-user-dbus.c
+++ b/src/login/logind-user-dbus.c
@@ -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;
diff --git a/src/login/logind-user.c b/src/login/logind-user.c
index 068bc455b5..94e250b94a 100644
--- a/src/login/logind-user.c
+++ b/src/login/logind-user.c
@@ -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 "alloc-util.h"
#include "bus-common-errors.h"
@@ -141,7 +143,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;
@@ -149,7 +151,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"
@@ -182,18 +185,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)
@@ -202,12 +205,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))
@@ -216,12 +219,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)
@@ -230,12 +233,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)
@@ -244,12 +247,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)
@@ -258,11 +261,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);
@@ -334,7 +337,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");
@@ -425,12 +428,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;
}
@@ -541,7 +543,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
@@ -552,7 +554,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;
}
@@ -617,7 +619,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;
diff --git a/src/login/logind-user.h b/src/login/logind-user.h
index 4f0966dc77..ad1686ffc5 100644
--- a/src/login/logind-user.h
+++ b/src/login/logind-user.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/login/logind-utmp.c b/src/login/logind-utmp.c
index 00c4cbcf4f..ab35d0e326 100644
--- a/src/login/logind-utmp.c
+++ b/src/login/logind-utmp.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/login/logind.c b/src/login/logind.c
index 6046596684..49ca367e18 100644
--- a/src/login/logind.c
+++ b/src/login/logind.c
@@ -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) {
diff --git a/src/login/logind.h b/src/login/logind.h
index 2a8c663a7d..8262367135 100644
--- a/src/login/logind.h
+++ b/src/login/logind.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/login/meson.build b/src/login/meson.build
index d0723f134f..33f9ed48cc 100644
--- a/src/login/meson.build
+++ b/src/login/meson.build
@@ -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)
diff --git a/src/login/org.freedesktop.login1.conf b/src/login/org.freedesktop.login1.conf
index 27aac0dd7c..d842411781 100644
--- a/src/login/org.freedesktop.login1.conf
+++ b/src/login/org.freedesktop.login1.conf
@@ -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
diff --git a/src/login/org.freedesktop.login1.policy.in b/src/login/org.freedesktop.login1.policy.in
index 3e8a9bbe3f..47162022d2 100644
--- a/src/login/org.freedesktop.login1.policy.in
+++ b/src/login/org.freedesktop.login1.policy.in
@@ -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>
@@ -102,8 +104,8 @@
</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>
@@ -112,8 +114,8 @@
</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>
@@ -122,8 +124,8 @@
</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>
@@ -132,8 +134,8 @@
</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>
@@ -143,8 +145,8 @@
</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>
@@ -153,8 +155,8 @@
</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>
@@ -164,8 +166,8 @@
</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>
@@ -175,8 +177,8 @@
</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>
@@ -186,8 +188,8 @@
</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>
@@ -197,8 +199,8 @@
</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>
@@ -208,8 +210,8 @@
</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>
@@ -219,8 +221,8 @@
</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>
@@ -230,8 +232,8 @@
</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>
@@ -241,8 +243,8 @@
</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>
@@ -252,8 +254,8 @@
</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>
@@ -262,8 +264,8 @@
</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>
@@ -273,8 +275,8 @@
</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>
@@ -284,8 +286,8 @@
</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>
@@ -294,8 +296,8 @@
</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>
@@ -305,8 +307,8 @@
</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>
@@ -316,8 +318,8 @@
</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>
@@ -326,8 +328,8 @@
</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>
@@ -336,8 +338,8 @@
</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>
@@ -346,8 +348,8 @@
</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>
diff --git a/src/login/org.freedesktop.login1.service b/src/login/org.freedesktop.login1.service
index 762dae2bb3..68f1ed0f48 100644
--- a/src/login/org.freedesktop.login1.service
+++ b/src/login/org.freedesktop.login1.service
@@ -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/src/login/pam_systemd.c b/src/login/pam_systemd.c
index 730e0f1b5a..246bbddeee 100644
--- a/src/login/pam_systemd.c
+++ b/src/login/pam_systemd.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/login/pam_systemd.sym b/src/login/pam_systemd.sym
index 23ff75f688..d48b9e8ccd 100644
--- a/src/login/pam_systemd.sym
+++ b/src/login/pam_systemd.sym
@@ -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/login/sysfs-show.c b/src/login/sysfs-show.c
index 29785e2f11..ca8bfa2677 100644
--- a/src/login/sysfs-show.c
+++ b/src/login/sysfs-show.c
@@ -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)");
diff --git a/src/login/sysfs-show.h b/src/login/sysfs-show.h
index 3e94bc3ed5..15c902cc3a 100644
--- a/src/login/sysfs-show.h
+++ b/src/login/sysfs-show.h
@@ -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);
diff --git a/src/login/test-inhibit.c b/src/login/test-inhibit.c
index a3cf9d293b..ad4700f328 100644
--- a/src/login/test-inhibit.c
+++ b/src/login/test-inhibit.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/login/test-login-shared.c b/src/login/test-login-shared.c
index 3d233f017c..bf08b6ee9f 100644
--- a/src/login/test-login-shared.c
+++ b/src/login/test-login-shared.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/login/test-login-tables.c b/src/login/test-login-tables.c
index 4fbc893a9a..7772f4b854 100644
--- a/src/login/test-login-tables.c
+++ b/src/login/test-login-tables.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd
diff --git a/src/machine-id-setup/machine-id-setup-main.c b/src/machine-id-setup/machine-id-setup-main.c
index 2244b1cc76..de6d869d30 100644
--- a/src/machine-id-setup/machine-id-setup-main.c
+++ b/src/machine-id-setup/machine-id-setup-main.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/machine/image-dbus.c b/src/machine/image-dbus.c
index 18e0e34896..10d1b06016 100644
--- a/src/machine/image-dbus.c
+++ b/src/machine/image-dbus.c
@@ -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;
}
diff --git a/src/machine/image-dbus.h b/src/machine/image-dbus.h
index bc8a6c3400..119c69c25a 100644
--- a/src/machine/image-dbus.h
+++ b/src/machine/image-dbus.h
@@ -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);
diff --git a/src/machine/machine-dbus.c b/src/machine/machine-dbus.c
index 36568b65ef..3761267b57 100644
--- a/src/machine/machine-dbus.c
+++ b/src/machine/machine-dbus.c
@@ -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;
}
diff --git a/src/machine/machine-dbus.h b/src/machine/machine-dbus.h
index 2aa7b4ce06..f8c931fc38 100644
--- a/src/machine/machine-dbus.h
+++ b/src/machine/machine-dbus.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/machine/machine.c b/src/machine/machine.c
index 399e41f870..7375d83a44 100644
--- a/src/machine/machine.c
+++ b/src/machine/machine.c
@@ -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. */
diff --git a/src/machine/machine.h b/src/machine/machine.h
index 6bdb204ed6..1ee82ffe81 100644
--- a/src/machine/machine.h
+++ b/src/machine/machine.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/machine/machinectl.c b/src/machine/machinectl.c
index 2447e734a2..c435bb9b5a 100644
--- a/src/machine/machinectl.c
+++ b/src/machine/machinectl.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
@@ -52,15 +53,16 @@
#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();
diff --git a/src/machine/machined-dbus.c b/src/machine/machined-dbus.c
index c9b92d2765..330d6b3d6e 100644
--- a/src/machine/machined-dbus.c
+++ b/src/machine/machined-dbus.c
@@ -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),
diff --git a/src/machine/machined.c b/src/machine/machined.c
index d8ddbec8b9..d481020893 100644
--- a/src/machine/machined.c
+++ b/src/machine/machined.c
@@ -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);
diff --git a/src/machine/machined.h b/src/machine/machined.h
index 7b9b148044..b00c4c182e 100644
--- a/src/machine/machined.h
+++ b/src/machine/machined.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/machine/meson.build b/src/machine/meson.build
index 693503da53..7ea5d9de80 100644
--- a/src/machine/meson.build
+++ b/src/machine/meson.build
@@ -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
diff --git a/src/machine/operation.c b/src/machine/operation.c
index 9b2d13dde1..6aba1a2af4 100644
--- a/src/machine/operation.c
+++ b/src/machine/operation.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/machine/operation.h b/src/machine/operation.h
index 9831b123d7..361bf1fb44 100644
--- a/src/machine/operation.h
+++ b/src/machine/operation.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/machine/org.freedesktop.machine1.conf b/src/machine/org.freedesktop.machine1.conf
index daa365a9dd..73b7e07103 100644
--- a/src/machine/org.freedesktop.machine1.conf
+++ b/src/machine/org.freedesktop.machine1.conf
@@ -122,6 +122,18 @@
<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"
@@ -206,6 +218,18 @@
<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"/>
diff --git a/src/machine/org.freedesktop.machine1.policy.in b/src/machine/org.freedesktop.machine1.policy.in
index 69f78a5c25..eeeeb4c0f8 100644
--- a/src/machine/org.freedesktop.machine1.policy.in
+++ b/src/machine/org.freedesktop.machine1.policy.in
@@ -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>
diff --git a/src/machine/org.freedesktop.machine1.service b/src/machine/org.freedesktop.machine1.service
index d3dc99852b..d07bcae6eb 100644
--- a/src/machine/org.freedesktop.machine1.service
+++ b/src/machine/org.freedesktop.machine1.service
@@ -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/src/machine/test-machine-tables.c b/src/machine/test-machine-tables.c
index f851a4d37d..fc08785f14 100644
--- a/src/machine/test-machine-tables.c
+++ b/src/machine/test-machine-tables.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd
diff --git a/src/modules-load/modules-load.c b/src/modules-load/modules-load.c
index 6efebcd94f..c5f57685a2 100644
--- a/src/modules-load/modules-load.c
+++ b/src/modules-load/modules-load.c
@@ -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;
diff --git a/src/mount/mount-tool.c b/src/mount/mount-tool.c
index 64438cd6d7..da3647e7e2 100644
--- a/src/mount/mount-tool.c
+++ b/src/mount/mount-tool.c
@@ -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);
diff --git a/src/network/meson.build b/src/network/meson.build
index 38c2220e8b..f97484eb26 100644
--- a/src/network/meson.build
+++ b/src/network/meson.build
@@ -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],
diff --git a/src/network/netdev/bond.c b/src/network/netdev/bond.c
index 19b0e8da40..f6c9cebda3 100644
--- a/src/network/netdev/bond.c
+++ b/src/network/netdev/bond.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/network/netdev/bond.h b/src/network/netdev/bond.h
index fb88b538ed..31be5b83a3 100644
--- a/src/network/netdev/bond.h
+++ b/src/network/netdev/bond.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/network/netdev/bridge.c b/src/network/netdev/bridge.c
index 16fff78bf8..00d4d30a67 100644
--- a/src/network/netdev/bridge.c
+++ b/src/network/netdev/bridge.c
@@ -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 = {
diff --git a/src/network/netdev/bridge.h b/src/network/netdev/bridge.h
index b303cfd3f3..7fc993bb8d 100644
--- a/src/network/netdev/bridge.h
+++ b/src/network/netdev/bridge.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/network/netdev/dummy.c b/src/network/netdev/dummy.c
index 5e6e162931..c55009092a 100644
--- a/src/network/netdev/dummy.c
+++ b/src/network/netdev/dummy.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/network/netdev/dummy.h b/src/network/netdev/dummy.h
index a908400459..abfb7c71ef 100644
--- a/src/network/netdev/dummy.h
+++ b/src/network/netdev/dummy.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/network/netdev/geneve.c b/src/network/netdev/geneve.c
index e71ea58a10..1d50963e04 100644
--- a/src/network/netdev/geneve.c
+++ b/src/network/netdev/geneve.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/network/netdev/geneve.h b/src/network/netdev/geneve.h
index bde28bac55..9aec8f505b 100644
--- a/src/network/netdev/geneve.h
+++ b/src/network/netdev/geneve.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/network/netdev/ipvlan.c b/src/network/netdev/ipvlan.c
index 3b5c30fed8..df9487418b 100644
--- a/src/network/netdev/ipvlan.c
+++ b/src/network/netdev/ipvlan.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/network/netdev/ipvlan.h b/src/network/netdev/ipvlan.h
index 7d7d0184f1..cb43db4348 100644
--- a/src/network/netdev/ipvlan.h
+++ b/src/network/netdev/ipvlan.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/network/netdev/macvlan.c b/src/network/netdev/macvlan.c
index 93f650def5..9924e16055 100644
--- a/src/network/netdev/macvlan.c
+++ b/src/network/netdev/macvlan.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/network/netdev/macvlan.h b/src/network/netdev/macvlan.h
index 118d55658c..7d6d346438 100644
--- a/src/network/netdev/macvlan.h
+++ b/src/network/netdev/macvlan.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/network/netdev/netdev-gperf.gperf b/src/network/netdev/netdev-gperf.gperf
index 002efd7e9c..628e6648b7 100644
--- a/src/network/netdev/netdev-gperf.gperf
+++ b/src/network/netdev/netdev-gperf.gperf
@@ -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)
diff --git a/src/network/netdev/netdev.c b/src/network/netdev/netdev.c
index 0e1a7d1335..5530760e19 100644
--- a/src/network/netdev/netdev.c
+++ b/src/network/netdev/netdev.c
@@ -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;
diff --git a/src/network/netdev/netdev.h b/src/network/netdev/netdev.h
index a961e2ac3b..ec65251464 100644
--- a/src/network/netdev/netdev.h
+++ b/src/network/netdev/netdev.h
@@ -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;
diff --git a/src/network/netdev/tunnel.c b/src/network/netdev/tunnel.c
index 64d87e5e07..8d6d54d567 100644
--- a/src/network/netdev/tunnel.c
+++ b/src/network/netdev/tunnel.c
@@ -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);
diff --git a/src/network/netdev/tunnel.h b/src/network/netdev/tunnel.h
index 53690d9075..67f8fe35c7 100644
--- a/src/network/netdev/tunnel.h
+++ b/src/network/netdev/tunnel.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/network/netdev/tuntap.c b/src/network/netdev/tuntap.c
index 3d62808842..4597a7feeb 100644
--- a/src/network/netdev/tuntap.c
+++ b/src/network/netdev/tuntap.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/network/netdev/tuntap.h b/src/network/netdev/tuntap.h
index 95d3fcf1e9..dbfa3de180 100644
--- a/src/network/netdev/tuntap.h
+++ b/src/network/netdev/tuntap.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/network/netdev/vcan.c b/src/network/netdev/vcan.c
index 7f56702938..780cf91143 100644
--- a/src/network/netdev/vcan.c
+++ b/src/network/netdev/vcan.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/network/netdev/vcan.h b/src/network/netdev/vcan.h
index 00838b7675..6c4d68e694 100644
--- a/src/network/netdev/vcan.h
+++ b/src/network/netdev/vcan.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/network/netdev/veth.c b/src/network/netdev/veth.c
index 350b59bf03..9220b3200f 100644
--- a/src/network/netdev/veth.c
+++ b/src/network/netdev/veth.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/network/netdev/veth.h b/src/network/netdev/veth.h
index b00ce476e8..bb2139ff57 100644
--- a/src/network/netdev/veth.h
+++ b/src/network/netdev/veth.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/network/netdev/vlan.c b/src/network/netdev/vlan.c
index 6f41633ead..3a0100d7e6 100644
--- a/src/network/netdev/vlan.c
+++ b/src/network/netdev/vlan.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/network/netdev/vlan.h b/src/network/netdev/vlan.h
index 780d61262a..c4688d9b13 100644
--- a/src/network/netdev/vlan.h
+++ b/src/network/netdev/vlan.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/network/netdev/vrf.c b/src/network/netdev/vrf.c
index a3b271ca23..5e04bbd272 100644
--- a/src/network/netdev/vrf.c
+++ b/src/network/netdev/vrf.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/network/netdev/vrf.h b/src/network/netdev/vrf.h
index 06f3c17bc1..58f4ef30a4 100644
--- a/src/network/netdev/vrf.h
+++ b/src/network/netdev/vrf.h
@@ -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
index 0000000000..a41ca7e256
--- /dev/null
+++ b/src/network/netdev/vxcan.c
@@ -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
index 0000000000..f37213513f
--- /dev/null
+++ b/src/network/netdev/vxcan.h
@@ -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;
diff --git a/src/network/netdev/vxlan.c b/src/network/netdev/vxlan.c
index b5b7aec2c0..580e5e6505 100644
--- a/src/network/netdev/vxlan.c
+++ b/src/network/netdev/vxlan.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/network/netdev/vxlan.h b/src/network/netdev/vxlan.h
index 1eeda022a2..3bb8884380 100644
--- a/src/network/netdev/vxlan.h
+++ b/src/network/netdev/vxlan.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/network/networkctl.c b/src/network/networkctl.c
index e4b95e4195..59ce098cd1 100644
--- a/src/network/networkctl.c
+++ b/src/network/networkctl.c
@@ -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);
diff --git a/src/network/networkd-address-label.c b/src/network/networkd-address-label.c
index b89995ec44..4fd5fa4f58 100644
--- a/src/network/networkd-address-label.c
+++ b/src/network/networkd-address-label.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/network/networkd-address-label.h b/src/network/networkd-address-label.h
index 8724ea8cb5..9ddf707763 100644
--- a/src/network/networkd-address-label.h
+++ b/src/network/networkd-address-label.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/network/networkd-address-pool.c b/src/network/networkd-address-pool.c
index a63b925a4a..22582ab9f1 100644
--- a/src/network/networkd-address-pool.c
+++ b/src/network/networkd-address-pool.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/network/networkd-address-pool.h b/src/network/networkd-address-pool.h
index af30decfe0..1fcff09be9 100644
--- a/src/network/networkd-address-pool.h
+++ b/src/network/networkd-address-pool.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c
index 214192ffe8..ff125e35de 100644
--- a/src/network/networkd-address.c
+++ b/src/network/networkd-address.c
@@ -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)
diff --git a/src/network/networkd-address.h b/src/network/networkd-address.h
index 3281c6d3c2..3f5dffac4c 100644
--- a/src/network/networkd-address.h
+++ b/src/network/networkd-address.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/network/networkd-brvlan.c b/src/network/networkd-brvlan.c
index fa5d3ee7fa..99dd416296 100644
--- a/src/network/networkd-brvlan.c
+++ b/src/network/networkd-brvlan.c
@@ -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;
diff --git a/src/network/networkd-brvlan.h b/src/network/networkd-brvlan.h
index b37633f94f..be99436b67 100644
--- a/src/network/networkd-brvlan.h
+++ b/src/network/networkd-brvlan.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/network/networkd-conf.c b/src/network/networkd-conf.c
index 025662437b..1f791fcec0 100644
--- a/src/network/networkd-conf.c
+++ b/src/network/networkd-conf.c
@@ -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] = {
diff --git a/src/network/networkd-conf.h b/src/network/networkd-conf.h
index 1136975a5e..8d93cff61c 100644
--- a/src/network/networkd-conf.h
+++ b/src/network/networkd-conf.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c
index e1e3e88708..0b46deb009 100644
--- a/src/network/networkd-dhcp4.c
+++ b/src/network/networkd-dhcp4.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
@@ -23,11 +24,14 @@
#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);
diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c
index 6ba2d170e7..a46a11bf16 100644
--- a/src/network/networkd-dhcp6.c
+++ b/src/network/networkd-dhcp6.c
@@ -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;
diff --git a/src/network/networkd-fdb.c b/src/network/networkd-fdb.c
index 3d7f4d2b2d..380581e09a 100644
--- a/src/network/networkd-fdb.c
+++ b/src/network/networkd-fdb.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/network/networkd-fdb.h b/src/network/networkd-fdb.h
index 2d7d28735c..d34d3e5cbd 100644
--- a/src/network/networkd-fdb.h
+++ b/src/network/networkd-fdb.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/network/networkd-gperf.gperf b/src/network/networkd-gperf.gperf
index eca436d9fd..54161446bb 100644
--- a/src/network/networkd-gperf.gperf
+++ b/src/network/networkd-gperf.gperf
@@ -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"
diff --git a/src/network/networkd-ipv4ll.c b/src/network/networkd-ipv4ll.c
index d2b10107b8..e3ebbddfee 100644
--- a/src/network/networkd-ipv4ll.c
+++ b/src/network/networkd-ipv4ll.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/network/networkd-ipv6-proxy-ndp.c b/src/network/networkd-ipv6-proxy-ndp.c
index 00790c0c13..31b7c6b0f4 100644
--- a/src/network/networkd-ipv6-proxy-ndp.c
+++ b/src/network/networkd-ipv6-proxy-ndp.c
@@ -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)
diff --git a/src/network/networkd-ipv6-proxy-ndp.h b/src/network/networkd-ipv6-proxy-ndp.h
index f09169f40f..ac24c58637 100644
--- a/src/network/networkd-ipv6-proxy-ndp.h
+++ b/src/network/networkd-ipv6-proxy-ndp.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/network/networkd-link-bus.c b/src/network/networkd-link-bus.c
index c39c648334..2f4850b1a1 100644
--- a/src/network/networkd-link-bus.c
+++ b/src/network/networkd-link-bus.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index 6b591271a0..60ac980ad9 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -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);
}
}
diff --git a/src/network/networkd-link.h b/src/network/networkd-link.h
index 6479f4a2e5..8aaaa679ff 100644
--- a/src/network/networkd-link.h
+++ b/src/network/networkd-link.h
@@ -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);
diff --git a/src/network/networkd-lldp-tx.c b/src/network/networkd-lldp-tx.c
index 2de63ce746..b8d160a1f8 100644
--- a/src/network/networkd-lldp-tx.c
+++ b/src/network/networkd-lldp-tx.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/network/networkd-lldp-tx.h b/src/network/networkd-lldp-tx.h
index 4680c9d950..be7a989226 100644
--- a/src/network/networkd-lldp-tx.h
+++ b/src/network/networkd-lldp-tx.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/network/networkd-manager-bus.c b/src/network/networkd-manager-bus.c
index cbb1b93031..6d57036eb5 100644
--- a/src/network/networkd-manager-bus.c
+++ b/src/network/networkd-manager-bus.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c
index 71445d5dda..cc17af9391 100644
--- a/src/network/networkd-manager.c
+++ b/src/network/networkd-manager.c
@@ -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;
diff --git a/src/network/networkd-manager.h b/src/network/networkd-manager.h
index 254aab8452..186cb41891 100644
--- a/src/network/networkd-manager.h
+++ b/src/network/networkd-manager.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/network/networkd-ndisc.c b/src/network/networkd-ndisc.c
index d52b511bb5..df4630bf12 100644
--- a/src/network/networkd-ndisc.c
+++ b/src/network/networkd-ndisc.c
@@ -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");
diff --git a/src/network/networkd-ndisc.h b/src/network/networkd-ndisc.h
index 127126190e..f5eb8cd360 100644
--- a/src/network/networkd-ndisc.h
+++ b/src/network/networkd-ndisc.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/network/networkd-network-bus.c b/src/network/networkd-network-bus.c
index 3b835b52f9..8d3d7236fc 100644
--- a/src/network/networkd-network-bus.c
+++ b/src/network/networkd-network-bus.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf
index af39d77ce9..57a96aff94 100644
--- a/src/network/networkd-network-gperf.gperf
+++ b/src/network/networkd-network-gperf.gperf
@@ -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
diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c
index 3a7eb2c2a8..8e37a0a229 100644
--- a/src/network/networkd-network.c
+++ b/src/network/networkd-network.c
@@ -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;
diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h
index 9fb0eae380..49c62654b6 100644
--- a/src/network/networkd-network.h
+++ b/src/network/networkd-network.h
@@ -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 */
diff --git a/src/network/networkd-radv.c b/src/network/networkd-radv.c
index 6768208cfa..535454c472 100644
--- a/src/network/networkd-radv.c
+++ b/src/network/networkd-radv.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
@@ -21,9 +22,150 @@
#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);
}
diff --git a/src/network/networkd-radv.h b/src/network/networkd-radv.h
index a186b111a1..f23029935a 100644
--- a/src/network/networkd-radv.h
+++ b/src/network/networkd-radv.h
@@ -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);
diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c
index cf42037915..b0ad707811 100644
--- a/src/network/networkd-route.c
+++ b/src/network/networkd-route.c
@@ -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)
diff --git a/src/network/networkd-route.h b/src/network/networkd-route.h
index 89d32e9214..cfb85cbd6d 100644
--- a/src/network/networkd-route.h
+++ b/src/network/networkd-route.h
@@ -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);
diff --git a/src/network/networkd-routing-policy-rule.c b/src/network/networkd-routing-policy-rule.c
index 6850135fc1..1314564c11 100644
--- a/src/network/networkd-routing-policy-rule.c
+++ b/src/network/networkd-routing-policy-rule.c
@@ -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++;
}
}
}
diff --git a/src/network/networkd-routing-policy-rule.h b/src/network/networkd-routing-policy-rule.h
index d9fd93b9bf..70a861723b 100644
--- a/src/network/networkd-routing-policy-rule.h
+++ b/src/network/networkd-routing-policy-rule.h
@@ -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);
diff --git a/src/network/networkd-util.c b/src/network/networkd-util.c
index 8856e76269..b9c533fcc7 100644
--- a/src/network/networkd-util.c
+++ b/src/network/networkd-util.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/network/networkd-util.h b/src/network/networkd-util.h
index d5c385bea4..69ea93ad08 100644
--- a/src/network/networkd-util.h
+++ b/src/network/networkd-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/network/networkd.c b/src/network/networkd.c
index d5ba6893e3..9243384af8 100644
--- a/src/network/networkd.c
+++ b/src/network/networkd.c
@@ -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");
diff --git a/src/network/org.freedesktop.network1.service b/src/network/org.freedesktop.network1.service
index bea885fe53..641a1a5cc1 100644
--- a/src/network/org.freedesktop.network1.service
+++ b/src/network/org.freedesktop.network1.service
@@ -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/src/network/test-network.c b/src/network/test-network.c
index 64d2f23fc1..f3e8f508f3 100644
--- a/src/network/test-network.c
+++ b/src/network/test-network.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
@@ -17,10 +18,15 @@
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);
}
diff --git a/src/network/test-networkd-conf.c b/src/network/test-networkd-conf.c
index 0e1a18457d..530bbf8636 100644
--- a/src/network/test-networkd-conf.c
+++ b/src/network/test-networkd-conf.c
@@ -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
index 0000000000..c29d134de2
--- /dev/null
+++ b/src/network/test-routing-policy-rule.c
@@ -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;
+}
diff --git a/src/network/wait-online/link.c b/src/network/wait-online/link.c
index bd8578cf93..f0cb70ab4c 100644
--- a/src/network/wait-online/link.c
+++ b/src/network/wait-online/link.c
@@ -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);
diff --git a/src/network/wait-online/link.h b/src/network/wait-online/link.h
index c846e60c45..ab623ff4de 100644
--- a/src/network/wait-online/link.h
+++ b/src/network/wait-online/link.h
@@ -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);
diff --git a/src/network/wait-online/manager.c b/src/network/wait-online/manager.c
index d51b0a59d6..05f030dbe7 100644
--- a/src/network/wait-online/manager.c
+++ b/src/network/wait-online/manager.c
@@ -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);
}
diff --git a/src/network/wait-online/manager.h b/src/network/wait-online/manager.h
index 052f6b9780..7a8c4ea473 100644
--- a/src/network/wait-online/manager.h
+++ b/src/network/wait-online/manager.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/network/wait-online/wait-online.c b/src/network/wait-online/wait-online.c
index 268cbdb629..7b13a5d879 100644
--- a/src/network/wait-online/wait-online.c
+++ b/src/network/wait-online/wait-online.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/notify/notify.c b/src/notify/notify.c
index 70b6f868b9..3e511b7e47 100644
--- a/src/notify/notify.c
+++ b/src/notify/notify.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/nspawn/meson.build b/src/nspawn/meson.build
index b6ac6006ab..b1e7134bef 100644
--- a/src/nspawn/meson.build
+++ b/src/nspawn/meson.build
@@ -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(
diff --git a/src/nspawn/nspawn-cgroup.c b/src/nspawn/nspawn-cgroup.c
index fd565c09cd..d51585a652 100644
--- a/src/nspawn/nspawn-cgroup.c
+++ b/src/nspawn/nspawn-cgroup.c
@@ -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;
}
diff --git a/src/nspawn/nspawn-cgroup.h b/src/nspawn/nspawn-cgroup.h
index fa4321ab43..3855e5b4ea 100644
--- a/src/nspawn/nspawn-cgroup.h
+++ b/src/nspawn/nspawn-cgroup.h
@@ -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
index 0000000000..43a19d84f5
--- /dev/null
+++ b/src/nspawn/nspawn-def.h
@@ -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))
diff --git a/src/nspawn/nspawn-expose-ports.c b/src/nspawn/nspawn-expose-ports.c
index bcaf0aaeaa..98eb85081e 100644
--- a/src/nspawn/nspawn-expose-ports.c
+++ b/src/nspawn/nspawn-expose-ports.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/nspawn/nspawn-expose-ports.h b/src/nspawn/nspawn-expose-ports.h
index 741ad9765c..bd88343a02 100644
--- a/src/nspawn/nspawn-expose-ports.h
+++ b/src/nspawn/nspawn-expose-ports.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/nspawn/nspawn-gperf.gperf b/src/nspawn/nspawn-gperf.gperf
index b61b347ee7..ea66971fac 100644
--- a/src/nspawn/nspawn-gperf.gperf
+++ b/src/nspawn/nspawn-gperf.gperf
@@ -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"
diff --git a/src/nspawn/nspawn-mount.c b/src/nspawn/nspawn-mount.c
index 531f29cb7b..920e114718 100644
--- a/src/nspawn/nspawn-mount.c
+++ b/src/nspawn/nspawn-mount.c
@@ -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(
diff --git a/src/nspawn/nspawn-mount.h b/src/nspawn/nspawn-mount.h
index 2777d2169b..79c2390303 100644
--- a/src/nspawn/nspawn-mount.h
+++ b/src/nspawn/nspawn-mount.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/nspawn/nspawn-network.c b/src/nspawn/nspawn-network.c
index aa61aaaa79..ef1da333da 100644
--- a/src/nspawn/nspawn-network.c
+++ b/src/nspawn/nspawn-network.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/nspawn/nspawn-network.h b/src/nspawn/nspawn-network.h
index 3d8861e1e5..b79e1397b6 100644
--- a/src/nspawn/nspawn-network.h
+++ b/src/nspawn/nspawn-network.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/nspawn/nspawn-patch-uid.c b/src/nspawn/nspawn-patch-uid.c
index 063fdb1053..7081ed0db2 100644
--- a/src/nspawn/nspawn-patch-uid.c
+++ b/src/nspawn/nspawn-patch-uid.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
@@ -23,13 +24,16 @@
#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:
diff --git a/src/nspawn/nspawn-patch-uid.h b/src/nspawn/nspawn-patch-uid.h
index 55d0990016..fc1d22beb3 100644
--- a/src/nspawn/nspawn-patch-uid.h
+++ b/src/nspawn/nspawn-patch-uid.h
@@ -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);
diff --git a/src/nspawn/nspawn-register.c b/src/nspawn/nspawn-register.c
index 5b0faf809c..ef9db31df7 100644
--- a/src/nspawn/nspawn-register.c
+++ b/src/nspawn/nspawn-register.c
@@ -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,
diff --git a/src/nspawn/nspawn-register.h b/src/nspawn/nspawn-register.h
index 6694b3f6b1..fa3644c443 100644
--- a/src/nspawn/nspawn-register.h
+++ b/src/nspawn/nspawn-register.h
@@ -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);
diff --git a/src/nspawn/nspawn-seccomp.c b/src/nspawn/nspawn-seccomp.c
index 1890dd8e27..92e5ff9c36 100644
--- a/src/nspawn/nspawn-seccomp.c
+++ b/src/nspawn/nspawn-seccomp.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/nspawn/nspawn-seccomp.h b/src/nspawn/nspawn-seccomp.h
index 5cf5ad1e14..2421b00a12 100644
--- a/src/nspawn/nspawn-seccomp.h
+++ b/src/nspawn/nspawn-seccomp.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/nspawn/nspawn-settings.c b/src/nspawn/nspawn-settings.c
index c02c1ea697..a1518a6e81 100644
--- a/src/nspawn/nspawn-settings.c
+++ b/src/nspawn/nspawn-settings.c
@@ -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;
}
diff --git a/src/nspawn/nspawn-settings.h b/src/nspawn/nspawn-settings.h
index 75d68ce4cf..c0c5a153b0 100644
--- a/src/nspawn/nspawn-settings.h
+++ b/src/nspawn/nspawn-settings.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/nspawn/nspawn-setuid.c b/src/nspawn/nspawn-setuid.c
index b8e8e091c8..31f5dd3cdd 100644
--- a/src/nspawn/nspawn-setuid.c
+++ b/src/nspawn/nspawn-setuid.c
@@ -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");
diff --git a/src/nspawn/nspawn-setuid.h b/src/nspawn/nspawn-setuid.h
index b4968ba1fc..20fc8854f1 100644
--- a/src/nspawn/nspawn-setuid.h
+++ b/src/nspawn/nspawn-setuid.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/nspawn/nspawn-stub-pid1.c b/src/nspawn/nspawn-stub-pid1.c
index 0c48434db8..7f2f8f1f13 100644
--- a/src/nspawn/nspawn-stub-pid1.c
+++ b/src/nspawn/nspawn-stub-pid1.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/nspawn/nspawn-stub-pid1.h b/src/nspawn/nspawn-stub-pid1.h
index 7ca83078c0..fef2252e22 100644
--- a/src/nspawn/nspawn-stub-pid1.h
+++ b/src/nspawn/nspawn-stub-pid1.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 4e3803be82..71b14e2302 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -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"
@@ -106,11 +108,11 @@
#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;
diff --git a/src/nspawn/test-patch-uid.c b/src/nspawn/test-patch-uid.c
index 11c5321788..cdc438f269 100644
--- a/src/nspawn/test-patch-uid.c
+++ b/src/nspawn/test-patch-uid.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/nss-myhostname/nss-myhostname.c b/src/nss-myhostname/nss-myhostname.c
index 96ed161ba7..39714fe3c2 100644
--- a/src/nss-myhostname/nss-myhostname.c
+++ b/src/nss-myhostname/nss-myhostname.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/nss-myhostname/nss-myhostname.sym b/src/nss-myhostname/nss-myhostname.sym
index 78646c38b4..0dcdb9bd40 100644
--- a/src/nss-myhostname/nss-myhostname.sym
+++ b/src/nss-myhostname/nss-myhostname.sym
@@ -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/nss-mymachines/nss-mymachines.c b/src/nss-mymachines/nss-mymachines.c
index 6e468853a2..b2f46e3db2 100644
--- a/src/nss-mymachines/nss-mymachines.c
+++ b/src/nss-mymachines/nss-mymachines.c
@@ -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*) "/";
diff --git a/src/nss-mymachines/nss-mymachines.sym b/src/nss-mymachines/nss-mymachines.sym
index 0728ac3ba7..056d4276f9 100644
--- a/src/nss-mymachines/nss-mymachines.sym
+++ b/src/nss-mymachines/nss-mymachines.sym
@@ -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/nss-resolve/nss-resolve.c b/src/nss-resolve/nss-resolve.c
index 17d125c821..cab3c22bb2 100644
--- a/src/nss-resolve/nss-resolve.c
+++ b/src/nss-resolve/nss-resolve.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/nss-resolve/nss-resolve.sym b/src/nss-resolve/nss-resolve.sym
index df8dff2a20..27570dfce4 100644
--- a/src/nss-resolve/nss-resolve.sym
+++ b/src/nss-resolve/nss-resolve.sym
@@ -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/nss-systemd/nss-systemd.c b/src/nss-systemd/nss-systemd.c
index d856c4c165..cc641e1615 100644
--- a/src/nss-systemd/nss-systemd.c
+++ b/src/nss-systemd/nss-systemd.c
@@ -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;
diff --git a/src/nss-systemd/nss-systemd.sym b/src/nss-systemd/nss-systemd.sym
index 955078788a..e3fe56f684 100644
--- a/src/nss-systemd/nss-systemd.sym
+++ b/src/nss-systemd/nss-systemd.sym
@@ -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
index 0000000000..901b33e39e
--- /dev/null
+++ b/src/partition/growfs.c
@@ -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
index 0000000000..e5e125255b
--- /dev/null
+++ b/src/partition/makefs.c
@@ -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;
+}
diff --git a/src/path/path.c b/src/path/path.c
index 61d877fcf8..0f029c4ae6 100644
--- a/src/path/path.c
+++ b/src/path/path.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/quotacheck/quotacheck.c b/src/quotacheck/quotacheck.c
index 1339564edb..ec5be21a34 100644
--- a/src/quotacheck/quotacheck.c
+++ b/src/quotacheck/quotacheck.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/random-seed/random-seed.c b/src/random-seed/random-seed.c
index 6748bb9dd3..23a6fda08c 100644
--- a/src/random-seed/random-seed.c
+++ b/src/random-seed/random-seed.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/rc-local-generator/rc-local-generator.c b/src/rc-local-generator/rc-local-generator.c
index db3bf5bd21..196947ca51 100644
--- a/src/rc-local-generator/rc-local-generator.c
+++ b/src/rc-local-generator/rc-local-generator.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/remount-fs/remount-fs.c b/src/remount-fs/remount-fs.c
index 0cb9bd9261..2d7cf723f4 100644
--- a/src/remount-fs/remount-fs.c
+++ b/src/remount-fs/remount-fs.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/reply-password/reply-password.c b/src/reply-password/reply-password.c
index a17c8a62b8..6f82bf73f0 100644
--- a/src/reply-password/reply-password.c
+++ b/src/reply-password/reply-password.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/resolve/RFCs b/src/resolve/RFCs
index 09c85f9518..7190c16faa 100644
--- a/src/resolve/RFCs
+++ b/src/resolve/RFCs
@@ -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:
diff --git a/src/resolve/dns-type.c b/src/resolve/dns-type.c
index d89ae28dcd..347252a90f 100644
--- a/src/resolve/dns-type.c
+++ b/src/resolve/dns-type.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/resolve/dns-type.h b/src/resolve/dns-type.h
index e675fe4ea3..583ceee191 100644
--- a/src/resolve/dns-type.h
+++ b/src/resolve/dns-type.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/resolve/generate-dns_type-gperf.py b/src/resolve/generate-dns_type-gperf.py
index 8a0b43c277..d4f7b94738 100755
--- a/src/resolve/generate-dns_type-gperf.py
+++ b/src/resolve/generate-dns_type-gperf.py
@@ -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))
diff --git a/src/resolve/meson.build b/src/resolve/meson.build
index 75e654e60d..ee1acb5166 100644
--- a/src/resolve/meson.build
+++ b/src/resolve/meson.build
@@ -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
index 0000000000..da948eb0b7
--- /dev/null
+++ b/src/resolve/org.freedesktop.resolve1.policy.in
@@ -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>
diff --git a/src/resolve/org.freedesktop.resolve1.service b/src/resolve/org.freedesktop.resolve1.service
index 7ac5c323f0..2c25a6129c 100644
--- a/src/resolve/org.freedesktop.resolve1.service
+++ b/src/resolve/org.freedesktop.resolve1.service
@@ -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/src/resolve/resolv.conf b/src/resolve/resolv.conf
index b8034d6829..34a6b9257f 100644
--- a/src/resolve/resolv.conf
+++ b/src/resolve/resolv.conf
@@ -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
diff --git a/src/resolve/resolve-tool.c b/src/resolve/resolve-tool.c
index 708378573f..0252bdfcd7 100644
--- a/src/resolve/resolve-tool.c
+++ b/src/resolve/resolve-tool.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
@@ -25,8 +26,10 @@
#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;
}
diff --git a/src/resolve/resolved-bus.c b/src/resolve/resolved-bus.c
index c6f14eb416..9157d9ea68 100644
--- a/src/resolve/resolved-bus.c
+++ b/src/resolve/resolved-bus.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
@@ -24,7 +25,11 @@
#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");
diff --git a/src/resolve/resolved-bus.h b/src/resolve/resolved-bus.h
index f49e1337d2..11ddae9d8d 100644
--- a/src/resolve/resolved-bus.h
+++ b/src/resolve/resolved-bus.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/resolve/resolved-conf.c b/src/resolve/resolved-conf.c
index 3cf4261ff0..ca69d70e3c 100644
--- a/src/resolve/resolved-conf.c
+++ b/src/resolve/resolved-conf.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
@@ -21,10 +22,14 @@
#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;
diff --git a/src/resolve/resolved-conf.h b/src/resolve/resolved-conf.h
index 8184d6cadf..4ebb45f3aa 100644
--- a/src/resolve/resolved-conf.h
+++ b/src/resolve/resolved-conf.h
@@ -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_;
diff --git a/src/resolve/resolved-def.h b/src/resolve/resolved-def.h
index c4c1915b18..64c2b1503e 100644
--- a/src/resolve/resolved-def.h
+++ b/src/resolve/resolved-def.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/resolve/resolved-dns-answer.c b/src/resolve/resolved-dns-answer.c
index db86b4dcf6..ecc6143e62 100644
--- a/src/resolve/resolved-dns-answer.c
+++ b/src/resolve/resolved-dns-answer.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/resolve/resolved-dns-answer.h b/src/resolve/resolved-dns-answer.h
index 11d2e25eeb..af33787044 100644
--- a/src/resolve/resolved-dns-answer.h
+++ b/src/resolve/resolved-dns-answer.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/resolve/resolved-dns-cache.c b/src/resolve/resolved-dns-cache.c
index f8dab01308..942956dd71 100644
--- a/src/resolve/resolved-dns-cache.c
+++ b/src/resolve/resolved-dns-cache.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/resolve/resolved-dns-cache.h b/src/resolve/resolved-dns-cache.h
index 22a7c17377..a5ace2c4c6 100644
--- a/src/resolve/resolved-dns-cache.h
+++ b/src/resolve/resolved-dns-cache.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/resolve/resolved-dns-dnssec.c b/src/resolve/resolved-dns-dnssec.c
index 33bb5a1f95..e3eca7e62c 100644
--- a/src/resolve/resolved-dns-dnssec.c
+++ b/src/resolve/resolved-dns-dnssec.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
@@ -17,12 +18,16 @@
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;
}
diff --git a/src/resolve/resolved-dns-dnssec.h b/src/resolve/resolved-dns-dnssec.h
index 77bd4d71bf..25e3e08c1b 100644
--- a/src/resolve/resolved-dns-dnssec.h
+++ b/src/resolve/resolved-dns-dnssec.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/resolve/resolved-dns-packet.c b/src/resolve/resolved-dns-packet.c
index e2f227bfc6..d7a839a823 100644
--- a/src/resolve/resolved-dns-packet.c
+++ b/src/resolve/resolved-dns-packet.c
@@ -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;
diff --git a/src/resolve/resolved-dns-packet.h b/src/resolve/resolved-dns-packet.h
index b873c0f745..15994d24b1 100644
--- a/src/resolve/resolved-dns-packet.h
+++ b/src/resolve/resolved-dns-packet.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/resolve/resolved-dns-query.c b/src/resolve/resolved-dns-query.c
index c2b29bc452..227d0b5d11 100644
--- a/src/resolve/resolved-dns-query.c
+++ b/src/resolve/resolved-dns-query.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/resolve/resolved-dns-query.h b/src/resolve/resolved-dns-query.h
index b8ea48f6af..c01dc35777 100644
--- a/src/resolve/resolved-dns-query.h
+++ b/src/resolve/resolved-dns-query.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/resolve/resolved-dns-question.c b/src/resolve/resolved-dns-question.c
index 24f3e8e351..4dc3de4052 100644
--- a/src/resolve/resolved-dns-question.c
+++ b/src/resolve/resolved-dns-question.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/resolve/resolved-dns-question.h b/src/resolve/resolved-dns-question.h
index a9a1863b1e..666eb92b8d 100644
--- a/src/resolve/resolved-dns-question.h
+++ b/src/resolve/resolved-dns-question.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/resolve/resolved-dns-rr.c b/src/resolve/resolved-dns-rr.c
index e8c05ed0da..eb5592d3cf 100644
--- a/src/resolve/resolved-dns-rr.c
+++ b/src/resolve/resolved-dns-rr.c
@@ -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",
diff --git a/src/resolve/resolved-dns-rr.h b/src/resolve/resolved-dns-rr.h
index 42d39a1251..8e1a6bb2dc 100644
--- a/src/resolve/resolved-dns-rr.h
+++ b/src/resolve/resolved-dns-rr.h
@@ -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);
diff --git a/src/resolve/resolved-dns-scope.c b/src/resolve/resolved-dns-scope.c
index ca54158898..ea4459a89a 100644
--- a/src/resolve/resolved-dns-scope.c
+++ b/src/resolve/resolved-dns-scope.c
@@ -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;
+}
diff --git a/src/resolve/resolved-dns-scope.h b/src/resolve/resolved-dns-scope.h
index 6f94b1fdcd..6f58c3c257 100644
--- a/src/resolve/resolved-dns-scope.h
+++ b/src/resolve/resolved-dns-scope.h
@@ -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);
diff --git a/src/resolve/resolved-dns-search-domain.c b/src/resolve/resolved-dns-search-domain.c
index 1386e6a17b..585c518e19 100644
--- a/src/resolve/resolved-dns-search-domain.c
+++ b/src/resolve/resolved-dns-search-domain.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/resolve/resolved-dns-search-domain.h b/src/resolve/resolved-dns-search-domain.h
index eaacef4edc..8442fbd7da 100644
--- a/src/resolve/resolved-dns-search-domain.h
+++ b/src/resolve/resolved-dns-search-domain.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/resolve/resolved-dns-server.c b/src/resolve/resolved-dns-server.c
index 1b61dea626..d470a64524 100644
--- a/src/resolve/resolved-dns-server.c
+++ b/src/resolve/resolved-dns-server.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/resolve/resolved-dns-server.h b/src/resolve/resolved-dns-server.h
index 00edd47d9a..acc9281b12 100644
--- a/src/resolve/resolved-dns-server.h
+++ b/src/resolve/resolved-dns-server.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/resolve/resolved-dns-stream.c b/src/resolve/resolved-dns-stream.c
index 5892534687..52f23cd864 100644
--- a/src/resolve/resolved-dns-stream.c
+++ b/src/resolve/resolved-dns-stream.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/resolve/resolved-dns-stream.h b/src/resolve/resolved-dns-stream.h
index 4cdb4f6806..e099158e1e 100644
--- a/src/resolve/resolved-dns-stream.h
+++ b/src/resolve/resolved-dns-stream.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/resolve/resolved-dns-stub.c b/src/resolve/resolved-dns-stub.c
index 5bc79a313e..5ce8d240dd 100644
--- a/src/resolve/resolved-dns-stub.c
+++ b/src/resolve/resolved-dns-stub.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/resolve/resolved-dns-stub.h b/src/resolve/resolved-dns-stub.h
index 12b86f6753..197f2cc758 100644
--- a/src/resolve/resolved-dns-stub.h
+++ b/src/resolve/resolved-dns-stub.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/resolve/resolved-dns-synthesize.c b/src/resolve/resolved-dns-synthesize.c
index e8592a60d8..e71fcbdcca 100644
--- a/src/resolve/resolved-dns-synthesize.c
+++ b/src/resolve/resolved-dns-synthesize.c
@@ -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;
diff --git a/src/resolve/resolved-dns-synthesize.h b/src/resolve/resolved-dns-synthesize.h
index 5d829bb2e7..385863786f 100644
--- a/src/resolve/resolved-dns-synthesize.h
+++ b/src/resolve/resolved-dns-synthesize.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/resolve/resolved-dns-transaction.c b/src/resolve/resolved-dns-transaction.c
index 3cda429c3c..f4bbde0219 100644
--- a/src/resolve/resolved-dns-transaction.c
+++ b/src/resolve/resolved-dns-transaction.c
@@ -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;
diff --git a/src/resolve/resolved-dns-transaction.h b/src/resolve/resolved-dns-transaction.h
index a8d97738ef..31dcd7627a 100644
--- a/src/resolve/resolved-dns-transaction.h
+++ b/src/resolve/resolved-dns-transaction.h
@@ -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;
diff --git a/src/resolve/resolved-dns-trust-anchor.c b/src/resolve/resolved-dns-trust-anchor.c
index e169c8f02f..c6e47ed0e9 100644
--- a/src/resolve/resolved-dns-trust-anchor.c
+++ b/src/resolve/resolved-dns-trust-anchor.c
@@ -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);
}
diff --git a/src/resolve/resolved-dns-trust-anchor.h b/src/resolve/resolved-dns-trust-anchor.h
index 635c75fde5..94d620e657 100644
--- a/src/resolve/resolved-dns-trust-anchor.h
+++ b/src/resolve/resolved-dns-trust-anchor.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/resolve/resolved-dns-zone.c b/src/resolve/resolved-dns-zone.c
index ad024b54f5..dcb9702e57 100644
--- a/src/resolve/resolved-dns-zone.c
+++ b/src/resolve/resolved-dns-zone.c
@@ -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;
+}
diff --git a/src/resolve/resolved-dns-zone.h b/src/resolve/resolved-dns-zone.h
index 545ec958fb..c9c7440351 100644
--- a/src/resolve/resolved-dns-zone.h
+++ b/src/resolve/resolved-dns-zone.h
@@ -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
index 0000000000..c914e8f8d2
--- /dev/null
+++ b/src/resolve/resolved-dnssd-bus.c
@@ -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
index 0000000000..ab915c86f9
--- /dev/null
+++ b/src/resolve/resolved-dnssd-bus.h
@@ -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
index 0000000000..2780b856bf
--- /dev/null
+++ b/src/resolve/resolved-dnssd-gperf.gperf
@@ -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
index 0000000000..db589f4436
--- /dev/null
+++ b/src/resolve/resolved-dnssd.c
@@ -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
index 0000000000..fbc043d673
--- /dev/null
+++ b/src/resolve/resolved-dnssd.h
@@ -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);
diff --git a/src/resolve/resolved-etc-hosts.c b/src/resolve/resolved-etc-hosts.c
index 0a284825a1..769cfb78e7 100644
--- a/src/resolve/resolved-etc-hosts.c
+++ b/src/resolve/resolved-etc-hosts.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/resolve/resolved-etc-hosts.h b/src/resolve/resolved-etc-hosts.h
index 9d5a175f18..6756f13b41 100644
--- a/src/resolve/resolved-etc-hosts.h
+++ b/src/resolve/resolved-etc-hosts.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/resolve/resolved-gperf.gperf b/src/resolve/resolved-gperf.gperf
index 5153563b99..a5865ce6c2 100644
--- a/src/resolve/resolved-gperf.gperf
+++ b/src/resolve/resolved-gperf.gperf
@@ -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"
diff --git a/src/resolve/resolved-link-bus.c b/src/resolve/resolved-link-bus.c
index 59cd6cf1cb..711dff0954 100644
--- a/src/resolve/resolved-link-bus.c
+++ b/src/resolve/resolved-link-bus.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/resolve/resolved-link-bus.h b/src/resolve/resolved-link-bus.h
index 646031b631..deed6fe66d 100644
--- a/src/resolve/resolved-link-bus.h
+++ b/src/resolve/resolved-link-bus.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/resolve/resolved-link.c b/src/resolve/resolved-link.c
index 3d26831b06..e3e50eca53 100644
--- a/src/resolve/resolved-link.c
+++ b/src/resolve/resolved-link.c
@@ -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);
diff --git a/src/resolve/resolved-link.h b/src/resolve/resolved-link.h
index c20b8b6d29..261e34bfe2 100644
--- a/src/resolve/resolved-link.h
+++ b/src/resolve/resolved-link.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/resolve/resolved-llmnr.c b/src/resolve/resolved-llmnr.c
index 0cf4583572..59499c9c0b 100644
--- a/src/resolve/resolved-llmnr.c
+++ b/src/resolve/resolved-llmnr.c
@@ -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));
diff --git a/src/resolve/resolved-llmnr.h b/src/resolve/resolved-llmnr.h
index 8133582fa7..7670380c51 100644
--- a/src/resolve/resolved-llmnr.h
+++ b/src/resolve/resolved-llmnr.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c
index 23c6731954..2dbf432df9 100644
--- a/src/resolve/resolved-manager.c
+++ b/src/resolve/resolved-manager.c
@@ -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;
+}
diff --git a/src/resolve/resolved-manager.h b/src/resolve/resolved-manager.h
index 32a0e5fe0f..5c1a6670ef 100644
--- a/src/resolve/resolved-manager.h
+++ b/src/resolve/resolved-manager.h
@@ -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);
diff --git a/src/resolve/resolved-mdns.c b/src/resolve/resolved-mdns.c
index 6fbf755878..38e2c54227 100644
--- a/src/resolve/resolved-mdns.c
+++ b/src/resolve/resolved-mdns.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
@@ -21,10 +22,13 @@
#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;
}
diff --git a/src/resolve/resolved-mdns.h b/src/resolve/resolved-mdns.h
index 06bd3296be..af9f7a9aa6 100644
--- a/src/resolve/resolved-mdns.h
+++ b/src/resolve/resolved-mdns.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/resolve/resolved-resolv-conf.c b/src/resolve/resolved-resolv-conf.c
index e3d6a33409..bad04d6a29 100644
--- a/src/resolve/resolved-resolv-conf.c
+++ b/src/resolve/resolved-resolv-conf.c
@@ -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"
@@ -31,11 +33,41 @@
#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;
}
diff --git a/src/resolve/resolved-resolv-conf.h b/src/resolve/resolved-resolv-conf.h
index 75fa080e4c..ef34f8e09e 100644
--- a/src/resolve/resolved-resolv-conf.h
+++ b/src/resolve/resolved-resolv-conf.h
@@ -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);
diff --git a/src/resolve/resolved.c b/src/resolve/resolved.c
index 2eb7bfd030..a4cda0b5ef 100644
--- a/src/resolve/resolved.c
+++ b/src/resolve/resolved.c
@@ -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...");
diff --git a/src/resolve/test-dns-packet.c b/src/resolve/test-dns-packet.c
index 00dde9b6bd..458c908fad 100644
--- a/src/resolve/test-dns-packet.c
+++ b/src/resolve/test-dns-packet.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd
diff --git a/src/resolve/test-dnssec-complex.c b/src/resolve/test-dnssec-complex.c
index 25ec6f4352..e7b077939f 100644
--- a/src/resolve/test-dnssec-complex.c
+++ b/src/resolve/test-dnssec-complex.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/resolve/test-dnssec.c b/src/resolve/test-dnssec.c
index 8cb4b50393..2d2b5e31bf 100644
--- a/src/resolve/test-dnssec.c
+++ b/src/resolve/test-dnssec.c
@@ -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();
diff --git a/src/resolve/test-resolve-tables.c b/src/resolve/test-resolve-tables.c
index 2d615130e1..808ec76a41 100644
--- a/src/resolve/test-resolve-tables.c
+++ b/src/resolve/test-resolve-tables.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd
diff --git a/src/resolve/test-resolved-packet.c b/src/resolve/test-resolved-packet.c
index ab11fbcd32..af5bec1391 100644
--- a/src/resolve/test-resolved-packet.c
+++ b/src/resolve/test-resolved-packet.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd
diff --git a/src/rfkill/rfkill.c b/src/rfkill/rfkill.c
index 3aa468f40b..ff951450b5 100644
--- a/src/rfkill/rfkill.c
+++ b/src/rfkill/rfkill.c
@@ -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;
diff --git a/src/run/run.c b/src/run/run.c
index f9ca5683a2..5d7441ac93 100644
--- a/src/run/run.c
+++ b/src/run/run.c
@@ -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);
diff --git a/src/shared/acl-util.c b/src/shared/acl-util.c
index 79a3b9591d..889a971d88 100644
--- a/src/shared/acl-util.c
+++ b/src/shared/acl-util.c
@@ -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;
diff --git a/src/shared/acl-util.h b/src/shared/acl-util.h
index a0e31d8e29..6b581cbc42 100644
--- a/src/shared/acl-util.h
+++ b/src/shared/acl-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/shared/acpi-fpdt.c b/src/shared/acpi-fpdt.c
index 6779691c28..1a640f4f1b 100644
--- a/src/shared/acpi-fpdt.c
+++ b/src/shared/acpi-fpdt.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/shared/acpi-fpdt.h b/src/shared/acpi-fpdt.h
index fc28175d0a..4521a1e686 100644
--- a/src/shared/acpi-fpdt.h
+++ b/src/shared/acpi-fpdt.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/shared/apparmor-util.c b/src/shared/apparmor-util.c
index edd695fd23..e9c4081892 100644
--- a/src/shared/apparmor-util.c
+++ b/src/shared/apparmor-util.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/shared/apparmor-util.h b/src/shared/apparmor-util.h
index 524f740152..33ebd4d612 100644
--- a/src/shared/apparmor-util.h
+++ b/src/shared/apparmor-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/shared/ask-password-api.c b/src/shared/ask-password-api.c
index e33d8b11cf..17928a9732 100644
--- a/src/shared/ask-password-api.c
+++ b/src/shared/ask-password-api.c
@@ -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);
diff --git a/src/shared/ask-password-api.h b/src/shared/ask-password-api.h
index 9d7f65130c..f3ca6743a9 100644
--- a/src/shared/ask-password-api.h
+++ b/src/shared/ask-password-api.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/shared/base-filesystem.c b/src/shared/base-filesystem.c
index 903a187861..3c25aa534c 100644
--- a/src/shared/base-filesystem.c
+++ b/src/shared/base-filesystem.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/shared/base-filesystem.h b/src/shared/base-filesystem.h
index 49599f0a60..5d134b4eb9 100644
--- a/src/shared/base-filesystem.h
+++ b/src/shared/base-filesystem.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/shared/boot-timestamps.c b/src/shared/boot-timestamps.c
index 7e0152761c..543e01a364 100644
--- a/src/shared/boot-timestamps.c
+++ b/src/shared/boot-timestamps.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/shared/boot-timestamps.h b/src/shared/boot-timestamps.h
index 6f691026be..8c67d302b4 100644
--- a/src/shared/boot-timestamps.h
+++ b/src/shared/boot-timestamps.h
@@ -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
index 0000000000..c0a10417d8
--- /dev/null
+++ b/src/shared/bootspec.c
@@ -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
index 0000000000..d9c641bf08
--- /dev/null
+++ b/src/shared/bootspec.h
@@ -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);
diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c
index e191f8c93e..b58abed2b5 100644
--- a/src/shared/bus-unit-util.c
+++ b/src/shared/bus-unit-util.c
@@ -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;
}
diff --git a/src/shared/bus-unit-util.h b/src/shared/bus-unit-util.h
index d102ea180e..1a137e8b84 100644
--- a/src/shared/bus-unit-util.h
+++ b/src/shared/bus-unit-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c
index 7609d9c522..7a185461a3 100644
--- a/src/shared/bus-util.c
+++ b/src/shared/bus-util.c
@@ -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;
diff --git a/src/shared/bus-util.h b/src/shared/bus-util.h
index d9ce4263bb..a9f4969d7d 100644
--- a/src/shared/bus-util.h
+++ b/src/shared/bus-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/shared/cgroup-show.c b/src/shared/cgroup-show.c
index 436130edea..0ddae95434 100644
--- a/src/shared/cgroup-show.c
+++ b/src/shared/cgroup-show.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/shared/cgroup-show.h b/src/shared/cgroup-show.h
index 1764f76744..efa597aad0 100644
--- a/src/shared/cgroup-show.h
+++ b/src/shared/cgroup-show.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/shared/clean-ipc.c b/src/shared/clean-ipc.c
index 64f81bb5d3..7e2ef4a8eb 100644
--- a/src/shared/clean-ipc.c
+++ b/src/shared/clean-ipc.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/shared/clean-ipc.h b/src/shared/clean-ipc.h
index c04ed3596b..0ade561b3f 100644
--- a/src/shared/clean-ipc.h
+++ b/src/shared/clean-ipc.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/shared/condition.c b/src/shared/condition.c
index 74d5e854e1..3f32dfb7b6 100644
--- a/src/shared/condition.c
+++ b/src/shared/condition.c
@@ -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;
}
diff --git a/src/shared/condition.h b/src/shared/condition.h
index d0b592bc43..534906b6d6 100644
--- a/src/shared/condition.h
+++ b/src/shared/condition.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/shared/conf-parser.c b/src/shared/conf-parser.c
index c304ae3334..daddb7cf20 100644
--- a/src/shared/conf-parser.c
+++ b/src/shared/conf-parser.c
@@ -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;
}
diff --git a/src/shared/conf-parser.h b/src/shared/conf-parser.h
index ce1113485d..2fd135baa0 100644
--- a/src/shared/conf-parser.h
+++ b/src/shared/conf-parser.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
@@ -29,8 +30,14 @@
#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 */
diff --git a/src/shared/dev-setup.c b/src/shared/dev-setup.c
index b2d464c117..6d2cc685fa 100644
--- a/src/shared/dev-setup.c
+++ b/src/shared/dev-setup.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/shared/dev-setup.h b/src/shared/dev-setup.h
index 5766a62060..4dd591de0a 100644
--- a/src/shared/dev-setup.h
+++ b/src/shared/dev-setup.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c
index 4b59f2ca7d..e8d7db8f0c 100644
--- a/src/shared/dissect-image.c
+++ b/src/shared/dissect-image.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
@@ -17,50 +18,68 @@
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",
diff --git a/src/shared/dissect-image.h b/src/shared/dissect-image.h
index cdb083be6f..53a1554a28 100644
--- a/src/shared/dissect-image.h
+++ b/src/shared/dissect-image.h
@@ -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);
diff --git a/src/shared/dns-domain.c b/src/shared/dns-domain.c
index 4739cc880b..8c807e0e23 100644
--- a/src/shared/dns-domain.c
+++ b/src/shared/dns-domain.c
@@ -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;
diff --git a/src/shared/dns-domain.h b/src/shared/dns-domain.h
index a44d9d48d4..cd3dbb7a89 100644
--- a/src/shared/dns-domain.h
+++ b/src/shared/dns-domain.h
@@ -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);
diff --git a/src/shared/dropin.c b/src/shared/dropin.c
index 059b50dbd0..f0966874ee 100644
--- a/src/shared/dropin.c
+++ b/src/shared/dropin.c
@@ -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);
diff --git a/src/shared/dropin.h b/src/shared/dropin.h
index a2b8cdce61..102fc9403c 100644
--- a/src/shared/dropin.h
+++ b/src/shared/dropin.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/shared/efivars.c b/src/shared/efivars.c
index a3850bede2..9ca51cf750 100644
--- a/src/shared/efivars.c
+++ b/src/shared/efivars.c
@@ -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)
diff --git a/src/shared/efivars.h b/src/shared/efivars.h
index 72bace0d07..9a4880de7d 100644
--- a/src/shared/efivars.h
+++ b/src/shared/efivars.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/shared/fdset.c b/src/shared/fdset.c
index 090f3fdcdd..9ce1295223 100644
--- a/src/shared/fdset.c
+++ b/src/shared/fdset.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/shared/fdset.h b/src/shared/fdset.h
index 16efe5bdf2..864ab676f7 100644
--- a/src/shared/fdset.h
+++ b/src/shared/fdset.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/shared/firewall-util.c b/src/shared/firewall-util.c
index 6d295ea65b..a6859462ac 100644
--- a/src/shared/firewall-util.c
+++ b/src/shared/firewall-util.c
@@ -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);
diff --git a/src/shared/firewall-util.h b/src/shared/firewall-util.h
index 5915266b4b..fd7e3b456e 100644
--- a/src/shared/firewall-util.h
+++ b/src/shared/firewall-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/shared/fstab-util.c b/src/shared/fstab-util.c
index ec2e868ca8..bcd7b43084 100644
--- a/src/shared/fstab-util.c
+++ b/src/shared/fstab-util.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/shared/fstab-util.h b/src/shared/fstab-util.h
index bbf0441351..87f82dcfb4 100644
--- a/src/shared/fstab-util.h
+++ b/src/shared/fstab-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/shared/gcrypt-util.c b/src/shared/gcrypt-util.c
index e10a38dcfc..1bfb776725 100644
--- a/src/shared/gcrypt-util.c
+++ b/src/shared/gcrypt-util.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
diff --git a/src/shared/gcrypt-util.h b/src/shared/gcrypt-util.h
index f08ed6052c..69faf08e56 100644
--- a/src/shared/gcrypt-util.h
+++ b/src/shared/gcrypt-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
diff --git a/src/shared/generator.c b/src/shared/generator.c
index 18fc469098..3495a7ef7d 100644
--- a/src/shared/generator.c
+++ b/src/shared/generator.c
@@ -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);
+}
diff --git a/src/shared/generator.h b/src/shared/generator.h
index e70016839f..32d1ad021c 100644
--- a/src/shared/generator.h
+++ b/src/shared/generator.h
@@ -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);
diff --git a/src/shared/gpt.h b/src/shared/gpt.h
index cc752006fa..7589f6fb7a 100644
--- a/src/shared/gpt.h
+++ b/src/shared/gpt.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/shared/ima-util.c b/src/shared/ima-util.c
index 789064d653..064f38be6f 100644
--- a/src/shared/ima-util.c
+++ b/src/shared/ima-util.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/shared/ima-util.h b/src/shared/ima-util.h
index 5be94761fd..5633c78be9 100644
--- a/src/shared/ima-util.h
+++ b/src/shared/ima-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/shared/import-util.c b/src/shared/import-util.c
index ab701ad8b2..07ba216e93 100644
--- a/src/shared/import-util.c
+++ b/src/shared/import-util.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/shared/import-util.h b/src/shared/import-util.h
index 77b17d91f3..583845b1a4 100644
--- a/src/shared/import-util.h
+++ b/src/shared/import-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/shared/install-printf.c b/src/shared/install-printf.c
index c10ed3d311..aaab2e6665 100644
--- a/src/shared/install-printf.c
+++ b/src/shared/install-printf.c
@@ -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
diff --git a/src/shared/install-printf.h b/src/shared/install-printf.h
index 8a570fc265..d868f65cfa 100644
--- a/src/shared/install-printf.h
+++ b/src/shared/install-printf.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/shared/install.c b/src/shared/install.c
index 7598bf6a23..05ccc586a9 100644
--- a/src/shared/install.c
+++ b/src/shared/install.c
@@ -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);
diff --git a/src/shared/install.h b/src/shared/install.h
index c1fcbe96ed..6d7518d72a 100644
--- a/src/shared/install.h
+++ b/src/shared/install.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/shared/journal-util.c b/src/shared/journal-util.c
index fff3dfc9d1..eb7a75295f 100644
--- a/src/shared/journal-util.c
+++ b/src/shared/journal-util.c
@@ -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;
+}
diff --git a/src/shared/journal-util.h b/src/shared/journal-util.h
index 499e6c62ec..ef5e314d37 100644
--- a/src/shared/journal-util.h
+++ b/src/shared/journal-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
@@ -19,7 +20,10 @@
***/
#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);
diff --git a/src/shared/linux/auto_dev-ioctl.h b/src/shared/linux/auto_dev-ioctl.h
index aeaeb3ea7a..b3555fb2c8 100644
--- a/src/shared/linux/auto_dev-ioctl.h
+++ b/src/shared/linux/auto_dev-ioctl.h
@@ -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>
diff --git a/src/shared/logs-show.c b/src/shared/logs-show.c
index 0626d80b19..afc3dcd219 100644
--- a/src/shared/logs-show.c
+++ b/src/shared/logs-show.c
@@ -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;
}
diff --git a/src/shared/logs-show.h b/src/shared/logs-show.h
index 6643440881..eaa69b6e90 100644
--- a/src/shared/logs-show.h
+++ b/src/shared/logs-show.h
@@ -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);
diff --git a/src/shared/loop-util.c b/src/shared/loop-util.c
index 047e213634..097de690e5 100644
--- a/src/shared/loop-util.c
+++ b/src/shared/loop-util.c
@@ -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) {
diff --git a/src/shared/loop-util.h b/src/shared/loop-util.h
index 45fead5f18..7e18e5779d 100644
--- a/src/shared/loop-util.h
+++ b/src/shared/loop-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/shared/machine-image.c b/src/shared/machine-image.c
index 859e5ffc1a..66eefb3036 100644
--- a/src/shared/machine-image.c
+++ b/src/shared/machine-image.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
@@ -33,12 +34,17 @@
#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);
diff --git a/src/shared/machine-image.h b/src/shared/machine-image.h
index 7410168c4f..3df9a29a24 100644
--- a/src/shared/machine-image.h
+++ b/src/shared/machine-image.h
@@ -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);
diff --git a/src/shared/machine-pool.c b/src/shared/machine-pool.c
index c581bdeb79..167bcfad36 100644
--- a/src/shared/machine-pool.c
+++ b/src/shared/machine-pool.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/shared/machine-pool.h b/src/shared/machine-pool.h
index 40fe5ecb3a..6e390521e8 100644
--- a/src/shared/machine-pool.h
+++ b/src/shared/machine-pool.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/shared/meson.build b/src/shared/meson.build
index 883821352e..06a944c49d 100644
--- a/src/shared/meson.build
+++ b/src/shared/meson.build
@@ -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
diff --git a/src/shared/nsflags.c b/src/shared/nsflags.c
index aeb79b131e..05ec9feb8d 100644
--- a/src/shared/nsflags.c
+++ b/src/shared/nsflags.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/shared/nsflags.h b/src/shared/nsflags.h
index 152ab8b936..dcac6cd0b2 100644
--- a/src/shared/nsflags.h
+++ b/src/shared/nsflags.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/shared/output-mode.c b/src/shared/output-mode.c
index 29dcba9f6b..5256e917a3 100644
--- a/src/shared/output-mode.c
+++ b/src/shared/output-mode.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/shared/output-mode.h b/src/shared/output-mode.h
index 2a1bfd98d0..747f7eb1b9 100644
--- a/src/shared/output-mode.h
+++ b/src/shared/output-mode.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/shared/pager.c b/src/shared/pager.c
index 0661ff0bb9..39997278f1 100644
--- a/src/shared/pager.c
+++ b/src/shared/pager.c
@@ -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");
diff --git a/src/shared/pager.h b/src/shared/pager.h
index 893e1d2bb6..99716f8747 100644
--- a/src/shared/pager.h
+++ b/src/shared/pager.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/shared/path-lookup.c b/src/shared/path-lookup.c
index 802e4b9c8d..d57c78a8b1 100644
--- a/src/shared/path-lookup.c
+++ b/src/shared/path-lookup.c
@@ -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
diff --git a/src/shared/path-lookup.h b/src/shared/path-lookup.h
index fc8b8ed8c7..42a870aa3e 100644
--- a/src/shared/path-lookup.h
+++ b/src/shared/path-lookup.h
@@ -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);
diff --git a/src/shared/ptyfwd.c b/src/shared/ptyfwd.c
index 0c92184ba5..94a4dd513f 100644
--- a/src/shared/ptyfwd.c
+++ b/src/shared/ptyfwd.c
@@ -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;
}
diff --git a/src/shared/ptyfwd.h b/src/shared/ptyfwd.h
index 3fad1d3b26..6a0e0c6a2b 100644
--- a/src/shared/ptyfwd.h
+++ b/src/shared/ptyfwd.h
@@ -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);
diff --git a/src/shared/resolve-util.c b/src/shared/resolve-util.c
index e2da81bab7..edcb8e05e7 100644
--- a/src/shared/resolve-util.c
+++ b/src/shared/resolve-util.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/shared/resolve-util.h b/src/shared/resolve-util.h
index 8636a6c134..975156ca96 100644
--- a/src/shared/resolve-util.h
+++ b/src/shared/resolve-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/shared/seccomp-util.c b/src/shared/seccomp-util.c
index 14a75bfffe..62742858c7 100644
--- a/src/shared/seccomp-util.c
+++ b/src/shared/seccomp-util.c
@@ -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));
}
}
diff --git a/src/shared/seccomp-util.h b/src/shared/seccomp-util.h
index 6dfa465ef3..ad2ab7f6b5 100644
--- a/src/shared/seccomp-util.h
+++ b/src/shared/seccomp-util.h
@@ -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);
diff --git a/src/shared/sleep-config.c b/src/shared/sleep-config.c
index 8c1624ff46..ecac98e0ab 100644
--- a/src/shared/sleep-config.c
+++ b/src/shared/sleep-config.c
@@ -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 */
diff --git a/src/shared/sleep-config.h b/src/shared/sleep-config.h
index ad10039ff4..fc5a81d954 100644
--- a/src/shared/sleep-config.h
+++ b/src/shared/sleep-config.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/shared/spawn-ask-password-agent.c b/src/shared/spawn-ask-password-agent.c
index a46b7525f0..9af5faa3dd 100644
--- a/src/shared/spawn-ask-password-agent.c
+++ b/src/shared/spawn-ask-password-agent.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/shared/spawn-ask-password-agent.h b/src/shared/spawn-ask-password-agent.h
index fb0749b13f..158f8839ab 100644
--- a/src/shared/spawn-ask-password-agent.h
+++ b/src/shared/spawn-ask-password-agent.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/shared/spawn-polkit-agent.c b/src/shared/spawn-polkit-agent.c
index 9a40147662..423069fb0e 100644
--- a/src/shared/spawn-polkit-agent.c
+++ b/src/shared/spawn-polkit-agent.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/shared/spawn-polkit-agent.h b/src/shared/spawn-polkit-agent.h
index 42b2989ded..9f26fa10a7 100644
--- a/src/shared/spawn-polkit-agent.h
+++ b/src/shared/spawn-polkit-agent.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
@@ -19,5 +20,22 @@
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();
+}
diff --git a/src/shared/specifier.c b/src/shared/specifier.c
index 81379041cc..23aaa88c4b 100644
--- a/src/shared/specifier.c
+++ b/src/shared/specifier.c
@@ -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
@@ -38,11 +41,16 @@
*
*/
+/* 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;
+}
diff --git a/src/shared/specifier.h b/src/shared/specifier.h
index 6b1623ee61..bd6bc55577 100644
--- a/src/shared/specifier.h
+++ b/src/shared/specifier.h
@@ -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);
diff --git a/src/shared/switch-root.c b/src/shared/switch-root.c
index afdf1ab5ad..3c51fa36f3 100644
--- a/src/shared/switch-root.c
+++ b/src/shared/switch-root.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/shared/switch-root.h b/src/shared/switch-root.h
index a7a080b3e8..abcdc1c65f 100644
--- a/src/shared/switch-root.h
+++ b/src/shared/switch-root.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
#include <stdbool.h>
diff --git a/src/shared/sysctl-util.c b/src/shared/sysctl-util.c
index e1ccb3294c..189580e3ed 100644
--- a/src/shared/sysctl-util.c
+++ b/src/shared/sysctl-util.c
@@ -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) {
diff --git a/src/shared/sysctl-util.h b/src/shared/sysctl-util.h
index 2decb39f58..446aa6f384 100644
--- a/src/shared/sysctl-util.h
+++ b/src/shared/sysctl-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/shared/test-tables.h b/src/shared/test-tables.h
index 228e510104..6b223b1ee5 100644
--- a/src/shared/test-tables.h
+++ b/src/shared/test-tables.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd
diff --git a/src/shared/tests.c b/src/shared/tests.c
index f300bbc66f..d78ab7b069 100644
--- a/src/shared/tests.c
+++ b/src/shared/tests.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/shared/tests.h b/src/shared/tests.h
index 7055124990..b070f386e3 100644
--- a/src/shared/tests.h
+++ b/src/shared/tests.h
@@ -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
index 0000000000..390fff6152
--- /dev/null
+++ b/src/shared/tomoyo-util.c
@@ -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
index 0000000000..4fb309fd54
--- /dev/null
+++ b/src/shared/tomoyo-util.h
@@ -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);
diff --git a/src/shared/udev-util.c b/src/shared/udev-util.c
index f708dcfa14..65a09e9c2e 100644
--- a/src/shared/udev-util.c
+++ b/src/shared/udev-util.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/shared/udev-util.h b/src/shared/udev-util.h
index a415be249e..c5e4197dff 100644
--- a/src/shared/udev-util.h
+++ b/src/shared/udev-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/shared/uid-range.c b/src/shared/uid-range.c
index b6ec474390..c38b7cc984 100644
--- a/src/shared/uid-range.c
+++ b/src/shared/uid-range.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/shared/uid-range.h b/src/shared/uid-range.h
index 4044eb4c9c..882f6624cd 100644
--- a/src/shared/uid-range.h
+++ b/src/shared/uid-range.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/shared/utmp-wtmp.c b/src/shared/utmp-wtmp.c
index fc8548c5b3..1715c0fb24 100644
--- a/src/shared/utmp-wtmp.c
+++ b/src/shared/utmp-wtmp.c
@@ -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 {
diff --git a/src/shared/utmp-wtmp.h b/src/shared/utmp-wtmp.h
index 8f4fbcdeff..2c75d4097e 100644
--- a/src/shared/utmp-wtmp.h
+++ b/src/shared/utmp-wtmp.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/shared/vlan-util.c b/src/shared/vlan-util.c
index 1edd96fbe7..fa270164bb 100644
--- a/src/shared/vlan-util.c
+++ b/src/shared/vlan-util.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/shared/vlan-util.h b/src/shared/vlan-util.h
index 365ed14d88..6d287fd32a 100644
--- a/src/shared/vlan-util.h
+++ b/src/shared/vlan-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/shared/volatile-util.c b/src/shared/volatile-util.c
index e7e9721411..85512d00af 100644
--- a/src/shared/volatile-util.c
+++ b/src/shared/volatile-util.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/shared/volatile-util.h b/src/shared/volatile-util.h
index 17930ba6ae..3ad037af8b 100644
--- a/src/shared/volatile-util.h
+++ b/src/shared/volatile-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/shared/watchdog.c b/src/shared/watchdog.c
index 4f3e0125f3..b0a422da84 100644
--- a/src/shared/watchdog.c
+++ b/src/shared/watchdog.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
@@ -26,10 +27,12 @@
#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;
diff --git a/src/shared/watchdog.h b/src/shared/watchdog.h
index f6ec178ea1..5694338db3 100644
--- a/src/shared/watchdog.h
+++ b/src/shared/watchdog.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
@@ -24,6 +25,11 @@
#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);
+}
diff --git a/src/sleep/sleep.c b/src/sleep/sleep.c
index 4d774c90b3..518032ec69 100644
--- a/src/sleep/sleep.c
+++ b/src/sleep/sleep.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/socket-proxy/socket-proxyd.c b/src/socket-proxy/socket-proxyd.c
index 34c938438c..d4f401d996 100644
--- a/src/socket-proxy/socket-proxyd.c
+++ b/src/socket-proxy/socket-proxyd.c
@@ -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);
diff --git a/src/stdio-bridge/stdio-bridge.c b/src/stdio-bridge/stdio-bridge.c
index 097f8c1a4b..4c099990ed 100644
--- a/src/stdio-bridge/stdio-bridge.c
+++ b/src/stdio-bridge/stdio-bridge.c
@@ -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
index 90e6f3e716..0000000000
--- a/src/sulogin-shell/meson.build
+++ /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)
diff --git a/src/sulogin-shell/sulogin-shell.c b/src/sulogin-shell/sulogin-shell.c
index 7933ddcc21..70659df417 100644
--- a/src/sulogin-shell/sulogin-shell.c
+++ b/src/sulogin-shell/sulogin-shell.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
@@ -22,21 +23,43 @@
#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;
}
diff --git a/src/sysctl/sysctl.c b/src/sysctl/sysctl.c
index ce4ff8c8a3..a1dc95b2bb 100644
--- a/src/sysctl/sysctl.c
+++ b/src/sysctl/sysctl.c
@@ -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++;
diff --git a/src/system-update-generator/system-update-generator.c b/src/system-update-generator/system-update-generator.c
index f1514c9638..1796bae340 100644
--- a/src/system-update-generator/system-update-generator.c
+++ b/src/system-update-generator/system-update-generator.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index f218bb05f2..18c64241ba 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -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;
@@ -6284,7 +6392,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";
@@ -6454,7 +6562,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,
@@ -6516,7 +6624,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,
@@ -7144,6 +7252,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"
@@ -7153,12 +7262,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"
@@ -7388,6 +7499,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,
@@ -7443,6 +7555,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 },
@@ -7652,6 +7765,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;
@@ -7857,7 +7974,7 @@ static int halt_parse_argv(int argc, char *argv[]) {
break;
case 'w':
- arg_dry = true;
+ arg_dry_run = true;
break;
case 'd':
@@ -7968,7 +8085,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:
@@ -8000,15 +8117,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 */
@@ -8289,7 +8406,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 },
@@ -8391,24 +8508,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;
@@ -8423,12 +8544,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;
}
@@ -8470,7 +8596,7 @@ static int logind_schedule_shutdown(void) {
break;
}
- if (arg_dry)
+ if (arg_dry_run)
action = strjoina("dry-", action);
(void) logind_set_wall_message();
@@ -8509,8 +8635,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;
}
@@ -8530,7 +8656,7 @@ static int halt_main(void) {
}
}
- if (!arg_dry && !arg_force)
+ if (!arg_dry_run && !arg_force)
return start_with_fallback();
assert(geteuid() == 0);
@@ -8545,7 +8671,7 @@ static int halt_main(void) {
}
}
- if (arg_dry)
+ if (arg_dry_run)
return 0;
r = halt_now(arg_action);
@@ -8693,6 +8819,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;
diff --git a/src/systemd/_sd-common.h b/src/systemd/_sd-common.h
index 97c3943861..b4400e7b36 100644
--- a/src/systemd/_sd-common.h
+++ b/src/systemd/_sd-common.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#ifndef foosdcommonhfoo
#define foosdcommonhfoo
diff --git a/src/systemd/meson.build b/src/systemd/meson.build
index debbd46dff..16e4b3540c 100644
--- a/src/systemd/meson.build
+++ b/src/systemd/meson.build
@@ -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
diff --git a/src/systemd/sd-bus-protocol.h b/src/systemd/sd-bus-protocol.h
index 623cee0c50..63e3702fbf 100644
--- a/src/systemd/sd-bus-protocol.h
+++ b/src/systemd/sd-bus-protocol.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#ifndef foosdbusprotocolhfoo
#define foosdbusprotocolhfoo
diff --git a/src/systemd/sd-bus-vtable.h b/src/systemd/sd-bus-vtable.h
index 1e82cae038..f6fb40fbb5 100644
--- a/src/systemd/sd-bus-vtable.h
+++ b/src/systemd/sd-bus-vtable.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#ifndef foosdbusvtablehfoo
#define foosdbusvtablehfoo
diff --git a/src/systemd/sd-bus.h b/src/systemd/sd-bus.h
index 2b6aeb7989..c5c7096d55 100644
--- a/src/systemd/sd-bus.h
+++ b/src/systemd/sd-bus.h
@@ -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);
diff --git a/src/systemd/sd-daemon.h b/src/systemd/sd-daemon.h
index 8c096f610f..9772a05dad 100644
--- a/src/systemd/sd-daemon.h
+++ b/src/systemd/sd-daemon.h
@@ -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_.
diff --git a/src/systemd/sd-device.h b/src/systemd/sd-device.h
index c1d07561d7..6ac0b13c0c 100644
--- a/src/systemd/sd-device.h
+++ b/src/systemd/sd-device.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#ifndef foosddevicehfoo
#define foosddevicehfoo
diff --git a/src/systemd/sd-dhcp-client.h b/src/systemd/sd-dhcp-client.h
index 5e46d8d0e8..6eb9eb61a8 100644
--- a/src/systemd/sd-dhcp-client.h
+++ b/src/systemd/sd-dhcp-client.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#ifndef foosddhcpclienthfoo
#define foosddhcpclienthfoo
diff --git a/src/systemd/sd-dhcp-lease.h b/src/systemd/sd-dhcp-lease.h
index 7ab99cccd1..3cc7fcabe3 100644
--- a/src/systemd/sd-dhcp-lease.h
+++ b/src/systemd/sd-dhcp-lease.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#ifndef foosddhcpleasehfoo
#define foosddhcpleasehfoo
diff --git a/src/systemd/sd-dhcp-server.h b/src/systemd/sd-dhcp-server.h
index d4517a26d6..9d39e43b98 100644
--- a/src/systemd/sd-dhcp-server.h
+++ b/src/systemd/sd-dhcp-server.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#ifndef foosddhcpserverhfoo
#define foosddhcpserverhfoo
diff --git a/src/systemd/sd-dhcp6-client.h b/src/systemd/sd-dhcp6-client.h
index 7819f0d2de..37803c71d8 100644
--- a/src/systemd/sd-dhcp6-client.h
+++ b/src/systemd/sd-dhcp6-client.h
@@ -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);
diff --git a/src/systemd/sd-dhcp6-lease.h b/src/systemd/sd-dhcp6-lease.h
index 184fbb8e0d..5807b1836b 100644
--- a/src/systemd/sd-dhcp6-lease.h
+++ b/src/systemd/sd-dhcp6-lease.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#ifndef foosddhcp6leasehfoo
#define foosddhcp6leasehfoo
diff --git a/src/systemd/sd-event.h b/src/systemd/sd-event.h
index f8cb895660..9083d5fa9e 100644
--- a/src/systemd/sd-event.h
+++ b/src/systemd/sd-event.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#ifndef foosdeventhfoo
#define foosdeventhfoo
diff --git a/src/systemd/sd-hwdb.h b/src/systemd/sd-hwdb.h
index 7105920492..fd69aaf3d4 100644
--- a/src/systemd/sd-hwdb.h
+++ b/src/systemd/sd-hwdb.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#ifndef foosdhwdbhfoo
#define foosdhwdbhfoo
diff --git a/src/systemd/sd-id128.h b/src/systemd/sd-id128.h
index 9b38969b77..67fc595669 100644
--- a/src/systemd/sd-id128.h
+++ b/src/systemd/sd-id128.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#ifndef foosdid128hfoo
#define foosdid128hfoo
diff --git a/src/systemd/sd-ipv4acd.h b/src/systemd/sd-ipv4acd.h
index 16d99983a8..677ae3b216 100644
--- a/src/systemd/sd-ipv4acd.h
+++ b/src/systemd/sd-ipv4acd.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#ifndef foosdipv4acdfoo
#define foosdipv4acdfoo
diff --git a/src/systemd/sd-ipv4ll.h b/src/systemd/sd-ipv4ll.h
index 5ba92083f4..c330b0ae9e 100644
--- a/src/systemd/sd-ipv4ll.h
+++ b/src/systemd/sd-ipv4ll.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#ifndef foosdipv4llfoo
#define foosdipv4llfoo
diff --git a/src/systemd/sd-journal.h b/src/systemd/sd-journal.h
index 9c36b27157..2a70d5e818 100644
--- a/src/systemd/sd-journal.h
+++ b/src/systemd/sd-journal.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#ifndef foosdjournalhfoo
#define foosdjournalhfoo
diff --git a/src/systemd/sd-lldp.h b/src/systemd/sd-lldp.h
index 3f35eebea3..0a76fa6314 100644
--- a/src/systemd/sd-lldp.h
+++ b/src/systemd/sd-lldp.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#ifndef foosdlldphfoo
#define foosdlldphfoo
diff --git a/src/systemd/sd-login.h b/src/systemd/sd-login.h
index e3ecbd8378..d8e2c6822d 100644
--- a/src/systemd/sd-login.h
+++ b/src/systemd/sd-login.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#ifndef foosdloginhfoo
#define foosdloginhfoo
diff --git a/src/systemd/sd-messages.h b/src/systemd/sd-messages.h
index 8c23486779..5a3f78bdbc 100644
--- a/src/systemd/sd-messages.h
+++ b/src/systemd/sd-messages.h
@@ -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 \
diff --git a/src/systemd/sd-ndisc.h b/src/systemd/sd-ndisc.h
index 9f7d4ef71a..152114507a 100644
--- a/src/systemd/sd-ndisc.h
+++ b/src/systemd/sd-ndisc.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#ifndef foosdndiscfoo
#define foosdndiscfoo
diff --git a/src/systemd/sd-netlink.h b/src/systemd/sd-netlink.h
index b28fc0da00..d6e3816c64 100644
--- a/src/systemd/sd-netlink.h
+++ b/src/systemd/sd-netlink.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#ifndef foosdnetlinkhfoo
#define foosdnetlinkhfoo
diff --git a/src/systemd/sd-network.h b/src/systemd/sd-network.h
index 0f13e2bae7..2d48946d2a 100644
--- a/src/systemd/sd-network.h
+++ b/src/systemd/sd-network.h
@@ -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);
diff --git a/src/systemd/sd-path.h b/src/systemd/sd-path.h
index be6abdcd03..2dfc8967b4 100644
--- a/src/systemd/sd-path.h
+++ b/src/systemd/sd-path.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#ifndef foosdpathhfoo
#define foosdpathhfoo
diff --git a/src/systemd/sd-radv.h b/src/systemd/sd-radv.h
index 0cc1d670b9..94d5e71e8a 100644
--- a/src/systemd/sd-radv.h
+++ b/src/systemd/sd-radv.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#ifndef foosdradvfoo
#define foosdradvfoo
@@ -33,6 +34,11 @@
_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;
diff --git a/src/systemd/sd-resolve.h b/src/systemd/sd-resolve.h
index 1c792dab39..14d0cbde04 100644
--- a/src/systemd/sd-resolve.h
+++ b/src/systemd/sd-resolve.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#ifndef foosdresolvehfoo
#define foosdresolvehfoo
diff --git a/src/systemd/sd-utf8.h b/src/systemd/sd-utf8.h
index 6781983878..cd02c6a296 100644
--- a/src/systemd/sd-utf8.h
+++ b/src/systemd/sd-utf8.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#ifndef foosdutf8hfoo
#define foosdutf8hfoo
diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c
index 6ef00d8f25..d8009458ee 100644
--- a/src/sysusers/sysusers.c
+++ b/src/sysusers/sysusers.c
@@ -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);
diff --git a/src/sysv-generator/sysv-generator.c b/src/sysv-generator/sysv-generator.c
index 195f7a0604..51306b5625 100644
--- a/src/sysv-generator/sysv-generator.c
+++ b/src/sysv-generator/sysv-generator.c
@@ -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)
diff --git a/src/test/meson.build b/src/test/meson.build
index 1f3db65781..6bb5bd629e 100644
--- a/src/test/meson.build
+++ b/src/test/meson.build
@@ -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,
diff --git a/src/test/test-acl-util.c b/src/test/test-acl-util.c
index 5b572bb0bf..70ffdbc519 100644
--- a/src/test/test-acl-util.c
+++ b/src/test/test-acl-util.c
@@ -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;
diff --git a/src/test/test-af-list.c b/src/test/test-af-list.c
index bbaf18b08a..2d42dc2c54 100644
--- a/src/test/test-af-list.c
+++ b/src/test/test-af-list.c
@@ -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;
}
diff --git a/src/test/test-alloc-util.c b/src/test/test-alloc-util.c
index cc4821eaf5..ed598e106c 100644
--- a/src/test/test-alloc-util.c
+++ b/src/test/test-alloc-util.c
@@ -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;
}
diff --git a/src/test/test-architecture.c b/src/test/test-architecture.c
index 68975b790a..586d54b140 100644
--- a/src/test/test-architecture.c
+++ b/src/test/test-architecture.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
@@ -24,6 +25,14 @@
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);
diff --git a/src/test/test-arphrd-list.c b/src/test/test-arphrd-list.c
index bb51518c9c..e503582820 100644
--- a/src/test/test-arphrd-list.c
+++ b/src/test/test-arphrd-list.c
@@ -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;
}
diff --git a/src/test/test-ask-password-api.c b/src/test/test-ask-password-api.c
index 86666597c7..da44465821 100644
--- a/src/test/test-ask-password-api.c
+++ b/src/test/test-ask-password-api.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/test/test-async.c b/src/test/test-async.c
index 4ebc27f0bd..2055ce25bf 100644
--- a/src/test/test-async.c
+++ b/src/test/test-async.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd
diff --git a/src/test/test-barrier.c b/src/test/test-barrier.c
index e6aa3b5cfe..1001cc2a5a 100644
--- a/src/test/test-barrier.c
+++ b/src/test/test-barrier.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/test/test-bitmap.c b/src/test/test-bitmap.c
index ff22117745..fa38056126 100644
--- a/src/test/test-bitmap.c
+++ b/src/test/test-bitmap.c
@@ -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);
diff --git a/src/test/test-boot-timestamps.c b/src/test/test-boot-timestamps.c
index 8e68d6510d..37e799d783 100644
--- a/src/test/test-boot-timestamps.c
+++ b/src/test/test-boot-timestamps.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/test/test-bpf.c b/src/test/test-bpf.c
index 74e9d50561..361cf100be 100644
--- a/src/test/test-bpf.c
+++ b/src/test/test-bpf.c
@@ -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);
diff --git a/src/test/test-btrfs.c b/src/test/test-btrfs.c
index ce29d88412..645594ce6c 100644
--- a/src/test/test-btrfs.c
+++ b/src/test/test-btrfs.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/test/test-calendarspec.c b/src/test/test-calendarspec.c
index bd5bebe66d..1a95b60740 100644
--- a/src/test/test-calendarspec.c
+++ b/src/test/test-calendarspec.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/test/test-cap-list.c b/src/test/test-cap-list.c
index c1af277f34..935567cc23 100644
--- a/src/test/test-cap-list.c
+++ b/src/test/test-cap-list.c
@@ -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;
}
diff --git a/src/test/test-capability.c b/src/test/test-capability.c
index 8276c75987..e5db52d404 100644
--- a/src/test/test-capability.c
+++ b/src/test/test-capability.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd
@@ -25,9 +26,12 @@
#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();
diff --git a/src/test/test-cgroup-mask.c b/src/test/test-cgroup-mask.c
index 02aae84152..10ae523b52 100644
--- a/src/test/test-cgroup-mask.c
+++ b/src/test/test-cgroup-mask.c
@@ -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;
}
diff --git a/src/test/test-cgroup-util.c b/src/test/test-cgroup-util.c
index d5bc73feff..45eb3ef8b1 100644
--- a/src/test/test-cgroup-util.c
+++ b/src/test/test-cgroup-util.c
@@ -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;
}
diff --git a/src/test/test-cgroup.c b/src/test/test-cgroup.c
index 71e318a15b..2ae95db162 100644
--- a/src/test/test-cgroup.c
+++ b/src/test/test-cgroup.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/test/test-clock.c b/src/test/test-clock.c
index 94f8b50f41..11773cc180 100644
--- a/src/test/test-clock.c
+++ b/src/test/test-clock.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/test/test-condition.c b/src/test/test-condition.c
index 278ac2ab6c..d43db3a7cd 100644
--- a/src/test/test-condition.c
+++ b/src/test/test-condition.c
@@ -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);
diff --git a/src/test/test-conf-files.c b/src/test/test-conf-files.c
index 777b5ca32b..de91efac72 100644
--- a/src/test/test-conf-files.c
+++ b/src/test/test-conf-files.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/test/test-conf-parser.c b/src/test/test-conf-parser.c
index 7a7de98bec..770bb9600f 100644
--- a/src/test/test-conf-parser.c
+++ b/src/test/test-conf-parser.c
@@ -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:
diff --git a/src/test/test-copy.c b/src/test/test-copy.c
index 187baa2d53..d277b78c5b 100644
--- a/src/test/test-copy.c
+++ b/src/test/test-copy.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd
diff --git a/src/test/test-cpu-set-util.c b/src/test/test-cpu-set-util.c
index e510633584..1a7220d17a 100644
--- a/src/test/test-cpu-set-util.c
+++ b/src/test/test-cpu-set-util.c
@@ -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");
diff --git a/src/test/test-daemon.c b/src/test/test-daemon.c
index e5887cc06a..0e82ba634f 100644
--- a/src/test/test-daemon.c
+++ b/src/test/test-daemon.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/test/test-date.c b/src/test/test-date.c
index c09d615396..85867db8dc 100644
--- a/src/test/test-date.c
+++ b/src/test/test-date.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/test/test-device-nodes.c b/src/test/test-device-nodes.c
index af75b38948..042907c8e0 100644
--- a/src/test/test-device-nodes.c
+++ b/src/test/test-device-nodes.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/test/test-dissect-image.c b/src/test/test-dissect-image.c
index 2bb68be0db..c594047c76 100644
--- a/src/test/test-dissect-image.c
+++ b/src/test/test-dissect-image.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/test/test-dlopen.c b/src/test/test-dlopen.c
index 9f5343a7ea..dd43da559f 100644
--- a/src/test/test-dlopen.c
+++ b/src/test/test-dlopen.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/test/test-dns-domain.c b/src/test/test-dns-domain.c
index 75bc5e4a73..0ad7d088aa 100644
--- a/src/test/test-dns-domain.c
+++ b/src/test/test-dns-domain.c
@@ -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();
diff --git a/src/test/test-ellipsize.c b/src/test/test-ellipsize.c
index d4f09b08a5..421774c074 100644
--- a/src/test/test-ellipsize.c
+++ b/src/test/test-ellipsize.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/test/test-engine.c b/src/test/test-engine.c
index 6916f838d4..a7cdbb6018 100644
--- a/src/test/test-engine.c
+++ b/src/test/test-engine.c
@@ -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;
diff --git a/src/test/test-env-util.c b/src/test/test-env-util.c
index 3a2492dc6f..b1e69d4a5a 100644
--- a/src/test/test-env-util.c
+++ b/src/test/test-env-util.c
@@ -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;
diff --git a/src/test/test-escape.c b/src/test/test-escape.c
index d060afaffa..aa05520abd 100644
--- a/src/test/test-escape.c
+++ b/src/test/test-escape.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/test/test-exec-util.c b/src/test/test-exec-util.c
index c192d3522c..bd9c809296 100644
--- a/src/test/test-exec-util.c
+++ b/src/test/test-exec-util.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/test/test-execute.c b/src/test/test-execute.c
index 6786d56197..fba798e22b 100644
--- a/src/test/test-execute.c
+++ b/src/test/test-execute.c
@@ -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);
diff --git a/src/test/test-extract-word.c b/src/test/test-extract-word.c
index 7a23fa7b7b..84ab083e87 100644
--- a/src/test/test-extract-word.c
+++ b/src/test/test-extract-word.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/test/test-fd-util.c b/src/test/test-fd-util.c
index 4425b5fe5f..e5a0e9d51b 100644
--- a/src/test/test-fd-util.c
+++ b/src/test/test-fd-util.c
@@ -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;
}
diff --git a/src/test/test-fdset.c b/src/test/test-fdset.c
index adbf99a7ec..bc5d5d4f2b 100644
--- a/src/test/test-fdset.c
+++ b/src/test/test-fdset.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd
diff --git a/src/test/test-fileio.c b/src/test/test-fileio.c
index 27495fa5be..286867d2dc 100644
--- a/src/test/test-fileio.c
+++ b/src/test/test-fileio.c
@@ -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);
diff --git a/src/test/test-firewall-util.c b/src/test/test-firewall-util.c
index 77e809c5bf..38e433a762 100644
--- a/src/test/test-firewall-util.c
+++ b/src/test/test-firewall-util.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/test/test-fs-util.c b/src/test/test-fs-util.c
index 9e964a8bbb..86d963c4c7 100644
--- a/src/test/test-fs-util.c
+++ b/src/test/test-fs-util.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
@@ -34,7 +35,7 @@
static void test_chase_symlinks(void) {
_cleanup_free_ char *result = NULL;
char temp[] = "/tmp/test-chase.XXXXXX";
- const char *top, *p, *q;
+ const char *top, *p, *pslash, *q, *qslash;
int r;
assert_se(mkdtemp(temp));
@@ -65,93 +66,134 @@ static void test_chase_symlinks(void) {
r = chase_symlinks(p, NULL, 0, &result);
assert_se(r > 0);
assert_se(path_equal(result, "/usr"));
+ result = mfree(result);
+ pslash = strjoina(p, "/");
+ r = chase_symlinks(pslash, NULL, 0, &result);
+ assert_se(r > 0);
+ assert_se(path_equal(result, "/usr/"));
result = mfree(result);
+
r = chase_symlinks(p, temp, 0, &result);
assert_se(r == -ENOENT);
+ r = chase_symlinks(pslash, temp, 0, &result);
+ assert_se(r == -ENOENT);
+
q = strjoina(temp, "/usr");
r = chase_symlinks(p, temp, CHASE_NONEXISTENT, &result);
assert_se(r == 0);
assert_se(path_equal(result, q));
+ result = mfree(result);
- assert_se(mkdir(q, 0700) >= 0);
+ qslash = strjoina(q, "/");
+ r = chase_symlinks(pslash, temp, CHASE_NONEXISTENT, &result);
+ assert_se(r == 0);
+ assert_se(path_equal(result, qslash));
result = mfree(result);
+
+ assert_se(mkdir(q, 0700) >= 0);
+
r = chase_symlinks(p, temp, 0, &result);
assert_se(r > 0);
assert_se(path_equal(result, q));
+ result = mfree(result);
+
+ r = chase_symlinks(pslash, temp, 0, &result);
+ assert_se(r > 0);
+ assert_se(path_equal(result, qslash));
+ result = mfree(result);
p = strjoina(temp, "/slash");
assert_se(symlink("/", p) >= 0);
- result = mfree(result);
r = chase_symlinks(p, NULL, 0, &result);
assert_se(r > 0);
assert_se(path_equal(result, "/"));
-
result = mfree(result);
+
r = chase_symlinks(p, temp, 0, &result);
assert_se(r > 0);
assert_se(path_equal(result, temp));
+ result = mfree(result);
/* Paths that would "escape" outside of the "root" */
p = strjoina(temp, "/6dots");
assert_se(symlink("../../..", p) >= 0);
- result = mfree(result);
r = chase_symlinks(p, temp, 0, &result);
assert_se(r > 0 && path_equal(result, temp));
+ result = mfree(result);
p = strjoina(temp, "/6dotsusr");
assert_se(symlink("../../../usr", p) >= 0);
- result = mfree(result);
r = chase_symlinks(p, temp, 0, &result);
assert_se(r > 0 && path_equal(result, q));
+ result = mfree(result);
p = strjoina(temp, "/top/8dotsusr");
assert_se(symlink("../../../../usr", p) >= 0);
- result = mfree(result);
r = chase_symlinks(p, temp, 0, &result);
assert_se(r > 0 && path_equal(result, q));
+ result = mfree(result);
/* Paths that contain repeated slashes */
p = strjoina(temp, "/slashslash");
assert_se(symlink("///usr///", p) >= 0);
- result = mfree(result);
r = chase_symlinks(p, NULL, 0, &result);
assert_se(r > 0);
assert_se(path_equal(result, "/usr"));
-
result = mfree(result);
+
r = chase_symlinks(p, temp, 0, &result);
assert_se(r > 0);
assert_se(path_equal(result, q));
+ result = mfree(result);
/* Paths using . */
- result = mfree(result);
r = chase_symlinks("/etc/./.././", NULL, 0, &result);
assert_se(r > 0);
assert_se(path_equal(result, "/"));
-
result = mfree(result);
+
r = chase_symlinks("/etc/./.././", "/etc", 0, &result);
assert_se(r > 0 && path_equal(result, "/etc"));
+ result = mfree(result);
+ r = chase_symlinks("/../.././//../../etc", NULL, 0, &result);
+ assert_se(r > 0);
+ assert_se(streq(result, "/etc"));
+ result = mfree(result);
+
+ r = chase_symlinks("/../.././//../../test-chase.fsldajfl", NULL, CHASE_NONEXISTENT, &result);
+ assert_se(r == 0);
+ assert_se(streq(result, "/test-chase.fsldajfl"));
result = mfree(result);
+
+ r = chase_symlinks("/../.././//../../etc", "/", CHASE_PREFIX_ROOT, &result);
+ assert_se(r > 0);
+ assert_se(streq(result, "/etc"));
+ result = mfree(result);
+
+ r = chase_symlinks("/../.././//../../test-chase.fsldajfl", "/", CHASE_PREFIX_ROOT|CHASE_NONEXISTENT, &result);
+ assert_se(r == 0);
+ assert_se(streq(result, "/test-chase.fsldajfl"));
+ result = mfree(result);
+
r = chase_symlinks("/etc/machine-id/foo", NULL, 0, &result);
assert_se(r == -ENOTDIR);
+ result = mfree(result);
/* Path that loops back to self */
- result = mfree(result);
p = strjoina(temp, "/recursive-symlink");
assert_se(symlink("recursive-symlink", p) >= 0);
r = chase_symlinks(p, NULL, 0, &result);
@@ -220,8 +262,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);
@@ -230,6 +273,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);
@@ -237,6 +282,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);
}
@@ -270,9 +317,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"));
@@ -315,6 +362,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();
@@ -322,6 +395,7 @@ int main(int argc, char *argv[]) {
test_var_tmp();
test_chase_symlinks();
test_dot_or_dot_dot();
+ test_access_fd();
return 0;
}
diff --git a/src/test/test-fstab-util.c b/src/test/test-fstab-util.c
index 63a4b8c243..081ec6a901 100644
--- a/src/test/test-fstab-util.c
+++ b/src/test/test-fstab-util.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/test/test-glob-util.c b/src/test/test-glob-util.c
index af866e004b..bd2f8fcfde 100644
--- a/src/test/test-glob-util.c
+++ b/src/test/test-glob-util.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/test/test-hash.c b/src/test/test-hash.c
index 02d1cfaee3..f3b4258d6b 100644
--- a/src/test/test-hash.c
+++ b/src/test/test-hash.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/test/test-hashmap-plain.c b/src/test/test-hashmap-plain.c
index 0471cd2f2f..1725766e5a 100644
--- a/src/test/test-hashmap-plain.c
+++ b/src/test/test-hashmap-plain.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd
diff --git a/src/test/test-hashmap.c b/src/test/test-hashmap.c
index 83cea360e6..dd9195425e 100644
--- a/src/test/test-hashmap.c
+++ b/src/test/test-hashmap.c
@@ -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();
diff --git a/src/test/test-helper.c b/src/test/test-helper.c
index 5b707c3276..c371e199ba 100644
--- a/src/test/test-helper.c
+++ b/src/test/test-helper.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
@@ -22,20 +23,25 @@
#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);
}
diff --git a/src/test/test-helper.h b/src/test/test-helper.h
index 8af32c8744..1ee93f5c55 100644
--- a/src/test/test-helper.h
+++ b/src/test/test-helper.h
@@ -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);
diff --git a/src/test/test-hexdecoct.c b/src/test/test-hexdecoct.c
index fcae427e74..4f19cb406f 100644
--- a/src/test/test-hexdecoct.c
+++ b/src/test/test-hexdecoct.c
@@ -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) {
diff --git a/src/test/test-hostname-util.c b/src/test/test-hostname-util.c
index d2c3ea5e0d..329354831b 100644
--- a/src/test/test-hostname-util.c
+++ b/src/test/test-hostname-util.c
@@ -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;
}
diff --git a/src/test/test-hostname.c b/src/test/test-hostname.c
index b38507df5d..febb4c64c7 100644
--- a/src/test/test-hostname.c
+++ b/src/test/test-hostname.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/test/test-id128.c b/src/test/test-id128.c
index e5f45206f1..b7fca1540c 100644
--- a/src/test/test-id128.c
+++ b/src/test/test-id128.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/test/test-in-addr-util.c b/src/test/test-in-addr-util.c
index 8b7a1229fe..73692ec411 100644
--- a/src/test/test-in-addr-util.c
+++ b/src/test/test-in-addr-util.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd
diff --git a/src/test/test-install-root.c b/src/test/test-install-root.c
index e2754a0773..efdd82a797 100644
--- a/src/test/test-install-root.c
+++ b/src/test/test-install-root.c
@@ -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);
diff --git a/src/test/test-install.c b/src/test/test-install.c
index fb36aa83ca..2f919187a9 100644
--- a/src/test/test-install.c
+++ b/src/test/test-install.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/test/test-io-util.c b/src/test/test-io-util.c
index 10bd3833bc..9ed9864f29 100644
--- a/src/test/test-io-util.c
+++ b/src/test/test-io-util.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/test/test-ipcrm.c b/src/test/test-ipcrm.c
index ce6c7aa18a..c901e35841 100644
--- a/src/test/test-ipcrm.c
+++ b/src/test/test-ipcrm.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/test/test-job-type.c b/src/test/test-job-type.c
index 7f0b9f253c..46444a0462 100644
--- a/src/test/test-job-type.c
+++ b/src/test/test-job-type.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/test/test-journal-importer.c b/src/test/test-journal-importer.c
index a61212ce7b..931a281f54 100644
--- a/src/test/test-journal-importer.c
+++ b/src/test/test-journal-importer.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/test/test-libudev.c b/src/test/test-libudev.c
index 0f71c18b65..408d14133b 100644
--- a/src/test/test-libudev.c
+++ b/src/test/test-libudev.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/test/test-list.c b/src/test/test-list.c
index 0ccd745cc9..25ffd8fb86 100644
--- a/src/test/test-list.c
+++ b/src/test/test-list.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd
diff --git a/src/test/test-locale-util.c b/src/test/test-locale-util.c
index 427c698d1d..4467bdd48d 100644
--- a/src/test/test-locale-util.c
+++ b/src/test/test-locale-util.c
@@ -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;
}
diff --git a/src/test/test-log.c b/src/test/test-log.c
index 8ab569f477..9468349cba 100644
--- a/src/test/test-log.c
+++ b/src/test/test-log.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/test/test-loopback.c b/src/test/test-loopback.c
index c70633a0f3..3fe897ac08 100644
--- a/src/test/test-loopback.c
+++ b/src/test/test-loopback.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/test/test-mount-util.c b/src/test/test-mount-util.c
index 7c5929d009..09a624842c 100644
--- a/src/test/test-mount-util.c
+++ b/src/test/test-mount-util.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
@@ -19,14 +20,22 @@
#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;
}
diff --git a/src/test/test-namespace.c b/src/test/test-namespace.c
index de7be1f9cc..3b84b01961 100644
--- a/src/test/test-namespace.c
+++ b/src/test/test-namespace.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/test/test-netlink-manual.c b/src/test/test-netlink-manual.c
index bc6dd0926c..3b10b697af 100644
--- a/src/test/test-netlink-manual.c
+++ b/src/test/test-netlink-manual.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
@@ -26,38 +27,33 @@
#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;
}
diff --git a/src/test/test-ns.c b/src/test/test-ns.c
index b142c3a115..76e2b38b17 100644
--- a/src/test/test-ns.c
+++ b/src/test/test-ns.c
@@ -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,
diff --git a/src/test/test-nss.c b/src/test/test-nss.c
index 9f73bc9a5d..acfb6760a9 100644
--- a/src/test/test-nss.c
+++ b/src/test/test-nss.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/test/test-parse-util.c b/src/test/test-parse-util.c
index 1b29b2ea87..8259e133c3 100644
--- a/src/test/test-parse-util.c
+++ b/src/test/test-parse-util.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
@@ -21,8 +22,11 @@
#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_atou64(void) {
@@ -459,6 +493,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) {
@@ -492,6 +532,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) {
@@ -513,6 +559,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")) {
@@ -525,6 +574,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 */
@@ -540,6 +592,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) {
@@ -558,6 +613,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) {
@@ -596,6 +652,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);
@@ -606,6 +664,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();
@@ -625,6 +751,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;
}
diff --git a/src/test/test-path-lookup.c b/src/test/test-path-lookup.c
index 096326d176..834b061980 100644
--- a/src/test/test-path-lookup.c
+++ b/src/test/test-path-lookup.c
@@ -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);
}
diff --git a/src/test/test-path-util.c b/src/test/test-path-util.c
index ff46a896b5..0db835608a 100644
--- a/src/test/test-path-util.c
+++ b/src/test/test-path-util.c
@@ -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();
diff --git a/src/test/test-path.c b/src/test/test-path.c
index c1915017df..3f579b064d 100644
--- a/src/test/test-path.c
+++ b/src/test/test-path.c
@@ -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)) {
diff --git a/src/test/test-prioq.c b/src/test/test-prioq.c
index d81880a655..f558384a18 100644
--- a/src/test/test-prioq.c
+++ b/src/test/test-prioq.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/test/test-proc-cmdline.c b/src/test/test-proc-cmdline.c
index 12dac8585b..01b8cf0ca7 100644
--- a/src/test/test-proc-cmdline.c
+++ b/src/test/test-proc-cmdline.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/test/test-process-util.c b/src/test/test-process-util.c
index 0f0e2cbcb9..a38f917961 100644
--- a/src/test/test-process-util.c
+++ b/src/test/test-process-util.c
@@ -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);
diff --git a/src/test/test-random-util.c b/src/test/test-random-util.c
index 50f4da270d..d7ccc91f9b 100644
--- a/src/test/test-random-util.c
+++ b/src/test/test-random-util.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/test/test-ratelimit.c b/src/test/test-ratelimit.c
index 990b834c79..dcfa60e94d 100644
--- a/src/test/test-ratelimit.c
+++ b/src/test/test-ratelimit.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd
diff --git a/src/test/test-replace-var.c b/src/test/test-replace-var.c
index 60e05d04c9..56ce99e7ac 100644
--- a/src/test/test-replace-var.c
+++ b/src/test/test-replace-var.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/test/test-rlimit-util.c b/src/test/test-rlimit-util.c
index 62afd2de5e..93724434a5 100644
--- a/src/test/test-rlimit-util.c
+++ b/src/test/test-rlimit-util.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd
diff --git a/src/test/test-sched-prio.c b/src/test/test-sched-prio.c
index 9bed4b3832..804cee34e9 100644
--- a/src/test/test-sched-prio.c
+++ b/src/test/test-sched-prio.c
@@ -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);
diff --git a/src/test/test-seccomp.c b/src/test/test-seccomp.c
index 4d63b68809..36b49ebc71 100644
--- a/src/test/test-seccomp.c
+++ b/src/test/test-seccomp.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
@@ -17,12 +18,12 @@
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);
}
diff --git a/src/test/test-selinux.c b/src/test/test-selinux.c
index 190736aa47..f954dbb456 100644
--- a/src/test/test-selinux.c
+++ b/src/test/test-selinux.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/test/test-set.c b/src/test/test-set.c
index 3fab350cf6..0a29a62621 100644
--- a/src/test/test-set.c
+++ b/src/test/test-set.c
@@ -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();
diff --git a/src/test/test-sigbus.c b/src/test/test-sigbus.c
index bcc08b226c..75df8513f1 100644
--- a/src/test/test-sigbus.c
+++ b/src/test/test-sigbus.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/test/test-signal-util.c b/src/test/test-signal-util.c
index 92e3927784..13a1d2ba1f 100644
--- a/src/test/test-signal-util.c
+++ b/src/test/test-signal-util.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/test/test-siphash24.c b/src/test/test-siphash24.c
index b74b7ad2dd..7469457be2 100644
--- a/src/test/test-siphash24.c
+++ b/src/test/test-siphash24.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/test/test-sizeof.c b/src/test/test-sizeof.c
index bfc421e4ba..f472edcfa1 100644
--- a/src/test/test-sizeof.c
+++ b/src/test/test-sizeof.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/test/test-sleep.c b/src/test/test-sleep.c
index 97b6f3015d..3c2b115fbf 100644
--- a/src/test/test-sleep.c
+++ b/src/test/test-sleep.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/test/test-socket-util.c b/src/test/test-socket-util.c
index 8ac1d7989f..6a91baf6d2 100644
--- a/src/test/test-socket-util.c
+++ b/src/test/test-socket-util.c
@@ -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
index 0000000000..6bf312057a
--- /dev/null
+++ b/src/test/test-specifier.c
@@ -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;
+}
diff --git a/src/test/test-stat-util.c b/src/test/test-stat-util.c
index 8e027ff26c..c606425d2d 100644
--- a/src/test/test-stat-util.c
+++ b/src/test/test-stat-util.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
@@ -71,16 +72,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) {
@@ -95,7 +96,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;
diff --git a/src/test/test-strbuf.c b/src/test/test-strbuf.c
index 513218c397..891d7b1d42 100644
--- a/src/test/test-strbuf.c
+++ b/src/test/test-strbuf.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/test/test-string-util.c b/src/test/test-string-util.c
index 604701ff7a..07ee98465c 100644
--- a/src/test/test-string-util.c
+++ b/src/test/test-string-util.c
@@ -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();
diff --git a/src/test/test-strip-tab-ansi.c b/src/test/test-strip-tab-ansi.c
index 72b0f6fc11..aabb7c40e7 100644
--- a/src/test/test-strip-tab-ansi.c
+++ b/src/test/test-strip-tab-ansi.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/test/test-strv.c b/src/test/test-strv.c
index 88da69e2d7..aec00eb817 100644
--- a/src/test/test-strv.c
+++ b/src/test/test-strv.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/test/test-strxcpyx.c b/src/test/test-strxcpyx.c
index d95945f6b0..7e2d3c2522 100644
--- a/src/test/test-strxcpyx.c
+++ b/src/test/test-strxcpyx.c
@@ -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
index 0000000000..7e563551cd
--- /dev/null
+++ b/src/test/test-systemd-tmpfiles.py
@@ -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)
diff --git a/src/test/test-tables.c b/src/test/test-tables.c
index a16b04dbd2..023fae040d 100644
--- a/src/test/test-tables.c
+++ b/src/test/test-tables.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd
diff --git a/src/test/test-terminal-util.c b/src/test/test-terminal-util.c
index 373a1b70ba..51b3306d16 100644
--- a/src/test/test-terminal-util.c
+++ b/src/test/test-terminal-util.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/test/test-time.c b/src/test/test-time-util.c
index b7a06c7b19..ebf85fcc7c 100644
--- a/src/test/test-time.c
+++ b/src/test/test-time-util.c
@@ -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);
diff --git a/src/test/test-tmpfiles.c b/src/test/test-tmpfiles.c
index b4c76048a4..c479eccb8b 100644
--- a/src/test/test-tmpfiles.c
+++ b/src/test/test-tmpfiles.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/test/test-udev.c b/src/test/test-udev.c
index c84bd8991e..e765f716ca 100644
--- a/src/test/test-udev.c
+++ b/src/test/test-udev.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/test/test-uid-range.c b/src/test/test-uid-range.c
index 41f06a5cec..ce461d606b 100644
--- a/src/test/test-uid-range.c
+++ b/src/test/test-uid-range.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/test/test-unaligned.c b/src/test/test-unaligned.c
index 4f64398943..00445fa302 100644
--- a/src/test/test-unaligned.c
+++ b/src/test/test-unaligned.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd
diff --git a/src/test/test-unit-file.c b/src/test/test-unit-file.c
index 07f21d0d3d..40eeba6af5 100644
--- a/src/test/test-unit-file.c
+++ b/src/test/test-unit-file.c
@@ -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();
diff --git a/src/test/test-unit-name.c b/src/test/test-unit-name.c
index 1992357e1b..e24892b590 100644
--- a/src/test/test-unit-name.c
+++ b/src/test/test-unit-name.c
@@ -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());
diff --git a/src/test/test-user-util.c b/src/test/test-user-util.c
index 2a344a9f93..17a8520741 100644
--- a/src/test/test-user-util.c
+++ b/src/test/test-user-util.c
@@ -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();
diff --git a/src/test/test-utf8.c b/src/test/test-utf8.c
index 1ce5a5a24d..1ea0901f69 100644
--- a/src/test/test-utf8.c
+++ b/src/test/test-utf8.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/test/test-util.c b/src/test/test-util.c
index f8bf0cb875..2124511bf0 100644
--- a/src/test/test-util.c
+++ b/src/test/test-util.c
@@ -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;
diff --git a/src/test/test-verbs.c b/src/test/test-verbs.c
index 0fcdd9e78d..88276a21ea 100644
--- a/src/test/test-verbs.c
+++ b/src/test/test-verbs.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/test/test-watchdog.c b/src/test/test-watchdog.c
index 276b803cc2..e068d1ddd4 100644
--- a/src/test/test-watchdog.c
+++ b/src/test/test-watchdog.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/test/test-web-util.c b/src/test/test-web-util.c
index 79a3a13af6..f59a196721 100644
--- a/src/test/test-web-util.c
+++ b/src/test/test-web-util.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/test/test-xattr-util.c b/src/test/test-xattr-util.c
index 267f29426c..01c371a39c 100644
--- a/src/test/test-xattr-util.c
+++ b/src/test/test-xattr-util.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/test/test-xml.c b/src/test/test-xml.c
index b0b72fa78a..5b9abc16ba 100644
--- a/src/test/test-xml.c
+++ b/src/test/test-xml.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/timedate/meson.build b/src/timedate/meson.build
index ce92a6be69..80e5cd21be 100644
--- a/src/timedate/meson.build
+++ b/src/timedate/meson.build
@@ -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
diff --git a/src/timedate/org.freedesktop.timedate1.conf b/src/timedate/org.freedesktop.timedate1.conf
index 36557d5841..53f6c8435d 100644
--- a/src/timedate/org.freedesktop.timedate1.conf
+++ b/src/timedate/org.freedesktop.timedate1.conf
@@ -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
diff --git a/src/timedate/org.freedesktop.timedate1.policy.in b/src/timedate/org.freedesktop.timedate1.policy.in
index aa30b70831..cc2e1652da 100644
--- a/src/timedate/org.freedesktop.timedate1.policy.in
+++ b/src/timedate/org.freedesktop.timedate1.policy.in
@@ -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>
diff --git a/src/timedate/org.freedesktop.timedate1.service b/src/timedate/org.freedesktop.timedate1.service
index 875f4bec78..d5f3a6e30d 100644
--- a/src/timedate/org.freedesktop.timedate1.service
+++ b/src/timedate/org.freedesktop.timedate1.service
@@ -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/src/timedate/timedatectl.c b/src/timedate/timedatectl.c
index a30e783c09..d80a917870 100644
--- a/src/timedate/timedatectl.c
+++ b/src/timedate/timedatectl.c
@@ -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;
diff --git a/src/timedate/timedated.c b/src/timedate/timedated.c
index 1061b094d3..a55a929a49 100644
--- a/src/timedate/timedated.c
+++ b/src/timedate/timedated.c
@@ -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;
diff --git a/src/timesync/meson.build b/src/timesync/meson.build
index 690af9552c..e8bd3d59a9 100644
--- a/src/timesync/meson.build
+++ b/src/timesync/meson.build
@@ -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
diff --git a/src/timesync/test-timesync.c b/src/timesync/test-timesync.c
index a5a3433022..7d5cd38078 100644
--- a/src/timesync/test-timesync.c
+++ b/src/timesync/test-timesync.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/timesync/timesyncd-conf.c b/src/timesync/timesyncd-conf.c
index f394d0a2af..124d03da0b 100644
--- a/src/timesync/timesyncd-conf.c
+++ b/src/timesync/timesyncd-conf.c
@@ -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;
}
diff --git a/src/timesync/timesyncd-conf.h b/src/timesync/timesyncd-conf.h
index 0c4b44e707..8252298fe0 100644
--- a/src/timesync/timesyncd-conf.h
+++ b/src/timesync/timesyncd-conf.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/timesync/timesyncd-gperf.gperf b/src/timesync/timesyncd-gperf.gperf
index 29a2cfeef6..7d4cd2808e 100644
--- a/src/timesync/timesyncd-gperf.gperf
+++ b/src/timesync/timesyncd-gperf.gperf
@@ -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)
diff --git a/src/timesync/timesyncd-manager.c b/src/timesync/timesyncd-manager.c
index eacb10f1c0..8bd111fe0c 100644
--- a/src/timesync/timesyncd-manager.c
+++ b/src/timesync/timesyncd-manager.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
@@ -56,15 +57,8 @@
#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);
diff --git a/src/timesync/timesyncd-manager.h b/src/timesync/timesyncd-manager.h
index cf681f6098..4d6258839b 100644
--- a/src/timesync/timesyncd-manager.h
+++ b/src/timesync/timesyncd-manager.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
@@ -25,11 +26,19 @@
#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;
diff --git a/src/timesync/timesyncd-server.c b/src/timesync/timesyncd-server.c
index 57a7bf2c25..bd0030b982 100644
--- a/src/timesync/timesyncd-server.c
+++ b/src/timesync/timesyncd-server.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/timesync/timesyncd-server.h b/src/timesync/timesyncd-server.h
index 8a19e41d67..2dc51a9730 100644
--- a/src/timesync/timesyncd-server.h
+++ b/src/timesync/timesyncd-server.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/timesync/timesyncd.c b/src/timesync/timesyncd.c
index 6b802c607c..962285f7b1 100644
--- a/src/timesync/timesyncd.c
+++ b/src/timesync/timesyncd.c
@@ -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");
diff --git a/src/timesync/timesyncd.conf.in b/src/timesync/timesyncd.conf.in
index b6a2ada273..f91c034a01 100644
--- a/src/timesync/timesyncd.conf.in
+++ b/src/timesync/timesyncd.conf.in
@@ -14,3 +14,6 @@
[Time]
#NTP=
#FallbackNTP=@NTP_SERVERS@
+#RootDistanceMaxSec=5
+#PollIntervalMinSec=32
+#PollIntervalMaxSec=2048
diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c
index 7f457ca36e..a7ce1a8049 100644
--- a/src/tmpfiles/tmpfiles.c
+++ b/src/tmpfiles/tmpfiles.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
@@ -32,9 +33,12 @@
#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;
}
diff --git a/src/tty-ask-password-agent/tty-ask-password-agent.c b/src/tty-ask-password-agent/tty-ask-password-agent.c
index 495ae464b4..1553655a28 100644
--- a/src/tty-ask-password-agent/tty-ask-password-agent.c
+++ b/src/tty-ask-password-agent/tty-ask-password-agent.c
@@ -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;
}
}
diff --git a/src/udev/ata_id/ata_id.c b/src/udev/ata_id/ata_id.c
index 1dc62b69d5..7e3654c30f 100644
--- a/src/udev/ata_id/ata_id.c
+++ b/src/udev/ata_id/ata_id.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
/*
* ata_id - reads product/serial number from ATA drives
*
diff --git a/src/udev/cdrom_id/cdrom_id.c b/src/udev/cdrom_id/cdrom_id.c
index b9cf3bdf68..9644861adc 100644
--- a/src/udev/cdrom_id/cdrom_id.c
+++ b/src/udev/cdrom_id/cdrom_id.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
/*
* cdrom_id - optical drive and media information prober
*
diff --git a/src/udev/collect/collect.c b/src/udev/collect/collect.c
index 52229d82b5..3e278bd637 100644
--- a/src/udev/collect/collect.c
+++ b/src/udev/collect/collect.c
@@ -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;
}
diff --git a/src/udev/generate-keyboard-keys-gperf.sh b/src/udev/generate-keyboard-keys-gperf.sh
index 5724e4e3dc..eb977447e3 100755
--- a/src/udev/generate-keyboard-keys-gperf.sh
+++ b/src/udev/generate-keyboard-keys-gperf.sh
@@ -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 "%%"
diff --git a/src/udev/meson.build b/src/udev/meson.build
index dd24b7e9f7..d01cf8f194 100644
--- a/src/udev/meson.build
+++ b/src/udev/meson.build
@@ -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
diff --git a/src/udev/mtd_probe/mtd_probe.c b/src/udev/mtd_probe/mtd_probe.c
index 462fab7623..1d692f1187 100644
--- a/src/udev/mtd_probe/mtd_probe.c
+++ b/src/udev/mtd_probe/mtd_probe.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) 2010 - Maxim Levitsky
*
diff --git a/src/udev/mtd_probe/mtd_probe.h b/src/udev/mtd_probe/mtd_probe.h
index 68e4954537..39841f9b7d 100644
--- a/src/udev/mtd_probe/mtd_probe.h
+++ b/src/udev/mtd_probe/mtd_probe.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
#pragma once
/*
diff --git a/src/udev/mtd_probe/probe_smartmedia.c b/src/udev/mtd_probe/probe_smartmedia.c
index 89bceaa146..eb74fe1eb6 100644
--- a/src/udev/mtd_probe/probe_smartmedia.c
+++ b/src/udev/mtd_probe/probe_smartmedia.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) 2010 - Maxim Levitsky
*
diff --git a/src/udev/net/ethtool-util.c b/src/udev/net/ethtool-util.c
index a5b87cf51a..3ed8a51fd4 100644
--- a/src/udev/net/ethtool-util.c
+++ b/src/udev/net/ethtool-util.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/udev/net/ethtool-util.h b/src/udev/net/ethtool-util.h
index 909b56b1e6..5681472a9a 100644
--- a/src/udev/net/ethtool-util.h
+++ b/src/udev/net/ethtool-util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/udev/net/link-config-gperf.gperf b/src/udev/net/link-config-gperf.gperf
index 52bb4775dd..85f0a0625b 100644
--- a/src/udev/net/link-config-gperf.gperf
+++ b/src/udev/net/link-config-gperf.gperf
@@ -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"
diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c
index a5f3b1a1b0..89891f9e27 100644
--- a/src/udev/net/link-config.c
+++ b/src/udev/net/link-config.c
@@ -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 */
diff --git a/src/udev/net/link-config.h b/src/udev/net/link-config.h
index ff91a65135..a413251bd0 100644
--- a/src/udev/net/link-config.h
+++ b/src/udev/net/link-config.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
diff --git a/src/udev/scsi_id/scsi.h b/src/udev/scsi_id/scsi.h
index a27a84a40a..8b759a768d 100644
--- a/src/udev/scsi_id/scsi.h
+++ b/src/udev/scsi_id/scsi.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
#pragma once
/*
diff --git a/src/udev/scsi_id/scsi_id.c b/src/udev/scsi_id/scsi_id.c
index 0abbc510ee..ab4ee7b00b 100644
--- a/src/udev/scsi_id/scsi_id.c
+++ b/src/udev/scsi_id/scsi_id.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) IBM Corp. 2003
* Copyright (C) SUSE Linux Products GmbH, 2006
diff --git a/src/udev/scsi_id/scsi_id.h b/src/udev/scsi_id/scsi_id.h
index 5c2e1c28ee..9a33f6a158 100644
--- a/src/udev/scsi_id/scsi_id.h
+++ b/src/udev/scsi_id/scsi_id.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
#pragma once
/*
diff --git a/src/udev/scsi_id/scsi_serial.c b/src/udev/scsi_id/scsi_serial.c
index b56a541f78..bf6b28e8e5 100644
--- a/src/udev/scsi_id/scsi_serial.c
+++ b/src/udev/scsi_id/scsi_serial.c
@@ -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;
diff --git a/src/udev/udev-builtin-blkid.c b/src/udev/udev-builtin-blkid.c
index 4487e82693..6ff244e96c 100644
--- a/src/udev/udev-builtin-blkid.c
+++ b/src/udev/udev-builtin-blkid.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
/*
* probe disks for filesystems and partitions
*
diff --git a/src/udev/udev-builtin-btrfs.c b/src/udev/udev-builtin-btrfs.c
index 4d59cc82a8..9e0f1e0aac 100644
--- a/src/udev/udev-builtin-btrfs.c
+++ b/src/udev/udev-builtin-btrfs.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/udev/udev-builtin-hwdb.c b/src/udev/udev-builtin-hwdb.c
index acd1d1a6de..ca7f7c2304 100644
--- a/src/udev/udev-builtin-hwdb.c
+++ b/src/udev/udev-builtin-hwdb.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/udev/udev-builtin-input_id.c b/src/udev/udev-builtin-input_id.c
index 60f760ef77..b13fdb135b 100644
--- a/src/udev/udev-builtin-input_id.c
+++ b/src/udev/udev-builtin-input_id.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
/*
* expose input properties via udev
*
diff --git a/src/udev/udev-builtin-keyboard.c b/src/udev/udev-builtin-keyboard.c
index e316bb93ba..0044280399 100644
--- a/src/udev/udev-builtin-keyboard.c
+++ b/src/udev/udev-builtin-keyboard.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/udev/udev-builtin-kmod.c b/src/udev/udev-builtin-kmod.c
index 9665f678fd..2530fdfd23 100644
--- a/src/udev/udev-builtin-kmod.c
+++ b/src/udev/udev-builtin-kmod.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
/*
* load kernel modules
*
@@ -24,13 +25,14 @@
#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;
}
diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c
index 46eb6114ff..f3be27fdd0 100644
--- a/src/udev/udev-builtin-net_id.c
+++ b/src/udev/udev-builtin-net_id.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
@@ -274,7 +275,7 @@ static int dev_pci_slot(struct udev_device *dev, struct netnames *names) {
goto out;
}
- snprintf(slots, sizeof slots, "%s/slots", udev_device_get_syspath(pci));
+ xsprintf(slots, "%s/slots", udev_device_get_syspath(pci));
dir = opendir(slots);
if (!dir) {
err = -errno;
@@ -293,7 +294,7 @@ static int dev_pci_slot(struct udev_device *dev, struct netnames *names) {
if (i < 1)
continue;
- snprintf(str, sizeof str, "%s/%s/address", slots, dent->d_name);
+ xsprintf(str, "%s/%s/address", slots, dent->d_name);
if (read_one_line_file(str, &address) >= 0) {
/* match slot address with device by stripping the function */
if (strneq(address, udev_device_get_sysname(names->pcidev), strlen(address)))
diff --git a/src/udev/udev-builtin-net_setup_link.c b/src/udev/udev-builtin-net_setup_link.c
index 8e47775135..40158e0afc 100644
--- a/src/udev/udev-builtin-net_setup_link.c
+++ b/src/udev/udev-builtin-net_setup_link.c
@@ -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);
diff --git a/src/udev/udev-builtin-path_id.c b/src/udev/udev-builtin-path_id.c
index f5d7c23d9f..9ce2079a67 100644
--- a/src/udev/udev-builtin-path_id.c
+++ b/src/udev/udev-builtin-path_id.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
/*
* compose persistent device path
*
@@ -31,49 +32,55 @@
#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 = {
diff --git a/src/udev/udev-builtin-uaccess.c b/src/udev/udev-builtin-uaccess.c
index d92a10e1c5..edea242e65 100644
--- a/src/udev/udev-builtin-uaccess.c
+++ b/src/udev/udev-builtin-uaccess.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
/*
* manage device node user ACL
*
diff --git a/src/udev/udev-builtin-usb_id.c b/src/udev/udev-builtin-usb_id.c
index 3ce075f079..6d22dfe82c 100644
--- a/src/udev/udev-builtin-usb_id.c
+++ b/src/udev/udev-builtin-usb_id.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
/*
* USB device properties and persistent device path
*
diff --git a/src/udev/udev-builtin.c b/src/udev/udev-builtin.c
index e4dccd0b09..db2b6874f8 100644
--- a/src/udev/udev-builtin.c
+++ b/src/udev/udev-builtin.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/udev/udev-ctrl.c b/src/udev/udev-ctrl.c
index 92e4f8d9c0..7b8110582d 100644
--- a/src/udev/udev-ctrl.c
+++ b/src/udev/udev-ctrl.c
@@ -1,4 +1,5 @@
-/*
+/* SPDX-License-Identifier: LGPL-2.1+
+ *
* libudev - interface to udev device information
*
* Copyright (C) 2008 Kay Sievers <kay@vrfy.org>
diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c
index 4cadff7f6f..8f7c28f03d 100644
--- a/src/udev/udev-event.c
+++ b/src/udev/udev-event.c
@@ -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:
diff --git a/src/udev/udev-node.c b/src/udev/udev-node.c
index 01e56cac36..bb845889cc 100644
--- a/src/udev/udev-node.c
+++ b/src/udev/udev-node.c
@@ -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);
}
diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c
index 9aaec72baf..f4708bb066 100644
--- a/src/udev/udev-rules.c
+++ b/src/udev/udev-rules.c
@@ -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),
diff --git a/src/udev/udev-watch.c b/src/udev/udev-watch.c
index aa432bb90a..351cb6345a 100644
--- a/src/udev/udev-watch.c
+++ b/src/udev/udev-watch.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) 2004-2012 Kay Sievers <kay@vrfy.org>
* Copyright (C) 2009 Canonical Ltd.
diff --git a/src/udev/udev.h b/src/udev/udev.h
index 2204db5a95..ea11c2d29e 100644
--- a/src/udev/udev.h
+++ b/src/udev/udev.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
#pragma once
/*
diff --git a/src/udev/udevadm-control.c b/src/udev/udevadm-control.c
index 6f8e96a123..d80d61583d 100644
--- a/src/udev/udevadm-control.c
+++ b/src/udev/udevadm-control.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) 2005-2011 Kay Sievers <kay@vrfy.org>
*
@@ -23,12 +24,13 @@
#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;
diff --git a/src/udev/udevadm-hwdb.c b/src/udev/udevadm-hwdb.c
index 4a23270dfb..ab5dc7ab64 100644
--- a/src/udev/udevadm-hwdb.c
+++ b/src/udev/udevadm-hwdb.c
@@ -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;
diff --git a/src/udev/udevadm-info.c b/src/udev/udevadm-info.c
index 16b2aab0a1..580e95095b 100644
--- a/src/udev/udevadm-info.c
+++ b/src/udev/udevadm-info.c
@@ -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(" ");
diff --git a/src/udev/udevadm-monitor.c b/src/udev/udevadm-monitor.c
index 77ae3a9732..028ef92bc2 100644
--- a/src/udev/udevadm-monitor.c
+++ b/src/udev/udevadm-monitor.c
@@ -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);
diff --git a/src/udev/udevadm-settle.c b/src/udev/udevadm-settle.c
index 6a5dc6e9e4..0af3e6412b 100644
--- a/src/udev/udevadm-settle.c
+++ b/src/udev/udevadm-settle.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) 2006-2009 Kay Sievers <kay@vrfy.org>
* Copyright (C) 2009 Canonical Ltd.
@@ -28,13 +29,14 @@
#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;
diff --git a/src/udev/udevadm-test-builtin.c b/src/udev/udevadm-test-builtin.c
index b5662be5c2..f5a39a11c1 100644
--- a/src/udev/udevadm-test-builtin.c
+++ b/src/udev/udevadm-test-builtin.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) 2011 Kay Sievers <kay@vrfy.org>
*
@@ -24,12 +25,13 @@
#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) {
diff --git a/src/udev/udevadm-test.c b/src/udev/udevadm-test.c
index e8ffe2f309..ef1f2f0269 100644
--- a/src/udev/udevadm-test.c
+++ b/src/udev/udevadm-test.c
@@ -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>
@@ -28,13 +29,14 @@
#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) {
diff --git a/src/udev/udevadm-trigger.c b/src/udev/udevadm-trigger.c
index e2ce317e01..f78a2ba437 100644
--- a/src/udev/udevadm-trigger.c
+++ b/src/udev/udevadm-trigger.c
@@ -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;
diff --git a/src/udev/udevadm-util.c b/src/udev/udevadm-util.c
index beda7c36bb..b71b9ebd99 100644
--- a/src/udev/udevadm-util.c
+++ b/src/udev/udevadm-util.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) 2008-2009 Kay Sievers <kay@vrfy.org>
*
diff --git a/src/udev/udevadm-util.h b/src/udev/udevadm-util.h
index dc712b0d93..8262a8343f 100644
--- a/src/udev/udevadm-util.h
+++ b/src/udev/udevadm-util.h
@@ -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);
+}
diff --git a/src/udev/udevadm.c b/src/udev/udevadm.c
index befc3bad7b..06be1e8af5 100644
--- a/src/udev/udevadm.c
+++ b/src/udev/udevadm.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) 2007-2012 Kay Sievers <kay@vrfy.org>
*
diff --git a/src/udev/udevd.c b/src/udev/udevd.c
index 83f846fbc8..1644935ff9 100644
--- a/src/udev/udevd.c
+++ b/src/udev/udevd.c
@@ -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");
diff --git a/src/udev/v4l_id/v4l_id.c b/src/udev/v4l_id/v4l_id.c
index aec6676a33..05f31d479e 100644
--- a/src/udev/v4l_id/v4l_id.c
+++ b/src/udev/v4l_id/v4l_id.c
@@ -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>
diff --git a/src/update-done/update-done.c b/src/update-done/update-done.c
index ec467f1953..ccf2d47196 100644
--- a/src/update-done/update-done.c
+++ b/src/update-done/update-done.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/update-utmp/update-utmp.c b/src/update-utmp/update-utmp.c
index b1b3800cea..e16f67be29 100644
--- a/src/update-utmp/update-utmp.c
+++ b/src/update-utmp/update-utmp.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/user-sessions/user-sessions.c b/src/user-sessions/user-sessions.c
index 9b29b5ba1d..795766a657 100644
--- a/src/user-sessions/user-sessions.c
+++ b/src/user-sessions/user-sessions.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/src/vconsole/90-vconsole.rules.in b/src/vconsole/90-vconsole.rules.in
index 84b4d575bd..11137163ed 100644
--- a/src/vconsole/90-vconsole.rules.in
+++ b/src/vconsole/90-vconsole.rules.in
@@ -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/src/vconsole/meson.build b/src/vconsole/meson.build
index 120057cec1..745aec4f14 100644
--- a/src/vconsole/meson.build
+++ b/src/vconsole/meson.build
@@ -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',
diff --git a/src/vconsole/vconsole-setup.c b/src/vconsole/vconsole-setup.c
index f531aece7f..e19a1637bf 100644
--- a/src/vconsole/vconsole-setup.c
+++ b/src/vconsole/vconsole-setup.c
@@ -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;
diff --git a/src/veritysetup/veritysetup-generator.c b/src/veritysetup/veritysetup-generator.c
index 0bb0bd6e8f..5919b1380e 100644
--- a/src/veritysetup/veritysetup-generator.c
+++ b/src/veritysetup/veritysetup-generator.c
@@ -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)
diff --git a/src/veritysetup/veritysetup.c b/src/veritysetup/veritysetup.c
index c6a79541f7..d3066ca429 100644
--- a/src/veritysetup/veritysetup.c
+++ b/src/veritysetup/veritysetup.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
@@ -17,10 +18,10 @@
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);
diff --git a/src/volatile-root/volatile-root.c b/src/volatile-root/volatile-root.c
index 3c0b6fa1de..56aaa373ff 100644
--- a/src/volatile-root/volatile-root.c
+++ b/src/volatile-root/volatile-root.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
diff --git a/sysctl.d/50-default.conf b/sysctl.d/50-default.conf
index aff99300d9..e263cf0628 100644
--- a/sysctl.d/50-default.conf
+++ b/sysctl.d/50-default.conf
@@ -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
diff --git a/sysctl.d/meson.build b/sysctl.d/meson.build
index 121874c7d2..1e612de41e 100644
--- a/sysctl.d/meson.build
+++ b/sysctl.d/meson.build
@@ -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)
diff --git a/sysusers.d/basic.conf.in b/sysusers.d/basic.conf.in
index 7d6021e855..8e358c02d6 100644
--- a/sysusers.d/basic.conf.in
+++ b/sysusers.d/basic.conf.in
@@ -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@ - -
diff --git a/sysusers.d/meson.build b/sysusers.d/meson.build
index 2f3f3ebd99..a240761837 100644
--- a/sysusers.d/meson.build
+++ b/sysusers.d/meson.build
@@ -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
diff --git a/sysusers.d/systemd-remote.conf.m4 b/sysusers.d/systemd-remote.conf.m4
index 83b362643f..988917672b 100644
--- a/sysusers.d/systemd-remote.conf.m4
+++ b/sysusers.d/systemd-remote.conf.m4
@@ -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
diff --git a/sysusers.d/systemd.conf.m4 b/sysusers.d/systemd.conf.m4
index ef5a3cb619..82e23ca5a8 100644
--- a/sysusers.d/systemd.conf.m4
+++ b/sysusers.d/systemd.conf.m4
@@ -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
index 1916d09a6c..0000000000
--- a/test/Makefile.guess
+++ /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
diff --git a/test/TEST-01-BASIC/Makefile b/test/TEST-01-BASIC/Makefile
index b895de8bcb..3a212a07a9 100644
--- a/test/TEST-01-BASIC/Makefile
+++ b/test/TEST-01-BASIC/Makefile
@@ -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 --$@
diff --git a/test/TEST-02-CRYPTSETUP/test.sh b/test/TEST-02-CRYPTSETUP/test.sh
index 1280148b58..545602e17a 100755
--- a/test/TEST-02-CRYPTSETUP/test.sh
+++ b/test/TEST-02-CRYPTSETUP/test.sh
@@ -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
diff --git a/test/TEST-04-JOURNAL/test-journal.sh b/test/TEST-04-JOURNAL/test-journal.sh
index 493ff00ce0..260cae09ab 100755
--- a/test/TEST-04-JOURNAL/test-journal.sh
+++ b/test/TEST-04-JOURNAL/test-journal.sh
@@ -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
diff --git a/test/TEST-10-ISSUE-2467/test.sh b/test/TEST-10-ISSUE-2467/test.sh
index e7eb1cb303..2f95e9062d 100755
--- a/test/TEST-10-ISSUE-2467/test.sh
+++ b/test/TEST-10-ISSUE-2467/test.sh
@@ -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
diff --git a/test/TEST-13-NSPAWN-SMOKE/Makefile b/test/TEST-13-NSPAWN-SMOKE/Makefile
index 41cca23c7f..ddcbbc302f 100644
--- a/test/TEST-13-NSPAWN-SMOKE/Makefile
+++ b/test/TEST-13-NSPAWN-SMOKE/Makefile
@@ -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 --$@
diff --git a/test/TEST-13-NSPAWN-SMOKE/test.sh b/test/TEST-13-NSPAWN-SMOKE/test.sh
index 7f7380fd62..239c7e0731 100755
--- a/test/TEST-13-NSPAWN-SMOKE/test.sh
+++ b/test/TEST-13-NSPAWN-SMOKE/test.sh
@@ -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
}
diff --git a/test/TEST-14-MACHINE-ID/test.sh b/test/TEST-14-MACHINE-ID/test.sh
index b932060bc2..7342645bc5 100755
--- a/test/TEST-14-MACHINE-ID/test.sh
+++ b/test/TEST-14-MACHINE-ID/test.sh
@@ -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
index 0000000000..e9f93b1104
--- /dev/null
+++ b/test/TEST-16-EXTEND-TIMEOUT/Makefile
@@ -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
index 0000000000..e7f643f9ad
--- /dev/null
+++ b/test/TEST-16-EXTEND-TIMEOUT/assess.sh
@@ -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
index 0000000000..1fd2768fd2
--- /dev/null
+++ b/test/TEST-16-EXTEND-TIMEOUT/extend_timeout_test_service.sh
@@ -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
index 0000000000..4544672066
--- /dev/null
+++ b/test/TEST-16-EXTEND-TIMEOUT/test.sh
@@ -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
index 0000000000..e0b9f6a70b
--- /dev/null
+++ b/test/TEST-16-EXTEND-TIMEOUT/testsuite-fail-runtime.service
@@ -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
index 0000000000..c3fcf23dc0
--- /dev/null
+++ b/test/TEST-16-EXTEND-TIMEOUT/testsuite-fail-start.service
@@ -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
index 0000000000..ce76d10db7
--- /dev/null
+++ b/test/TEST-16-EXTEND-TIMEOUT/testsuite-fail-stop.service
@@ -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
index 0000000000..666f4229bf
--- /dev/null
+++ b/test/TEST-16-EXTEND-TIMEOUT/testsuite-success-all.service
@@ -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
index 0000000000..dc226f5054
--- /dev/null
+++ b/test/TEST-16-EXTEND-TIMEOUT/testsuite-success-runtime.service
@@ -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
index 0000000000..228eece73e
--- /dev/null
+++ b/test/TEST-16-EXTEND-TIMEOUT/testsuite-success-start.service
@@ -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
index 0000000000..b809397bf3
--- /dev/null
+++ b/test/TEST-16-EXTEND-TIMEOUT/testsuite-success-stop.service
@@ -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
index 0000000000..e1cd5caeea
--- /dev/null
+++ b/test/TEST-16-EXTEND-TIMEOUT/testsuite.service
@@ -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
index 0000000000..3a212a07a9
--- /dev/null
+++ b/test/TEST-17-UDEV-WANTS/Makefile
@@ -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
index 0000000000..24989ebcf6
--- /dev/null
+++ b/test/TEST-17-UDEV-WANTS/test.sh
@@ -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
index 0000000000..5f97084cee
--- /dev/null
+++ b/test/TEST-17-UDEV-WANTS/testsuite.sh
@@ -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
index 0000000000..3a212a07a9
--- /dev/null
+++ b/test/TEST-18-FAILUREACTION/Makefile
@@ -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
index 0000000000..e48ba9bac3
--- /dev/null
+++ b/test/TEST-18-FAILUREACTION/test.sh
@@ -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
index 0000000000..1867cc3c47
--- /dev/null
+++ b/test/TEST-18-FAILUREACTION/testsuite.sh
@@ -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
index 0000000000..3a212a07a9
--- /dev/null
+++ b/test/TEST-19-DELEGATE/Makefile
@@ -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
index 0000000000..841a29c06f
--- /dev/null
+++ b/test/TEST-19-DELEGATE/test.sh
@@ -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
index 0000000000..c738bea10e
--- /dev/null
+++ b/test/TEST-19-DELEGATE/testsuite.sh
@@ -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
diff --git a/test/create-sys-script.py b/test/create-sys-script.py
index a4f1f302f6..e25f3b4f8f 100755
--- a/test/create-sys-script.py
+++ b/test/create-sys-script.py
@@ -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
#
diff --git a/test/hwdb-test.sh b/test/hwdb-test.sh
index 2221c0d7fd..a1f3270b64 100755
--- a/test/hwdb-test.sh
+++ b/test/hwdb-test.sh
@@ -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
diff --git a/test/meson.build b/test/meson.build
index 995a971778..5c533f4833 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -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
diff --git a/test/networkd-test.py b/test/networkd-test.py
index 5760ca5137..3918d85ef0 100755
--- a/test/networkd-test.py
+++ b/test/networkd-test.py
@@ -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
diff --git a/test/rule-syntax-check.py b/test/rule-syntax-check.py
index 14739df493..e053b027ca 100755
--- a/test/rule-syntax-check.py
+++ b/test/rule-syntax-check.py
@@ -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
index 0000000000..7d70be3fea
--- /dev/null
+++ b/test/run-integration-tests.sh
@@ -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"
diff --git a/test/sys-script.py b/test/sys-script.py
index 2de7d7ea30..468c1dc972 100755
--- a/test/sys-script.py
+++ b/test/sys-script.py
@@ -1,4 +1,5 @@
#!/usr/bin/env python3
+# SPDX-License-Identifier: LGPL-2.1+
#
# sys-script.py
#
diff --git a/test/sysv-generator-test.py b/test/sysv-generator-test.py
index 18bb40f812..0b4710aeab 100755
--- a/test/sysv-generator-test.py
+++ b/test/sysv-generator-test.py
@@ -1,4 +1,5 @@
#!/usr/bin/env python3
+# SPDX-License-Identifier: LGPL-2.1+
#
# systemd-sysv-generator integration test
#
diff --git a/test/test-exec-deserialization.py b/test/test-exec-deserialization.py
index c3fe0824c7..1b8863746c 100755
--- a/test/test-exec-deserialization.py
+++ b/test/test-exec-deserialization.py
@@ -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
index 0000000000..7bd8fa7402
--- /dev/null
+++ b/test/test-execute/exec-bindpaths.service
@@ -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
index 0000000000..84d550a385
--- /dev/null
+++ b/test/test-execute/exec-cpuaffinity1.service
@@ -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
index 0000000000..0dda77f939
--- /dev/null
+++ b/test/test-execute/exec-cpuaffinity2.service
@@ -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
index 0000000000..4a45d3b2d5
--- /dev/null
+++ b/test/test-execute/exec-cpuaffinity3.service
@@ -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
index 0000000000..83bdfb311a
--- /dev/null
+++ b/test/test-execute/exec-dynamicuser-statedir-migrate-step1.service
@@ -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
index 0000000000..8154922a2f
--- /dev/null
+++ b/test/test-execute/exec-dynamicuser-statedir-migrate-step2.service
@@ -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
diff --git a/test/test-execute/exec-dynamicuser-state-dir.service b/test/test-execute/exec-dynamicuser-statedir.service
index 7e2d88450b..cc09c938cf 100644
--- a/test/test-execute/exec-dynamicuser-state-dir.service
+++ b/test/test-execute/exec-dynamicuser-statedir.service
@@ -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
index 0000000000..cf0773229e
--- /dev/null
+++ b/test/test-execute/exec-group-nogroup.service
@@ -0,0 +1,7 @@
+[Unit]
+Description=Test for Group
+
+[Service]
+ExecStart=/bin/sh -x -c 'test "$$(id -n -g)" = "nogroup"'
+Type=oneshot
+Group=nogroup
diff --git a/test/test-execute/exec-read-only-path-succeed.service b/test/test-execute/exec-readonlypaths-simple.service
index b54d48f281..a9a715905c 100644
--- a/test/test-execute/exec-read-only-path-succeed.service
+++ b/test/test-execute/exec-readonlypaths-simple.service
@@ -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
index 0000000000..ea9211395d
--- /dev/null
+++ b/test/test-execute/exec-readonlypaths-with-bindpaths.service
@@ -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-restrict-namespaces-mnt-blacklist.service b/test/test-execute/exec-restrictnamespaces-mnt-blacklist.service
index ab909cbd94..ab909cbd94 100644
--- a/test/test-execute/exec-restrict-namespaces-mnt-blacklist.service
+++ b/test/test-execute/exec-restrictnamespaces-mnt-blacklist.service
diff --git a/test/test-execute/exec-restrict-namespaces-mnt.service b/test/test-execute/exec-restrictnamespaces-mnt.service
index 1aeed72717..1aeed72717 100644
--- a/test/test-execute/exec-restrict-namespaces-mnt.service
+++ b/test/test-execute/exec-restrictnamespaces-mnt.service
diff --git a/test/test-execute/exec-restrict-namespaces-no.service b/test/test-execute/exec-restrictnamespaces-no.service
index 33500302d2..33500302d2 100644
--- a/test/test-execute/exec-restrict-namespaces-no.service
+++ b/test/test-execute/exec-restrictnamespaces-no.service
diff --git a/test/test-execute/exec-restrict-namespaces-yes.service b/test/test-execute/exec-restrictnamespaces-yes.service
index 3fe70e2bea..3fe70e2bea 100644
--- a/test/test-execute/exec-restrict-namespaces-yes.service
+++ b/test/test-execute/exec-restrictnamespaces-yes.service
diff --git a/test/test-execute/exec-spec-interpolation.service b/test/test-execute/exec-specifier-interpolation.service
index 3e62662aa9..3e62662aa9 100644
--- a/test/test-execute/exec-spec-interpolation.service
+++ b/test/test-execute/exec-specifier-interpolation.service
diff --git a/test/test-execute/exec-specifier.service b/test/test-execute/exec-specifier.service
new file mode 100644
index 0000000000..37852390ac
--- /dev/null
+++ b/test/test-execute/exec-specifier.service
@@ -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
index 0000000000..0015dffca6
--- /dev/null
+++ b/test/test-execute/exec-specifier@.service
@@ -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
index 0000000000..1ca536ffc5
--- /dev/null
+++ b/test/test-execute/exec-standardinput-data.service
@@ -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
index 0000000000..8fd11caf8e
--- /dev/null
+++ b/test/test-execute/exec-standardinput-file.service
@@ -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
diff --git a/test/test-execute/exec-systemcallerrornumber.service b/test/test-execute/exec-systemcallerrornumber-name.service
index ff7da3c1a4..e167d2716b 100644
--- a/test/test-execute/exec-systemcallerrornumber.service
+++ b/test/test-execute/exec-systemcallerrornumber-name.service
@@ -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
index 0000000000..203215682f
--- /dev/null
+++ b/test/test-execute/exec-systemcallerrornumber-number.service
@@ -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
diff --git a/test/test-execute/exec-systemcallfilter-failing.service b/test/test-execute/exec-systemcallfilter-failing.service
index 5c6422f0fd..bcebc99507 100644
--- a/test/test-execute/exec-systemcallfilter-failing.service
+++ b/test/test-execute/exec-systemcallfilter-failing.service
@@ -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
diff --git a/test/test-execute/exec-systemcallfilter-failing2.service b/test/test-execute/exec-systemcallfilter-failing2.service
index 3516078e1f..2fdc0ed772 100644
--- a/test/test-execute/exec-systemcallfilter-failing2.service
+++ b/test/test-execute/exec-systemcallfilter-failing2.service
@@ -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
diff --git a/test/test-execute/exec-systemcallfilter-not-failing.service b/test/test-execute/exec-systemcallfilter-not-failing.service
index c794b67edd..f3a752b3ef 100644
--- a/test/test-execute/exec-systemcallfilter-not-failing.service
+++ b/test/test-execute/exec-systemcallfilter-not-failing.service
@@ -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
diff --git a/test/test-execute/exec-systemcallfilter-not-failing2.service b/test/test-execute/exec-systemcallfilter-not-failing2.service
index a62c81bd48..1df076ab90 100644
--- a/test/test-execute/exec-systemcallfilter-not-failing2.service
+++ b/test/test-execute/exec-systemcallfilter-not-failing2.service
@@ -2,6 +2,6 @@
Description=Test for SystemCallFilter
[Service]
-ExecStart=/bin/echo "Foo bar"
+ExecStart=/bin/sh -c 'echo "Foo bar"'
Type=oneshot
SystemCallFilter=
diff --git a/test/test-execute/exec-systemcallfilter-system-user-nfsnobody.service b/test/test-execute/exec-systemcallfilter-system-user-nfsnobody.service
index 9393e0a998..b1195d0d25 100644
--- a/test/test-execute/exec-systemcallfilter-system-user-nfsnobody.service
+++ b/test/test-execute/exec-systemcallfilter-system-user-nfsnobody.service
@@ -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
diff --git a/test/test-execute/exec-systemcallfilter-system-user.service b/test/test-execute/exec-systemcallfilter-system-user.service
index 462f94133d..da129a30e4 100644
--- a/test/test-execute/exec-systemcallfilter-system-user.service
+++ b/test/test-execute/exec-systemcallfilter-system-user.service
@@ -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
index 0000000000..8380d5a155
--- /dev/null
+++ b/test/test-execute/exec-systemcallfilter-with-errno-name.service
@@ -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
index 0000000000..dbb9540a1e
--- /dev/null
+++ b/test/test-execute/exec-systemcallfilter-with-errno-number.service
@@ -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
diff --git a/test/test-execute/exec-unset-environment.service b/test/test-execute/exec-unsetenvironment.service
index 5b0123b81e..5b0123b81e 100644
--- a/test/test-execute/exec-unset-environment.service
+++ b/test/test-execute/exec-unsetenvironment.service
diff --git a/test/test-functions b/test/test-functions
index 745c0a9abe..a2f82725d1 100644
--- a/test/test-functions
+++ b/test/test-functions
@@ -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="sh bash setsid loadkeys setfont login sulogin gzip sleep echo mount umount cryptsetup date dmsetup modprobe sed cmp tee rm"
+BASICTOOLS="test sh bash setsid loadkeys setfont login sulogin gzip sleep echo mount umount cryptsetup date dmsetup modprobe sed cmp tee rm 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
diff --git a/tmpfiles.d/etc.conf.m4 b/tmpfiles.d/etc.conf.m4
index 35e3809f57..df8d42101c 100644
--- a/tmpfiles.d/etc.conf.m4
+++ b/tmpfiles.d/etc.conf.m4
@@ -14,7 +14,7 @@ m4_ifdef(`HAVE_SMACK_RUN_LABEL',
t /etc/mtab - - - - security.SMACK64=_
)m4_dnl
m4_ifdef(`ENABLE_RESOLVE',
-L! /etc/resolv.conf - - - - ../usr/lib/systemd/resolv.conf
+L! /etc/resolv.conf - - - - ../run/systemd/resolve/stub-resolv.conf
)m4_dnl
C /etc/nsswitch.conf - - - -
m4_ifdef(`HAVE_PAM',
diff --git a/tmpfiles.d/meson.build b/tmpfiles.d/meson.build
index 9a594a289a..37a8dfea2d 100644
--- a/tmpfiles.d/meson.build
+++ b/tmpfiles.d/meson.build
@@ -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', ''],
diff --git a/tools/catalog-report.py b/tools/catalog-report.py
index 357e498cdc..426ea0d891 100755
--- a/tools/catalog-report.py
+++ b/tools/catalog-report.py
@@ -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
index 0000000000..33b40f93f7
--- /dev/null
+++ b/tools/find-build-dir.sh
@@ -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)"
diff --git a/tools/gdb-sd_dump_hashmaps.py b/tools/gdb-sd_dump_hashmaps.py
index 62ce8006f5..b3c356b579 100644
--- a/tools/gdb-sd_dump_hashmaps.py
+++ b/tools/gdb-sd_dump_hashmaps.py
@@ -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.
#
diff --git a/tools/make-directive-index.py b/tools/make-directive-index.py
index f9203ddd1a..fb2b0b7c6f 100755
--- a/tools/make-directive-index.py
+++ b/tools/make-directive-index.py
@@ -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.
#
diff --git a/tools/make-man-index.py b/tools/make-man-index.py
index 0618e2e677..5ff3616652 100755
--- a/tools/make-man-index.py
+++ b/tools/make-man-index.py
@@ -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.
#
diff --git a/tools/make-man-rules.py b/tools/make-man-rules.py
index e0f18d6fbe..444d4a6ee4 100755
--- a/tools/make-man-rules.py
+++ b/tools/make-man-rules.py
@@ -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.
#
diff --git a/tools/meson-check-help.sh b/tools/meson-check-help.sh
index 47a5099a04..4210491a98 100755
--- a/tools/meson-check-help.sh
+++ b/tools/meson-check-help.sh
@@ -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:"
diff --git a/tools/meson-hwdb-update.sh b/tools/meson-hwdb-update.sh
index 33d603e16a..e9a78c647f 100755
--- a/tools/meson-hwdb-update.sh
+++ b/tools/meson-hwdb-update.sh
@@ -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
diff --git a/tools/xml_helper.py b/tools/xml_helper.py
index 0088be5bd9..47434c7156 100755
--- a/tools/xml_helper.py
+++ b/tools/xml_helper.py
@@ -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')
diff --git a/units/basic.target b/units/basic.target
index 3e3527f894..4f44292249 100644
--- a/units/basic.target
+++ b/units/basic.target
@@ -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/bluetooth.target b/units/bluetooth.target
index dd4ae14cfb..62407d363e 100644
--- a/units/bluetooth.target
+++ b/units/bluetooth.target
@@ -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/busnames.target b/units/busnames.target
index 5e866b403d..9e2d7c3194 100644
--- a/units/busnames.target
+++ b/units/busnames.target
@@ -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/console-getty.service.m4.in b/units/console-getty.service.m4.in
index e75576adf7..3c553240a2 100644
--- a/units/console-getty.service.m4.in
+++ b/units/console-getty.service.m4.in
@@ -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/container-getty@.service.m4.in b/units/container-getty@.service.m4.in
index 4b822f0e3b..087ab7f9b1 100644
--- a/units/container-getty@.service.m4.in
+++ b/units/container-getty@.service.m4.in
@@ -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/cryptsetup-pre.target b/units/cryptsetup-pre.target
index 6cb28a61ae..12e4107f60 100644
--- a/units/cryptsetup-pre.target
+++ b/units/cryptsetup-pre.target
@@ -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/cryptsetup.target b/units/cryptsetup.target
index 10b17fd387..fdb572bc70 100644
--- a/units/cryptsetup.target
+++ b/units/cryptsetup.target
@@ -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/debug-shell.service.in b/units/debug-shell.service.in
index f72e5ef6b6..2d48faa105 100644
--- a/units/debug-shell.service.in
+++ b/units/debug-shell.service.in
@@ -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/dev-hugepages.mount b/units/dev-hugepages.mount
index 86ad7ac2c9..278ed9b610 100644
--- a/units/dev-hugepages.mount
+++ b/units/dev-hugepages.mount
@@ -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/dev-mqueue.mount b/units/dev-mqueue.mount
index b2adfeb835..be32433d6c 100644
--- a/units/dev-mqueue.mount
+++ b/units/dev-mqueue.mount
@@ -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/emergency.service.in b/units/emergency.service.in
index 9a81fc4da9..d259b6b112 100644
--- a/units/emergency.service.in
+++ b/units/emergency.service.in
@@ -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/emergency.target b/units/emergency.target
index 0760d66f95..a4e954e857 100644
--- a/units/emergency.target
+++ b/units/emergency.target
@@ -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/exit.target b/units/exit.target
index f5f953d112..0a79533a9e 100644
--- a/units/exit.target
+++ b/units/exit.target
@@ -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/final.target b/units/final.target
index 42819105c8..0e12386d4d 100644
--- a/units/final.target
+++ b/units/final.target
@@ -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/getty-pre.target b/units/getty-pre.target
index f6c78b6c2e..adb98bf92c 100644
--- a/units/getty-pre.target
+++ b/units/getty-pre.target
@@ -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/getty.target b/units/getty.target
index c33d44657a..b3110179bf 100644
--- a/units/getty.target
+++ b/units/getty.target
@@ -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/getty@.service.m4 b/units/getty@.service.m4
index ff1b3c3d87..80e793bb73 100644
--- a/units/getty@.service.m4
+++ b/units/getty@.service.m4
@@ -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/graphical.target b/units/graphical.target
index 87be97e13a..f3e30e9756 100644
--- a/units/graphical.target
+++ b/units/graphical.target
@@ -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/halt-local.service.in b/units/halt-local.service.in
index c8be8965a3..f6c2e9c692 100644
--- a/units/halt-local.service.in
+++ b/units/halt-local.service.in
@@ -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/halt.target b/units/halt.target
index a21d984b26..87c33745f2 100644
--- a/units/halt.target
+++ b/units/halt.target
@@ -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/hibernate.target b/units/hibernate.target
index 0e1bc03258..8580c658e6 100644
--- a/units/hibernate.target
+++ b/units/hibernate.target
@@ -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/hybrid-sleep.target b/units/hybrid-sleep.target
index 410e131b6e..e5e22b8187 100644
--- a/units/hybrid-sleep.target
+++ b/units/hybrid-sleep.target
@@ -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/initrd-cleanup.service.in b/units/initrd-cleanup.service.in
index b1dda16b5f..9775540c94 100644
--- a/units/initrd-cleanup.service.in
+++ b/units/initrd-cleanup.service.in
@@ -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/initrd-fs.target b/units/initrd-fs.target
index 7ec838a680..33822bde66 100644
--- a/units/initrd-fs.target
+++ b/units/initrd-fs.target
@@ -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/initrd-parse-etc.service.in b/units/initrd-parse-etc.service.in
index 42c059bbd2..2b3cd61cd6 100644
--- a/units/initrd-parse-etc.service.in
+++ b/units/initrd-parse-etc.service.in
@@ -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/initrd-root-device.target b/units/initrd-root-device.target
index 9d44d2d303..580c666b23 100644
--- a/units/initrd-root-device.target
+++ b/units/initrd-root-device.target
@@ -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/initrd-root-fs.target b/units/initrd-root-fs.target
index 64f0a9291c..9b955f618a 100644
--- a/units/initrd-root-fs.target
+++ b/units/initrd-root-fs.target
@@ -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/initrd-switch-root.service.in b/units/initrd-switch-root.service.in
index d31497f5e3..6ce468e872 100644
--- a/units/initrd-switch-root.service.in
+++ b/units/initrd-switch-root.service.in
@@ -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/initrd-switch-root.target b/units/initrd-switch-root.target
index 934d82f667..ad82245121 100644
--- a/units/initrd-switch-root.target
+++ b/units/initrd-switch-root.target
@@ -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/initrd-udevadm-cleanup-db.service.in b/units/initrd-udevadm-cleanup-db.service.in
index 5c6654efc4..5059605c27 100644
--- a/units/initrd-udevadm-cleanup-db.service.in
+++ b/units/initrd-udevadm-cleanup-db.service.in
@@ -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/initrd.target b/units/initrd.target
index 8be7e2b399..a74a447c91 100644
--- a/units/initrd.target
+++ b/units/initrd.target
@@ -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/kexec.target b/units/kexec.target
index 90795d0c5a..706cd7065c 100644
--- a/units/kexec.target
+++ b/units/kexec.target
@@ -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/kmod-static-nodes.service.in b/units/kmod-static-nodes.service.in
index a9c8df1184..a6c5eb228f 100644
--- a/units/kmod-static-nodes.service.in
+++ b/units/kmod-static-nodes.service.in
@@ -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/ldconfig.service b/units/ldconfig.service
index d7b78bacf9..3c3cbf5607 100644
--- a/units/ldconfig.service
+++ b/units/ldconfig.service
@@ -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/local-fs-pre.target b/units/local-fs-pre.target
index 809f2ed236..9aca15b953 100644
--- a/units/local-fs-pre.target
+++ b/units/local-fs-pre.target
@@ -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/local-fs.target b/units/local-fs.target
index d2e5429c71..6ba4930087 100644
--- a/units/local-fs.target
+++ b/units/local-fs.target
@@ -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/machine.slice b/units/machine.slice
index 3d40dfd73b..b4e4c17d88 100644
--- a/units/machine.slice
+++ b/units/machine.slice
@@ -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/machines.target b/units/machines.target
index e07b0bb6ae..224765aa90 100644
--- a/units/machines.target
+++ b/units/machines.target
@@ -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/meson.build b/units/meson.build
index 8494d23e9e..814ee7885b 100644
--- a/units/meson.build
+++ b/units/meson.build
@@ -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', ''],
@@ -209,7 +225,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'],
['systemd-volatile-root.service', ''],
diff --git a/units/multi-user.target b/units/multi-user.target
index 0f0e5e99a7..386e1b547d 100644
--- a/units/multi-user.target
+++ b/units/multi-user.target
@@ -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/network-online.target b/units/network-online.target
index 5130d8c5e3..8b8c7851e2 100644
--- a/units/network-online.target
+++ b/units/network-online.target
@@ -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/network-pre.target b/units/network-pre.target
index 0d54a4cff8..806eb720f8 100644
--- a/units/network-pre.target
+++ b/units/network-pre.target
@@ -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/network.target b/units/network.target
index f8331b6124..3e4fdff144 100644
--- a/units/network.target
+++ b/units/network.target
@@ -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/nss-lookup.target b/units/nss-lookup.target
index c9e3a7c419..8d56c8ea36 100644
--- a/units/nss-lookup.target
+++ b/units/nss-lookup.target
@@ -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/nss-user-lookup.target b/units/nss-user-lookup.target
index 80023cdfb6..7436b6c80d 100644
--- a/units/nss-user-lookup.target
+++ b/units/nss-user-lookup.target
@@ -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/paths.target b/units/paths.target
index 25c7fd031e..9b6ed1c13f 100644
--- a/units/paths.target
+++ b/units/paths.target
@@ -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/poweroff.target b/units/poweroff.target
index dd92d816ca..47c109ceed 100644
--- a/units/poweroff.target
+++ b/units/poweroff.target
@@ -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/printer.target b/units/printer.target
index a6b86caa8d..e1fb0d4e34 100644
--- a/units/printer.target
+++ b/units/printer.target
@@ -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/proc-sys-fs-binfmt_misc.automount b/units/proc-sys-fs-binfmt_misc.automount
index 1067bcd839..30a6bc9918 100644
--- a/units/proc-sys-fs-binfmt_misc.automount
+++ b/units/proc-sys-fs-binfmt_misc.automount
@@ -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/proc-sys-fs-binfmt_misc.mount b/units/proc-sys-fs-binfmt_misc.mount
index 27773cd4ea..091191e139 100644
--- a/units/proc-sys-fs-binfmt_misc.mount
+++ b/units/proc-sys-fs-binfmt_misc.mount
@@ -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/quotaon.service.in b/units/quotaon.service.in
index f3e1e270c9..25c747439a 100644
--- a/units/quotaon.service.in
+++ b/units/quotaon.service.in
@@ -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/rc-local.service.in b/units/rc-local.service.in
index 480dddbe37..5dbd62aecb 100644
--- a/units/rc-local.service.in
+++ b/units/rc-local.service.in
@@ -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/reboot.target b/units/reboot.target
index 668b98d9e4..c2782db631 100644
--- a/units/reboot.target
+++ b/units/reboot.target
@@ -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/remote-cryptsetup.target b/units/remote-cryptsetup.target
index 60943bd1cb..4445d5defe 100644
--- a/units/remote-cryptsetup.target
+++ b/units/remote-cryptsetup.target
@@ -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
diff --git a/units/remote-fs-pre.target b/units/remote-fs-pre.target
index 36a196cfda..3f22605c8c 100644
--- a/units/remote-fs-pre.target
+++ b/units/remote-fs-pre.target
@@ -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/remote-fs.target b/units/remote-fs.target
index 43ffa5c107..0d44348e75 100644
--- a/units/remote-fs.target
+++ b/units/remote-fs.target
@@ -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/rescue.service.in b/units/rescue.service.in
index 6cd5aa4864..2a8f034b94 100644
--- a/units/rescue.service.in
+++ b/units/rescue.service.in
@@ -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/rescue.target b/units/rescue.target
index bd92ed2df3..0e04a94f39 100644
--- a/units/rescue.target
+++ b/units/rescue.target
@@ -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/rpcbind.target b/units/rpcbind.target
index e03e915ee0..801ee4d6ef 100644
--- a/units/rpcbind.target
+++ b/units/rpcbind.target
@@ -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/serial-getty@.service.m4 b/units/serial-getty@.service.m4
index e56f47652c..757b86ab2f 100644
--- a/units/serial-getty@.service.m4
+++ b/units/serial-getty@.service.m4
@@ -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/shutdown.target b/units/shutdown.target
index 73e302b8b2..d48e6d6494 100644
--- a/units/shutdown.target
+++ b/units/shutdown.target
@@ -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/sigpwr.target b/units/sigpwr.target
index a52e7cffc9..8228541dac 100644
--- a/units/sigpwr.target
+++ b/units/sigpwr.target
@@ -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/sleep.target b/units/sleep.target
index 10c7c8d594..9409dc6707 100644
--- a/units/sleep.target
+++ b/units/sleep.target
@@ -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/slices.target b/units/slices.target
index a29310c047..84a04d6385 100644
--- a/units/slices.target
+++ b/units/slices.target
@@ -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/smartcard.target b/units/smartcard.target
index 5fefe84703..717ea2311d 100644
--- a/units/smartcard.target
+++ b/units/smartcard.target
@@ -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/sockets.target b/units/sockets.target
index 26ab065d02..9af67fdb1f 100644
--- a/units/sockets.target
+++ b/units/sockets.target
@@ -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/sound.target b/units/sound.target
index 6699adeceb..19afc2a637 100644
--- a/units/sound.target
+++ b/units/sound.target
@@ -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/suspend.target b/units/suspend.target
index 80d652755c..1a156b4147 100644
--- a/units/suspend.target
+++ b/units/suspend.target
@@ -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/swap.target b/units/swap.target
index 23a7d0dc9c..8cef5b6489 100644
--- a/units/swap.target
+++ b/units/swap.target
@@ -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/sys-fs-fuse-connections.mount b/units/sys-fs-fuse-connections.mount
index 492ceb16f3..7e7b05c3a2 100644
--- a/units/sys-fs-fuse-connections.mount
+++ b/units/sys-fs-fuse-connections.mount
@@ -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/sys-kernel-config.mount b/units/sys-kernel-config.mount
index b585f32561..e213ca58b3 100644
--- a/units/sys-kernel-config.mount
+++ b/units/sys-kernel-config.mount
@@ -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/sys-kernel-debug.mount b/units/sys-kernel-debug.mount
index 808dbf08f4..53ce820b87 100644
--- a/units/sys-kernel-debug.mount
+++ b/units/sys-kernel-debug.mount
@@ -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/sysinit.target b/units/sysinit.target
index ec33503330..b6c16a1412 100644
--- a/units/sysinit.target
+++ b/units/sysinit.target
@@ -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/syslog.socket b/units/syslog.socket
index 43981904ea..c4b1cea2d6 100644
--- a/units/syslog.socket
+++ b/units/syslog.socket
@@ -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/system-update-cleanup.service.in b/units/system-update-cleanup.service.in
index dc524da7a3..51399f1c07 100644
--- a/units/system-update-cleanup.service.in
+++ b/units/system-update-cleanup.service.in
@@ -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/system-update.target b/units/system-update.target
index b95639a876..c46bfe754a 100644
--- a/units/system-update.target
+++ b/units/system-update.target
@@ -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/system.slice b/units/system.slice
index 8281fe58f6..a4d5edfae8 100644
--- a/units/system.slice
+++ b/units/system.slice
@@ -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/systemd-ask-password-console.path b/units/systemd-ask-password-console.path
index 7899ae788f..d686ca634c 100644
--- a/units/systemd-ask-password-console.path
+++ b/units/systemd-ask-password-console.path
@@ -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/systemd-ask-password-console.service.in b/units/systemd-ask-password-console.service.in
index adaa60da87..6923d68df0 100644
--- a/units/systemd-ask-password-console.service.in
+++ b/units/systemd-ask-password-console.service.in
@@ -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/systemd-ask-password-wall.path b/units/systemd-ask-password-wall.path
index a3ca617256..5a356b97d0 100644
--- a/units/systemd-ask-password-wall.path
+++ b/units/systemd-ask-password-wall.path
@@ -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/systemd-ask-password-wall.service.in b/units/systemd-ask-password-wall.service.in
index be380023a7..1e4808b6d5 100644
--- a/units/systemd-ask-password-wall.service.in
+++ b/units/systemd-ask-password-wall.service.in
@@ -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/systemd-backlight@.service.in b/units/systemd-backlight@.service.in
index 9aa0c7498d..d3022856f2 100644
--- a/units/systemd-backlight@.service.in
+++ b/units/systemd-backlight@.service.in
@@ -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/systemd-binfmt.service.in b/units/systemd-binfmt.service.in
index d53073ee61..df9396d895 100644
--- a/units/systemd-binfmt.service.in
+++ b/units/systemd-binfmt.service.in
@@ -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/systemd-coredump.socket b/units/systemd-coredump.socket
index 4cb2460471..c9971b9199 100644
--- a/units/systemd-coredump.socket
+++ b/units/systemd-coredump.socket
@@ -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/systemd-coredump@.service.in b/units/systemd-coredump@.service.in
index ef58f0cb3e..68fa55c807 100644
--- a/units/systemd-coredump@.service.in
+++ b/units/systemd-coredump@.service.in
@@ -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/systemd-exit.service.in b/units/systemd-exit.service.in
index 2dbfb36b41..2fb6ebd767 100644
--- a/units/systemd-exit.service.in
+++ b/units/systemd-exit.service.in
@@ -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/systemd-firstboot.service.in b/units/systemd-firstboot.service.in
index 405c6f3fd2..d4deba90b7 100644
--- a/units/systemd-firstboot.service.in
+++ b/units/systemd-firstboot.service.in
@@ -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/systemd-fsck-root.service.in b/units/systemd-fsck-root.service.in
index 3617abf04a..25aca1943f 100644
--- a/units/systemd-fsck-root.service.in
+++ b/units/systemd-fsck-root.service.in
@@ -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/systemd-fsck@.service.in b/units/systemd-fsck@.service.in
index 6ca6b07e9e..078edcc01a 100644
--- a/units/systemd-fsck@.service.in
+++ b/units/systemd-fsck@.service.in
@@ -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/systemd-halt.service.in b/units/systemd-halt.service.in
index d55d622c1c..09c1005829 100644
--- a/units/systemd-halt.service.in
+++ b/units/systemd-halt.service.in
@@ -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/systemd-hibernate-resume@.service.in b/units/systemd-hibernate-resume@.service.in
index 65e8eb83f1..d1b1aeeabb 100644
--- a/units/systemd-hibernate-resume@.service.in
+++ b/units/systemd-hibernate-resume@.service.in
@@ -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/systemd-hibernate.service.in b/units/systemd-hibernate.service.in
index 29d9b696a8..963b257ab8 100644
--- a/units/systemd-hibernate.service.in
+++ b/units/systemd-hibernate.service.in
@@ -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/systemd-hostnamed.service.in b/units/systemd-hostnamed.service.in
index cfee2cbbf1..993134f3d6 100644
--- a/units/systemd-hostnamed.service.in
+++ b/units/systemd-hostnamed.service.in
@@ -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/systemd-hwdb-update.service.in b/units/systemd-hwdb-update.service.in
index 7135cff3d9..259fe0de8b 100644
--- a/units/systemd-hwdb-update.service.in
+++ b/units/systemd-hwdb-update.service.in
@@ -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/systemd-hybrid-sleep.service.in b/units/systemd-hybrid-sleep.service.in
index 914b686c36..466ade974c 100644
--- a/units/systemd-hybrid-sleep.service.in
+++ b/units/systemd-hybrid-sleep.service.in
@@ -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/systemd-importd.service.in b/units/systemd-importd.service.in
index 695a5f21cb..8e93c2d524 100644
--- a/units/systemd-importd.service.in
+++ b/units/systemd-importd.service.in
@@ -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/systemd-initctl.service.in b/units/systemd-initctl.service.in
index 5505309e92..6cfed3da11 100644
--- a/units/systemd-initctl.service.in
+++ b/units/systemd-initctl.service.in
@@ -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/systemd-initctl.socket b/units/systemd-initctl.socket
index f628c2e867..61f877ba7d 100644
--- a/units/systemd-initctl.socket
+++ b/units/systemd-initctl.socket
@@ -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/systemd-journal-catalog-update.service.in b/units/systemd-journal-catalog-update.service.in
index 276f052b1a..6a7bf006cd 100644
--- a/units/systemd-journal-catalog-update.service.in
+++ b/units/systemd-journal-catalog-update.service.in
@@ -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/systemd-journal-flush.service.in b/units/systemd-journal-flush.service.in
index a0a2e3fdb4..439f5f3f76 100644
--- a/units/systemd-journal-flush.service.in
+++ b/units/systemd-journal-flush.service.in
@@ -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/systemd-journal-gatewayd.service.in b/units/systemd-journal-gatewayd.service.in
index 44caa0e0b2..9768928c57 100644
--- a/units/systemd-journal-gatewayd.service.in
+++ b/units/systemd-journal-gatewayd.service.in
@@ -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/systemd-journal-gatewayd.socket b/units/systemd-journal-gatewayd.socket
index 79d9b04210..7c3632b323 100644
--- a/units/systemd-journal-gatewayd.socket
+++ b/units/systemd-journal-gatewayd.socket
@@ -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/systemd-journal-remote.service.in b/units/systemd-journal-remote.service.in
index 92cec21c2f..a94265f215 100644
--- a/units/systemd-journal-remote.service.in
+++ b/units/systemd-journal-remote.service.in
@@ -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/systemd-journal-remote.socket b/units/systemd-journal-remote.socket
index 076dcae8a3..48d0a656ba 100644
--- a/units/systemd-journal-remote.socket
+++ b/units/systemd-journal-remote.socket
@@ -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/systemd-journal-upload.service.in b/units/systemd-journal-upload.service.in
index 98a4b2bb7a..42da70f473 100644
--- a/units/systemd-journal-upload.service.in
+++ b/units/systemd-journal-upload.service.in
@@ -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
diff --git a/units/systemd-journald-audit.socket b/units/systemd-journald-audit.socket
index 541f2cf38d..cb8b774963 100644
--- a/units/systemd-journald-audit.socket
+++ b/units/systemd-journald-audit.socket
@@ -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/systemd-journald-dev-log.socket b/units/systemd-journald-dev-log.socket
index ffd44bb507..80ad6ac845 100644
--- a/units/systemd-journald-dev-log.socket
+++ b/units/systemd-journald-dev-log.socket
@@ -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/systemd-journald.service.in b/units/systemd-journald.service.in
index a747fe3f1f..df76fe4226 100644
--- a/units/systemd-journald.service.in
+++ b/units/systemd-journald.service.in
@@ -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/systemd-journald.socket b/units/systemd-journald.socket
index 71737014ca..c95ae5ab64 100644
--- a/units/systemd-journald.socket
+++ b/units/systemd-journald.socket
@@ -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/systemd-kexec.service.in b/units/systemd-kexec.service.in
index 61303f917f..1201b23289 100644
--- a/units/systemd-kexec.service.in
+++ b/units/systemd-kexec.service.in
@@ -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/systemd-localed.service.in b/units/systemd-localed.service.in
index 5dd8b18894..ba8a08f3b4 100644
--- a/units/systemd-localed.service.in
+++ b/units/systemd-localed.service.in
@@ -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/systemd-logind.service.in b/units/systemd-logind.service.in
index de380a27d3..968b92a45c 100644
--- a/units/systemd-logind.service.in
+++ b/units/systemd-logind.service.in
@@ -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/systemd-machine-id-commit.service.in b/units/systemd-machine-id-commit.service.in
index 1f3f5da0f3..4f348730ee 100644
--- a/units/systemd-machine-id-commit.service.in
+++ b/units/systemd-machine-id-commit.service.in
@@ -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/systemd-machined.service.in b/units/systemd-machined.service.in
index 03b9bf5c0d..f9e789db42 100644
--- a/units/systemd-machined.service.in
+++ b/units/systemd-machined.service.in
@@ -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/systemd-modules-load.service.in b/units/systemd-modules-load.service.in
index 9de6d31349..26abe21d1b 100644
--- a/units/systemd-modules-load.service.in
+++ b/units/systemd-modules-load.service.in
@@ -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/systemd-networkd-wait-online.service.in b/units/systemd-networkd-wait-online.service.in
index 89ca865b55..7666e16669 100644
--- a/units/systemd-networkd-wait-online.service.in
+++ b/units/systemd-networkd-wait-online.service.in
@@ -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/systemd-networkd.service.in b/units/systemd-networkd.service.in
index 932dd63964..63ee735415 100644
--- a/units/systemd-networkd.service.in
+++ b/units/systemd-networkd.service.in
@@ -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/systemd-networkd.socket b/units/systemd-networkd.socket
index 9e4e9dd338..113306607b 100644
--- a/units/systemd-networkd.socket
+++ b/units/systemd-networkd.socket
@@ -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/systemd-nspawn@.service.in b/units/systemd-nspawn@.service.in
index 9893ae2b36..c3194d4f21 100644
--- a/units/systemd-nspawn@.service.in
+++ b/units/systemd-nspawn@.service.in
@@ -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
TasksMax=16384
diff --git a/units/systemd-poweroff.service.in b/units/systemd-poweroff.service.in
index 3630719733..e9fd655508 100644
--- a/units/systemd-poweroff.service.in
+++ b/units/systemd-poweroff.service.in
@@ -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/systemd-quotacheck.service.in b/units/systemd-quotacheck.service.in
index 6b1999aa51..244da0a307 100644
--- a/units/systemd-quotacheck.service.in
+++ b/units/systemd-quotacheck.service.in
@@ -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/systemd-random-seed.service.in b/units/systemd-random-seed.service.in
index b244a8ce43..8903ee896c 100644
--- a/units/systemd-random-seed.service.in
+++ b/units/systemd-random-seed.service.in
@@ -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/systemd-reboot.service.in b/units/systemd-reboot.service.in
index d99bd3e701..4763ccfdca 100644
--- a/units/systemd-reboot.service.in
+++ b/units/systemd-reboot.service.in
@@ -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/systemd-remount-fs.service.in b/units/systemd-remount-fs.service.in
index 29d0674ab3..2e5b75ec03 100644
--- a/units/systemd-remount-fs.service.in
+++ b/units/systemd-remount-fs.service.in
@@ -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/systemd-resolved.service.in b/units/systemd-resolved.service.in
index cda83ee966..8059aa7b62 100644
--- a/units/systemd-resolved.service.in
+++ b/units/systemd-resolved.service.in
@@ -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/systemd-rfkill.service.in b/units/systemd-rfkill.service.in
index 5cdd747d22..4b68f0b5a7 100644
--- a/units/systemd-rfkill.service.in
+++ b/units/systemd-rfkill.service.in
@@ -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/systemd-rfkill.socket b/units/systemd-rfkill.socket
index 20ae2f8adb..c8e9f71bf6 100644
--- a/units/systemd-rfkill.socket
+++ b/units/systemd-rfkill.socket
@@ -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/systemd-suspend.service.in b/units/systemd-suspend.service.in
index 3a702d2e22..11ed383ba9 100644
--- a/units/systemd-suspend.service.in
+++ b/units/systemd-suspend.service.in
@@ -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/systemd-sysctl.service.in b/units/systemd-sysctl.service.in
index 980f611df2..5b0f7f9df4 100644
--- a/units/systemd-sysctl.service.in
+++ b/units/systemd-sysctl.service.in
@@ -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/systemd-sysusers.service.in b/units/systemd-sysusers.service.in
index 4d8309ab6b..4d11bbb762 100644
--- a/units/systemd-sysusers.service.in
+++ b/units/systemd-sysusers.service.in
@@ -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/systemd-timedated.service.in b/units/systemd-timedated.service.in
index 97130e93c3..cf13e40ced 100644
--- a/units/systemd-timedated.service.in
+++ b/units/systemd-timedated.service.in
@@ -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/systemd-timesyncd.service.in b/units/systemd-timesyncd.service.in
index 8d3f46cf5e..d3bc4e9841 100644
--- a/units/systemd-timesyncd.service.in
+++ b/units/systemd-timesyncd.service.in
@@ -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
diff --git a/units/systemd-tmpfiles-clean.service.in b/units/systemd-tmpfiles-clean.service.in
index 133c8c94c4..d1025afadb 100644
--- a/units/systemd-tmpfiles-clean.service.in
+++ b/units/systemd-tmpfiles-clean.service.in
@@ -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,4 +18,5 @@ Before=shutdown.target
[Service]
Type=oneshot
ExecStart=@rootbindir@/systemd-tmpfiles --clean
+SuccessExitStatus=65
IOSchedulingClass=idle
diff --git a/units/systemd-tmpfiles-clean.timer b/units/systemd-tmpfiles-clean.timer
index 9975dcfaca..3e3017820f 100644
--- a/units/systemd-tmpfiles-clean.timer
+++ b/units/systemd-tmpfiles-clean.timer
@@ -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/systemd-tmpfiles-setup-dev.service.in b/units/systemd-tmpfiles-setup-dev.service.in
index 0123a030e4..6a6ebed955 100644
--- a/units/systemd-tmpfiles-setup-dev.service.in
+++ b/units/systemd-tmpfiles-setup-dev.service.in
@@ -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,3 +20,4 @@ ConditionCapability=CAP_SYS_MODULE
Type=oneshot
RemainAfterExit=yes
ExecStart=@rootbindir@/systemd-tmpfiles --prefix=/dev --create --boot
+SuccessExitStatus=65
diff --git a/units/systemd-tmpfiles-setup.service.in b/units/systemd-tmpfiles-setup.service.in
index e895cda0e6..0410d0bfd8 100644
--- a/units/systemd-tmpfiles-setup.service.in
+++ b/units/systemd-tmpfiles-setup.service.in
@@ -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,3 +20,4 @@ RefuseManualStop=yes
Type=oneshot
RemainAfterExit=yes
ExecStart=@rootbindir@/systemd-tmpfiles --create --remove --boot --exclude-prefix=/dev
+SuccessExitStatus=65
diff --git a/units/systemd-udev-settle.service.in b/units/systemd-udev-settle.service.in
index 0817803a39..c9e1c91852 100644
--- a/units/systemd-udev-settle.service.in
+++ b/units/systemd-udev-settle.service.in
@@ -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/systemd-udev-trigger.service.in b/units/systemd-udev-trigger.service.in
index 0c33909cee..3cdde94446 100644
--- a/units/systemd-udev-trigger.service.in
+++ b/units/systemd-udev-trigger.service.in
@@ -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/systemd-udevd-control.socket b/units/systemd-udevd-control.socket
index 46f704ed79..5b8628c754 100644
--- a/units/systemd-udevd-control.socket
+++ b/units/systemd-udevd-control.socket
@@ -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/systemd-udevd-kernel.socket b/units/systemd-udevd-kernel.socket
index 1a16206951..b2a65f1a84 100644
--- a/units/systemd-udevd-kernel.socket
+++ b/units/systemd-udevd-kernel.socket
@@ -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/systemd-udevd.service.in b/units/systemd-udevd.service.in
index 03909f5d7f..8557522e7b 100644
--- a/units/systemd-udevd.service.in
+++ b/units/systemd-udevd.service.in
@@ -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/systemd-update-done.service.in b/units/systemd-update-done.service.in
index ec7d906392..6e82ec7474 100644
--- a/units/systemd-update-done.service.in
+++ b/units/systemd-update-done.service.in
@@ -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/systemd-update-utmp-runlevel.service.in b/units/systemd-update-utmp-runlevel.service.in
index 99783e2e69..642d926a31 100644
--- a/units/systemd-update-utmp-runlevel.service.in
+++ b/units/systemd-update-utmp-runlevel.service.in
@@ -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/systemd-update-utmp.service.in b/units/systemd-update-utmp.service.in
index 163eccd91f..b9a668faeb 100644
--- a/units/systemd-update-utmp.service.in
+++ b/units/systemd-update-utmp.service.in
@@ -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/systemd-user-sessions.service.in b/units/systemd-user-sessions.service.in
index b4ea5a134b..6d585eb0a1 100644
--- a/units/systemd-user-sessions.service.in
+++ b/units/systemd-user-sessions.service.in
@@ -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/systemd-vconsole-setup.service.in b/units/systemd-vconsole-setup.service.in
index 8bb75c6a4f..f4178f495a 100644
--- a/units/systemd-vconsole-setup.service.in
+++ b/units/systemd-vconsole-setup.service.in
@@ -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/systemd-volatile-root.service.in b/units/systemd-volatile-root.service.in
index c5a4ca3c27..8f228bce9f 100644
--- a/units/systemd-volatile-root.service.in
+++ b/units/systemd-volatile-root.service.in
@@ -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/time-sync.target b/units/time-sync.target
index debee74109..1533c7c33c 100644
--- a/units/time-sync.target
+++ b/units/time-sync.target
@@ -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/timers.target b/units/timers.target
index 251fa68065..b1aa8c797c 100644
--- a/units/timers.target
+++ b/units/timers.target
@@ -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/tmp.mount b/units/tmp.mount
index 3a333d22ec..742d86385c 100644
--- a/units/tmp.mount
+++ b/units/tmp.mount
@@ -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/umount.target b/units/umount.target
index 39668d85d2..54fa5aebf2 100644
--- a/units/umount.target
+++ b/units/umount.target
@@ -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.slice b/units/user.slice
index 9fa6284c12..3f2d98fcdf 100644
--- a/units/user.slice
+++ b/units/user.slice
@@ -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/basic.target b/units/user/basic.target
index afc6e9360a..1ae8275c80 100644
--- a/units/user/basic.target
+++ b/units/user/basic.target
@@ -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/default.target b/units/user/default.target
index 9853c33b40..da319ce675 100644
--- a/units/user/default.target
+++ b/units/user/default.target
@@ -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/exit.target b/units/user/exit.target
index e8148b78c7..11a6f8eabe 100644
--- a/units/user/exit.target
+++ b/units/user/exit.target
@@ -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/graphical-session-pre.target b/units/user/graphical-session-pre.target
index 86d15aff33..3adfc5aaa4 100644
--- a/units/user/graphical-session-pre.target
+++ b/units/user/graphical-session-pre.target
@@ -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/graphical-session.target b/units/user/graphical-session.target
index 00d16230b7..a38eaabbc4 100644
--- a/units/user/graphical-session.target
+++ b/units/user/graphical-session.target
@@ -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/meson.build b/units/user/meson.build
index b507144c05..e463ae226c 100644
--- a/units/user/meson.build
+++ b/units/user/meson.build
@@ -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',
]
foreach file : units
@@ -21,6 +39,8 @@ endforeach
in_units = [
'systemd-exit.service',
+ 'systemd-tmpfiles-clean.service',
+ 'systemd-tmpfiles-setup.service',
]
foreach file : in_units
diff --git a/units/user/systemd-exit.service.in b/units/user/systemd-exit.service.in
index 987fab8120..9ce6f1c2ac 100644
--- a/units/user/systemd-exit.service.in
+++ b/units/user/systemd-exit.service.in
@@ -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
index 0000000000..9cd19720d3
--- /dev/null
+++ b/units/user/systemd-tmpfiles-clean.service.in
@@ -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
index 0000000000..d1dbad98de
--- /dev/null
+++ b/units/user/systemd-tmpfiles-clean.timer
@@ -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
index 0000000000..6467dab896
--- /dev/null
+++ b/units/user/systemd-tmpfiles-setup.service.in
@@ -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
diff --git a/units/user@.service.in b/units/user@.service.in
index 1beb901db8..e8195acbb6 100644
--- a/units/user@.service.in
+++ b/units/user@.service.in
@@ -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,6 +18,6 @@ Type=notify
ExecStart=-@rootlibexecdir@/systemd --user
Slice=user-%i.slice
KillMode=mixed
-Delegate=yes
+Delegate=pids cpu
TasksMax=infinity
TimeoutStopSec=120s
diff --git a/units/var-lib-machines.mount b/units/var-lib-machines.mount
index 7eba68f214..5da0c6fa32 100644
--- a/units/var-lib-machines.mount
+++ b/units/var-lib-machines.mount
@@ -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