summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@parabola.nu>2018-08-16 21:59:47 -0400
committerLuke Shumaker <lukeshu@parabola.nu>2018-08-16 21:59:47 -0400
commit4c6ce68ea04d726748e8a40a24c7ecb585d078ae (patch)
tree0deb72f4b70291d65a19aa46e8528dbe90bef5ff
parent1e21cd5b0c118c66cc22e0316a1edbdd9c95d217 (diff)
parent533c6b93ec1f8af64483f31f6adb98306653ece9 (diff)
Merge tag 'notsystemd/v234.1' into notsystemd/master
-rw-r--r--.dir-locals.el6
-rw-r--r--.github/CONTRIBUTING.md12
-rw-r--r--.github/ISSUE_TEMPLATE.md11
-rw-r--r--.gitignore7
-rw-r--r--.mailmap21
-rw-r--r--.mkosi/mkosi.arch9
-rw-r--r--.mkosi/mkosi.debian8
-rw-r--r--.mkosi/mkosi.fedora12
-rw-r--r--HACKING2
-rw-r--r--Makefile-man.am64
-rw-r--r--Makefile.am293
-rw-r--r--NEWS135
-rw-r--r--README47
-rw-r--r--README.md2
-rw-r--r--TODO9
-rw-r--r--catalog/meson.build28
-rw-r--r--configure.ac118
-rw-r--r--docs/sysvinit/meson.build9
-rw-r--r--docs/var-log/meson.build9
-rw-r--r--hwdb/20-OUI.hwdb5347
-rw-r--r--hwdb/20-acpi-vendor.hwdb42
-rw-r--r--hwdb/20-pci-vendor-model.hwdb1127
-rw-r--r--hwdb/20-usb-vendor-model.hwdb908
-rw-r--r--hwdb/60-evdev.hwdb53
-rw-r--r--hwdb/60-keyboard.hwdb62
-rw-r--r--hwdb/60-sensor.hwdb23
-rw-r--r--hwdb/70-joystick.hwdb50
-rw-r--r--hwdb/70-mouse.hwdb16
-rw-r--r--hwdb/70-pointingstick.hwdb10
-rw-r--r--hwdb/70-touchpad.hwdb7
-rwxr-xr-xhwdb/acpi-update.py2
-rw-r--r--hwdb/meson.build44
-rwxr-xr-xhwdb/parse_hwdb.py10
-rwxr-xr-xman/90-rearrange-path.py2
-rw-r--r--man/custom-entities.ent.in7
-rw-r--r--man/environment.d.xml5
-rw-r--r--man/journalctl.xml14
-rw-r--r--man/kernel-command-line.xml4
-rw-r--r--man/less-variables.xml4
-rw-r--r--man/locale.conf.xml8
-rw-r--r--man/logind.conf.xml9
-rw-r--r--man/machinectl.xml29
-rw-r--r--man/meson.build204
-rw-r--r--man/networkctl.xml33
-rw-r--r--man/nss-resolve.xml15
-rw-r--r--man/nss-systemd.xml2
-rw-r--r--man/rules/meson.build766
-rw-r--r--man/sd_bus_add_match.xml43
-rw-r--r--man/sd_bus_error.xml2
-rw-r--r--man/sd_bus_message_append.xml21
-rw-r--r--man/sd_get_seats.xml13
-rw-r--r--man/sd_id128_randomize.xml2
-rw-r--r--man/sd_journal_get_catalog.xml2
-rw-r--r--man/sd_notify.xml52
-rw-r--r--man/sd_pid_get_session.xml10
-rw-r--r--man/sd_seat_get_active.xml5
-rw-r--r--man/sd_session_is_active.xml5
-rw-r--r--man/systemctl.xml27
-rw-r--r--man/systemd-ask-password.xml2
-rw-r--r--man/systemd-coredump.xml2
-rw-r--r--man/systemd-delta.xml2
-rw-r--r--man/systemd-environment-d-generator.xml2
-rw-r--r--man/systemd-fstab-generator.xml8
-rw-r--r--man/systemd-hibernate-resume-generator.xml2
-rw-r--r--man/systemd-hibernate-resume@.service.xml2
-rw-r--r--man/systemd-mount.xml21
-rw-r--r--man/systemd-nspawn.xml58
-rw-r--r--man/systemd-resolve.xml2
-rw-r--r--man/systemd-vconsole-setup.service.xml2
-rw-r--r--man/systemd.environment-generator.xml3
-rw-r--r--man/systemd.exec.xml72
-rw-r--r--man/systemd.journal-fields.xml6
-rw-r--r--man/systemd.link.xml41
-rw-r--r--man/systemd.mount.xml18
-rw-r--r--man/systemd.netdev.xml116
-rw-r--r--man/systemd.network.xml104
-rw-r--r--man/systemd.service.xml81
-rw-r--r--man/systemd.special.xml88
-rw-r--r--man/systemd.target.xml37
-rw-r--r--man/systemd.time.xml28
-rw-r--r--man/systemd.timer.xml4
-rw-r--r--man/systemd.unit.xml99
-rw-r--r--man/sysusers.d.xml33
-rw-r--r--man/udevadm.xml4
-rw-r--r--man/vconsole.conf.xml7
-rw-r--r--meson.build2529
-rw-r--r--meson_options.txt256
-rwxr-xr-xmkosi.build10
-rw-r--r--network/meson.build12
-rw-r--r--po/LINGUAS1
-rw-r--r--po/cs.po211
-rw-r--r--po/meson.build12
-rw-r--r--po/pt_BR.po240
-rw-r--r--po/sk.po556
-rw-r--r--po/sv.po113
-rw-r--r--rules/.gitignore1
-rw-r--r--rules/50-udev-default.rules.in (renamed from rules/50-udev-default.rules)5
-rw-r--r--rules/60-cdrom_id.rules2
-rw-r--r--rules/60-evdev.rules2
-rw-r--r--rules/60-input-id.rules7
-rw-r--r--rules/60-persistent-input.rules2
-rw-r--r--rules/60-sensor.rules8
-rw-r--r--rules/70-joystick.rules12
-rw-r--r--rules/meson.build40
-rw-r--r--shell-completion/bash/meson.build50
-rw-r--r--shell-completion/bash/networkctl2
-rw-r--r--shell-completion/bash/systemctl.in2
-rw-r--r--shell-completion/zsh/_networkctl1
-rw-r--r--shell-completion/zsh/_sd_outputmodes2
-rw-r--r--shell-completion/zsh/meson.build47
-rw-r--r--src/activate/activate.c5
-rw-r--r--src/analyze/analyze.c2
-rw-r--r--src/analyze/meson.build5
-rw-r--r--src/basic/af-to-name.awk9
-rw-r--r--src/basic/architecture.c5
-rw-r--r--src/basic/architecture.h40
-rw-r--r--src/basic/arphrd-to-name.awk9
-rw-r--r--src/basic/blkid-util.h2
-rw-r--r--src/basic/build.h7
-rw-r--r--src/basic/calendarspec.c99
-rw-r--r--src/basic/cap-to-name.awk9
-rw-r--r--src/basic/cgroup-util.c84
-rw-r--r--src/basic/cgroup-util.h2
-rw-r--r--src/basic/def.h4
-rw-r--r--src/basic/dirent-util.c11
-rw-r--r--src/basic/dirent-util.h2
-rw-r--r--src/basic/env-util.c4
-rw-r--r--src/basic/errno-to-name.awk9
-rw-r--r--src/basic/escape.c38
-rw-r--r--src/basic/escape.h23
-rw-r--r--src/basic/extract-word.c7
-rw-r--r--src/basic/extract-word.h2
-rw-r--r--src/basic/fd-util.c3
-rw-r--r--src/basic/fileio-label.c4
-rw-r--r--src/basic/fileio-label.h5
-rw-r--r--src/basic/fileio.c19
-rw-r--r--src/basic/fileio.h10
-rw-r--r--src/basic/fs-util.c2
-rwxr-xr-xsrc/basic/generate-af-list.sh5
-rwxr-xr-xsrc/basic/generate-arphrd-list.sh5
-rwxr-xr-xsrc/basic/generate-cap-list.sh5
-rwxr-xr-xsrc/basic/generate-errno-list.sh4
-rwxr-xr-xsrc/basic/generate-gperfs.py16
-rw-r--r--src/basic/glob-util.c64
-rw-r--r--src/basic/glob-util.h4
-rw-r--r--src/basic/in-addr-util.c42
-rw-r--r--src/basic/in-addr-util.h1
-rw-r--r--src/basic/log.c150
-rw-r--r--src/basic/log.h112
-rw-r--r--src/basic/macro.h1
-rw-r--r--src/basic/meson.build281
-rw-r--r--src/basic/missing.h50
-rw-r--r--src/basic/missing_syscall.h16
-rw-r--r--src/basic/mount-util.c22
-rw-r--r--src/basic/mount-util.h1
-rw-r--r--src/basic/parse-util.c15
-rw-r--r--src/basic/parse-util.h1
-rw-r--r--src/basic/path-util.c4
-rw-r--r--src/basic/path-util.h2
-rw-r--r--src/basic/process-util.c85
-rw-r--r--src/basic/process-util.h15
-rw-r--r--src/basic/random-util.c128
-rw-r--r--src/basic/random-util.h4
-rw-r--r--src/basic/rm-rf.c9
-rw-r--r--src/basic/selinux-util.c22
-rw-r--r--src/basic/selinux-util.h1
-rw-r--r--src/basic/socket-util.c11
-rw-r--r--src/basic/stat-util.c6
-rw-r--r--src/basic/stat-util.h2
-rw-r--r--src/basic/strv.c6
-rw-r--r--src/basic/strxcpyx.c32
-rw-r--r--src/basic/terminal-util.c2
-rw-r--r--src/basic/time-util.c65
-rw-r--r--src/basic/time-util.h17
-rw-r--r--src/basic/unit-name.c9
-rw-r--r--src/basic/unit-name.h12
-rw-r--r--src/basic/util.c4
-rw-r--r--src/basic/virt.c4
-rw-r--r--src/boot/bootctl.c69
-rw-r--r--src/boot/efi/boot.c26
-rw-r--r--src/boot/efi/measure.c6
-rw-r--r--src/boot/efi/measure.h5
-rw-r--r--src/boot/efi/meson.build205
-rwxr-xr-xsrc/boot/efi/no-undefined-symbols.sh6
-rw-r--r--src/boot/efi/pe.c (renamed from src/boot/efi/pefile.c)130
-rw-r--r--src/boot/efi/pe.h (renamed from src/boot/efi/pefile.h)6
-rw-r--r--src/boot/efi/shim.c262
-rw-r--r--src/boot/efi/shim.h31
-rw-r--r--src/boot/efi/stub.c20
-rw-r--r--src/busctl/busctl-introspect.c (renamed from src/libsystemd/sd-bus/busctl-introspect.c)0
-rw-r--r--src/busctl/busctl-introspect.h (renamed from src/libsystemd/sd-bus/busctl-introspect.h)0
-rw-r--r--src/busctl/busctl.c (renamed from src/libsystemd/sd-bus/busctl.c)23
-rw-r--r--src/cgtop/cgtop.c20
-rw-r--r--src/core/audit-fd.c8
-rw-r--r--src/core/automount.c60
-rw-r--r--src/core/busname.c4
-rw-r--r--src/core/cgroup.c5
-rw-r--r--src/core/dbus-cgroup.c10
-rw-r--r--src/core/dbus-execute.c132
-rw-r--r--src/core/dbus-service.c33
-rw-r--r--src/core/dbus-timer.c20
-rw-r--r--src/core/dbus-unit.c1
-rw-r--r--src/core/dbus.c2
-rw-r--r--src/core/device.c8
-rw-r--r--src/core/execute.c113
-rw-r--r--src/core/execute.h5
-rw-r--r--src/core/ima-setup.c8
-rw-r--r--src/core/job.c73
-rw-r--r--src/core/job.h3
-rw-r--r--src/core/load-dropin.c19
-rw-r--r--src/core/load-fragment-gperf-nulstr.awk14
-rw-r--r--src/core/load-fragment-gperf.gperf.m411
-rw-r--r--src/core/load-fragment.c164
-rw-r--r--src/core/loopback-setup.c150
-rw-r--r--src/core/main.c47
-rw-r--r--src/core/manager.c29
-rw-r--r--src/core/meson.build235
-rw-r--r--src/core/namespace.c44
-rw-r--r--src/core/selinux-access.c7
-rw-r--r--src/core/service.c273
-rw-r--r--src/core/service.h12
-rw-r--r--src/core/shutdown.c2
-rw-r--r--src/core/smack-setup.c64
-rw-r--r--src/core/socket.c6
-rw-r--r--src/core/swap.c72
-rw-r--r--src/core/target.c5
-rw-r--r--src/core/timer.c41
-rw-r--r--src/core/timer.h2
-rw-r--r--src/core/transaction.c2
-rw-r--r--src/core/umount.c2
-rw-r--r--src/core/unit.c69
-rw-r--r--src/core/unit.h1
-rw-r--r--src/coredump/coredump.c13
-rw-r--r--src/coredump/meson.build24
-rw-r--r--src/cryptsetup/cryptsetup.c10
-rw-r--r--src/delta/delta.c127
-rw-r--r--src/environment-d-generator/environment-d-generator.c2
-rw-r--r--src/escape/escape.c2
-rw-r--r--src/firstboot/firstboot.c2
-rw-r--r--src/fstab-generator/fstab-generator.c65
-rw-r--r--src/gpt-auto-generator/gpt-auto-generator.c16
-rw-r--r--src/hostname/meson.build14
-rw-r--r--src/hwdb/hwdb.c2
-rw-r--r--src/import/meson.build77
-rw-r--r--src/import/pull-common.c34
-rw-r--r--src/import/pull-job.c48
-rw-r--r--src/import/pull-job.h8
-rw-r--r--src/import/pull-raw.c17
-rw-r--r--src/import/pull-tar.c26
-rw-r--r--src/initctl/initctl.c4
-rw-r--r--src/journal-remote/journal-remote.c12
-rw-r--r--src/journal-remote/journal-upload-journal.c2
-rw-r--r--src/journal-remote/journal-upload.c8
-rwxr-xr-xsrc/journal-remote/log-generator.py2
-rw-r--r--src/journal-remote/meson.build49
-rw-r--r--src/journal-remote/microhttpd-util.c3
-rw-r--r--src/journal-remote/microhttpd-util.h13
-rw-r--r--src/journal/audit_type-to-name.awk9
-rw-r--r--src/journal/fsprg.c3
-rwxr-xr-xsrc/journal/generate-audit_type-list.sh14
-rw-r--r--src/journal/journal-file.c28
-rw-r--r--src/journal/journal-file.h1
-rw-r--r--src/journal/journal-qrcode.c2
-rw-r--r--src/journal/journal-verify.c124
-rw-r--r--src/journal/journalctl.c23
-rw-r--r--src/journal/journald-kmsg.c2
-rw-r--r--src/journal/journald-native.c2
-rw-r--r--src/journal/journald-server.c12
-rw-r--r--src/journal/journald-stream.c2
-rw-r--r--src/journal/journald-syslog.c4
-rw-r--r--src/journal/journald.c4
-rw-r--r--src/journal/meson.build122
-rw-r--r--src/journal/mmap-cache.c163
-rw-r--r--src/journal/mmap-cache.h8
-rw-r--r--src/journal/sd-journal.c11
-rw-r--r--src/journal/test-compress-benchmark.c9
-rw-r--r--src/journal/test-compress.c6
-rw-r--r--src/journal/test-mmap-cache.c14
-rw-r--r--src/kernel-install/50-depmod.install12
-rw-r--r--src/kernel-install/90-loaderentry.install8
-rw-r--r--src/kernel-install/kernel-install27
-rw-r--r--src/kernel-install/meson.build11
-rw-r--r--src/libsystemd-network/dhcp-lease-internal.h2
-rw-r--r--src/libsystemd-network/icmp6-util.c117
-rw-r--r--src/libsystemd-network/icmp6-util.h13
-rw-r--r--src/libsystemd-network/lldp-neighbor.c7
-rw-r--r--src/libsystemd-network/meson.build48
-rw-r--r--src/libsystemd-network/ndisc-internal.h7
-rw-r--r--src/libsystemd-network/network-internal.c39
-rw-r--r--src/libsystemd-network/network-internal.h7
-rw-r--r--src/libsystemd-network/radv-internal.h88
-rw-r--r--src/libsystemd-network/sd-dhcp-client.c8
-rw-r--r--src/libsystemd-network/sd-dhcp-lease.c134
-rw-r--r--src/libsystemd-network/sd-dhcp-server.c46
-rw-r--r--src/libsystemd-network/sd-ipv4ll.c6
-rw-r--r--src/libsystemd-network/sd-ndisc.c184
-rw-r--r--src/libsystemd-network/sd-radv.c653
-rw-r--r--src/libsystemd-network/test-dhcp-server.c2
-rw-r--r--src/libsystemd-network/test-ipv4ll.c17
-rw-r--r--src/libsystemd-network/test-ndisc-ra.c359
-rw-r--r--src/libsystemd-network/test-ndisc-rs.c115
-rw-r--r--src/libsystemd-network/test-sd-dhcp-lease.c90
-rw-r--r--src/libsystemd/libsystemd.sym5
-rw-r--r--src/libsystemd/meson.build96
-rw-r--r--src/libsystemd/sd-bus/DIFFERENCES25
-rw-r--r--src/libsystemd/sd-bus/GVARIANT-SERIALIZATION23
-rw-r--r--src/libsystemd/sd-bus/PORTING-DBUS1535
-rw-r--r--src/libsystemd/sd-bus/bus-control.c274
-rw-r--r--src/libsystemd/sd-bus/bus-convenience.c10
-rw-r--r--src/libsystemd/sd-bus/bus-creds.c2
-rw-r--r--src/libsystemd/sd-bus/bus-internal.h1
-rw-r--r--src/libsystemd/sd-bus/bus-kernel.c2
-rw-r--r--src/libsystemd/sd-bus/bus-message.c12
-rw-r--r--src/libsystemd/sd-bus/bus-message.h2
-rw-r--r--src/libsystemd/sd-bus/bus-objects.c26
-rw-r--r--src/libsystemd/sd-bus/bus-socket.c2
-rw-r--r--src/libsystemd/sd-bus/sd-bus.c21
-rw-r--r--src/libsystemd/sd-bus/test-bus-benchmark.c2
-rw-r--r--src/libsystemd/sd-bus/test-bus-kernel-bloom.c2
-rw-r--r--src/libsystemd/sd-bus/test-bus-kernel.c2
-rw-r--r--src/libsystemd/sd-bus/test-bus-track.c2
l---------src/libsystemd/sd-bus/test-bus-vtable-cc.cc1
-rw-r--r--src/libsystemd/sd-bus/test-bus-vtable.c81
-rw-r--r--src/libsystemd/sd-bus/test-bus-zero-copy.c2
-rw-r--r--src/libsystemd/sd-daemon/sd-daemon.c6
-rw-r--r--src/libsystemd/sd-device/device-enumerator.c12
-rw-r--r--src/libsystemd/sd-device/device-private.c6
-rw-r--r--src/libsystemd/sd-device/sd-device.c7
-rw-r--r--src/libsystemd/sd-event/sd-event.c4
-rw-r--r--src/libsystemd/sd-event/test-event.c12
-rw-r--r--src/libsystemd/sd-id128/sd-id128.c2
-rw-r--r--src/libsystemd/sd-login/sd-login.c77
-rw-r--r--src/libsystemd/sd-login/test-login.c319
-rw-r--r--src/libsystemd/sd-netlink/netlink-message.c3
-rw-r--r--src/libsystemd/sd-netlink/netlink-types.c63
-rw-r--r--src/libsystemd/sd-netlink/netlink-types.h1
-rw-r--r--src/libsystemd/sd-netlink/netlink-util.c45
-rw-r--r--src/libsystemd/sd-netlink/netlink-util.h23
-rw-r--r--src/libsystemd/sd-netlink/rtnl-message.c54
-rw-r--r--src/libsystemd/sd-netlink/sd-netlink.c4
-rw-r--r--src/libsystemd/sd-resolve/sd-resolve.c4
-rw-r--r--src/libudev/libudev-monitor.c2
-rw-r--r--src/libudev/libudev.c76
-rw-r--r--src/libudev/libudev.pc.in2
-rw-r--r--src/libudev/meson.build41
-rw-r--r--src/locale/keymap-util.c5
-rw-r--r--src/locale/localed.c3
-rw-r--r--src/locale/meson.build42
-rw-r--r--src/login/70-power-switch.rules9
-rw-r--r--src/login/loginctl.c40
-rw-r--r--src/login/logind-button.c119
-rw-r--r--src/login/logind-core.c6
-rw-r--r--src/login/logind-dbus.c3
-rw-r--r--src/login/logind-session-dbus.c17
-rw-r--r--src/login/logind-session-device.c81
-rw-r--r--src/login/logind-session-device.h5
-rw-r--r--src/login/logind-session.c87
-rw-r--r--src/login/logind-session.h4
-rw-r--r--src/login/logind.c83
-rw-r--r--src/login/meson.build104
-rw-r--r--src/login/pam_systemd.c5
-rw-r--r--src/machine/image-dbus.c1
-rw-r--r--src/machine/machinectl.c7
-rw-r--r--src/machine/machined.c5
-rw-r--r--src/machine/meson.build45
-rw-r--r--src/machine/operation.c2
-rw-r--r--src/mount/mount-tool.c498
-rw-r--r--src/network/meson.build150
-rw-r--r--src/network/netdev/bridge.c4
-rw-r--r--src/network/netdev/geneve.c315
-rw-r--r--src/network/netdev/geneve.h85
-rw-r--r--src/network/netdev/netdev-gperf.gperf19
-rw-r--r--src/network/netdev/netdev.c3
-rw-r--r--src/network/netdev/netdev.h1
-rw-r--r--src/network/netdev/vlan.c30
-rw-r--r--src/network/netdev/vlan.h5
-rw-r--r--src/network/netdev/vxlan.c38
-rw-r--r--src/network/netdev/vxlan.h22
-rw-r--r--src/network/networkctl.c74
-rw-r--r--src/network/networkd-address-label.c223
-rw-r--r--src/network/networkd-address-label.h58
-rw-r--r--src/network/networkd-address.c248
-rw-r--r--src/network/networkd-address.h22
-rw-r--r--src/network/networkd-conf.c8
-rw-r--r--src/network/networkd-ipv4ll.c12
-rw-r--r--src/network/networkd-ipv6-proxy-ndp.c3
-rw-r--r--src/network/networkd-link.c124
-rw-r--r--src/network/networkd-link.h3
-rw-r--r--src/network/networkd-manager.c15
-rw-r--r--src/network/networkd-network-gperf.gperf19
-rw-r--r--src/network/networkd-network.c27
-rw-r--r--src/network/networkd-network.h18
-rw-r--r--src/network/networkd-radv.c79
-rw-r--r--src/network/networkd-radv.h24
-rw-r--r--src/network/networkd-route.c164
-rw-r--r--src/network/networkd-route.h9
-rw-r--r--src/nspawn/meson.build40
-rw-r--r--src/nspawn/nspawn-cgroup.c2
-rw-r--r--src/nspawn/nspawn-network.c1
-rw-r--r--src/nspawn/nspawn-register.c236
-rw-r--r--src/nspawn/nspawn-register.h2
-rw-r--r--src/nspawn/nspawn-stub-pid1.c13
-rw-r--r--src/nspawn/nspawn.c60
-rw-r--r--src/rc-local-generator/rc-local-generator.c8
-rw-r--r--src/resolve/dns_type-to-name.awk11
-rwxr-xr-xsrc/resolve/generate-dns_type-gperf.py18
-rw-r--r--src/resolve/generate-dns_type-list.sed1
-rw-r--r--src/resolve/meson.build187
-rw-r--r--src/resolve/resolved-bus.c7
-rw-r--r--src/resolve/resolved-conf.c14
-rw-r--r--src/resolve/resolved-dns-packet.c22
-rw-r--r--src/resolve/resolved-dns-packet.h4
-rw-r--r--src/resolve/resolved-dns-question.c14
-rw-r--r--src/resolve/resolved-dns-server.c13
-rw-r--r--src/resolve/resolved-dns-transaction.c2
-rw-r--r--src/resolve/resolved-dns-trust-anchor.c2
-rw-r--r--src/resolve/resolved-link.c13
-rw-r--r--src/resolve/resolved-manager.c34
-rw-r--r--src/resolve/test-dnssec-complex.c2
-rw-r--r--src/resolve/test-resolved-packet.c5
-rw-r--r--src/run/run.c2
-rw-r--r--src/shared/ask-password-api.c3
-rw-r--r--src/shared/base-filesystem.c5
-rw-r--r--src/shared/bus-unit-util.c32
-rw-r--r--src/shared/bus-util.c21
-rw-r--r--src/shared/cgroup-show.c2
-rw-r--r--src/shared/cgroup-show.h2
-rw-r--r--src/shared/condition.c65
-rw-r--r--src/shared/condition.h3
-rw-r--r--src/shared/conf-parser.c54
-rw-r--r--src/shared/conf-parser.h2
-rw-r--r--src/shared/dissect-image.c14
-rw-r--r--src/shared/dns-domain.c45
-rw-r--r--src/shared/dns-domain.h2
-rw-r--r--src/shared/efivars.c1
-rw-r--r--src/shared/fstab-util.c33
-rw-r--r--src/shared/fstab-util.h3
-rw-r--r--src/shared/generator.c50
-rw-r--r--src/shared/generator.h6
-rw-r--r--src/shared/install.c4
-rw-r--r--src/shared/linux-3.13/dm-ioctl.h355
-rw-r--r--src/shared/logs-show.c16
-rw-r--r--src/shared/meson.build158
-rw-r--r--src/shared/output-mode.c1
-rw-r--r--src/shared/output-mode.h1
-rw-r--r--src/shared/pager.c33
-rw-r--r--src/shared/seccomp-util.c156
-rw-r--r--src/shared/seccomp-util.h22
-rw-r--r--src/shared/sleep-config.c6
-rw-r--r--src/shared/udev-util.c56
-rw-r--r--src/shared/udev-util.h2
-rw-r--r--src/shared/vlan-util.c31
-rw-r--r--src/shared/vlan-util.h1
-rw-r--r--src/stdio-bridge/stdio-bridge.c2
-rw-r--r--src/sulogin-shell/.gitignore1
-rw-r--r--src/sulogin-shell/meson.build7
-rwxr-xr-xsrc/sulogin-shell/systemd-sulogin-shell.in12
-rw-r--r--src/systemctl/systemctl.c133
-rw-r--r--src/systemd/meson.build59
-rw-r--r--src/systemd/sd-bus.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-event.h2
-rw-r--r--src/systemd/sd-ipv4ll.h1
-rw-r--r--src/systemd/sd-netlink.h4
-rw-r--r--src/systemd/sd-radv.h81
-rw-r--r--src/sysusers/sysusers.c617
-rw-r--r--src/sysv-generator/sysv-generator.c3
-rwxr-xr-xsrc/test/generate-sym-test.py23
-rw-r--r--src/test/meson.build906
-rw-r--r--src/test/test-af-list.c2
-rw-r--r--src/test/test-calendarspec.c5
-rw-r--r--src/test/test-cgroup.c6
-rw-r--r--src/test/test-condition.c153
-rw-r--r--src/test/test-date.c43
-rw-r--r--src/test/test-dlopen.c32
-rw-r--r--src/test/test-dns-domain.c60
-rw-r--r--src/test/test-env-util.c45
-rw-r--r--src/test/test-escape.c57
-rw-r--r--src/test/test-exec-util.c2
-rw-r--r--src/test/test-execute.c10
-rw-r--r--src/test/test-fs-util.c2
-rw-r--r--src/test/test-glob-util.c66
-rw-r--r--src/test/test-hash.c10
-rw-r--r--src/test/test-hashmap-ordered.awk11
-rw-r--r--src/test/test-id128.c23
-rw-r--r--src/test/test-libudev.c2
-rw-r--r--src/test/test-log.c15
-rw-r--r--src/test/test-loopback.c1
-rw-r--r--src/test/test-nss.c10
-rw-r--r--src/test/test-parse-util.c83
-rw-r--r--src/test/test-path-util.c44
-rw-r--r--src/test/test-process-util.c133
-rw-r--r--src/test/test-random-util.c65
-rw-r--r--src/test/test-seccomp.c107
-rw-r--r--src/test/test-selinux.c8
-rw-r--r--src/test/test-sigbus.c10
-rw-r--r--src/test/test-signal-util.c10
-rw-r--r--src/test/test-sizeof.c25
-rw-r--r--src/test/test-stat-util.c6
-rw-r--r--src/test/test-strxcpyx.c7
-rw-r--r--src/test/test-time.c142
-rw-r--r--src/test/test-tmpfiles.c4
-rw-r--r--src/test/test-udev.c2
-rw-r--r--src/test/test-unit-file.c14
-rw-r--r--src/timedate/meson.build14
-rw-r--r--src/timesync/meson.build42
-rw-r--r--src/timesync/test-timesync.c51
-rw-r--r--src/timesync/timesyncd-conf.c8
-rw-r--r--src/timesync/timesyncd.c3
-rw-r--r--src/tmpfiles/tmpfiles.c18
-rw-r--r--src/udev/ata_id/ata_id.c2
-rw-r--r--src/udev/cdrom_id/cdrom_id.c6
-rw-r--r--src/udev/collect/collect.c27
-rwxr-xr-xsrc/udev/generate-keyboard-keys-gperf.sh10
-rwxr-xr-xsrc/udev/generate-keyboard-keys-list.sh6
-rw-r--r--src/udev/meson.build152
-rw-r--r--src/udev/net/ethtool-util.c29
-rw-r--r--src/udev/net/ethtool-util.h24
-rw-r--r--src/udev/net/link-config-gperf.gperf1
-rw-r--r--src/udev/net/link-config.c10
-rw-r--r--src/udev/net/link-config.h1
-rw-r--r--src/udev/scsi_id/scsi_id.c4
-rw-r--r--src/udev/udev-builtin-blkid.c19
-rw-r--r--src/udev/udev-builtin-input_id.c59
-rw-r--r--src/udev/udev-builtin-keyboard.c26
-rw-r--r--src/udev/udev-builtin-net_id.c107
-rw-r--r--src/udev/udev-ctrl.c2
-rw-r--r--src/udev/udev-event.c10
-rw-r--r--src/udev/udev-rules.c53
-rw-r--r--src/udev/udev.pc.in2
-rw-r--r--src/udev/udevadm-hwdb.c2
-rw-r--r--src/udev/udevadm-info.c2
-rw-r--r--src/udev/udevadm-test.c2
-rw-r--r--src/udev/udevadm.c13
-rw-r--r--src/udev/udevd.c23
-rw-r--r--src/update-done/update-done.c55
-rw-r--r--src/update-utmp/update-utmp.c5
-rw-r--r--src/vconsole/meson.build8
-rw-r--r--src/vconsole/vconsole-setup.c204
-rw-r--r--sysctl.d/meson.build21
-rw-r--r--sysusers.d/basic.conf.in1
-rw-r--r--sysusers.d/meson.build31
-rw-r--r--test/README.testsuite2
-rwxr-xr-xtest/TEST-12-ISSUE-3171/test.sh8
-rwxr-xr-xtest/create-sys-script.py4
-rw-r--r--test/meson.build167
-rwxr-xr-xtest/networkd-test.py78
-rwxr-xr-xtest/rule-syntax-check.py2
-rwxr-xr-xtest/sys-script.py2
-rwxr-xr-xtest/sysv-generator-test.py2
-rwxr-xr-xtest/test-efi-create-disk.sh32
-rwxr-xr-xtest/test-exec-deserialization.py192
-rw-r--r--test/test-execute/exec-inaccessiblepaths-mount-propagation.service2
-rw-r--r--test/test-execute/exec-inaccessiblepaths-proc.service7
-rw-r--r--test/test-execute/exec-protectkernelmodules-yes-mount-propagation.service2
-rw-r--r--test/test-execute/exec-readonlypaths-mount-propagation.service2
-rw-r--r--test/test-execute/exec-readwritepaths-mount-propagation.service2
-rw-r--r--test/test-functions32
-rw-r--r--tmpfiles.d/.gitignore2
-rw-r--r--tmpfiles.d/meson.build51
-rw-r--r--tmpfiles.d/systemd-remote.conf.m4 (renamed from tmpfiles.d/systemd-remote.conf)4
-rw-r--r--tmpfiles.d/var.conf.m4 (renamed from tmpfiles.d/var.conf)3
-rwxr-xr-x[-rw-r--r--]tools/catalog-report.py2
-rw-r--r--tools/gdb-sd_dump_hashmaps.py2
-rwxr-xr-xtools/make-directive-index.py2
-rwxr-xr-xtools/make-man-index.py2
-rwxr-xr-x[-rw-r--r--]tools/make-man-rules.py48
-rwxr-xr-xtools/meson-check-compilation.sh3
-rwxr-xr-xtools/meson-check-help.sh20
-rwxr-xr-xtools/meson-git-contrib.sh8
-rwxr-xr-xtools/meson-hwdb-update.sh15
-rw-r--r--tools/meson-link-test.c1
-rwxr-xr-xtools/meson-make-symlink.sh11
-rwxr-xr-x[-rw-r--r--]tools/xml_helper.py2
-rw-r--r--units/console-getty.service.m4.in5
-rw-r--r--units/container-getty@.service.m4.in5
-rw-r--r--units/dev-hugepages.mount2
-rw-r--r--units/dev-mqueue.mount2
-rw-r--r--units/emergency.service.in4
-rw-r--r--units/getty@.service.m45
-rwxr-xr-xunits/meson-add-wants.sh27
-rw-r--r--units/meson.build329
-rw-r--r--units/network-online.target2
-rw-r--r--units/network-pre.target2
-rw-r--r--units/network.target2
-rw-r--r--units/org.freedesktop.hostname1.busname2
-rw-r--r--units/org.freedesktop.locale1.busname2
-rw-r--r--units/org.freedesktop.login1.busname4
-rw-r--r--units/org.freedesktop.machine1.busname2
-rw-r--r--units/org.freedesktop.resolve1.busname2
-rw-r--r--units/org.freedesktop.systemd1.busname2
-rw-r--r--units/org.freedesktop.timedate1.busname2
-rw-r--r--units/proc-sys-fs-binfmt_misc.automount4
-rw-r--r--units/proc-sys-fs-binfmt_misc.mount4
-rw-r--r--units/quotaon.service.in2
-rw-r--r--units/rescue.service.in4
-rw-r--r--units/serial-getty@.service.m411
-rw-r--r--units/sys-fs-fuse-connections.mount2
-rw-r--r--units/sys-kernel-config.mount4
-rw-r--r--units/sys-kernel-debug.mount4
-rw-r--r--units/syslog.socket4
-rw-r--r--units/systemd-ask-password-console.service.in1
-rw-r--r--units/systemd-ask-password-wall.service.in1
-rw-r--r--units/systemd-coredump@.service.in17
-rw-r--r--units/systemd-hostnamed.service.in10
-rw-r--r--units/systemd-importd.service.in6
-rw-r--r--units/systemd-initctl.service.in3
-rw-r--r--units/systemd-journal-gatewayd.service.in5
-rw-r--r--units/systemd-journal-remote.service.in6
-rw-r--r--units/systemd-journal-upload.service.in6
-rw-r--r--units/systemd-journald.service.in7
-rw-r--r--units/systemd-localed.service.in10
-rw-r--r--units/systemd-logind.service.in9
-rw-r--r--units/systemd-machined.service.in6
-rw-r--r--units/systemd-networkd-wait-online.service.in2
-rw-r--r--units/systemd-networkd.service.m4.in8
-rw-r--r--units/systemd-quotacheck.service.in2
-rw-r--r--units/systemd-remount-fs.service.in2
-rw-r--r--units/systemd-resolved.service.m4.in13
-rw-r--r--units/systemd-timedated.service.in10
-rw-r--r--units/systemd-timesyncd.service.in8
-rw-r--r--units/systemd-udevd.service.in1
-rw-r--r--units/tmp.mount.m44
-rw-r--r--units/user/meson.build33
625 files changed, 28345 insertions, 5979 deletions
diff --git a/.dir-locals.el b/.dir-locals.el
index 3e1b2d76c0..5ef7e11634 100644
--- a/.dir-locals.el
+++ b/.dir-locals.el
@@ -20,4 +20,8 @@
(eval . (c-set-offset 'arglist-intro '++))
(eval . (c-set-offset 'arglist-close 0))))
(nxml-mode . ((nxml-child-indent . 2)
- (fill-column . 119))))
+ (fill-column . 119)))
+ (meson-mode . ((meson-indent-basic . 8)))
+ (sh-mode . ((sh-basic-offset . 8)
+ (sh-indentation . 8)))
+ (awk-mode . ((c-basic-offset . 8))))
diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index abee9cc740..f2ed0d9f64 100644
--- a/.github/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -4,13 +4,23 @@ We welcome contributions from everyone. However, please follow the following gui
## Filing Issues
-* We use GitHub Issues **exclusively** for tracking **bugs** and **feature** **requests** of systemd. If you are looking for help, please contact our [mailing list](http://lists.freedesktop.org/mailman/listinfo/systemd-devel) instead.
+* We use GitHub Issues **exclusively** for tracking **bugs** and **feature** **requests** of systemd. If you are looking for help, please contact our [mailing list](https://lists.freedesktop.org/mailman/listinfo/systemd-devel) instead.
* We only track bugs in the **two** **most** **recently** **released** **versions** of systemd in the GitHub Issue tracker. If you are using an older version of systemd, please contact your distribution's bug tracker instead.
* When filing an issue, specify the **systemd** **version** you are experiencing the issue with. Also, indicate which **distribution** you are using.
* Please include an explanation how to reproduce the issue you are pointing out.
Following these guidelines makes it easier for us to process your issue, and ensures we won't close your issue right-away for being misfiled.
+### Older downstream versions
+For older versions that are still supported by your distribution please use respective downstream tracker:
+* **Fedora** - [bugzilla](https://bugzilla.redhat.com/enter_bug.cgi?product=Fedora&component=systemd)
+* **RHEL-7/CentOS-7** - [bugzilla](https://bugzilla.redhat.com/enter_bug.cgi?product=Red%20Hat%20Enterprise%20Linux%207&component=systemd) or [systemd-rhel github](https://github.com/lnykryn/systemd-rhel/issues)
+* **Debian** - [bugs.debian.org](https://bugs.debian.org/cgi-bin/pkgreport.cgi?pkg=systemd)
+
+## Security vulnerability reports
+
+If you discover a security vulnerability, we'd appreciate a non-public disclosure. The issue tracker and mailing list listed above are fully public. If you need to reach systemd developers in a non-public way, report the issue in one of the "big" distributions using systemd: [Fedora](https://bugzilla.redhat.com/enter_bug.cgi?product=Fedora&component=systemd) (be sure to check "Security Sensitive Bug" under "Show Advanced Fields"), [Ubuntu](https://launchpad.net/ubuntu/+source/systemd/+filebug) (be sure to change "This bug contains information that is" from "Public" to "Private Security"), or [Debian](mailto:security@debian.org). Various systemd developers are active distribution maintainers and will propagate the information about the bug to other parties.
+
## Posting Pull Requests
* Make sure to post PRs only relative to a very recent git master.
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
index 750f9e774d..687270eaae 100644
--- a/.github/ISSUE_TEMPLATE.md
+++ b/.github/ISSUE_TEMPLATE.md
@@ -1,15 +1,18 @@
### Submission type
- - [ ] Bug report
- - [ ] Request for enhancement (RFE)
+<!-- Delete the inappropriate option below: -->
-*NOTE: Do not submit anything other than bug reports or RFEs via the issue tracker!*
+ - Bug report
+ - Request for enhancement (RFE)
+
+<!-- **NOTE:** Do not submit anything other than bug reports or RFEs via the issue tracker! -->
### systemd version the issue has been seen with
> …
-*NOTE: Do not submit bug reports about anything but the two most recently released systemd versions upstream!*
+<!-- **NOTE:** Do not submit bug reports about anything but the two most recently released systemd versions upstream! -->
+<!-- For older version please use distribution trackers (see https://github.com/systemd/systemd/blob/master/.github/CONTRIBUTING.md#filing-issues). -->
### Used distribution
diff --git a/.gitignore b/.gitignore
index 25b976a0e3..8c4331e54f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -28,7 +28,7 @@
/TAGS
/ata_id
/bootctl
-/build-aux
+/build*
/busctl
/cdrom_id
/collect
@@ -160,6 +160,8 @@
/test-bus-server
/test-bus-signature
/test-bus-track
+/test-bus-vtable
+/test-bus-vtable-cc
/test-bus-zero-copy
/test-calendarspec
/test-cap-list
@@ -265,6 +267,7 @@
/test-process-util
/test-pty
/test-qcow2
+/test-random-util
/test-ratelimit
/test-replace-var
/test-resolve
@@ -273,6 +276,7 @@
/test-ring
/test-rlimit-util
/test-sched-prio
+/test-sd-dhcp-lease
/test-seccomp
/test-selinux
/test-set
@@ -291,6 +295,7 @@
/test-tables
/test-terminal-util
/test-time
+/test-timesync
/test-tmpfiles
/test-udev
/test-uid-range
diff --git a/.mailmap b/.mailmap
index d46c166cf9..e2a390bbea 100644
--- a/.mailmap
+++ b/.mailmap
@@ -102,3 +102,24 @@ Paolo Giangrandi <paolo@luccalug.it>
Karl Kraus <karl.kraus@tum.de> <laqueray@gmail.com>
Tibor Nagy <xnagytibor@gmail.com>
Stuart McLaren <stuart.mclaren@hp.com>
+John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
+John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de> <glaubitz@suse.com>
+Sjoerd Simons <sjoerd.simons@collabora.co.uk>
+Neil Brown <neil@brown.name>
+Michal Suchanek <msuchanek@suse.de> <hramrach@gmail.com>
+Michal Suchanek <msuchanek@suse.de>
+Bastien Nocera <hadess@hadess.net> <hadess@users.noreply.github.com>
+Umut Tezduyar Lindskog <umut@tezduyar.com>
+Alexander Kurtz <alexander@kurtz.be>
+Piotr Szydełko <wiertel@users.sourceforge.net>
+Łukasz Stelmach <l.stelmach@samsung.com> <stlman@poczta.fm>
+Krzysztof Jackiewicz <k.jackiewicz@samsung.com> <kjackiewicz@users.noreply.github.com>
+Marcus Cooper <marcusc@axis.com> <codekipper@gmail.com>
+Insun Pyo <insun.pyo@samsung.com> <iplayinsun@gmail.com>
+Ted Wood <ted.l.wood@gmail.com>
+Ted Wood <ted@mailchimp.com>
+Anthony Parsons <flussence@users.noreply.github.com>
+Federico Di Pierro <nierro92@gmail.com>
+Josef Andersson <josef.andersson@fripost.org>
+Josef Andersson <l10nl18nsweja@gmail.com>
+Hendrik Westerberg <hendrik@gestorf.com>
diff --git a/.mkosi/mkosi.arch b/.mkosi/mkosi.arch
index 4c44f288ae..613ef4746f 100644
--- a/.mkosi/mkosi.arch
+++ b/.mkosi/mkosi.arch
@@ -32,8 +32,6 @@ RootSize=2G
Cache=/var/cache/pacman/pkg/
BuildPackages=
acl
- autoconf
- automake
bzip2
cryptsetup
curl
@@ -50,7 +48,7 @@ BuildPackages=
kmod
libcap
libgcrypt
- libidn
+ libidn2
libmicrohttpd
libseccomp
libtool
@@ -58,10 +56,13 @@ BuildPackages=
libxkbcommon
libxslt
lz4
- make
+ meson
pam
pkgconfig
python
python-lxml
qrencode
xz
+
+Packages=
+ libidn2
diff --git a/.mkosi/mkosi.debian b/.mkosi/mkosi.debian
index a68d9dfa11..c41fc1d419 100644
--- a/.mkosi/mkosi.debian
+++ b/.mkosi/mkosi.debian
@@ -32,9 +32,6 @@ RootSize=2G
[Packages]
BuildPackages=
acl
- autoconf
- automake
- diffutils
docbook-xml
docbook-xsl
gcc
@@ -55,7 +52,7 @@ BuildPackages=
libfdisk-dev
libgcrypt20-dev
libgnutls28-dev
- libidn11-dev
+ libidn2-0-dev
libkmod-dev
liblzma-dev
liblz4-dev
@@ -68,7 +65,7 @@ BuildPackages=
libsmartcols-dev
libtool
libxkbcommon-dev
- make
+ meson
pkg-config
python3
python3-lxml
@@ -80,3 +77,4 @@ BuildPackages=
Packages=
libqrencode3
locales
+ libidn2-0
diff --git a/.mkosi/mkosi.fedora b/.mkosi/mkosi.fedora
index 1b8dd47ca4..c38ee7e6d3 100644
--- a/.mkosi/mkosi.fedora
+++ b/.mkosi/mkosi.fedora
@@ -20,7 +20,7 @@
[Distribution]
Distribution=fedora
-Release=25
+Release=26
[Output]
Format=raw_btrfs
@@ -32,8 +32,6 @@ RootSize=3G
[Packages]
BuildPackages=
audit-libs-devel
- autoconf
- automake
bzip2-devel
cryptsetup-devel
dbus-devel
@@ -54,7 +52,7 @@ BuildPackages=
libcap-devel
libcurl-devel
libgcrypt-devel
- libidn-devel
+ libidn2-devel
libmicrohttpd-devel
libmount-devel
libseccomp-devel
@@ -62,8 +60,9 @@ BuildPackages=
libtool
libxkbcommon-devel
libxslt
+ lz4
lz4-devel
- make
+ meson
pam-devel
pkgconfig
python3-devel
@@ -71,3 +70,6 @@ BuildPackages=
qrencode-devel
tree
xz-devel
+
+Packages=
+ libidn2
diff --git a/HACKING b/HACKING
index 0d1a93e211..193cff13f7 100644
--- a/HACKING
+++ b/HACKING
@@ -30,7 +30,7 @@ systemd-nspawn or in an UEFI-capable VM:
or:
- # qemu-kvm -m 512 -smp 2 -bios /usr/share/edk2/ovmf/OVMF_CODE.fd -hda image.raw
+ # qemu-system-x86_64 -enable-kvm -m 512 -smp 2 -bios /usr/share/edk2/ovmf/OVMF_CODE.fd -hda image.raw
Every time you rerun the "mkosi" command a fresh image is built, incorporating
all current changes you made to the project tree.
diff --git a/Makefile-man.am b/Makefile-man.am
index d5626411a5..d51236ed56 100644
--- a/Makefile-man.am
+++ b/Makefile-man.am
@@ -11,7 +11,6 @@ MANPAGES += \
man/bootup.7 \
man/busctl.1 \
man/daemon.7 \
- man/environment.d.5 \
man/file-hierarchy.7 \
man/halt.8 \
man/hostname.5 \
@@ -24,7 +23,6 @@ MANPAGES += \
man/localtime.5 \
man/machine-id.5 \
man/machine-info.5 \
- man/nss-systemd.8 \
man/os-release.5 \
man/sd-bus-errors.3 \
man/sd-bus.3 \
@@ -111,15 +109,12 @@ MANPAGES += \
man/systemd-debug-generator.8 \
man/systemd-delta.1 \
man/systemd-detect-virt.1 \
- man/systemd-environment-d-generator.8 \
man/systemd-escape.1 \
man/systemd-fsck@.service.8 \
man/systemd-fstab-generator.8 \
man/systemd-getty-generator.8 \
man/systemd-gpt-auto-generator.8 \
man/systemd-halt.service.8 \
- man/systemd-hibernate-resume-generator.8 \
- man/systemd-hibernate-resume@.service.8 \
man/systemd-inhibit.1 \
man/systemd-initctl.service.8 \
man/systemd-journald.service.8 \
@@ -130,7 +125,6 @@ MANPAGES += \
man/systemd-nspawn.1 \
man/systemd-path.1 \
man/systemd-remount-fs.service.8 \
- man/systemd-resolve.1 \
man/systemd-run.1 \
man/systemd-sleep.conf.5 \
man/systemd-socket-activate.1 \
@@ -148,7 +142,6 @@ MANPAGES += \
man/systemd.1 \
man/systemd.automount.5 \
man/systemd.device.5 \
- man/systemd.environment-generator.7 \
man/systemd.exec.5 \
man/systemd.generator.7 \
man/systemd.journal-fields.7 \
@@ -187,7 +180,6 @@ MANPAGES += \
man/udev_new.3 \
man/udevadm.8
MANPAGES_ALIAS += \
- man/30-systemd-environment-d-generator.8 \
man/SD_ALERT.3 \
man/SD_BUS_ERROR_ACCESS_DENIED.3 \
man/SD_BUS_ERROR_ADDRESS_IN_USE.3 \
@@ -266,7 +258,6 @@ MANPAGES_ALIAS += \
man/SD_WARNING.3 \
man/init.1 \
man/journald.conf.d.5 \
- man/libnss_systemd.so.2.8 \
man/poweroff.8 \
man/reboot.8 \
man/sd_bus_creds_get_audit_login_uid.3 \
@@ -326,6 +317,7 @@ MANPAGES_ALIAS += \
man/sd_bus_message_append_array_space.3 \
man/sd_bus_message_append_string_iovec.3 \
man/sd_bus_message_append_string_space.3 \
+ man/sd_bus_message_appendv.3 \
man/sd_bus_message_get_realtime_usec.3 \
man/sd_bus_message_get_reply_cookie.3 \
man/sd_bus_message_get_seqnum.3 \
@@ -462,7 +454,6 @@ MANPAGES_ALIAS += \
man/systemd-ask-password-wall.service.8 \
man/systemd-fsck-root.service.8 \
man/systemd-fsck.8 \
- man/systemd-hibernate-resume.8 \
man/systemd-hibernate.service.8 \
man/systemd-hybrid-sleep.service.8 \
man/systemd-initctl.8 \
@@ -546,7 +537,6 @@ MANPAGES_ALIAS += \
man/udev_ref.3 \
man/udev_unref.3 \
man/user.conf.d.5
-man/30-systemd-environment-d-generator.8: man/systemd-environment-d-generator.8
man/SD_ALERT.3: man/sd-daemon.3
man/SD_BUS_ERROR_ACCESS_DENIED.3: man/sd-bus-errors.3
man/SD_BUS_ERROR_ADDRESS_IN_USE.3: man/sd-bus-errors.3
@@ -625,7 +615,6 @@ man/SD_NOTICE.3: man/sd-daemon.3
man/SD_WARNING.3: man/sd-daemon.3
man/init.1: man/systemd.1
man/journald.conf.d.5: man/journald.conf.5
-man/libnss_systemd.so.2.8: man/nss-systemd.8
man/poweroff.8: man/halt.8
man/reboot.8: man/halt.8
man/sd_bus_creds_get_audit_login_uid.3: man/sd_bus_creds_get_pid.3
@@ -685,6 +674,7 @@ man/sd_bus_message_append_array_memfd.3: man/sd_bus_message_append_array.3
man/sd_bus_message_append_array_space.3: man/sd_bus_message_append_array.3
man/sd_bus_message_append_string_iovec.3: man/sd_bus_message_append_string_memfd.3
man/sd_bus_message_append_string_space.3: man/sd_bus_message_append_string_memfd.3
+man/sd_bus_message_appendv.3: man/sd_bus_message_append.3
man/sd_bus_message_get_realtime_usec.3: man/sd_bus_message_get_monotonic_usec.3
man/sd_bus_message_get_reply_cookie.3: man/sd_bus_message_get_cookie.3
man/sd_bus_message_get_seqnum.3: man/sd_bus_message_get_monotonic_usec.3
@@ -821,7 +811,6 @@ man/systemd-ask-password-wall.path.8: man/systemd-ask-password-console.service.8
man/systemd-ask-password-wall.service.8: man/systemd-ask-password-console.service.8
man/systemd-fsck-root.service.8: man/systemd-fsck@.service.8
man/systemd-fsck.8: man/systemd-fsck@.service.8
-man/systemd-hibernate-resume.8: man/systemd-hibernate-resume@.service.8
man/systemd-hibernate.service.8: man/systemd-suspend.service.8
man/systemd-hybrid-sleep.service.8: man/systemd-suspend.service.8
man/systemd-initctl.8: man/systemd-initctl.service.8
@@ -905,9 +894,6 @@ man/udev_monitor_unref.3: man/udev_monitor_new_from_netlink.3
man/udev_ref.3: man/udev_new.3
man/udev_unref.3: man/udev_new.3
man/user.conf.d.5: man/systemd-system.conf.5
-man/30-systemd-environment-d-generator.html: man/systemd-environment-d-generator.html
- $(html-alias)
-
man/SD_ALERT.html: man/sd-daemon.html
$(html-alias)
@@ -1142,9 +1128,6 @@ man/init.html: man/systemd.html
man/journald.conf.d.html: man/journald.conf.html
$(html-alias)
-man/libnss_systemd.so.2.html: man/nss-systemd.html
- $(html-alias)
-
man/poweroff.html: man/halt.html
$(html-alias)
@@ -1322,6 +1305,9 @@ man/sd_bus_message_append_string_iovec.html: man/sd_bus_message_append_string_me
man/sd_bus_message_append_string_space.html: man/sd_bus_message_append_string_memfd.html
$(html-alias)
+man/sd_bus_message_appendv.html: man/sd_bus_message_append.html
+ $(html-alias)
+
man/sd_bus_message_get_realtime_usec.html: man/sd_bus_message_get_monotonic_usec.html
$(html-alias)
@@ -1730,9 +1716,6 @@ man/systemd-fsck-root.service.html: man/systemd-fsck@.service.html
man/systemd-fsck.html: man/systemd-fsck@.service.html
$(html-alias)
-man/systemd-hibernate-resume.html: man/systemd-hibernate-resume@.service.html
- $(html-alias)
-
man/systemd-hibernate.service.html: man/systemd-suspend.service.html
$(html-alias)
@@ -2038,6 +2021,19 @@ MANPAGES_ALIAS += \
endif
+if ENABLE_ENVIRONMENT_D
+MANPAGES += \
+ man/environment.d.5 \
+ man/systemd-environment-d-generator.8 \
+ man/systemd.environment-generator.7
+MANPAGES_ALIAS += \
+ man/30-systemd-environment-d-generator.8
+man/30-systemd-environment-d-generator.8: man/systemd-environment-d-generator.8
+man/30-systemd-environment-d-generator.html: man/systemd-environment-d-generator.html
+ $(html-alias)
+
+endif
+
if ENABLE_FIRSTBOOT
MANPAGES += \
man/systemd-firstboot.1
@@ -2049,6 +2045,18 @@ man/systemd-firstboot.service.html: man/systemd-firstboot.html
endif
+if ENABLE_HIBERNATE
+MANPAGES += \
+ man/systemd-hibernate-resume-generator.8 \
+ man/systemd-hibernate-resume@.service.8
+MANPAGES_ALIAS += \
+ man/systemd-hibernate-resume.8
+man/systemd-hibernate-resume.8: man/systemd-hibernate-resume@.service.8
+man/systemd-hibernate-resume.html: man/systemd-hibernate-resume@.service.html
+ $(html-alias)
+
+endif
+
if ENABLE_HOSTNAMED
MANPAGES += \
man/hostnamectl.1 \
@@ -2156,6 +2164,17 @@ man/systemd-networkd.html: man/systemd-networkd.service.html
endif
+if ENABLE_NSS_SYSTEMD
+MANPAGES += \
+ man/nss-systemd.8
+MANPAGES_ALIAS += \
+ man/libnss_systemd.so.2.8
+man/libnss_systemd.so.2.8: man/nss-systemd.8
+man/libnss_systemd.so.2.html: man/nss-systemd.html
+ $(html-alias)
+
+endif
+
if ENABLE_QUOTACHECK
MANPAGES += \
man/systemd-quotacheck.service.8
@@ -2183,6 +2202,7 @@ MANPAGES += \
man/dnssec-trust-anchors.d.5 \
man/nss-resolve.8 \
man/resolved.conf.5 \
+ man/systemd-resolve.1 \
man/systemd-resolved.service.8
MANPAGES_ALIAS += \
man/libnss_resolve.so.2.8 \
diff --git a/Makefile.am b/Makefile.am
index f6ab0f481a..8962e7943c 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -42,9 +42,9 @@ LIBUDEV_CURRENT=7
LIBUDEV_REVISION=6
LIBUDEV_AGE=6
-LIBSYSTEMD_CURRENT=18
+LIBSYSTEMD_CURRENT=19
LIBSYSTEMD_REVISION=0
-LIBSYSTEMD_AGE=18
+LIBSYSTEMD_AGE=19
# Dirs of external packages
dbuspolicydir=@dbuspolicydir@
@@ -269,8 +269,10 @@ INSTALL_DIRS =
SHUTDOWN_TARGET_WANTS =
LOCAL_FS_TARGET_WANTS =
+REMOTE_FS_TARGET_WANTS =
MULTI_USER_TARGET_WANTS =
GRAPHICAL_TARGET_WANTS =
+MACHINES_TARGET_WANTS =
RESCUE_TARGET_WANTS =
SYSINIT_TARGET_WANTS =
SOCKETS_TARGET_WANTS =
@@ -287,6 +289,8 @@ GENERAL_ALIASES =
install-target-wants-hook:
what="$(SHUTDOWN_TARGET_WANTS)" && wants=shutdown.target && dir=$(systemunitdir) && $(add-wants)
what="$(LOCAL_FS_TARGET_WANTS)" && wants=local-fs.target && dir=$(systemunitdir) && $(add-wants)
+ what="$(REMOTE_FS_TARGET_WANTS)" && wants=remote-fs.target && dir=$(systemunitdir) && $(add-wants)
+ what="$(MACHINES_TARGET_WANTS)" && wants=machines.target && dir=$(systemunitdir) && $(add-wants)
what="$(MULTI_USER_TARGET_WANTS)" && wants=multi-user.target && dir=$(systemunitdir) && $(add-wants)
what="$(GRAPHICAL_TARGET_WANTS)" && wants=graphical.target && dir=$(systemunitdir) && $(add-wants)
what="$(RESCUE_TARGET_WANTS)" && wants=rescue.target && dir=$(systemunitdir) && $(add-wants)
@@ -443,6 +447,12 @@ userenvgenerator_PROGRAMS = \
30-systemd-environment-d-generator
endif
+rootlibexec_SCRIPTS = \
+ src/sulogin-shell/systemd-sulogin-shell
+
+EXTRA_DIST += \
+ src/sulogin-shell/systemd-sulogin-shell.in
+
dist_bashcompletion_data = \
shell-completion/bash/busctl \
shell-completion/bash/journalctl \
@@ -533,7 +543,6 @@ dist_systemunit_DATA = \
units/sys-kernel-debug.mount \
units/sys-fs-fuse-connections.mount \
units/tmp.mount \
- units/var-lib-machines.mount \
units/printer.target \
units/sound.target \
units/bluetooth.target \
@@ -651,7 +660,7 @@ EXTRA_DIST += \
units/initrd-switch-root.service.in \
units/systemd-nspawn@.service.in \
units/systemd-update-done.service.in \
- units/tmp.mount.m4
+ units/tmp.mount.m4
if HAVE_SYSV_COMPAT
nodist_systemunit_DATA += \
@@ -678,8 +687,6 @@ dist_doc_DATA = \
LICENSE.LGPL2.1 \
LICENSE.GPL2 \
DISTRO_PORTING \
- src/libsystemd/sd-bus/PORTING-DBUS1 \
- src/libsystemd/sd-bus/DIFFERENCES \
src/libsystemd/sd-bus/GVARIANT-SERIALIZATION
EXTRA_DIST += \
@@ -745,9 +752,11 @@ man/index.html: man/systemd.index.html
$(AM_V_LN)$(LN_S) -f systemd.index.html $@
if HAVE_PYTHON
+if ENABLE_MANPAGES
noinst_DATA += \
man/index.html
endif
+endif
CLEANFILES += \
man/index.html
@@ -1017,7 +1026,9 @@ libshared_la_SOURCES = \
src/shared/output-mode.c \
src/shared/gpt.h \
src/shared/udev-util.h \
+ src/shared/udev-util.c \
src/shared/linux/auto_dev-ioctl.h \
+ src/shared/linux-3.13/dm-ioctl.h \
src/shared/initreq.h \
src/shared/dns-domain.c \
src/shared/dns-domain.h \
@@ -1130,6 +1141,7 @@ libshared_la_CFLAGS = \
$(AM_CFLAGS) \
$(ACL_CFLAGS) \
$(LIBIDN_CFLAGS) \
+ $(LIBIDN2_CFLAGS) \
$(SECCOMP_CFLAGS) \
$(BLKID_CFLAGS) \
$(LIBCRYPTSETUP_CFLAGS)
@@ -1141,6 +1153,7 @@ libshared_la_LIBADD = \
libudev-internal.la \
$(ACL_LIBS) \
$(LIBIDN_LIBS) \
+ $(LIBIDN2_LIBS) \
$(SECCOMP_LIBS) \
$(BLKID_LIBS) \
$(LIBCRYPTSETUP_LIBS)
@@ -1164,6 +1177,7 @@ libsystemd_shared_la_CFLAGS = \
$(libudev_internal_la_CFLAGS) \
$(ACL_CFLAGS) \
$(LIBIDN_CFLAGS) \
+ $(LIBIDN2_CFLAGS) \
$(SECCOMP_CFLAGS) \
$(BLKID_CFLAGS) \
$(LIBCRYPTSETUP_CFLAGS) \
@@ -1178,6 +1192,7 @@ libsystemd_shared_la_LIBADD = \
$(libudev_internal_la_LIBADD) \
$(ACL_LIBS) \
$(LIBIDN_LIBS) \
+ $(LIBIDN2_LIBS) \
$(SECCOMP_LIBS) \
$(BLKID_LIBS) \
$(LIBCRYPTSETUP_LIBS)
@@ -1609,6 +1624,7 @@ tests += \
test-conf-parser \
test-capability \
test-async \
+ test-random-util \
test-ratelimit \
test-condition \
test-uid-range \
@@ -1725,6 +1741,7 @@ TEST_DATA_FILES += \
test/test-execute/exec-readonlypaths-mount-propagation.service \
test/test-execute/exec-readwritepaths-mount-propagation.service \
test/test-execute/exec-inaccessiblepaths-mount-propagation.service \
+ test/test-execute/exec-inaccessiblepaths-proc.service \
test/test-execute/exec-spec-interpolation.service \
test/test-execute/exec-systemcallerrornumber.service \
test/test-execute/exec-systemcallfilter-failing2.service \
@@ -1929,6 +1946,12 @@ test_fstab_util_SOURCES = \
test_fstab_util_LDADD = \
libsystemd-shared.la
+test_random_util_SOURCES = \
+ src/test/test-random-util.c
+
+test_random_util_LDADD = \
+ libsystemd-shared.la
+
test_ratelimit_SOURCES = \
src/test/test-ratelimit.c
@@ -2132,6 +2155,10 @@ test_acl_util_LDADD = \
test_seccomp_SOURCES = \
src/test/test-seccomp.c
+test_seccomp_CFLAGS = \
+ $(AM_CFLAGS) \
+ $(SECCOMP_CFLAGS)
+
test_seccomp_LDADD = \
libsystemd-shared.la \
$(SECCOMP_LIBS)
@@ -2177,9 +2204,6 @@ test_selinux_LDADD = \
test_sizeof_SOURCES = \
src/test/test-sizeof.c
-test_sizeof_LDADD = \
- libsystemd-shared.la
-
BUILT_SOURCES += \
src/test/test-hashmap-ordered.c
@@ -2431,6 +2455,7 @@ test_execute_SOURCES = \
test_execute_CFLAGS = \
$(AM_CFLAGS) \
+ $(SECCOMP_CFLAGS) \
$(MOUNT_CFLAGS)
test_execute_LDADD = \
@@ -2661,13 +2686,13 @@ nodist_systemunit_DATA += \
nodist_tmpfiles_DATA = \
tmpfiles.d/systemd.conf \
+ tmpfiles.d/var.conf \
tmpfiles.d/etc.conf
dist_tmpfiles_DATA = \
tmpfiles.d/systemd-nologin.conf \
tmpfiles.d/tmp.conf \
tmpfiles.d/x11.conf \
- tmpfiles.d/var.conf \
tmpfiles.d/home.conf \
tmpfiles.d/systemd-nspawn.conf \
tmpfiles.d/journal-nocow.conf
@@ -2677,6 +2702,11 @@ dist_tmpfiles_DATA += \
tmpfiles.d/legacy.conf
endif
+if HAVE_REMOTE
+nodist_tmpfiles_DATA += \
+ tmpfiles.d/systemd-remote.conf
+endif
+
SYSINIT_TARGET_WANTS += \
systemd-tmpfiles-setup-dev.service \
systemd-tmpfiles-setup.service
@@ -2694,7 +2724,9 @@ endif
EXTRA_DIST += \
tmpfiles.d/systemd.conf.m4 \
+ tmpfiles.d/systemd-remote.conf.m4 \
tmpfiles.d/etc.conf.m4 \
+ tmpfiles.d/var.conf.m4 \
units/systemd-tmpfiles-setup-dev.service.in \
units/systemd-tmpfiles-setup.service.in \
units/systemd-tmpfiles-clean.service.in
@@ -2814,9 +2846,6 @@ systemd_detect_virt_SOURCES = \
systemd_detect_virt_LDADD = \
libsystemd-shared.la
-INSTALL_EXEC_HOOKS += \
- systemd-detect-virt-install-hook
-
# ------------------------------------------------------------------------------
systemd_delta_SOURCES = \
src/delta/delta.c
@@ -2980,28 +3009,37 @@ if ARCH_AARCH64
efi_ldflags += --defsym=EFI_SUBSYSTEM=0xa
EFI_FORMAT = -O binary
else
+if ARCH_ARM
+efi_ldflags += --defsym=EFI_SUBSYSTEM=0xa
+EFI_FORMAT = -O binary
+else
EFI_FORMAT = --target=efi-app-$(EFI_ARCH)
endif
endif
endif
+endif
# ------------------------------------------------------------------------------
-systemd_boot_headers = \
- src/boot/efi/util.h \
+efi_headers = \
src/boot/efi/console.h \
+ src/boot/efi/disk.h \
src/boot/efi/graphics.h \
- src/boot/efi/pefile.h \
+ src/boot/efi/linux.h \
src/boot/efi/measure.h \
- src/boot/efi/disk.h
+ src/boot/efi/pe.h \
+ src/boot/efi/splash.h \
+ src/boot/efi/util.h \
+ src/boot/efi/shim.h
systemd_boot_sources = \
- src/boot/efi/util.c \
+ src/boot/efi/boot.c \
src/boot/efi/console.c \
- src/boot/efi/graphics.c \
- src/boot/efi/pefile.c \
src/boot/efi/disk.c \
+ src/boot/efi/graphics.c \
src/boot/efi/measure.c \
- src/boot/efi/boot.c
+ src/boot/efi/pe.c \
+ src/boot/efi/util.c \
+ src/boot/efi/shim.c
EXTRA_DIST += $(systemd_boot_sources) $(systemd_boot_headers)
@@ -3013,7 +3051,7 @@ if ENABLE_EFI
if HAVE_GNUEFI
bootlib_DATA = $(systemd_boot)
-$(top_builddir)/src/boot/efi/%.o: $(top_srcdir)/src/boot/efi/%.c $(addprefix $(top_srcdir)/,$(systemd_boot_headers))
+$(top_builddir)/src/boot/efi/%.o: $(top_srcdir)/src/boot/efi/%.c $(addprefix $(top_srcdir)/,$(efi_headers))
@$(MKDIR_P) $(top_builddir)/src/boot/efi/
$(AM_V_CC)$(EFI_CC) $(efi_cppflags) $(efi_cflags) -c $< -o $@
@@ -3031,24 +3069,15 @@ endif
CLEANFILES += $(systemd_boot_objects) $(systemd_boot_solib) $(systemd_boot)
# ------------------------------------------------------------------------------
-stub_headers = \
- src/boot/efi/util.h \
- src/boot/efi/pefile.h \
- src/boot/efi/disk.h \
- src/boot/efi/graphics.h \
- src/boot/efi/splash.h \
- src/boot/efi/measure.h \
- src/boot/efi/linux.h
-
stub_sources = \
- src/boot/efi/util.c \
- src/boot/efi/pefile.c \
src/boot/efi/disk.c \
src/boot/efi/graphics.c \
- src/boot/efi/splash.c \
src/boot/efi/linux.c \
src/boot/efi/measure.c \
- src/boot/efi/stub.c
+ src/boot/efi/pe.c \
+ src/boot/efi/splash.c \
+ src/boot/efi/stub.c \
+ src/boot/efi/util.c
EXTRA_DIST += \
$(stub_sources) \
@@ -3063,10 +3092,6 @@ if ENABLE_EFI
if HAVE_GNUEFI
bootlib_DATA += $(stub)
-$(top_builddir)/src/boot/efi/%.o: $(top_srcdir)/src/boot/efi/%.c $(addprefix $(top_srcdir)/,$(stub_headers))
- @$(MKDIR_P) $(top_builddir)/src/boot/efi/
- $(AM_V_CC)$(EFI_CC) $(efi_cppflags) $(efi_cflags) -c $< -o $@
-
$(stub_solib): $(stub_objects)
$(AM_V_CCLD)$(LD) $(efi_ldflags) $(stub_objects) \
-o $@ -lefi -lgnuefi $(shell $(CC) -print-libgcc-file-name); \
@@ -3084,8 +3109,8 @@ CLEANFILES += $(stub_objects) $(stub_solib) $(stub)
# ------------------------------------------------------------------------------
CLEANFILES += test-efi-disk.img
-test-efi-disk.img: $(systemd_boot) $(stub) test/test-efi-create-disk.sh
- $(AM_V_GEN)test/test-efi-create-disk.sh
+test-efi-disk.img: $(systemd_boot) $(stub) test/splash.bmp test/test-efi-create-disk.sh
+ $(AM_V_GEN)test/test-efi-create-disk.sh $@ $(systemd_boot) $(stub) test/splash.bmp
test-efi: test-efi-disk.img
$(QEMU) -machine accel=kvm -m 1024 -bios $(QEMU_BIOS) -snapshot test-efi-disk.img
@@ -3414,7 +3439,6 @@ noinst_LTLIBRARIES += \
EXTRA_DIST += \
src/libsystemd/libsystemd.pc.in \
- src/libsystemd/sd-bus/DIFFERENCES \
src/libsystemd/sd-bus/GVARIANT-SERIALIZATION
libsystemd_la_SOURCES =
@@ -3457,6 +3481,7 @@ tests += \
test-bus-zero-copy \
test-bus-introspect \
test-bus-objects \
+ test-bus-vtable \
test-bus-error \
test-bus-creds \
test-bus-gvariant \
@@ -3526,6 +3551,12 @@ test_bus_objects_SOURCES = \
test_bus_objects_LDADD = \
libsystemd-shared.la
+test_bus_vtable_SOURCES = \
+ src/libsystemd/sd-bus/test-bus-vtable.c
+
+test_bus_vtable_LDADD = \
+ libsystemd-shared.la
+
test_bus_error_SOURCES = \
src/libsystemd/sd-bus/test-bus-error.c
@@ -3611,9 +3642,9 @@ test_resolve_LDADD = \
libsystemd-shared.la
busctl_SOURCES = \
- src/libsystemd/sd-bus/busctl.c \
- src/libsystemd/sd-bus/busctl-introspect.c \
- src/libsystemd/sd-bus/busctl-introspect.h
+ src/busctl/busctl.c \
+ src/busctl/busctl-introspect.c \
+ src/busctl/busctl-introspect.h
busctl_LDADD = \
libsystemd-shared.la
@@ -3633,6 +3664,7 @@ libsystemd_network_la_SOURCES = \
src/systemd/sd-ipv4ll.h \
src/systemd/sd-ipv4acd.h \
src/systemd/sd-ndisc.h \
+ src/systemd/sd-radv.h \
src/systemd/sd-dhcp6-client.h \
src/systemd/sd-dhcp6-lease.h \
src/systemd/sd-lldp.h \
@@ -3656,6 +3688,8 @@ libsystemd_network_la_SOURCES = \
src/libsystemd-network/ndisc-internal.h \
src/libsystemd-network/ndisc-router.h \
src/libsystemd-network/ndisc-router.c \
+ src/libsystemd-network/sd-radv.c \
+ src/libsystemd-network/radv-internal.h \
src/libsystemd-network/icmp6-util.h \
src/libsystemd-network/icmp6-util.c \
src/libsystemd-network/sd-dhcp6-client.c \
@@ -3686,6 +3720,14 @@ test_dhcp_option_LDADD = \
libsystemd-network.la \
libsystemd-shared.la
+test_sd_dhcp_lease_SOURCES = \
+ src/libsystemd-network/dhcp-lease-internal.h \
+ src/libsystemd-network/test-sd-dhcp-lease.c
+
+test_sd_dhcp_lease_LDADD = \
+ libsystemd-network.la \
+ libsystemd-shared.la
+
test_dhcp_client_SOURCES = \
src/systemd/sd-dhcp-client.h \
src/libsystemd-network/dhcp-protocol.h \
@@ -3741,6 +3783,16 @@ test_ndisc_rs_LDADD = \
libudev.la \
libsystemd-shared.la
+test_ndisc_ra_SOURCES = \
+ src/systemd/sd-ndisc.h \
+ src/libsystemd-network/icmp6-util.h \
+ src/libsystemd-network/test-ndisc-ra.c
+
+test_ndisc_ra_LDADD = \
+ libsystemd-network.la \
+ libudev.la \
+ libsystemd-shared.la
+
test_dhcp6_client_SOURCES = \
src/systemd/sd-dhcp6-client.h \
src/libsystemd-network/dhcp6-internal.h \
@@ -3764,8 +3816,10 @@ tests += \
test-dhcp-option \
test-dhcp-client \
test-dhcp-server \
+ test-sd-dhcp-lease \
test-ipv4ll \
test-ndisc-rs \
+ test-ndisc-ra \
test-dhcp6-client \
test-lldp
@@ -3823,10 +3877,10 @@ dist_network_DATA = \
network/80-container-vz.network
dist_udevrules_DATA += \
- rules/50-udev-default.rules \
rules/60-block.rules \
rules/60-drm.rules \
rules/60-evdev.rules \
+ rules/60-input-id.rules \
rules/60-persistent-storage-tape.rules \
rules/60-persistent-input.rules \
rules/60-persistent-alsa.rules \
@@ -3834,6 +3888,7 @@ dist_udevrules_DATA += \
rules/60-sensor.rules \
rules/60-serial.rules \
rules/64-btrfs.rules \
+ rules/70-joystick.rules \
rules/70-mouse.rules \
rules/70-touchpad.rules \
rules/75-net-description.rules \
@@ -3841,6 +3896,7 @@ dist_udevrules_DATA += \
rules/80-net-setup-link.rules
nodist_udevrules_DATA += \
+ rules/50-udev-default.rules \
rules/99-systemd.rules
udevconfdir = $(sysconfdir)/udev
@@ -3851,6 +3907,7 @@ pkgconfigdata_DATA += \
src/udev/udev.pc
EXTRA_DIST += \
+ rules/50-udev-default.rules.in \
rules/99-systemd.rules.in \
src/udev/udev.pc.in
@@ -3878,10 +3935,10 @@ noinst_LTLIBRARIES += \
src/udev/keyboard-keys-list.txt:
$(AM_V_at)$(MKDIR_P) $(dir $@)
- $(AM_V_GEN)$(CPP) $(CFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS) -dM -include linux/input.h - < /dev/null | $(AWK) '/^#define[ \t]+KEY_[^ ]+[ \t]+[0-9K]/ { if ($$2 != "KEY_MAX") { print $$2 } }' > $@
+ $(AM_V_GEN)$(top_srcdir)/src/udev/generate-keyboard-keys-list.sh "$(CPP) $(CFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS)" > $@
src/udev/keyboard-keys-from-name.gperf: src/udev/keyboard-keys-list.txt
- $(AM_V_GEN)$(AWK) 'BEGIN{ print "struct key { const char* name; unsigned short id; };"; print "%null-strings"; print "%%";} { print tolower(substr($$1 ,5)) ", " $$1 }' < $< > $@
+ $(AM_V_GEN)$(top_srcdir)/src/udev/generate-keyboard-keys-gperf.sh $< > $@
src/udev/keyboard-keys-from-name.h: src/udev/keyboard-keys-from-name.gperf
$(AM_V_GPERF)$(GPERF) -L ANSI-C -t -N keyboard_lookup_key -H hash_key_name -p -C < $< > $@
@@ -3920,7 +3977,8 @@ gperf_gperf_sources += \
libudev_core_la_CFLAGS = \
$(AM_CFLAGS) \
$(BLKID_CFLAGS) \
- $(KMOD_CFLAGS)
+ $(KMOD_CFLAGS) \
+ -DLOG_REALM=LOG_REALM_UDEV
libudev_core_la_LIBADD = \
libsystemd-network.la \
@@ -3952,6 +4010,10 @@ endif
systemd_udevd_SOURCES = \
src/udev/udevd.c
+systemd_udevd_CFLAGS = \
+ $(AM_CFLAGS) \
+ -DLOG_REALM=LOG_REALM_UDEV
+
systemd_udevd_LDADD = \
libudev-core.la \
libbasic.la
@@ -4002,6 +4064,7 @@ dist_udevhwdb_DATA = \
hwdb/60-evdev.hwdb \
hwdb/60-keyboard.hwdb \
hwdb/60-sensor.hwdb \
+ hwdb/70-joystick.hwdb \
hwdb/70-mouse.hwdb \
hwdb/70-pointingstick.hwdb \
hwdb/70-touchpad.hwdb
@@ -4095,6 +4158,10 @@ EXTRA_DIST += \
ata_id_SOURCES = \
src/udev/ata_id/ata_id.c
+ata_id_CFLAGS = \
+ $(AM_CFLAGS) \
+ -DLOG_REALM=LOG_REALM_UDEV
+
ata_id_LDADD = \
libshared.la
@@ -4105,6 +4172,10 @@ udevlibexec_PROGRAMS += \
cdrom_id_SOURCES = \
src/udev/cdrom_id/cdrom_id.c
+cdrom_id_CFLAGS = \
+ $(AM_CFLAGS) \
+ -DLOG_REALM=LOG_REALM_UDEV
+
cdrom_id_LDADD = \
libshared.la
@@ -4118,6 +4189,10 @@ dist_udevrules_DATA += \
collect_SOURCES = \
src/udev/collect/collect.c
+collect_CFLAGS = \
+ $(AM_CFLAGS) \
+ -DLOG_REALM=LOG_REALM_UDEV
+
collect_LDADD = \
libshared.la
@@ -4131,6 +4206,10 @@ scsi_id_SOURCES =\
src/udev/scsi_id/scsi.h \
src/udev/scsi_id/scsi_id.h
+scsi_id_CFLAGS = \
+ $(AM_CFLAGS) \
+ -DLOG_REALM=LOG_REALM_UDEV
+
scsi_id_LDADD = \
libshared.la
@@ -4144,6 +4223,10 @@ EXTRA_DIST += \
v4l_id_SOURCES = \
src/udev/v4l_id/v4l_id.c
+v4l_id_CFLAGS = \
+ $(AM_CFLAGS) \
+ -DLOG_REALM=LOG_REALM_UDEV
+
v4l_id_LDADD = \
libshared.la
@@ -4159,6 +4242,10 @@ mtd_probe_SOURCES = \
src/udev/mtd_probe/mtd_probe.h \
src/udev/mtd_probe/probe_smartmedia.c
+mtd_probe_CFLAGS = \
+ $(AM_CFLAGS) \
+ -DLOG_REALM=LOG_REALM_UDEV
+
dist_udevrules_DATA += \
rules/75-probe_mtd.rules
@@ -4265,11 +4352,6 @@ systemd_journal_remote_CFLAGS = \
systemd_journal_remote_LDADD += \
$(MICROHTTPD_LIBS)
-if ENABLE_TMPFILES
-dist_tmpfiles_DATA += \
- tmpfiles.d/systemd-remote.conf
-endif
-
if HAVE_GNUTLS
systemd_journal_remote_LDADD += \
$(GNUTLS_LIBS)
@@ -4565,10 +4647,8 @@ libsystemd_journal_internal_la_SOURCES += \
libsystemd_journal_internal_la_LIBADD += \
$(GCRYPT_LIBS)
-# fsprg.c is a drop-in file using void pointer arithmetic
libsystemd_journal_internal_la_CFLAGS += \
- $(GCRYPT_CFLAGS) \
- -Wno-pointer-arith
+ $(GCRYPT_CFLAGS)
endif
noinst_LTLIBRARIES += \
@@ -5024,10 +5104,6 @@ systemd_localed_LDADD = \
libsystemd-shared.la \
-ldl
-systemd_localed_CFLAGS = \
- $(AM_CFLAGS) \
- $(XKBCOMMON_CFLAGS)
-
nodist_systemunit_DATA += \
units/systemd-localed.service
@@ -5084,8 +5160,6 @@ dist_zshcompletion_data += \
shell-completion/zsh/_localectl
endif
-.PHONY: update-kbd-model-map
-
polkitpolicy_in_files += \
src/locale/org.freedesktop.locale1.policy.in
@@ -5165,6 +5239,25 @@ systemd_timesyncd_LDADD = \
libsystemd-shared.la \
-lm
+test_timesync_SOURCES = \
+ src/timesync/test-timesync.c \
+ src/timesync/timesyncd-manager.c \
+ src/timesync/timesyncd-manager.h \
+ src/timesync/timesyncd-conf.c \
+ src/timesync/timesyncd-conf.h \
+ src/timesync/timesyncd-server.c \
+ src/timesync/timesyncd-server.h
+
+nodist_test_timesync_SOURCES = \
+ src/timesync/timesyncd-gperf.c
+
+test_timesync_LDADD = \
+ libsystemd-shared.la \
+ -lm
+
+tests += \
+ test-timesync
+
rootlibexec_PROGRAMS += \
systemd-timesyncd
@@ -5199,6 +5292,7 @@ manual_tests += \
test-nss
# ------------------------------------------------------------------------------
+if ENABLE_NSS_SYSTEMD
libnss_systemd_la_SOURCES = \
src/nss-systemd/nss-systemd.sym \
src/nss-systemd/nss-systemd.c
@@ -5218,6 +5312,7 @@ libnss_systemd_la_LIBADD = \
rootlib_LTLIBRARIES += \
libnss_systemd.la
+endif
# ------------------------------------------------------------------------------
if HAVE_MYHOSTNAME
@@ -5244,6 +5339,10 @@ endif
# ------------------------------------------------------------------------------
if ENABLE_MACHINED
+
+dist_systemunit_DATA += \
+ units/var-lib-machines.mount
+
systemd_machined_SOURCES = \
src/machine/machined.c \
src/machine/machined.h
@@ -5616,6 +5715,9 @@ GENERAL_ALIASES += \
nodist_pkgsysconf_DATA += \
src/resolve/resolved.conf
+dist_rootlibexec_DATA += \
+ src/resolve/resolv.conf
+
libnss_resolve_la_SOURCES = \
src/nss-resolve/nss-resolve.sym \
src/nss-resolve/nss-resolve.c
@@ -5767,9 +5869,6 @@ EXTRA_DIST += \
units/systemd-resolved.service.m4.in \
src/resolve/resolved.conf.in
-dist_rootlibexec_DATA += \
- src/resolve/resolv.conf
-
# ------------------------------------------------------------------------------
if ENABLE_NETWORKD
rootlibexec_PROGRAMS += \
@@ -5804,6 +5903,8 @@ libnetworkd_core_la_SOURCES = \
src/network/netdev/veth.c \
src/network/netdev/vxlan.h \
src/network/netdev/vxlan.c \
+ src/network/netdev/geneve.h \
+ src/network/netdev/geneve.c \
src/network/netdev/vlan.h \
src/network/netdev/vlan.c \
src/network/netdev/macvlan.h \
@@ -5834,12 +5935,16 @@ libnetworkd_core_la_SOURCES = \
src/network/networkd-dhcp4.c \
src/network/networkd-dhcp6.c \
src/network/networkd-ndisc.h \
+ src/network/networkd-radv.c \
+ src/network/networkd-radv.h \
src/network/networkd-ndisc.c \
src/network/networkd-network.h \
src/network/networkd-network.c \
src/network/networkd-network-bus.c \
src/network/networkd-address.h \
src/network/networkd-address.c \
+ src/network/networkd-address-label.h \
+ src/network/networkd-address-label.c \
src/network/networkd-route.h \
src/network/networkd-route.c \
src/network/networkd-fdb.h \
@@ -5950,10 +6055,8 @@ dist_dbuspolicy_DATA += \
GENERAL_ALIASES += \
$(systemunitdir)/systemd-networkd.socket $(pkgsysconfdir)/system/sockets.target.wants/systemd-networkd.socket \
$(systemunitdir)/systemd-networkd.service $(pkgsysconfdir)/system/multi-user.target.wants/systemd-networkd.service \
- $(systemunitdir)/systemd-networkd-wait-online.service $(pkgsysconfdir)/system/network-online.target.wants/systemd-networkd-wait-online.service
-
-SYSTEM_UNIT_ALIASES += \
- systemd-networkd.service dbus-org.freedesktop.network1.service
+ $(systemunitdir)/systemd-networkd-wait-online.service $(pkgsysconfdir)/system/network-online.target.wants/systemd-networkd-wait-online.service \
+ $(systemunitdir)/systemd-networkd.service $(pkgsysconfdir)/system/dbus-org.freedesktop.network1.service
BUSNAMES_TARGET_WANTS += \
org.freedesktop.network1.busname
@@ -5976,7 +6079,8 @@ EXTRA_DIST += \
src/network/systemd-networkd.pkla \
units/systemd-networkd.service.m4.in \
units/systemd-networkd-wait-online.service.in \
- test/networkd-test.py
+ test/networkd-test.py \
+ test/test-exec-deserialization.py
# ------------------------------------------------------------------------------
if ENABLE_LOGIND
@@ -6081,10 +6185,10 @@ test_login_tables_LDADD = \
liblogind-core.la
manual_tests += \
- test-login \
test-inhibit
tests += \
+ test-login \
test-login-tables \
test-login-shared
@@ -6288,7 +6392,6 @@ substitutions = \
'|exec_prefix=$(exec_prefix)|' \
'|libdir=$(libdir)|' \
'|includedir=$(includedir)|' \
- '|VERSION=$(VERSION)|' \
'|rootprefix=$(rootprefix)|' \
'|udevlibexecdir=$(udevlibexecdir)|' \
'|SUSHELL=$(SUSHELL)|' \
@@ -6312,6 +6415,7 @@ substitutions = \
'|KILL_USER_PROCESSES=$(KILL_USER_PROCESSES)|' \
'|systemuidmax=$(SYSTEM_UID_MAX)|' \
'|systemgidmax=$(SYSTEM_GID_MAX)|' \
+ '|DEV_KVM_MODE=$(DEV_KVM_MODE)|' \
'|TTY_GID=$(TTY_GID)|' \
'|systemsleepdir=$(systemsleepdir)|' \
'|systemshutdowndir=$(systemshutdowndir)|' \
@@ -6345,6 +6449,10 @@ src/core/%.systemd: src/core/%.systemd.in
src/%.policy.in: src/%.policy.in.in
$(SED_PROCESS)
+src/sulogin-shell/%: src/sulogin-shell/%.in
+ $(SED_PROCESS)
+ $(AM_V_GEN)chmod +x $@
+
shell-completion/%: shell-completion/%.in
$(SED_PROCESS)
@@ -6388,8 +6496,10 @@ nodist_polkitpolicy_DATA = \
$(polkitpolicy_files) \
$(polkitpolicy_in_in_files:.policy.in.in=.policy)
polkitrules_DATA = $(polkitrules_files)
+if ENABLE_POLKIT_PKLA
polkitpkla_DATA = $(polkitpkla_files)
endif
+endif
EXTRA_DIST += \
$(polkitpolicy_in_files) \
@@ -6412,7 +6522,7 @@ XSLTPROC_FLAGS = \
--stringparam funcsynopsis.style ansi \
--stringparam man.authors.section.enabled 0 \
--stringparam man.copyright.section.enabled 0 \
- --stringparam systemd.version $(VERSION) \
+ --stringparam systemd.version $(PACKAGE_VERSION) \
--path '$(builddir)/man:$(srcdir)/man'
XSLT = $(if $(XSLTPROC), $(XSLTPROC), xsltproc)
@@ -6493,7 +6603,9 @@ SYSINIT_TARGET_WANTS += \
LOCAL_FS_TARGET_WANTS += \
systemd-remount-fs.service \
- tmp.mount \
+ tmp.mount
+
+REMOTE_FS_TARGET_WANTS += \
var-lib-machines.mount
MULTI_USER_TARGET_WANTS += \
@@ -6509,6 +6621,11 @@ SYSINIT_TARGET_WANTS += \
systemd-sysctl.service \
systemd-ask-password-console.path
+if ENABLE_MACHINED
+MACHINES_TARGET_WANTS += \
+ var-lib-machines.mount
+endif
+
if HAVE_SYSV_COMPAT
SYSTEM_UNIT_ALIASES += \
poweroff.target runlevel0.target \
@@ -6628,34 +6745,27 @@ dist-check-includes: $(public_headers)
done; exit $$res
.PHONY: hwdb-update
-hwdb-update:
- ( cd $(top_srcdir)/hwdb && \
- wget -O usb.ids 'http://www.linux-usb.org/usb.ids' && \
- wget -O pci.ids 'http://pci-ids.ucw.cz/v2.2/pci.ids' && \
- wget -O ma-large.txt 'http://standards.ieee.org/develop/regauth/oui/oui.txt' && \
- wget -O ma-medium.txt 'http://standards.ieee.org/develop/regauth/oui28/mam.txt' && \
- wget -O ma-small.txt 'http://standards.ieee.org/develop/regauth/oui36/oui36.txt' && \
- wget -O pnp_id_registry.html 'http://www.uefi.org/uefi-pnp-export' && \
- wget -O acpi_id_registry.html 'http://www.uefi.org/uefi-acpi-export' && \
- ./ids-update.pl && \
- ./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 )
+hwdb-update: tools/meson-hwdb-update.sh
+ $< $(top_srcdir)/hwdb
.PHONY: built-sources
built-sources: $(BUILT_SOURCES)
.PHONY: git-tag
git-tag:
- git tag -s "v$(VERSION)" -m "systemd $(VERSION)"
+ git tag -s "v$(PACKAGE_VERSION)" -m "systemd $(PACKAGE_VERSION)"
.PHONY: git-tar
git-tar:
- git archive --format=tar --prefix=systemd-$(VERSION)/ HEAD | gzip > systemd-$(VERSION).tar.gz
+ git archive -o systemd-$(PACKAGE_VERSION).tar.gz --prefix=systemd-$(PACKAGE_VERSION)/ HEAD
+
+%.asc: %
+ gpg2 --detach-sign -a -o $@ $<
www_target = www.freedesktop.org:/srv/www.freedesktop.org/www/software/systemd
.PHONY: doc-sync
-doc-sync: all
+doc-sync: man
rsync -rlv --delete-excluded --include="*.html" --exclude="*" --omit-dir-times man/ $(www_target)/man/
.PHONY: install-tree
@@ -6792,14 +6902,17 @@ cppcheck:
print-%:
@echo $($*)
+.PHONY: git-contrib
git-contrib:
@git shortlog -s `git describe --abbrev=0`.. | cut -c8- | sed 's/ / /g' | awk '{ print $$0 "," }' | sort -u
EXTRA_DIST += \
tools/gdb-sd_dump_hashmaps.py
+.PHONY: list-keys
list-keys:
gpg --verbose --no-options --no-default-keyring --no-auto-key-locate --batch --trust-model=always --keyring=$(srcdir)/src/import/import-pubring.gpg --list-keys
+.PHONY: add-key
add-key:
gpg --verbose --no-options --no-default-keyring --no-auto-key-locate --batch --trust-model=always --keyring=$(srcdir)/src/import/import-pubring.gpg --import -
diff --git a/NEWS b/NEWS
index 05822a2cdc..d56b7a6f27 100644
--- a/NEWS
+++ b/NEWS
@@ -1,7 +1,140 @@
systemd System and Service Manager
+CHANGES WITH 234:
+
+ * Meson is now supported as build system in addition to Automake. It is
+ our plan to remove Automake in one of our next releases, so that
+ Meson becomes our exclusive build system. Hence, please start using
+ the Meson build system in your downstream packaging. There's plenty
+ of documentation around how to use Meson, the extremely brief
+ summary:
+
+ ./autogen.sh && ./configure && make && sudo make install
+
+ becomes:
+
+ meson build && ninja -C build && sudo ninja -C build install
+
+ * Unit files gained support for a new JobRunningTimeoutUSec= setting,
+ which permits configuring a timeout on the time a job is
+ running. This is particularly useful for setting timeouts on jobs for
+ .device units.
+
+ * Unit files gained two new options ConditionUser= and ConditionGroup=
+ for conditionalizing units based on the identity of the user/group
+ running a systemd user instance.
+
+ * systemd-networkd now understands a new FlowLabel= setting in the
+ [VXLAN] section of .network files, as well as a Priority= in
+ [Bridge], GVRP= + MVRP= + LooseBinding= + ReorderHeader= in [VLAN]
+ and GatewayOnlink= + IPv6Preference= + Protocol= in [Route]. It also
+ gained support for configuration of GENEVE links, and IPv6 address
+ labels. The [Network] section gained the new IPv6ProxyNDP= setting.
+
+ * .link files now understand a new Port= setting.
+
+ * systemd-networkd's DHCP support gained support for DHCP option 119
+ (domain search list).
+
+ * systemd-networkd gained support for serving IPv6 address ranges using
+ the Router Advertisment protocol. The new .network configuration
+ section [IPv6Prefix] may be used to configure the ranges to
+ serve. This is implemented based on a new, minimal, native server
+ implementation of RA.
+
+ * journalctl's --output= switch gained support for a new parameter
+ "short-iso-precise" for a mode where timestamps are shown as precise
+ ISO date values.
+
+ * systemd-udevd's "net_id" builtin may now generate stable network
+ interface names from IBM PowerVM VIO devices as well as ACPI platform
+ devices.
+
+ * MulticastDNS support in systemd-resolved may now be explicitly
+ enabled/disabled using the new MulticastDNS= configuration file
+ option.
+
+ * systemd-resolved may now optionally use libidn2 instead of the libidn
+ for processing internationalized domain names. Support for libidn2
+ should be considered experimental and should not be enabled by
+ default yet.
+
+ * "machinectl pull-tar" and related call may now do verification of
+ downloaded images using SUSE-style .sha256 checksum files in addition
+ to the already existing support for validating using Ubuntu-style
+ SHA256SUMS files.
+
+ * sd-bus gained support for a new sd_bus_message_appendv() call which
+ is va_list equivalent of sd_bus_message_append().
+
+ * sd-boot gained support for validating images using SHIM/MOK.
+
+ * The SMACK code learnt support for "onlycap".
+
+ * systemd-mount --umount is now much smarter in figuring out how to
+ properly unmount a device given its mount or device path.
+
+ * The code to call libnss_dns as a fallback from libnss_resolve when
+ the communication with systemd-resolved fails was removed. This
+ fallback was redundant and interfered with the [!UNAVAIL=return]
+ suffix. See nss-resolve(8) for the recommended configuration.
+
+ * systemd-logind may now be restarted without losing state. It stores
+ the file descriptors for devices it manages in the system manager
+ using the FDSTORE= mechanism. Please note that further changes in
+ other components may be required to make use of this (for example
+ Xorg has code to listen for stops of systemd-logind and terminate
+ itself when logind is stopped or restarted, in order to avoid using
+ stale file descriptors for graphical devices, which is now
+ counterproductive and must be reverted in order for restarts of
+ systemd-logind to be safe. See
+ https://cgit.freedesktop.org/xorg/xserver/commit/?id=dc48bd653c7e101.)
+
+ * All kernel install plugins are called with the environment variable
+ KERNEL_INSTALL_MACHINE_ID which is set to the machine ID given by
+ /etc/machine-id. If the file is missing or empty, the variable is
+ empty and BOOT_DIR_ABS is the path of a temporary directory which is
+ removed after all the plugins exit. So, if KERNEL_INSTALL_MACHINE_ID
+ is empty, all plugins should not put anything in BOOT_DIR_ABS.
+
+ Contributions from: Adrian Heine né Lang, Aggelos Avgerinos, Alexander
+ Kurtz, Alexandros Frantzis, Alexey Brodkin, Alex Lu, Amir Pakdel, Amir
+ Yalon, Anchor Cat, Anthony Parsons, Bastien Nocera, Benjamin Gilbert,
+ Benjamin Robin, Boucman, Charles Plessy, Chris Chiu, Chris Lamb,
+ Christian Brauner, Christian Hesse, Colin Walters, Daniel Drake,
+ Danielle Church, Daniel Molkentin, Daniel Rusek, Daniel Wang, Davide
+ Cavalca, David Herrmann, David Michael, Dax Kelson, Dimitri John
+ Ledkov, Djalal Harouni, Dušan Kazik, Elias Probst, Evgeny Vereshchagin,
+ Federico Di Pierro, Felipe Sateler, Felix Zhang, Franck Bui, Gary
+ Tierney, George McCollister, Giedrius Statkevičius, Hans de Goede,
+ hecke, Hendrik Westerberg, Hristo Venev, Ian Wienand, Insun Pyo, Ivan
+ Shapovalov, James Cowgill, James Hemsing, Janne Heß, Jan Synacek, Jason
+ Reeder, João Paulo Rechi Vita, John Paul Adrian Glaubitz, Jörg
+ Thalheim, Josef Andersson, Josef Gajdusek, Julian Mehne, Kai Krakow,
+ Krzysztof Jackiewicz, Lars Karlitski, Lennart Poettering, Lluís Gili,
+ Lucas Werkmeister, Lukáš Nykrýn, Łukasz Stelmach, Mantas Mikulėnas,
+ Marcin Bachry, Marcus Cooper, Mark Stosberg, Martin Pitt, Matija Skala,
+ Matt Clarkson, Matthew Garrett, Matthias Greiner, Matthijs van Duin,
+ Max Resch, Michael Biebl, Michal Koutný, Michal Sekletar, Michal
+ Soltys, Michal Suchanek, Mike Gilbert, Nate Clark, Nathaniel R. Lewis,
+ Neil Brown, Nikolai Kondrashov, Pascal S. de Kloe, Pat Riehecky, Patrik
+ Flykt, Paul Kocialkowski, Peter Hutterer, Philip Withnall, Piotr
+ Szydełko, Rafael Fontenelle, Ray Strode, Richard Maw, Roelf Wichertjes,
+ Ronny Chevalier, Sarang S. Dalal, Sjoerd Simons, slodki, Stefan
+ Schweter, Susant Sahani, Ted Wood, Thomas Blume, Thomas Haller, Thomas
+ H. P. Andersen, Timothée Ravier, Tobias Jungel, Tobias Stoeckmann, Tom
+ Gundersen, Tom Yan, Torstein Husebø, Umut Tezduyar Lindskog,
+ userwithuid, Vito Caputo, Waldemar Brodkorb, WaLyong Cho, Yu, Li-Yu,
+ Yusuke Nojima, Yu Watanabe, Zbigniew Jędrzejewski-Szmek, Дамјан
+ Георгиевски
+
+ — Berlin, 2017-07-12
+
CHANGES WITH 233:
+ * This version requires at least gperf 3.1 for building, 3.0 is not
+ sufficient.
+
* The "hybrid" control group mode has been modified to improve
compatibility with "legacy" cgroups-v1 setups. Specifically, the
"hybrid" setup of /sys/fs/cgroup is now pretty much identical to
@@ -348,7 +481,7 @@ CHANGES WITH 233:
these NTP servers officially. We still recommend downstreams to
properly register an NTP pool with the NTP pool project though.
- * coredumpctl gained new new "--reverse" option for printing the list
+ * coredumpctl gained a new "--reverse" option for printing the list
of coredumps in reverse order.
* coredumpctl will now show additional information about truncated and
diff --git a/README b/README
index a4a6493959..60388eebe6 100644
--- a/README
+++ b/README
@@ -35,7 +35,7 @@ LICENSE:
- except src/udev/* which is (currently still) GPLv2, GPLv2+
REQUIREMENTS:
- Linux kernel >= 3.12
+ Linux kernel >= 3.13
Linux kernel >= 4.2 for unified cgroup hierarchy support
Kernel Config Options:
@@ -127,7 +127,8 @@ REQUIREMENTS:
glibc >= 2.16
libcap
libmount >= 2.27.1 (from util-linux)
- (util-linux *must* be built with --enable-libmount-force-mountinfo)
+ (util-linux < 2.29 *must* be built with --enable-libmount-force-mountinfo,
+ and later versions without --enable-libmount-support-mtab.)
libseccomp >= 2.3.1 (optional)
libblkid >= 2.24 (from util-linux) (optional)
libkmod >= 15 (optional)
@@ -142,7 +143,7 @@ REQUIREMENTS:
libqrencode (optional)
libmicrohttpd (optional)
libpython (optional)
- libidn (optional)
+ libidn2 or libidn (optional)
elfutils >= 158 (optional)
make, gcc, and similar tools
@@ -156,21 +157,47 @@ REQUIREMENTS:
dracut (optional)
PolicyKit (optional)
- When building from git, the following tools are needed:
+ Two build systems are supported: meson + ninja-build and autools + make.
+
+ The following tools are needed with both systems:
pkg-config
- docbook-xsl
- xsltproc
+ gperf >= 3.1
+ docbook-xsl (optional, required for documentation)
+ xsltproc (optional, required for documentation)
+ python-lxml (optional, required to build the indices)
+
+ When building with meson, python and ninja-build are required.
+
+ To build in directory build/:
+ meson build/ && ninja -C build
+
+ Any configuration options can be specfied as -Darg=value... arguments
+ to meson. After the build directory is initially configured, meson will
+ refuse to run again, and options must be changed with:
+ mesonconf -Darg=value...
+ mesonconf without any arguments will print out available options and
+ their current values.
+
+ Useful commands:
+ ninja -v some/target
+ ninja test
+ sudo ninja install
+ DESTDIR=... ninja install
+
+ When building with autotools, the following tools are needed:
+
automake
autoconf
libtool
intltool
- gperf
python (optional)
- python-lxml (optional, but required to build the indices)
- The build system is initialized with ./autogen.sh. A tar ball
- can be created with:
+ The build system is initialized with ./autogen.sh and the usual
+ ./configure && make
+ should be used.
+
+ A tar ball can be created with:
git archive --format=tar --prefix=systemd-222/ v222 | xz > systemd-222.tar.xz
When systemd-hostnamed is used, it is strongly recommended to
diff --git a/README.md b/README.md
index 82fb799b42..c406aca8dc 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,7 @@
# systemd - System and Service Manager
+<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)
diff --git a/TODO b/TODO
index 3cf4ce393c..61efa5e9f3 100644
--- a/TODO
+++ b/TODO
@@ -24,6 +24,15 @@ Janitorial Clean-ups:
Features:
+* 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.
+
+* add some optional flag to ReadWritePaths= and friends, that has the effect
+ that we create the dir in question when the service is started. Example:
+
+ 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)
diff --git a/catalog/meson.build b/catalog/meson.build
new file mode 100644
index 0000000000..6d205b1d42
--- /dev/null
+++ b/catalog/meson.build
@@ -0,0 +1,28 @@
+in_files = '''
+ systemd.bg.catalog
+ systemd.be.catalog
+ systemd.be@latin.catalog
+ systemd.fr.catalog
+ systemd.it.catalog
+ systemd.pl.catalog
+ systemd.pt_BR.catalog
+ systemd.ru.catalog
+ systemd.zh_CN.catalog
+ systemd.zh_TW.catalog
+ systemd.catalog
+'''.split()
+
+support_url = get_option('support-url')
+support_sed = 's~%SUPPORT_URL%~@0@~'.format(support_url)
+build_catalog_dir = meson.current_build_dir()
+
+foreach file : in_files
+ custom_target(
+ file,
+ input : file + '.in',
+ output: file,
+ command : [sed, support_sed, '@INPUT@'],
+ capture : true,
+ install : true,
+ install_dir : catalogdir)
+endforeach
diff --git a/configure.ac b/configure.ac
index 64b2d28048..afbb4e8ae5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -20,7 +20,7 @@
AC_PREREQ([2.64])
AC_INIT([systemd],
- [233],
+ [234],
[https://github.com/systemd/systemd/issues],
[systemd],
[https://www.freedesktop.org/wiki/Software/systemd])
@@ -57,6 +57,7 @@ AS_IF([test "x$enable_largefile" = "xno"], [AC_MSG_ERROR([--disable-largefile is
SET_ARCH(X86_64, x86_64*)
SET_ARCH(IA32, i*86*)
SET_ARCH(MIPS, mips*)
+SET_ARCH(ARM, arm*)
SET_ARCH(AARCH64, aarch64*)
# i18n stuff for the PolicyKit policy files, heck whether intltool can be found, disable NLS otherwise
@@ -327,7 +328,6 @@ AC_CHECK_DECLS([
pivot_root,
name_to_handle_at,
setns,
- getrandom,
renameat2,
kcmp,
keyctl,
@@ -342,6 +342,13 @@ AC_CHECK_DECLS([
#include <sched.h>
#include <string.h>
#include <linux/loop.h>
+]])
+
+AC_CHECK_DECLS([getrandom],
+ [AC_DEFINE([USE_SYS_RANDOM_H], [], [sys/random.h is usable])],
+ [AC_CHECK_DECLS([getrandom], [], [], [[
+#include <sys/random.h>
+]])], [[
#include <linux/random.h>
]])
@@ -360,7 +367,8 @@ AC_CHECK_DECLS([IFLA_INET6_ADDR_GEN_MODE,
IFLA_PHYS_PORT_ID,
IFLA_BOND_AD_INFO,
IFLA_VLAN_PROTOCOL,
- IFLA_VXLAN_REMCSUM_NOPARTIAL,
+ IFLA_VXLAN_GPE,
+ IFLA_GENEVE_LABEL,
IFLA_IPTUN_ENCAP_DPORT,
IFLA_GRE_ENCAP_DPORT,
IFLA_BRIDGE_VLAN_INFO,
@@ -398,13 +406,27 @@ AS_IF([test "x$enable_dbus" != "xno"], [
AM_CONDITIONAL(HAVE_DBUS, [test "$have_dbus" = "yes"])
# ------------------------------------------------------------------------------
+have_glib=no
+AC_ARG_ENABLE(glib, AS_HELP_STRING([--disable-glib], [disable usage of glib,gobject,gio in tests]))
+AS_IF([test "x$enable_glib" != "xno"], [
+ PKG_CHECK_MODULES(GLIB, [glib-2.0 >= 2.22.0 gobject-2.0 >= 2.22.0 gio-2.0],
+ [AC_DEFINE(HAVE_GLIB, 1, [Define if glib,gobject,gio are available]) have_glib=yes],
+ [have_glib=no])
+ AS_IF([test "x$have_glib" = "xno" -a "x$enable_glib" = "xyes"],
+ [AC_MSG_ERROR([*** glib support requested but libraries not found])])])
+
+# ------------------------------------------------------------------------------
have_utmp=yes
AC_ARG_ENABLE([utmp], AS_HELP_STRING([--disable-utmp], [disable utmp/wtmp log handling]),
AS_CASE("x${enableval}",
[xyes], [have_utmp=yes],
[xno], [have_utmp=no],
AC_MSG_ERROR(bad value ${enableval} for --enable-utmp)))
-AS_IF([test "x$have_utmp" = "xyes"], [AC_DEFINE(HAVE_UTMP, 1, [Define if utmp/wtmp support is enabled])])
+AS_IF([test "x$have_utmp" = "xyes"], [
+ AC_DEFINE(HAVE_UTMP, 1, [Define if utmp/wtmp support is enabled])
+ have_utmp=yes
+ M4_DEFINES="$M4_DEFINES -DHAVE_UTMP"],
+ [have_utmp=no])
AM_CONDITIONAL([HAVE_UTMP], [test "x$have_utmp" = "xyes"])
# ------------------------------------------------------------------------------
@@ -1011,6 +1033,40 @@ if test "x$enable_libidn" != "xno"; then
fi
AM_CONDITIONAL(HAVE_LIBIDN, [test "$have_libidn" = "yes"])
+have_libidn2=no
+AC_ARG_ENABLE(libidn2, AS_HELP_STRING([--disable-libidn2], [disable optional LIBIDN2 support]))
+if test "$have_libidn" != "yes"; then
+ if test "x$enable_libidn2" != "xno"; then
+ PKG_CHECK_MODULES(LIBIDN2, [libidn2 >= 2.0.0],
+ [AC_DEFINE(HAVE_LIBIDN2, 1, [Define if libidn2 is available])
+ have_libidn2=yes
+ M4_DEFINES="$M4_DEFINES -DHAVE_LIBIDN2"],
+ [have_libidn2=no])
+ if test "x$have_libidn2" = "xno" -a "x$enable_libidn2" = "xyes"; then
+ AC_MSG_ERROR([*** libidn2 support requested but libraries not found])
+ fi
+ fi
+fi
+AM_CONDITIONAL(HAVE_LIBIDN2, [test "$have_libidn2" = "yes"])
+
+# ------------------------------------------------------------------------------
+have_idn=no
+AC_ARG_ENABLE(idn, AS_HELP_STRING([--disable-idn], [disable IDN when printing host names]))
+if test "x$enable_idn" != "xno"; then
+ have_idn=yes
+ AC_DEFINE(ENABLE_IDN, [1], [IDN is enabled])
+fi
+AM_CONDITIONAL(ENABLE_IDN, [test "$have_idn" = "yes"])
+
+# ------------------------------------------------------------------------------
+have_nss_systemd=no
+AC_ARG_ENABLE(nss-systemd, AS_HELP_STRING([--disable-nss-systemd], [disable nss-systemd support]))
+if test "x$enable_nss_systemd" != "xno"; then
+ have_nss_systemd=yes
+ AC_DEFINE(ENABLE_NSS_SYSTEMD, [1], [nss-systemd is enabled])
+fi
+AM_CONDITIONAL(ENABLE_NSS_SYSTEMD, [test "$have_nss_systemd" = "yes"])
+
# ------------------------------------------------------------------------------
have_libiptc=no
AC_ARG_ENABLE(libiptc, AS_HELP_STRING([--disable-libiptc], [disable optional LIBIPTC support]))
@@ -1074,6 +1130,11 @@ if test "x$enable_sysusers" != "xno"; then
fi
AM_CONDITIONAL(ENABLE_SYSUSERS, [test "$have_sysusers" = "yes"])
+AC_ARG_ENABLE(gshadow, AS_HELP_STRING([--disable-gshadow], [disable shadow group support]))
+AS_IF([test "x${enable_gshadow}" != "xno"], [
+ AC_DEFINE(ENABLE_GSHADOW, 1, [shadow group support is enabled])
+])
+
# ------------------------------------------------------------------------------
have_firstboot=no
AC_ARG_ENABLE(firstboot, AS_HELP_STRING([--disable-firstboot], [disable firstboot support]))
@@ -1113,7 +1174,7 @@ if test "x$enable_logind" != "xno"; then
have_logind=yes
fi
AM_CONDITIONAL(ENABLE_LOGIND, [test "$have_logind" = "yes"])
-AS_IF([test "$have_logind" = "yes"], [ AC_DEFINE(HAVE_LOGIND, [1], [Logind support available]) ])
+AS_IF([test "$have_logind" = "yes"], [ AC_DEFINE(ENABLE_LOGIND, [1], [Logind support available]) ])
AC_ARG_WITH([kill-user-processes],
[AS_HELP_STRING([--without-kill-user-processes], [set logind's KillUserProcesses=no by default])])
@@ -1206,6 +1267,16 @@ AC_DEFINE_UNQUOTED(SYSTEM_GID_MAX, [$SYSTEM_GID_MAX], [Maximum System GID])
AC_SUBST(SYSTEM_GID_MAX)
# ------------------------------------------------------------------------------
+
+AC_ARG_WITH(dev-kvm-mode,
+ AS_HELP_STRING([--with-dev-kvm-mode=MODE],
+ [/dev/kvm access mode, defaults to "0660"]),
+ [DEV_KVM_MODE="$withval"],
+ [DEV_KVM_MODE="0660"])
+
+AC_SUBST(DEV_KVM_MODE, [$DEV_KVM_MODE], [/dev/kvm access mode])
+
+# ------------------------------------------------------------------------------
have_localed=no
AC_ARG_ENABLE(localed, AS_HELP_STRING([--disable-localed], [disable locale daemon]))
if test "x$enable_localed" != "xno"; then
@@ -1228,8 +1299,14 @@ AC_ARG_ENABLE(polkit, AS_HELP_STRING([--disable-polkit], [disable PolicyKit supp
if test "x$enable_polkit" != "xno"; then
AC_DEFINE(ENABLE_POLKIT, 1, [Define if PolicyKit support is to be enabled])
have_polkit=yes
+
+ # also enable support for *.pkla files on old polkit
+ PKG_CHECK_MODULES(POLKIT, [ polkit-gobject-1 < 0.106 ],
+ [polkit_pkla=yes],
+ [polkit_pkla=no])
fi
AM_CONDITIONAL(ENABLE_POLKIT, [test "x$have_polkit" = "xyes"])
+AM_CONDITIONAL(ENABLE_POLKIT_PKLA, [test "x$polkit_pkla" = "xyes"])
# ------------------------------------------------------------------------------
have_resolved=no
@@ -1258,6 +1335,11 @@ AC_ARG_WITH(default-dnssec,
[DEFAULT_DNSSEC_MODE="$withval"],
[DEFAULT_DNSSEC_MODE="allow-downgrade"])
+if test "x$have_gcrypt" = xno -a "x${DEFAULT_DNSSEC_MODE}" != xno ; then
+ AC_MSG_WARN(default-dnssec cannot be set to yes or allow-downgrade when gcrypt is disabled. Setting default-dnssec to no.)
+ DEFAULT_DNSSEC_MODE="no"
+fi
+
AS_CASE("x${DEFAULT_DNSSEC_MODE}",
[xno], [mode=DNSSEC_NO],
[xyes], [mode=DNSSEC_YES],
@@ -1297,6 +1379,9 @@ AM_COND_IF(ARCH_IA32, [
AM_COND_IF(ARCH_X86_64, [
EFI_MACHINE_TYPE_NAME=x64])
+AM_COND_IF(ARCH_ARM, [
+ EFI_MACHINE_TYPE_NAME=arm])
+
AM_COND_IF(ARCH_AARCH64, [
EFI_MACHINE_TYPE_NAME=aa64])
@@ -1306,7 +1391,13 @@ AC_SUBST([EFI_MACHINE_TYPE_NAME])
have_gnuefi=no
AC_ARG_ENABLE(gnuefi, AS_HELP_STRING([--enable-gnuefi], [enable optional gnuefi support]))
AS_IF([test "x$enable_gnuefi" != "xno"], [
- AC_CHECK_HEADERS(efi/${EFI_ARCH}/efibind.h,
+ AC_ARG_WITH(efi-includedir,
+ AS_HELP_STRING([--with-efi-includedir=PATH], [path to EFI include directory]),
+ [EFI_INC_DIR="$withval"], [EFI_INC_DIR="/usr/include"]
+ )
+ AC_SUBST([EFI_INC_DIR])
+
+ AC_CHECK_HEADERS(${EFI_INC_DIR}/efi/${EFI_ARCH}/efibind.h,
[AC_DEFINE(HAVE_GNUEFI, 1, [Define if gnuefi is available])
have_gnuefi=yes],
[AS_IF([test "x$enable_gnuefi" = xyes],
@@ -1335,12 +1426,6 @@ AS_IF([test "x$enable_gnuefi" != "xno"], [
[AS_IF([test "x$enable_gnuefi" = xyes],
[AC_MSG_ERROR([*** gnuefi support requested but files not found])],
[have_gnuefi=no])])
-
- AC_ARG_WITH(efi-includedir,
- AS_HELP_STRING([--with-efi-includedir=PATH], [path to EFI include directory]),
- [EFI_INC_DIR="$withval"], [EFI_INC_DIR="/usr/include"]
- )
- AC_SUBST([EFI_INC_DIR])
])
AM_CONDITIONAL(HAVE_GNUEFI, [test "x$have_gnuefi" = xyes])
@@ -1658,7 +1743,7 @@ AC_CONFIG_FILES([
AC_OUTPUT
AC_MSG_RESULT([
- $PACKAGE_NAME $VERSION
+ $PACKAGE_NAME $PACKAGE_VERSION
libcryptsetup: ${have_libcryptsetup}
PAM: ${have_pam}
@@ -1678,7 +1763,9 @@ AC_MSG_RESULT([
MICROHTTPD: ${have_microhttpd}
GNUTLS: ${have_gnutls}
libcurl: ${have_libcurl}
+ libidn2: ${have_libidn2}
libidn: ${have_libidn}
+ IDN: ${have_idn}
libiptc: ${have_libiptc}
ELFUTILS: ${have_elfutils}
binfmt: ${have_binfmt}
@@ -1707,7 +1794,7 @@ AC_MSG_RESULT([
default DNS servers: ${DNS_SERVERS}
default DNSSEC mode: ${DEFAULT_DNSSEC_MODE}
coredump: ${have_coredump}
- polkit: ${have_polkit}
+ polkit: ${have_polkit} (legacy pkla support: ${polkit_pkla})
efi: ${have_efi}
gnuefi: ${have_gnuefi}
efi arch: ${EFI_ARCH}
@@ -1721,7 +1808,9 @@ AC_MSG_RESULT([
blkid: ${have_blkid}
libmount: ${have_libmount}
dbus: ${have_dbus}
+ glib: ${have_glib}
nss-myhostname: ${have_myhostname}
+ nss-systemd: ${have_nss_systemd}
hwdb: ${enable_hwdb}
tpm: ${have_tpm}
Python: ${have_python}
@@ -1761,6 +1850,7 @@ AC_MSG_RESULT([
TTY GID: ${TTY_GID}
maximum system UID: ${SYSTEM_UID_MAX}
maximum system GID: ${SYSTEM_GID_MAX}
+ /dev/kvm access mode: ${DEV_KVM_MODE}
certificate root: ${CERTIFICATEROOT}
support URL: ${SUPPORT_URL}
nobody user name: ${NOBODY_USER_NAME}
diff --git a/docs/sysvinit/meson.build b/docs/sysvinit/meson.build
new file mode 100644
index 0000000000..79d1babf16
--- /dev/null
+++ b/docs/sysvinit/meson.build
@@ -0,0 +1,9 @@
+file = configure_file(
+ input : 'README.in',
+ output : 'README',
+ configuration : substs)
+
+if conf.get('HAVE_SYSV_COMPAT', false)
+ install_data(file,
+ install_dir : sysvinit_path)
+endif
diff --git a/docs/var-log/meson.build b/docs/var-log/meson.build
new file mode 100644
index 0000000000..d8364e38b9
--- /dev/null
+++ b/docs/var-log/meson.build
@@ -0,0 +1,9 @@
+file = configure_file(
+ input : 'README.in',
+ output : 'README',
+ configuration : substs)
+
+if conf.get('HAVE_SYSV_COMPAT', false)
+ install_data(file,
+ install_dir : varlogdir)
+endif
diff --git a/hwdb/20-OUI.hwdb b/hwdb/20-OUI.hwdb
index 2f0dbc9e74..5c1bb7fe20 100644
--- a/hwdb/20-OUI.hwdb
+++ b/hwdb/20-OUI.hwdb
@@ -101,9 +101,6 @@ OUI:70B3D55B1*
OUI:70B3D5EAE*
ID_OUI_FROM_DATABASE=Orlaco Products B.V.
-OUI:70B3D5066*
- ID_OUI_FROM_DATABASE=North Pole Engineering, Inc.
-
OUI:70B3D557D*
ID_OUI_FROM_DATABASE=WICOM1 GmbH
@@ -833,9 +830,6 @@ OUI:70B3D53A9*
OUI:001BC5087*
ID_OUI_FROM_DATABASE=Onnet Technologies and Innovations LLC
-OUI:70B3D5720*
- ID_OUI_FROM_DATABASE=Private
-
OUI:70B3D56BF*
ID_OUI_FROM_DATABASE=Otto Bihler Maschinenfabrik GmbH & Co. KG
@@ -908,9 +902,6 @@ OUI:70B3D5ABA*
OUI:70B3D565A*
ID_OUI_FROM_DATABASE=Aplex Technology Inc.
-OUI:70B3D5FFE*
- ID_OUI_FROM_DATABASE=Private
-
OUI:70B3D5721*
ID_OUI_FROM_DATABASE=Zoe Medical
@@ -1103,21 +1094,21 @@ OUI:70B3D58EC*
OUI:70B3D5CF5*
ID_OUI_FROM_DATABASE=Petring Energietechnik GmbH
+OUI:70B3D5269*
+ ID_OUI_FROM_DATABASE=Gilbarco Veeder-Root ‎
+
OUI:70B3D5FF7*
ID_OUI_FROM_DATABASE=Cybercom AB
OUI:70B3D5DCC*
ID_OUI_FROM_DATABASE=Eutron SPA
-OUI:70B3D5269*
- ID_OUI_FROM_DATABASE=Gilbarco Veeder-Root ‎
+OUI:70B3D515C*
+ ID_OUI_FROM_DATABASE=Woods Hole Oceanographic Institution
OUI:70B3D5173*
ID_OUI_FROM_DATABASE=National TeleConsultants LLC
-OUI:70B3D515C*
- ID_OUI_FROM_DATABASE=Woods Hole Oceanographic Institution
-
OUI:70B3D5CAE*
ID_OUI_FROM_DATABASE=THEMA
@@ -1133,12 +1124,12 @@ OUI:70B3D585A*
OUI:70B3D5FAF*
ID_OUI_FROM_DATABASE=Radig Hard & Software
-OUI:70B3D57A2*
- ID_OUI_FROM_DATABASE=Alpha ESS Co., Ltd.
-
OUI:70B3D50BC*
ID_OUI_FROM_DATABASE=Practical Software Studio LLC
+OUI:70B3D57A2*
+ ID_OUI_FROM_DATABASE=Alpha ESS Co., Ltd.
+
OUI:70B3D5724*
ID_OUI_FROM_DATABASE=Quan International Co., Ltd.
@@ -1169,9 +1160,6 @@ OUI:70B3D5209*
OUI:70B3D514C*
ID_OUI_FROM_DATABASE=CRDE
-OUI:70B3D5AB8*
- ID_OUI_FROM_DATABASE=HORIBA MEDICAL
-
OUI:70B3D5F9E*
ID_OUI_FROM_DATABASE=International Center for Elementary Particle Physics, The University of Tokyo
@@ -1205,6 +1193,162 @@ OUI:70B3D5585*
OUI:70B3D5495*
ID_OUI_FROM_DATABASE=Fiem Industries Ltd.
+OUI:70B3D5AD2*
+ ID_OUI_FROM_DATABASE=Wart-Elektronik
+
+OUI:70B3D52B4*
+ ID_OUI_FROM_DATABASE=Foerster-Technik GmbH
+
+OUI:70B3D5276*
+ ID_OUI_FROM_DATABASE=TELL Software Hungaria Kft.
+
+OUI:70B3D528C*
+ ID_OUI_FROM_DATABASE=Step Technica Co., Ltd.
+
+OUI:70B3D57E0*
+ ID_OUI_FROM_DATABASE=Sanko-sha,inc.
+
+OUI:70B3D5E50*
+ ID_OUI_FROM_DATABASE=Advanced Vision Technology Ltd
+
+OUI:70B3D58C1*
+ ID_OUI_FROM_DATABASE=Rievtech Electronic Co.,Ltd
+
+OUI:70B3D5F0C*
+ ID_OUI_FROM_DATABASE=ModulaTeam GmbH
+
+OUI:70B3D58AC*
+ ID_OUI_FROM_DATABASE=​ASUNG TECHNO CO.,Ltd
+
+OUI:70B3D5CE1*
+ ID_OUI_FROM_DATABASE=EA Elektroautomatik GmbH & Co. KG
+
+OUI:70B3D5677*
+ ID_OUI_FROM_DATABASE=Fraunhofer-Institut IIS
+
+OUI:70B3D538B*
+ ID_OUI_FROM_DATABASE=Lookman Electroplast Industries Ltd
+
+OUI:70B3D59DC*
+ ID_OUI_FROM_DATABASE=Shanghai Daorech Industry Developmnet Co.,Ltd
+
+OUI:70B3D5888*
+ ID_OUI_FROM_DATABASE=Zetechtics Ltd
+
+OUI:70B3D5168*
+ ID_OUI_FROM_DATABASE=Biwave Technologies, Inc.
+
+OUI:70B3D5F25*
+ ID_OUI_FROM_DATABASE=JSC “Scientific Industrial Enterprise Rubin
+
+OUI:70B3D5A48*
+ ID_OUI_FROM_DATABASE=Applied Satellite Engineering
+
+OUI:70B3D546C*
+ ID_OUI_FROM_DATABASE=SHANGHAI CHENZHU INSTRUMENT CO., LTD.
+
+OUI:70B3D580B*
+ ID_OUI_FROM_DATABASE=Fischer Block, Inc.
+
+OUI:70B3D5FAD*
+ ID_OUI_FROM_DATABASE=ARC Technology Solutions, LLC
+
+OUI:70B3D5AB8*
+ ID_OUI_FROM_DATABASE=HORIBA ABX SAS
+
+OUI:70B3D5E6C*
+ ID_OUI_FROM_DATABASE=Fusar Technologies inc
+
+OUI:70B3D52B0*
+ ID_OUI_FROM_DATABASE=Beijing Zhongyi Yue Tai Technology Co., Ltd
+
+OUI:70B3D52E2*
+ ID_OUI_FROM_DATABASE=Spark Lasers
+
+OUI:70B3D5446*
+ ID_OUI_FROM_DATABASE=Santa Barbara Imaging Systems
+
+OUI:70B3D556B*
+ ID_OUI_FROM_DATABASE=S.E.I. CO.,LTD.
+
+OUI:70B3D5B48*
+ ID_OUI_FROM_DATABASE=DWQ Informatikai Tanacsado es Vezerlestechnikai KFT
+
+OUI:70B3D5A7E*
+ ID_OUI_FROM_DATABASE=QUICCO SOUND Corporation
+
+OUI:70B3D5878*
+ ID_OUI_FROM_DATABASE=Package Guard, Inc
+
+OUI:70B3D5245*
+ ID_OUI_FROM_DATABASE=Newtec A/S
+
+OUI:70B3D5FFE*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:70B3D53FE*
+ ID_OUI_FROM_DATABASE=Mentor Graphics
+
+OUI:70B3D574D*
+ ID_OUI_FROM_DATABASE=SPEECH TECHNOLOGY CENTER LIMITED
+
+OUI:70B3D55BF*
+ ID_OUI_FROM_DATABASE=Aton srl
+
+OUI:70B3D5EEA*
+ ID_OUI_FROM_DATABASE=Dameca a/s
+
+OUI:70B3D59B8*
+ ID_OUI_FROM_DATABASE=Loma Systems
+
+OUI:70B3D5BEA*
+ ID_OUI_FROM_DATABASE=Virtuosys Ltd
+
+OUI:70B3D5066*
+ ID_OUI_FROM_DATABASE=North Pole Engineering, Inc.
+
+OUI:70B3D52A1*
+ ID_OUI_FROM_DATABASE=Blink Services AB
+
+OUI:70B3D5591*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:70B3D5133*
+ ID_OUI_FROM_DATABASE=Vidisys GmbH
+
+OUI:70B3D5720*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:70B3D51E6*
+ ID_OUI_FROM_DATABASE=Sanmina Israel
+
+OUI:70B3D5809*
+ ID_OUI_FROM_DATABASE=Tecnint HTE SRL
+
+OUI:70B3D52AB*
+ ID_OUI_FROM_DATABASE=NASA Johnson Space Center
+
+OUI:70B3D5254*
+ ID_OUI_FROM_DATABASE=Spectrum Brands
+
+OUI:70B3D57C9*
+ ID_OUI_FROM_DATABASE=Council Rock
+
+OUI:70B3D553A*
+ ID_OUI_FROM_DATABASE=Pano0ramic Power
+
+OUI:70B3D5E18*
+ ID_OUI_FROM_DATABASE=Plasmapp Co.,Ltd.
+
+OUI:70B3D5D44*
+ ID_OUI_FROM_DATABASE=ic-automation GmbH
+
+OUI:70B3D59D7*
+ ID_OUI_FROM_DATABASE=KM OptoElektronik GmbH
+
+OUI:70B3D561B*
+ ID_OUI_FROM_DATABASE=Nubewell Networks Pvt Ltd
+
OUI:70B3D5D60*
ID_OUI_FROM_DATABASE=Flintab AB
@@ -1337,9 +1481,6 @@ OUI:70B3D58A4*
OUI:70B3D5166*
ID_OUI_FROM_DATABASE=SERIAL IMAGE INC.
-OUI:70B3D5E59*
- ID_OUI_FROM_DATABASE=FRACARRO SPA
-
OUI:70B3D576D*
ID_OUI_FROM_DATABASE=Trimble
@@ -1775,9 +1916,6 @@ OUI:001BC5054*
OUI:001BC5050*
ID_OUI_FROM_DATABASE=TeliSwitch Solutions
-OUI:001BC5046*
- ID_OUI_FROM_DATABASE=Trans-European Research and Education Networking Association (TERENA)
-
OUI:001BC5040*
ID_OUI_FROM_DATABASE=OOO Actidata
@@ -1997,9 +2135,6 @@ OUI:70B3D5DE4*
OUI:70B3D5712*
ID_OUI_FROM_DATABASE=APG Cash Drawer, LLC
-OUI:70B3D5580*
- ID_OUI_FROM_DATABASE=Private
-
OUI:70B3D5776*
ID_OUI_FROM_DATABASE=Power Ltd.
@@ -2276,12 +2411,12 @@ OUI:70B3D521D*
OUI:70B3D5E9C*
ID_OUI_FROM_DATABASE=ATG UV Technology
-OUI:70B3D539E*
- ID_OUI_FROM_DATABASE=Lanmark Controls Inc.
-
OUI:70B3D5267*
ID_OUI_FROM_DATABASE=Zehntner Testing Instruments
+OUI:70B3D539E*
+ ID_OUI_FROM_DATABASE=Lanmark Controls Inc.
+
OUI:70B3D5C2E*
ID_OUI_FROM_DATABASE=Triax A/S
@@ -2324,12 +2459,12 @@ OUI:70B3D5DFD*
OUI:70B3D5B30*
ID_OUI_FROM_DATABASE=Systolé Hardware B.V.
-OUI:70B3D53BF*
- ID_OUI_FROM_DATABASE=Star Electronics GmbH & Co. KG
-
OUI:70B3D5745*
ID_OUI_FROM_DATABASE=TMSI LLC
+OUI:70B3D53BF*
+ ID_OUI_FROM_DATABASE=Star Electronics GmbH & Co. KG
+
OUI:70B3D5D1C*
ID_OUI_FROM_DATABASE=Specialised Imaging Limited
@@ -2342,12 +2477,12 @@ OUI:70B3D5ADF*
OUI:70B3D522C*
ID_OUI_FROM_DATABASE=Hiquel Elektronik- und Anlagenbau GmbH
-OUI:70B3D5DCE*
- ID_OUI_FROM_DATABASE=Stahl GmbH
-
OUI:70B3D52A2*
ID_OUI_FROM_DATABASE=Visualware, Inc.
+OUI:70B3D5DCE*
+ ID_OUI_FROM_DATABASE=Stahl GmbH
+
OUI:70B3D5D08*
ID_OUI_FROM_DATABASE=Veeco Instruments
@@ -2378,6 +2513,180 @@ OUI:70B3D542D*
OUI:70B3D5332*
ID_OUI_FROM_DATABASE=InnoSenT
+OUI:70B3D5A47*
+ ID_OUI_FROM_DATABASE=KANOA INC
+
+OUI:70B3D5F45*
+ ID_OUI_FROM_DATABASE=Norbit ODM AS
+
+OUI:70B3D5DEE*
+ ID_OUI_FROM_DATABASE=CRDE
+
+OUI:70B3D5E59*
+ ID_OUI_FROM_DATABASE=Fracarro srl
+
+OUI:70B3D5127*
+ ID_OUI_FROM_DATABASE=VITEC
+
+OUI:001BC5046*
+ ID_OUI_FROM_DATABASE=GÉANT
+
+OUI:70B3D573A*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:70B3D59DE*
+ ID_OUI_FROM_DATABASE=System 11 Sp. z o.o.
+
+OUI:70B3D596D*
+ ID_OUI_FROM_DATABASE=MSB Elektronik und Gerätebau GmbH
+
+OUI:70B3D5C17*
+ ID_OUI_FROM_DATABASE=Potter Electric Signal Co. LLC
+
+OUI:70B3D5108*
+ ID_OUI_FROM_DATABASE=TEX COMPUTER SRL
+
+OUI:70B3D54E7*
+ ID_OUI_FROM_DATABASE=Digital Domain
+
+OUI:70B3D5007*
+ ID_OUI_FROM_DATABASE=SENSONEO
+
+OUI:70B3D5D10*
+ ID_OUI_FROM_DATABASE=Contec DTx
+
+OUI:70B3D57F3*
+ ID_OUI_FROM_DATABASE=Shenzhen Virtual Clusters Information Technology Co.,Ltd.
+
+OUI:70B3D5C8C*
+ ID_OUI_FROM_DATABASE=Rollogo Limited
+
+OUI:70B3D5D4C*
+ ID_OUI_FROM_DATABASE=Elystec Technology Co., Ltd
+
+OUI:70B3D596B*
+ ID_OUI_FROM_DATABASE=FOCAL-JMLab
+
+OUI:70B3D584D*
+ ID_OUI_FROM_DATABASE=Quantum Design Inc.
+
+OUI:70B3D5E57*
+ ID_OUI_FROM_DATABASE=Iradimed
+
+OUI:70B3D5125*
+ ID_OUI_FROM_DATABASE=Securolytics, Inc.
+
+OUI:70B3D5C6E*
+ ID_OUI_FROM_DATABASE=Orion Technologies, LLC
+
+OUI:70B3D5CC8*
+ ID_OUI_FROM_DATABASE=PROFEN COMMUNICATIONS
+
+OUI:70B3D5FDB*
+ ID_OUI_FROM_DATABASE=Design SHIFT
+
+OUI:70B3D5791*
+ ID_OUI_FROM_DATABASE=Romteck Australia
+
+OUI:70B3D569F*
+ ID_OUI_FROM_DATABASE=T+A elektroakustik GmbH & Co.KG
+
+OUI:70B3D5D20*
+ ID_OUI_FROM_DATABASE=Rheonics GmbH
+
+OUI:70B3D55FB*
+ ID_OUI_FROM_DATABASE=TELEPLATFORMS
+
+OUI:70B3D5768*
+ ID_OUI_FROM_DATABASE=Kazan Networks Corporation
+
+OUI:70B3D56B2*
+ ID_OUI_FROM_DATABASE=CRDE
+
+OUI:70B3D57F7*
+ ID_OUI_FROM_DATABASE=JASCO Applied Sciences Canada Ltd
+
+OUI:70B3D5F42*
+ ID_OUI_FROM_DATABASE=Matsuhisa Corporation
+
+OUI:70B3D5381*
+ ID_OUI_FROM_DATABASE=CRDE
+
+OUI:70B3D5488*
+ ID_OUI_FROM_DATABASE=Cardinal Scale Mfg Co
+
+OUI:70B3D5273*
+ ID_OUI_FROM_DATABASE=WeVo Tech
+
+OUI:70B3D5379*
+ ID_OUI_FROM_DATABASE=Vensi, Inc.
+
+OUI:70B3D50B2*
+ ID_OUI_FROM_DATABASE=ndb technologies
+
+OUI:70B3D5CB3*
+ ID_OUI_FROM_DATABASE=KST technology
+
+OUI:70B3D530D*
+ ID_OUI_FROM_DATABASE=Fiberbase
+
+OUI:70B3D5842*
+ ID_OUI_FROM_DATABASE=PLUTO Solution co.,ltd.
+
+OUI:70B3D5EB9*
+ ID_OUI_FROM_DATABASE=Thiel Audio Products Company, LLC
+
+OUI:70B3D5031*
+ ID_OUI_FROM_DATABASE=SHENZHEN GAONA ELECTRONIC CO.LTD
+
+OUI:70B3D5548*
+ ID_OUI_FROM_DATABASE=DIGIVERV INC
+
+OUI:70B3D5284*
+ ID_OUI_FROM_DATABASE=Globalcom Engineering SPA
+
+OUI:70B3D5A4E*
+ ID_OUI_FROM_DATABASE=Array Technologies Inc.
+
+OUI:70B3D5580*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:70B3D52F2*
+ ID_OUI_FROM_DATABASE=Health Care Originals, Inc.
+
+OUI:70B3D5B98*
+ ID_OUI_FROM_DATABASE=GSF Corporation Pte Ltd
+
+OUI:70B3D5BA9*
+ ID_OUI_FROM_DATABASE=Alma
+
+OUI:70B3D50DE*
+ ID_OUI_FROM_DATABASE=Grossenbacher Systeme AG
+
+OUI:70B3D54B8*
+ ID_OUI_FROM_DATABASE=International Roll-Call Corporation
+
+OUI:70B3D5991*
+ ID_OUI_FROM_DATABASE=Javasparrow Inc.
+
+OUI:70B3D5894*
+ ID_OUI_FROM_DATABASE=UnI Systech Co.,Ltd
+
+OUI:70B3D516B*
+ ID_OUI_FROM_DATABASE=IOT Engineering
+
+OUI:70B3D53AA*
+ ID_OUI_FROM_DATABASE=RCATSONE
+
+OUI:70B3D5432*
+ ID_OUI_FROM_DATABASE=DEUTA-WERKE GmbH
+
+OUI:70B3D5086*
+ ID_OUI_FROM_DATABASE=Husty M.Styczen J.Hupert Sp.J.
+
+OUI:70B3D5E17*
+ ID_OUI_FROM_DATABASE=Private
+
OUI:70B3D5494*
ID_OUI_FROM_DATABASE=Schildknecht AG
@@ -3113,9 +3422,6 @@ OUI:70B3D50FA*
OUI:70B3D531E*
ID_OUI_FROM_DATABASE=GILLAM-FEI S.A.
-OUI:70B3D54D5*
- ID_OUI_FROM_DATABASE=Morgan Rekofa GmbH
-
OUI:70B3D58C5*
ID_OUI_FROM_DATABASE=HMicro Inc
@@ -3152,9 +3458,6 @@ OUI:70B3D54FE*
OUI:70B3D51FD*
ID_OUI_FROM_DATABASE=BRS Sistemas Eletrônicos
-OUI:70B3D5631*
- ID_OUI_FROM_DATABASE=SENSO2ME
-
OUI:70B3D5396*
ID_OUI_FROM_DATABASE=CTG sp. z o. o.
@@ -3173,9 +3476,6 @@ OUI:70B3D53D9*
OUI:70B3D535F*
ID_OUI_FROM_DATABASE=Aplex Technology Inc.
-OUI:70B3D5FFF*
- ID_OUI_FROM_DATABASE=Private
-
OUI:70B3D533E*
ID_OUI_FROM_DATABASE=Dynamic Connect (Suzhou) Hi-Tech Electronic Co.,Ltd.
@@ -3533,6 +3833,159 @@ OUI:70B3D5579*
OUI:70B3D59B2*
ID_OUI_FROM_DATABASE=CONTINENT, Ltd
+OUI:70B3D5365*
+ ID_OUI_FROM_DATABASE=CircuitMeter Inc.
+
+OUI:70B3D5805*
+ ID_OUI_FROM_DATABASE=Eurotronik Kranj d.o.o.
+
+OUI:70B3D5BF6*
+ ID_OUI_FROM_DATABASE=comtac AG
+
+OUI:70B3D50B4*
+ ID_OUI_FROM_DATABASE=AVER
+
+OUI:70B3D51B6*
+ ID_OUI_FROM_DATABASE=DACOM West GmbH
+
+OUI:70B3D59C1*
+ ID_OUI_FROM_DATABASE=Zeroplus Technology Co.,Ltd.
+
+OUI:70B3D5094*
+ ID_OUI_FROM_DATABASE=Circuitlink Pty Ltd
+
+OUI:70B3D5AA3*
+ ID_OUI_FROM_DATABASE=LINEAGE POWER PVT LTD.,
+
+OUI:70B3D5AEF*
+ ID_OUI_FROM_DATABASE=Baumtec GmbH
+
+OUI:70B3D5D92*
+ ID_OUI_FROM_DATABASE=Zamir Recognition Systems Ltd.
+
+OUI:70B3D5DA4*
+ ID_OUI_FROM_DATABASE=CRDE
+
+OUI:70B3D5CC9*
+ ID_OUI_FROM_DATABASE=Rapiscan Systems
+
+OUI:70B3D52D0*
+ ID_OUI_FROM_DATABASE=ijin co.,ltd.
+
+OUI:70B3D50A0*
+ ID_OUI_FROM_DATABASE=Cominfo, Inc.
+
+OUI:70B3D520F*
+ ID_OUI_FROM_DATABASE=Tieline Research Pty Ltd
+
+OUI:70B3D5C20*
+ ID_OUI_FROM_DATABASE=Mipot S.p.a.
+
+OUI:70B3D54D5*
+ ID_OUI_FROM_DATABASE=Moog Rekofa GmbH
+
+OUI:70B3D5D3C*
+ ID_OUI_FROM_DATABASE=HRT
+
+OUI:70B3D5DDB*
+ ID_OUI_FROM_DATABASE=Intra Corporation
+
+OUI:70B3D58EE*
+ ID_OUI_FROM_DATABASE=Network Additions
+
+OUI:70B3D5445*
+ ID_OUI_FROM_DATABASE=Advanced Devices SpA
+
+OUI:70B3D5674*
+ ID_OUI_FROM_DATABASE=Fortress Cyber Security
+
+OUI:70B3D5FFF*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:70B3D5DB8*
+ ID_OUI_FROM_DATABASE=SISTEM SA
+
+OUI:70B3D5FBC*
+ ID_OUI_FROM_DATABASE=Twoway Communications, Inc.
+
+OUI:70B3D5969*
+ ID_OUI_FROM_DATABASE=Emtel System Sp. z o.o.
+
+OUI:70B3D5C33*
+ ID_OUI_FROM_DATABASE=Dandong Dongfang Measurement & Control Technology Co., Ltd.
+
+OUI:70B3D5B2E*
+ ID_OUI_FROM_DATABASE=Green Access Ltd
+
+OUI:70B3D558C*
+ ID_OUI_FROM_DATABASE=OPTSYS
+
+OUI:70B3D595B*
+ ID_OUI_FROM_DATABASE=SRS Group s.r.o.
+
+OUI:70B3D534E*
+ ID_OUI_FROM_DATABASE=Risk Expert sarl
+
+OUI:70B3D56AD*
+ ID_OUI_FROM_DATABASE=CONNIT
+
+OUI:70B3D5C14*
+ ID_OUI_FROM_DATABASE=Grupo Epelsa S.L.
+
+OUI:70B3D5631*
+ ID_OUI_FROM_DATABASE=SENSO2ME bvba
+
+OUI:70B3D5C53*
+ ID_OUI_FROM_DATABASE=S Labs sp. z o.o.
+
+OUI:70B3D5F24*
+ ID_OUI_FROM_DATABASE=Daavlin
+
+OUI:70B3D56E7*
+ ID_OUI_FROM_DATABASE=AML
+
+OUI:70B3D577B*
+ ID_OUI_FROM_DATABASE=AeroVision Avionics, Inc.
+
+OUI:70B3D504E*
+ ID_OUI_FROM_DATABASE=HUGEL GmbH
+
+OUI:70B3D5319*
+ ID_OUI_FROM_DATABASE=ISO/TC 22/SC 31
+
+OUI:70B3D5844*
+ ID_OUI_FROM_DATABASE=SANSFIL Technologies
+
+OUI:70B3D5826*
+ ID_OUI_FROM_DATABASE=Elbit Systems of Amerixca
+
+OUI:70B3D5C42*
+ ID_OUI_FROM_DATABASE=CRDE
+
+OUI:70B3D5557*
+ ID_OUI_FROM_DATABASE=HEITEC AG
+
+OUI:70B3D568C*
+ ID_OUI_FROM_DATABASE=ND METER
+
+OUI:70B3D5727*
+ ID_OUI_FROM_DATABASE=LP Technologies Inc.
+
+OUI:70B3D549B*
+ ID_OUI_FROM_DATABASE=Algodue Elettronica Srl
+
+OUI:70B3D57F9*
+ ID_OUI_FROM_DATABASE=CSS Inc.
+
+OUI:70B3D592B*
+ ID_OUI_FROM_DATABASE=ENTEC Electric & Electronic Co., LTD.
+
+OUI:70B3D5B13*
+ ID_OUI_FROM_DATABASE=Omwave
+
+OUI:70B3D5EA7*
+ ID_OUI_FROM_DATABASE=S.I.C.E.S. srl
+
OUI:70B3D566B*
ID_OUI_FROM_DATABASE=Innitive B.V.
@@ -3698,9 +4151,6 @@ OUI:70B3D5435*
OUI:70B3D50CD*
ID_OUI_FROM_DATABASE=AML Oceanographic
-OUI:70B3D56E8*
- ID_OUI_FROM_DATABASE=BluWireless Technology Ltd
-
OUI:70B3D56B3*
ID_OUI_FROM_DATABASE=DuraComm Corporation
@@ -4232,9 +4682,6 @@ OUI:70B3D5528*
OUI:70B3D5B81*
ID_OUI_FROM_DATABASE=Instro Precision Limited
-OUI:70B3D5479*
- ID_OUI_FROM_DATABASE=LINEAGE POWER PVT. LTD.
-
OUI:70B3D5A66*
ID_OUI_FROM_DATABASE=Trapeze Software Group Inc
@@ -4712,6 +5159,126 @@ OUI:70B3D5138*
OUI:70B3D517A*
ID_OUI_FROM_DATABASE=Gencoa Ltd
+OUI:70B3D5C49*
+ ID_OUI_FROM_DATABASE=BTG Instruments AB
+
+OUI:70B3D530B*
+ ID_OUI_FROM_DATABASE=Ash Technologies
+
+OUI:70B3D56A6*
+ ID_OUI_FROM_DATABASE=WOW System
+
+OUI:70B3D5FEF*
+ ID_OUI_FROM_DATABASE=HANGZHOU HUALAN MICROELECTRONIQUE CO.,LTD
+
+OUI:70B3D5211*
+ ID_OUI_FROM_DATABASE=Fracarro srl
+
+OUI:70B3D560A*
+ ID_OUI_FROM_DATABASE=TATA POWER SED
+
+OUI:70B3D5129*
+ ID_OUI_FROM_DATABASE=OOO Microlink-Svyaz
+
+OUI:70B3D5479*
+ ID_OUI_FROM_DATABASE=LINEAGE POWER PVT LTD.,
+
+OUI:70B3D564C*
+ ID_OUI_FROM_DATABASE=ACEMIS FRANCE
+
+OUI:70B3D5763*
+ ID_OUI_FROM_DATABASE=A Trap, USA
+
+OUI:70B3D5175*
+ ID_OUI_FROM_DATABASE=Akribis Systems
+
+OUI:70B3D547F*
+ ID_OUI_FROM_DATABASE=ASE GmbH
+
+OUI:70B3D5DC9*
+ ID_OUI_FROM_DATABASE=Sensoterra BV
+
+OUI:70B3D5371*
+ ID_OUI_FROM_DATABASE=BEDEROV GmbH
+
+OUI:70B3D559C*
+ ID_OUI_FROM_DATABASE=DAVE SRL
+
+OUI:70B3D5C79*
+ ID_OUI_FROM_DATABASE=MB connect line GmbH Fernwartungssysteme
+
+OUI:70B3D5B04*
+ ID_OUI_FROM_DATABASE=Herrmann Datensysteme GmbH
+
+OUI:70B3D5229*
+ ID_OUI_FROM_DATABASE=CONTROL SYSTEMS Srl
+
+OUI:70B3D555E*
+ ID_OUI_FROM_DATABASE=BRS Sistemas Eletrônicos
+
+OUI:70B3D5EE3*
+ ID_OUI_FROM_DATABASE=Lithe Technology, LLC
+
+OUI:70B3D5D69*
+ ID_OUI_FROM_DATABASE=Thermo Fisher Scientific
+
+OUI:70B3D5FA0*
+ ID_OUI_FROM_DATABASE=TIAMA
+
+OUI:70B3D57DF*
+ ID_OUI_FROM_DATABASE=RDT Ltd
+
+OUI:70B3D508D*
+ ID_OUI_FROM_DATABASE=Clover Electronics Technology Co., Ltd.
+
+OUI:70B3D57D2*
+ ID_OUI_FROM_DATABASE=SDK Kristall
+
+OUI:70B3D5AF0*
+ ID_OUI_FROM_DATABASE=SEASON DESIGN TECHNOLOGY
+
+OUI:70B3D5D6C*
+ ID_OUI_FROM_DATABASE=GP Systems GmbH
+
+OUI:70B3D56AF*
+ ID_OUI_FROM_DATABASE=Sensorberg GmbH
+
+OUI:70B3D518E*
+ ID_OUI_FROM_DATABASE=NIPPON SEIKI CO., LTD.
+
+OUI:70B3D5C0C*
+ ID_OUI_FROM_DATABASE=Tech4Race
+
+OUI:70B3D55D8*
+ ID_OUI_FROM_DATABASE=LYNX Technik AG
+
+OUI:70B3D5374*
+ ID_OUI_FROM_DATABASE=OOO NPP Mars-Energo
+
+OUI:70B3D54A5*
+ ID_OUI_FROM_DATABASE=Intermind Inc.
+
+OUI:70B3D5C1D*
+ ID_OUI_FROM_DATABASE=Kranze Technology Solutions
+
+OUI:70B3D5CC3*
+ ID_OUI_FROM_DATABASE=Fidalia Networks Inc
+
+OUI:70B3D507F*
+ ID_OUI_FROM_DATABASE=Abalance Corporation
+
+OUI:70B3D56E8*
+ ID_OUI_FROM_DATABASE=Blu Wireless Technology Ltd
+
+OUI:70B3D5CD3*
+ ID_OUI_FROM_DATABASE=Controlrad
+
+OUI:70B3D54E5*
+ ID_OUI_FROM_DATABASE=viZaar industrial imaging AG
+
+OUI:70B3D5DE6*
+ ID_OUI_FROM_DATABASE=MB connect line GmbH Fernwartungssysteme
+
OUI:70B3D58AB*
ID_OUI_FROM_DATABASE=EMAC, Inc.
@@ -5192,9 +5759,6 @@ OUI:70B3D53C2*
OUI:70B3D5EF9*
ID_OUI_FROM_DATABASE=Critical Link
-OUI:001BC50B2*
- ID_OUI_FROM_DATABASE=SKODA electric a.s.
-
OUI:001BC50B6*
ID_OUI_FROM_DATABASE=Veilux inc.
@@ -5726,12 +6290,12 @@ OUI:70B3D520D*
OUI:70B3D5D55*
ID_OUI_FROM_DATABASE=WM Design s.r.o
-OUI:70B3D5523*
- ID_OUI_FROM_DATABASE=Tibit Communications
-
OUI:70B3D5E67*
ID_OUI_FROM_DATABASE=APPLIED PROCESSING
+OUI:70B3D5523*
+ ID_OUI_FROM_DATABASE=Tibit Communications
+
OUI:70B3D5241*
ID_OUI_FROM_DATABASE=Bolide Technology Group, Inc.
@@ -5762,15 +6326,15 @@ OUI:70B3D5A05*
OUI:70B3D5AA6*
ID_OUI_FROM_DATABASE=Proximus
+OUI:70B3D51D4*
+ ID_OUI_FROM_DATABASE=Brinkmann Audio GmbH
+
OUI:70B3D55E5*
ID_OUI_FROM_DATABASE=HAIYANG OLIX CO.,LTD.
OUI:70B3D5E2C*
ID_OUI_FROM_DATABASE=Fourth Frontier Technologies Private Limited
-OUI:70B3D51D4*
- ID_OUI_FROM_DATABASE=Brinkmann Audio GmbH
-
OUI:70B3D55CA*
ID_OUI_FROM_DATABASE=ACD Elekronik GmbH
@@ -5804,12 +6368,12 @@ OUI:70B3D5EC8*
OUI:70B3D53F0*
ID_OUI_FROM_DATABASE=Intervala
-OUI:70B3D5B1A*
- ID_OUI_FROM_DATABASE=Aaronia AG
-
OUI:70B3D5BD1*
ID_OUI_FROM_DATABASE=CableLabs
+OUI:70B3D5B1A*
+ ID_OUI_FROM_DATABASE=Aaronia AG
+
OUI:70B3D5F0D*
ID_OUI_FROM_DATABASE=MeQ Inc.
@@ -5852,6 +6416,138 @@ OUI:70B3D5442*
OUI:70B3D5C74*
ID_OUI_FROM_DATABASE=Qtechnology A/S
+OUI:70B3D5E16*
+ ID_OUI_FROM_DATABASE=China Entropy Co., Ltd.
+
+OUI:70B3D502E*
+ ID_OUI_FROM_DATABASE=Monnit Corporation
+
+OUI:70B3D5370*
+ ID_OUI_FROM_DATABASE=Inphi Corporation
+
+OUI:70B3D57E8*
+ ID_OUI_FROM_DATABASE=Mannkind Corporation
+
+OUI:70B3D53F3*
+ ID_OUI_FROM_DATABASE=SPEA SPA
+
+OUI:70B3D5549*
+ ID_OUI_FROM_DATABASE=Procon automatic systems GmbH
+
+OUI:70B3D5831*
+ ID_OUI_FROM_DATABASE=Arnouse Digital Devices Corp
+
+OUI:70B3D5D8E*
+ ID_OUI_FROM_DATABASE=Axatel SrL
+
+OUI:70B3D5A28*
+ ID_OUI_FROM_DATABASE=PEEK TRAFFIC
+
+OUI:70B3D5AC7*
+ ID_OUI_FROM_DATABASE=vivaMOS
+
+OUI:70B3D5DB2*
+ ID_OUI_FROM_DATABASE=Micro Electroninc Products
+
+OUI:70B3D5967*
+ ID_OUI_FROM_DATABASE=TATTILE SRL
+
+OUI:70B3D5C16*
+ ID_OUI_FROM_DATABASE=Southern Innovation
+
+OUI:70B3D590F*
+ ID_OUI_FROM_DATABASE=DTRON Communications (Pty) Ltd
+
+OUI:70B3D5E22*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:70B3D5408*
+ ID_OUI_FROM_DATABASE=Comrod AS
+
+OUI:70B3D5945*
+ ID_OUI_FROM_DATABASE=Symboticware Incorporated
+
+OUI:70B3D5D4D*
+ ID_OUI_FROM_DATABASE=The Morey Corporation
+
+OUI:70B3D5192*
+ ID_OUI_FROM_DATABASE=ASPT, INC.
+
+OUI:70B3D5807*
+ ID_OUI_FROM_DATABASE=Camsat Przemysław Gralak
+
+OUI:70B3D5DD1*
+ ID_OUI_FROM_DATABASE=em-tec GmbH
+
+OUI:70B3D5ED1*
+ ID_OUI_FROM_DATABASE=Przemyslowy Instytut Automatyki i Pomiarow
+
+OUI:70B3D514A*
+ ID_OUI_FROM_DATABASE=ExSens Technology (Pty) Ltd.
+
+OUI:70B3D5A69*
+ ID_OUI_FROM_DATABASE=Leviathan Solutions Ltd.
+
+OUI:70B3D5A9A*
+ ID_OUI_FROM_DATABASE=Amphenol Advanced Sensors
+
+OUI:70B3D5715*
+ ID_OUI_FROM_DATABASE=RIOT
+
+OUI:70B3D5FF8*
+ ID_OUI_FROM_DATABASE=Dutile, Glines and Higgins Corporation
+
+OUI:70B3D5413*
+ ID_OUI_FROM_DATABASE=Axess AG
+
+OUI:70B3D5E5E*
+ ID_OUI_FROM_DATABASE=Critical Link LLC
+
+OUI:70B3D5E7D*
+ ID_OUI_FROM_DATABASE=Nanjing Dandick Science&technology development co., LTD
+
+OUI:70B3D5D98*
+ ID_OUI_FROM_DATABASE=ACD Elekronik GmbH
+
+OUI:70B3D5FA6*
+ ID_OUI_FROM_DATABASE=RFL Electronics, Inc.
+
+OUI:70B3D5D43*
+ ID_OUI_FROM_DATABASE=EZSYS Co., Ltd.
+
+OUI:70B3D5A35*
+ ID_OUI_FROM_DATABASE=Sicon srl
+
+OUI:70B3D5359*
+ ID_OUI_FROM_DATABASE=Boutronic
+
+OUI:70B3D5279*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:001BC50B2*
+ ID_OUI_FROM_DATABASE=SKODA ELECTRIC a.s.
+
+OUI:70B3D5035*
+ ID_OUI_FROM_DATABASE=HKW-Elektronik GmbH
+
+OUI:70B3D5DFA*
+ ID_OUI_FROM_DATABASE=Newtouch Electronics (Shanghai) Co.,Ltd.
+
+OUI:70B3D5EC7*
+ ID_OUI_FROM_DATABASE=Neoptix Inc.
+
+OUI:70B3D55B8*
+ ID_OUI_FROM_DATABASE=Hella Gutmann Solutions GmbH
+
+OUI:70B3D5203*
+ ID_OUI_FROM_DATABASE=WOOJIN Inc
+
+OUI:70B3D5845*
+ ID_OUI_FROM_DATABASE=Harborside Technology
+
+OUI:70B3D52F4*
+ ID_OUI_FROM_DATABASE=Radixon s.r.o.
+
OUI:1C8776D*
ID_OUI_FROM_DATABASE=Qivivo
@@ -6110,9 +6806,6 @@ OUI:28FD803*
OUI:E818635*
ID_OUI_FROM_DATABASE=WETEK ELECTRONICS LIMITED
-OUI:E818632*
- ID_OUI_FROM_DATABASE=AVCON Information Technology Co.,Ltd
-
OUI:B8D812D*
ID_OUI_FROM_DATABASE=Lam Research
@@ -6368,9 +7061,6 @@ OUI:CCD31E3*
OUI:D0D94F9*
ID_OUI_FROM_DATABASE=Hangzhou xiaoben technology co.,Ltd
-OUI:D0D94F7*
- ID_OUI_FROM_DATABASE=Private
-
OUI:D0D94F0*
ID_OUI_FROM_DATABASE=Perfant Technology Co., Ltd
@@ -6392,39 +7082,18 @@ OUI:283638A*
OUI:CC1BE0F*
ID_OUI_FROM_DATABASE=Private
-OUI:F40E11F*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:D07650F*
- ID_OUI_FROM_DATABASE=Private
-
OUI:E81863F*
ID_OUI_FROM_DATABASE=Private
-OUI:F80278F*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:9802D8F*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:90C682F*
- ID_OUI_FROM_DATABASE=Private
-
OUI:283638D*
ID_OUI_FROM_DATABASE=APPEAK Technology System Co.Ltd.
-OUI:1CCAE3F*
- ID_OUI_FROM_DATABASE=Private
-
OUI:2836389*
ID_OUI_FROM_DATABASE=Shenzhen Zhi Hua Creative Technology Co., Ltd.
OUI:B0C5CA7*
ID_OUI_FROM_DATABASE=SHENZHEN KTC TECHNOLOGY GROUP
-OUI:283638E*
- ID_OUI_FROM_DATABASE=SCA Hygiene Products AB
-
OUI:F0ACD73*
ID_OUI_FROM_DATABASE=Med-Pat/Inn-Phone
@@ -6611,12 +7280,12 @@ OUI:40F3854*
OUI:40F3859*
ID_OUI_FROM_DATABASE=Fast Precision Technologies Co. Ltd.
-OUI:1CA0D32*
- ID_OUI_FROM_DATABASE=NovTech, Inc.
-
OUI:40F3850*
ID_OUI_FROM_DATABASE=SubPac
+OUI:1CA0D32*
+ ID_OUI_FROM_DATABASE=NovTech, Inc.
+
OUI:38FDFEC*
ID_OUI_FROM_DATABASE=New Garden Co., Ltd.
@@ -6656,12 +7325,12 @@ OUI:98AAFC8*
OUI:98AAFCC*
ID_OUI_FROM_DATABASE=dots Inc.
-OUI:08ED026*
- ID_OUI_FROM_DATABASE=SANGO ELECTRONICS CO
-
OUI:08ED023*
ID_OUI_FROM_DATABASE=Jiangsu Logread Network Technology Co., LTD.
+OUI:08ED026*
+ ID_OUI_FROM_DATABASE=SANGO ELECTRONICS CO
+
OUI:08ED024*
ID_OUI_FROM_DATABASE=Fio Corporation
@@ -6695,6 +7364,162 @@ OUI:8C147DC*
OUI:8C147D0*
ID_OUI_FROM_DATABASE=Nio
+OUI:A0C5F26*
+ ID_OUI_FROM_DATABASE=ShenZhen JuWangShi Tech
+
+OUI:A0C5F22*
+ ID_OUI_FROM_DATABASE=Speedgoat GmbH
+
+OUI:A0C5F24*
+ ID_OUI_FROM_DATABASE=AiCare Corp.
+
+OUI:4C65A8A*
+ ID_OUI_FROM_DATABASE=Suzhou Embedded Electronic Technology Co., Ltd.
+
+OUI:F88A3C8*
+ ID_OUI_FROM_DATABASE=Cadmus Electronic Co.,Ltd.
+
+OUI:7CBACCB*
+ ID_OUI_FROM_DATABASE=Briowireless Inc.
+
+OUI:7CBACC3*
+ ID_OUI_FROM_DATABASE=Izkare
+
+OUI:F40E11F*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:78D8001*
+ ID_OUI_FROM_DATABASE=Shenzhen Envicool Information Technology Co., Ltd
+
+OUI:78D8003*
+ ID_OUI_FROM_DATABASE=Shenzhen Scodeno Technology Co,. Ltd.
+
+OUI:78D8007*
+ ID_OUI_FROM_DATABASE=NimbeLink Corp
+
+OUI:78D800A*
+ ID_OUI_FROM_DATABASE=Insignal Co., Ltd.
+
+OUI:78D8008*
+ ID_OUI_FROM_DATABASE=Salunda Ltd
+
+OUI:78D800E*
+ ID_OUI_FROM_DATABASE=CL International
+
+OUI:28F5378*
+ ID_OUI_FROM_DATABASE=1MORE, INC.
+
+OUI:28F5379*
+ ID_OUI_FROM_DATABASE=Herbert Waldmann GmbH & Co. KG
+
+OUI:28F5375*
+ ID_OUI_FROM_DATABASE=Atomrock LLC
+
+OUI:1CCAE3F*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:90C682F*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:9802D8F*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:F80278F*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:D07650F*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:28F537C*
+ ID_OUI_FROM_DATABASE=Matricx Singapore Pte Ltd
+
+OUI:28F537B*
+ ID_OUI_FROM_DATABASE=LogiM GmbH Software und Entwicklung
+
+OUI:E818632*
+ ID_OUI_FROM_DATABASE=AVCON Information Technology Co.,Ltd
+
+OUI:34298F6*
+ ID_OUI_FROM_DATABASE=Bellman & Symfon
+
+OUI:34298F5*
+ ID_OUI_FROM_DATABASE=Highlite International B.V.
+
+OUI:34298FC*
+ ID_OUI_FROM_DATABASE=Albert Handtmann Maschinenfabrik GmbH&Co.KG
+
+OUI:34298F8*
+ ID_OUI_FROM_DATABASE=Nanjing Sandemarine Electric Co.,Ltd
+
+OUI:189BA5A*
+ ID_OUI_FROM_DATABASE=SHENZHEN FIONEXX TECHNOLOGIES LTD.
+
+OUI:189BA57*
+ ID_OUI_FROM_DATABASE=Beijing Xinertel Technology Co., Ltd.
+
+OUI:904E915*
+ ID_OUI_FROM_DATABASE=mcf88 SRL
+
+OUI:904E917*
+ ID_OUI_FROM_DATABASE=IBM
+
+OUI:904E916*
+ ID_OUI_FROM_DATABASE=Nuwa Robotics (HK) Limited Taiwan Branch
+
+OUI:904E910*
+ ID_OUI_FROM_DATABASE=Spirtech
+
+OUI:2C279ED*
+ ID_OUI_FROM_DATABASE=Jiangsu JianHu Science & Technology Co., Ltd.
+
+OUI:904E91E*
+ ID_OUI_FROM_DATABASE=Shenzhen Cloudynamo Internet Technologies Co.,LTD.
+
+OUI:2C279E0*
+ ID_OUI_FROM_DATABASE=Changzhou WEBO Weighing Device & System CO.,LTD
+
+OUI:904E91D*
+ ID_OUI_FROM_DATABASE=SKODA ELECTRIC a.s.
+
+OUI:2C279EC*
+ ID_OUI_FROM_DATABASE=WAYCOM Technology Co.,Ltd
+
+OUI:283638E*
+ ID_OUI_FROM_DATABASE=SCA Hygiene Products AB
+
+OUI:2C279E2*
+ ID_OUI_FROM_DATABASE=Kunyi electronic technology (Shanghai) Co., Ltd.
+
+OUI:2C279E9*
+ ID_OUI_FROM_DATABASE=octoScope, Inc.
+
+OUI:D0D94F7*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:CC2237C*
+ ID_OUI_FROM_DATABASE=Hebei ZHSF Technology Co.,Ltd.
+
+OUI:CC2237A*
+ ID_OUI_FROM_DATABASE=shenzhen zonglian network technology limited
+
+OUI:CC22375*
+ ID_OUI_FROM_DATABASE=Beijing Safesoft Greatmaker Co.,ltd
+
+OUI:CC22378*
+ ID_OUI_FROM_DATABASE=Safilo S.p.A.
+
+OUI:741AE00*
+ ID_OUI_FROM_DATABASE=Huano International Technology Limited
+
+OUI:741AE07*
+ ID_OUI_FROM_DATABASE=BÄR Bahnsicherung AG
+
+OUI:741AE01*
+ ID_OUI_FROM_DATABASE=Socionext Inc.
+
+OUI:741AE0A*
+ ID_OUI_FROM_DATABASE=SAIERCOM CORPORATION
+
OUI:1C8776C*
ID_OUI_FROM_DATABASE=Strone Technology
@@ -6755,9 +7580,6 @@ OUI:CC1BE0B*
OUI:CC1BE07*
ID_OUI_FROM_DATABASE=Sichuan Dianjia network technology Co.Ltd.
-OUI:CC1BE00*
- ID_OUI_FROM_DATABASE=MICROTECH SYSTEM
-
OUI:DC44270*
ID_OUI_FROM_DATABASE=Suritel
@@ -7265,9 +8087,6 @@ OUI:C0D3916*
OUI:C0D3912*
ID_OUI_FROM_DATABASE=Hofon Automation Co.,Ltd
-OUI:C0D391B*
- ID_OUI_FROM_DATABASE=Private
-
OUI:84E0F40*
ID_OUI_FROM_DATABASE=ShenZhen Panrich Technology Limited
@@ -7322,9 +8141,6 @@ OUI:D02212F*
OUI:100723F*
ID_OUI_FROM_DATABASE=Private
-OUI:B0C5CAF*
- ID_OUI_FROM_DATABASE=Private
-
OUI:2836383*
ID_OUI_FROM_DATABASE=Sabinetek
@@ -7334,15 +8150,6 @@ OUI:2836380*
OUI:8C192D7*
ID_OUI_FROM_DATABASE=SRETT
-OUI:7C70BCF*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:A43BFAF*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:B01F81F*
- ID_OUI_FROM_DATABASE=Private
-
OUI:0055DAF*
ID_OUI_FROM_DATABASE=Private
@@ -7472,15 +8279,15 @@ OUI:40F3855*
OUI:1CA0D35*
ID_OUI_FROM_DATABASE=Dynamic Connect (Suzhou) Hi-Tech Electronic Co.,Ltd.
-OUI:1CA0D33*
- ID_OUI_FROM_DATABASE=SAVELEC
-
OUI:1CA0D37*
ID_OUI_FROM_DATABASE=Private
OUI:A411634*
ID_OUI_FROM_DATABASE=AlterG, Inc.
+OUI:1CA0D33*
+ ID_OUI_FROM_DATABASE=SAVELEC
+
OUI:A411631*
ID_OUI_FROM_DATABASE=INTER CONTROL Hermann Köhler Elektrik GmbH & Co.KG
@@ -7520,24 +8327,141 @@ OUI:60D7E31*
OUI:04714B1*
ID_OUI_FROM_DATABASE=uAvionix Corporation
-OUI:04714B2*
- ID_OUI_FROM_DATABASE=Shenzhen WayOS Technology Crop., Ltd.
-
OUI:04714B8*
ID_OUI_FROM_DATABASE=Energport Inc
-OUI:8C147D5*
- ID_OUI_FROM_DATABASE=Unwired Networks
-
OUI:F023B94*
ID_OUI_FROM_DATABASE=EZVIS LIMITED
OUI:F023B9A*
ID_OUI_FROM_DATABASE=annapurnalabs
+OUI:8C147D5*
+ ID_OUI_FROM_DATABASE=Unwired Networks
+
OUI:8C147D2*
ID_OUI_FROM_DATABASE=Agilent S.p.A
+OUI:8C147DE*
+ ID_OUI_FROM_DATABASE=Electrical & Automation Larsen & Toubro Limited
+
+OUI:A0C5F29*
+ ID_OUI_FROM_DATABASE=Impulse Networks Pte Ltd
+
+OUI:A0C5F2B*
+ ID_OUI_FROM_DATABASE=Oray.com co., LTD.
+
+OUI:4C65A89*
+ ID_OUI_FROM_DATABASE=SHENZHEN LISAIER TRONICS CO.,LTD
+
+OUI:4C65A86*
+ ID_OUI_FROM_DATABASE=Nuviz Oy
+
+OUI:A0C5F23*
+ ID_OUI_FROM_DATABASE=Shenzhen Feima Robotics Technology Co.,Ltd
+
+OUI:7C70BCF*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:B01F81F*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:7CBACC5*
+ ID_OUI_FROM_DATABASE=Fortem Technologies, Inc.
+
+OUI:78D8006*
+ ID_OUI_FROM_DATABASE=Alango Technologies Ltd
+
+OUI:78D800C*
+ ID_OUI_FROM_DATABASE=Shenzhen Chenzhuo Technology Co., Ltd.
+
+OUI:28F5374*
+ ID_OUI_FROM_DATABASE=Phyn LLC
+
+OUI:A43BFAF*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:28F5376*
+ ID_OUI_FROM_DATABASE=MyOmega Systems GmbH
+
+OUI:28F5377*
+ ID_OUI_FROM_DATABASE=Shenzhen Modern Cowboy Technology Co.,Ltd.
+
+OUI:28F537A*
+ ID_OUI_FROM_DATABASE=Honeywell Safety Products USA, Inc
+
+OUI:B0C5CAF*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:34008A4*
+ ID_OUI_FROM_DATABASE=Fotonic i Norden AB
+
+OUI:34008A7*
+ ID_OUI_FROM_DATABASE=uberGARD Pte. Ltd.
+
+OUI:34008A8*
+ ID_OUI_FROM_DATABASE=Shenzhen Andakai Technologies Co., Ltd.
+
+OUI:34008A0*
+ ID_OUI_FROM_DATABASE=Angee Technologies Ltd.
+
+OUI:34008AC*
+ ID_OUI_FROM_DATABASE=Shenzhen Eternal Idea Tech Co.,Ltd
+
+OUI:34298F0*
+ ID_OUI_FROM_DATABASE=BlackEdge Capital
+
+OUI:34298F1*
+ ID_OUI_FROM_DATABASE=Chengdu Meross Technology Co., Ltd.
+
+OUI:CC1BE00*
+ ID_OUI_FROM_DATABASE=Microtech System,Inc
+
+OUI:189BA56*
+ ID_OUI_FROM_DATABASE=Mantra Softech India Pvt Ltd
+
+OUI:189BA52*
+ ID_OUI_FROM_DATABASE=Airprotec
+
+OUI:189BA50*
+ ID_OUI_FROM_DATABASE=Dectris Ltd.
+
+OUI:189BA5B*
+ ID_OUI_FROM_DATABASE=Eutron SPA
+
+OUI:189BA58*
+ ID_OUI_FROM_DATABASE=Shenzhen Tong Tai Yi information Technology Co.,Ltd
+
+OUI:C0D391B*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:904E918*
+ ID_OUI_FROM_DATABASE=CommandScape, Inc.
+
+OUI:2C279E6*
+ ID_OUI_FROM_DATABASE=Rutledge Omni Services Pte Ltd
+
+OUI:CC22372*
+ ID_OUI_FROM_DATABASE=Apeiron Data Systems
+
+OUI:04714B2*
+ ID_OUI_FROM_DATABASE=Shenzhen WayOS Technology Crop., Ltd.
+
+OUI:741AE04*
+ ID_OUI_FROM_DATABASE=Revl Inc.
+
+OUI:741AE09*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:741AE0B*
+ ID_OUI_FROM_DATABASE=SHEN ZHEN YINGJIACHUANG ELECTRONICS TECHNOLOGY CO.,LTD.
+
+OUI:741AE05*
+ ID_OUI_FROM_DATABASE=FUJIAN TAILI COMMUNICATION TECHNOLOGY CO.,LTD
+
+OUI:741AE0C*
+ ID_OUI_FROM_DATABASE=bistos.co.ltd
+
OUI:1C87765*
ID_OUI_FROM_DATABASE=Zhuhai MYZR Technology Co.,Ltd
@@ -7826,9 +8750,6 @@ OUI:2C265F0*
OUI:F80278D*
ID_OUI_FROM_DATABASE=Dueton Systems s.r.o.
-OUI:0CEFAFB*
- ID_OUI_FROM_DATABASE=Hubei Century Network Technology Co .Ltd
-
OUI:A44F291*
ID_OUI_FROM_DATABASE=Olssen B.V.
@@ -8135,27 +9056,12 @@ OUI:8C192DC*
OUI:8C192D9*
ID_OUI_FROM_DATABASE=ViaWear, Inc.
-OUI:BC3400F*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:7419F8F*
- ID_OUI_FROM_DATABASE=Private
-
OUI:1C21D1F*
ID_OUI_FROM_DATABASE=Private
-OUI:DC4427F*
- ID_OUI_FROM_DATABASE=Private
-
OUI:C88ED1F*
ID_OUI_FROM_DATABASE=Private
-OUI:80E4DAF*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:885D90F*
- ID_OUI_FROM_DATABASE=Private
-
OUI:2836385*
ID_OUI_FROM_DATABASE=CHARGELIB
@@ -8342,12 +9248,12 @@ OUI:1CA0D3B*
OUI:1CA0D3D*
ID_OUI_FROM_DATABASE=ERATO (HK) Corporation Limited
-OUI:1CA0D3A*
- ID_OUI_FROM_DATABASE=DSM Messtechnik GmbH
-
OUI:1CA0D38*
ID_OUI_FROM_DATABASE=Desarrollos y Soluciones Guinea I+D S.L.
+OUI:1CA0D3A*
+ ID_OUI_FROM_DATABASE=DSM Messtechnik GmbH
+
OUI:A411638*
ID_OUI_FROM_DATABASE=Dspread Technology (Beijing) Inc.
@@ -8357,12 +9263,12 @@ OUI:A411639*
OUI:A41163A*
ID_OUI_FROM_DATABASE=ISE GmbH
-OUI:A411635*
- ID_OUI_FROM_DATABASE=Carbon, Inc.
-
OUI:4CE1731*
ID_OUI_FROM_DATABASE=Nexoforge Inc.
+OUI:A411635*
+ ID_OUI_FROM_DATABASE=Carbon, Inc.
+
OUI:144FD70*
ID_OUI_FROM_DATABASE=annapurnalabs
@@ -8417,6 +9323,129 @@ OUI:F023B99*
OUI:F023B91*
ID_OUI_FROM_DATABASE=Ubiant
+OUI:8C147D7*
+ ID_OUI_FROM_DATABASE=UrbanHello
+
+OUI:8C147D9*
+ ID_OUI_FROM_DATABASE=Anyware Solutions ApS
+
+OUI:A0C5F27*
+ ID_OUI_FROM_DATABASE=Viettronimex JSC
+
+OUI:A0C5F25*
+ ID_OUI_FROM_DATABASE=Tango Wave
+
+OUI:A0C5F2C*
+ ID_OUI_FROM_DATABASE=Glooko inc
+
+OUI:4C65A83*
+ ID_OUI_FROM_DATABASE=Roost
+
+OUI:4C65A8D*
+ ID_OUI_FROM_DATABASE=Qingping Technology (Beijing) Co., Ltd.
+
+OUI:F88A3C4*
+ ID_OUI_FROM_DATABASE=GO-LINK TECHNOLOGY CO., LTD.
+
+OUI:F88A3C0*
+ ID_OUI_FROM_DATABASE=ART SPA
+
+OUI:F88A3CE*
+ ID_OUI_FROM_DATABASE=Avateq Corp.
+
+OUI:F88A3CA*
+ ID_OUI_FROM_DATABASE=Protos GmbH
+
+OUI:7CBACC0*
+ ID_OUI_FROM_DATABASE=TGT Limited
+
+OUI:7CBACCA*
+ ID_OUI_FROM_DATABASE=annapurnalabs
+
+OUI:7CBACC4*
+ ID_OUI_FROM_DATABASE=Sun Asia Trade Co.
+
+OUI:885D90F*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:BC3400F*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:28F537D*
+ ID_OUI_FROM_DATABASE=Skyrockettoys LLC
+
+OUI:7419F8F*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:80E4DAF*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:28F5373*
+ ID_OUI_FROM_DATABASE=PRIMETECH ENGINEERING CORP.
+
+OUI:34008A2*
+ ID_OUI_FROM_DATABASE=RPE Monitor
+
+OUI:0CEFAFB*
+ ID_OUI_FROM_DATABASE=Hubei Century Network Technology Co., Ltd
+
+OUI:34008AB*
+ ID_OUI_FROM_DATABASE=Project Engineering srl
+
+OUI:34298FA*
+ ID_OUI_FROM_DATABASE=Virtual Trunk Pte Ltd
+
+OUI:DC4427F*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:189BA5C*
+ ID_OUI_FROM_DATABASE=Christ Electronic System GmbH
+
+OUI:189BA59*
+ ID_OUI_FROM_DATABASE=APANA Inc.
+
+OUI:189BA51*
+ ID_OUI_FROM_DATABASE=ChengDu Vantron Technology, Ltd.
+
+OUI:189BA5D*
+ ID_OUI_FROM_DATABASE=legendsky tech
+
+OUI:904E911*
+ ID_OUI_FROM_DATABASE=Apollo Video Technology
+
+OUI:904E91B*
+ ID_OUI_FROM_DATABASE=Shanghai JaWay Information Technology Co., Ltd.
+
+OUI:904E912*
+ ID_OUI_FROM_DATABASE=North Pole Engineering, Inc.
+
+OUI:2C279E3*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:2C279EA*
+ ID_OUI_FROM_DATABASE=Exegy Inc
+
+OUI:2C279E1*
+ ID_OUI_FROM_DATABASE=Electronique Bluewave Inc.
+
+OUI:2C279E8*
+ ID_OUI_FROM_DATABASE=Institut Dr. Foerster GmbH & Co. KG
+
+OUI:CC2237D*
+ ID_OUI_FROM_DATABASE=SHENZHEN HOOENERGY TECHNOLOGY CO.,LTD
+
+OUI:CC22371*
+ ID_OUI_FROM_DATABASE=Terma Sp. z o.o.
+
+OUI:CC2237B*
+ ID_OUI_FROM_DATABASE=Tolomatic, Inc.
+
+OUI:AC1DDF6*
+ ID_OUI_FROM_DATABASE=Shenzheng SenseTime Technology Co. Ltd
+
+OUI:741AE02*
+ ID_OUI_FROM_DATABASE=NURA HOLDINGS PTY LTD
+
OUI:1C8776B*
ID_OUI_FROM_DATABASE=Hekatron Vertriebs GmbH
@@ -8912,9 +9941,6 @@ OUI:38B8EB1*
OUI:38B8EBA*
ID_OUI_FROM_DATABASE=SECAD SA
-OUI:38B8EB7*
- ID_OUI_FROM_DATABASE=Private
-
OUI:38FDFE6*
ID_OUI_FROM_DATABASE=Inspero Inc
@@ -9029,9 +10055,6 @@ OUI:F0ACD70*
OUI:F0ACD7E*
ID_OUI_FROM_DATABASE=Fiziico Co., Ltd.
-OUI:58E8760*
- ID_OUI_FROM_DATABASE=Private
-
OUI:58E8761*
ID_OUI_FROM_DATABASE=Beijing Perabytes IS Technology Co., Ltd
@@ -9119,45 +10142,15 @@ OUI:8C192DA*
OUI:A03E6BF*
ID_OUI_FROM_DATABASE=Private
-OUI:58FCDBF*
- ID_OUI_FROM_DATABASE=Private
-
OUI:283638C*
ID_OUI_FROM_DATABASE=Swisson AG
-OUI:E4956EF*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:74F8DBF*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:BC6641F*
- ID_OUI_FROM_DATABASE=Private
-
OUI:74E14AF*
ID_OUI_FROM_DATABASE=Private
OUI:B8D812F*
ID_OUI_FROM_DATABASE=Private
-OUI:2C265FF*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:2C6A6FF*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:64FB81F*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:28FD80F*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:A0BB3EF*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:2CD141F*
- ID_OUI_FROM_DATABASE=Private
-
OUI:2836388*
ID_OUI_FROM_DATABASE=Havells India Limited
@@ -9338,6 +10331,159 @@ OUI:8C147DA*
OUI:8C147D1*
ID_OUI_FROM_DATABASE=Private
+OUI:8C147DB*
+ ID_OUI_FROM_DATABASE=Bausch Datacom NV/SA
+
+OUI:A0C5F2D*
+ ID_OUI_FROM_DATABASE=UnaliWear, Inc.
+
+OUI:A0C5F20*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:A0C5F2E*
+ ID_OUI_FROM_DATABASE=Synapsys Solutions Ltd.
+
+OUI:4C65A88*
+ ID_OUI_FROM_DATABASE=Instant Byte, S.L.
+
+OUI:4C65A82*
+ ID_OUI_FROM_DATABASE=Orica Europe Pty Ltd & Co KG
+
+OUI:4C65A84*
+ ID_OUI_FROM_DATABASE=Plus One Japan Limited
+
+OUI:4C65A8C*
+ ID_OUI_FROM_DATABASE=Fuse
+
+OUI:F88A3C7*
+ ID_OUI_FROM_DATABASE=Josh.ai
+
+OUI:F88A3C1*
+ ID_OUI_FROM_DATABASE=Carefree of Colorado
+
+OUI:F88A3C5*
+ ID_OUI_FROM_DATABASE=KOKKIA INC
+
+OUI:F88A3C9*
+ ID_OUI_FROM_DATABASE=withus
+
+OUI:7CBACCC*
+ ID_OUI_FROM_DATABASE=Flying Loft Inc.
+
+OUI:7CBACCD*
+ ID_OUI_FROM_DATABASE=SIGMA-ELEKTRO GmbH
+
+OUI:7CBACC2*
+ ID_OUI_FROM_DATABASE=Maco Lighting Pty. Ltd.
+
+OUI:7CBACC9*
+ ID_OUI_FROM_DATABASE=Yongguan Electronic Technology (D.G)LTD
+
+OUI:74F8DBF*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:7CBACCE*
+ ID_OUI_FROM_DATABASE=ALPHA TECHNOLOGIES, LLC
+
+OUI:78D8009*
+ ID_OUI_FROM_DATABASE=SightLine Applications
+
+OUI:78D8005*
+ ID_OUI_FROM_DATABASE=Björkviks Consulting AB
+
+OUI:78D8002*
+ ID_OUI_FROM_DATABASE=Shanghai Espacetime Technology Co.,Ltd.
+
+OUI:28F5372*
+ ID_OUI_FROM_DATABASE=Unicair Communication Tec Co., Ltd.
+
+OUI:78D8000*
+ ID_OUI_FROM_DATABASE=Kverneland Group Mechatronics
+
+OUI:28F5371*
+ ID_OUI_FROM_DATABASE=Umojo
+
+OUI:64FB81F*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:58FCDBF*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:2C265FF*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:28FD80F*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:2CD141F*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:2C6A6FF*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:A0BB3EF*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:BC6641F*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:34008AA*
+ ID_OUI_FROM_DATABASE=Hibertek International Limited
+
+OUI:34008A6*
+ ID_OUI_FROM_DATABASE=Sithon Technologies SAS
+
+OUI:34298FD*
+ ID_OUI_FROM_DATABASE=Keystone Electronic Solutions
+
+OUI:34298F7*
+ ID_OUI_FROM_DATABASE=Dongguan Kingtron Electronics Tech Co., Ltd
+
+OUI:58E8760*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:34298FE*
+ ID_OUI_FROM_DATABASE=ARC Technology Co., Ltd
+
+OUI:189BA53*
+ ID_OUI_FROM_DATABASE=PHINETWORKS
+
+OUI:189BA55*
+ ID_OUI_FROM_DATABASE=Starfire Industries LLC
+
+OUI:E4956EF*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:189BA5E*
+ ID_OUI_FROM_DATABASE=Taiwan Name Plate Co.,LTD
+
+OUI:904E914*
+ ID_OUI_FROM_DATABASE=Wrtnode technology Inc.
+
+OUI:2C279E4*
+ ID_OUI_FROM_DATABASE=Shijiazhuang King Transportation Equipment Co.,Ltd
+
+OUI:2C279E5*
+ ID_OUI_FROM_DATABASE=AudioNord Distribution A/S
+
+OUI:38B8EB7*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:CC22377*
+ ID_OUI_FROM_DATABASE=Shanghai Doit IOT Technology Co.,Ltd.
+
+OUI:34298FB*
+ ID_OUI_FROM_DATABASE=Schnick-Schnack-Systems GmbH
+
+OUI:741AE0D*
+ ID_OUI_FROM_DATABASE=Voltaware Services Limited
+
+OUI:741AE0E*
+ ID_OUI_FROM_DATABASE=ITS Partner (O.B.S) S.L.
+
+OUI:AC1DDF5*
+ ID_OUI_FROM_DATABASE=Shenzhen Ouzheng Electronic Tech Co,.Ltd
+
OUI:1C87740*
ID_OUI_FROM_DATABASE=Philips Personal Health Solutions
@@ -9797,9 +10943,6 @@ OUI:7C477C6*
OUI:7C477CD*
ID_OUI_FROM_DATABASE=Speedifi Inc
-OUI:986D359*
- ID_OUI_FROM_DATABASE=Private
-
OUI:986D353*
ID_OUI_FROM_DATABASE=DH Mechatronic AG
@@ -9905,24 +11048,6 @@ OUI:2836387*
OUI:800A80F*
ID_OUI_FROM_DATABASE=Private
-OUI:B437D1F*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:0CEFAFF*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:78C2C0F*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:141FBAF*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:549A11F*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:807B85F*
- ID_OUI_FROM_DATABASE=Private
-
OUI:2836386*
ID_OUI_FROM_DATABASE=Georg Neumann GmbH
@@ -10139,15 +11264,186 @@ OUI:8C147D3*
OUI:8C147D4*
ID_OUI_FROM_DATABASE=Nanjing bilian information Technology Co.,Ltd.
+OUI:8C147D6*
+ ID_OUI_FROM_DATABASE=Shenzhen Meidou Technology Co, Ltd.
+
+OUI:8C147D8*
+ ID_OUI_FROM_DATABASE=V2 S.p.A.
+
+OUI:A0C5F28*
+ ID_OUI_FROM_DATABASE=CoolR Group Inc
+
+OUI:A0C5F2A*
+ ID_OUI_FROM_DATABASE=Serious Integrated, Inc.
+
+OUI:A0C5F21*
+ ID_OUI_FROM_DATABASE=KNS Group LLC (YADRO Company)
+
+OUI:4C65A81*
+ ID_OUI_FROM_DATABASE=Beijing Bluehalo Internet Inc.
+
+OUI:4C65A80*
+ ID_OUI_FROM_DATABASE=WELT Corporation
+
+OUI:4C65A87*
+ ID_OUI_FROM_DATABASE=Wuhan MoreQuick Network Technology Co., Ltd.
+
+OUI:4C65A85*
+ ID_OUI_FROM_DATABASE=TEL-Electronics Ltd
+
+OUI:4C65A8B*
+ ID_OUI_FROM_DATABASE=ZMIN Technologies
+
+OUI:F88A3CC*
+ ID_OUI_FROM_DATABASE=EXCETOP TECHNOLOGY (BEIJING) CO., LTD.
+
+OUI:F88A3C3*
+ ID_OUI_FROM_DATABASE=Shenzhen Shengyuan Tech Ltd.
+
+OUI:F88A3C6*
+ ID_OUI_FROM_DATABASE=Beijing Zhong Chuang Communication Technology Ltd.
+
+OUI:4C65A8E*
+ ID_OUI_FROM_DATABASE=High Infinity Germany
+
+OUI:F88A3C2*
+ ID_OUI_FROM_DATABASE=KLATU Networks Inc
+
+OUI:F88A3CD*
+ ID_OUI_FROM_DATABASE=THK Co.,LTD.
+
+OUI:F88A3CB*
+ ID_OUI_FROM_DATABASE=FARA AS
+
+OUI:7CBACC7*
+ ID_OUI_FROM_DATABASE=Virgin Orbit
+
+OUI:7CBACC1*
+ ID_OUI_FROM_DATABASE=Changsha SUNYE Electric Co., Ltd.
+
+OUI:807B85F*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:549A11F*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:141FBAF*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:B437D1F*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:7CBACC8*
+ ID_OUI_FROM_DATABASE=Collinear Networks Inc.
+
+OUI:7CBACC6*
+ ID_OUI_FROM_DATABASE=Fossil Power Systems Inc
+
+OUI:78D8004*
+ ID_OUI_FROM_DATABASE=CS Instruments GmbH
+
+OUI:78D800D*
+ ID_OUI_FROM_DATABASE=Korea Micro Wireless Co.,Ltd.
+
+OUI:78D800B*
+ ID_OUI_FROM_DATABASE=Maddalena S.p.A.
+
+OUI:28F5370*
+ ID_OUI_FROM_DATABASE=Valeo Siemens eAutomotive Norway
+
+OUI:78C2C0F*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:0CEFAFF*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:28F537E*
+ ID_OUI_FROM_DATABASE=Performance Motion Devices
+
+OUI:34008A9*
+ ID_OUI_FROM_DATABASE=Keruyun Technoligies(Beijing) Corporation Limited
+
+OUI:986D359*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:34008A3*
+ ID_OUI_FROM_DATABASE=Globex 99 LTD
+
+OUI:34008AD*
+ ID_OUI_FROM_DATABASE=ChengDu HuiZhong Cloud Information Technology Co., Ltd.
+
+OUI:34008A1*
+ ID_OUI_FROM_DATABASE=ZQAM Communications
+
+OUI:34008A5*
+ ID_OUI_FROM_DATABASE=Federal Aviation Administration
+
+OUI:34298F2*
+ ID_OUI_FROM_DATABASE=Shenzhen Advance River System Technology Co., Ltd
+
+OUI:34008AE*
+ ID_OUI_FROM_DATABASE=SHENZHEN WXL ELECTRONICS CO., LTD.
+
+OUI:34298F9*
+ ID_OUI_FROM_DATABASE=Wiesheu GmbH
+
+OUI:34298F3*
+ ID_OUI_FROM_DATABASE=Beijing Vorx Telecommunications Co., Ltd.
+
+OUI:34298F4*
+ ID_OUI_FROM_DATABASE=ISRA Vision AG
+
+OUI:189BA54*
+ ID_OUI_FROM_DATABASE=Innominds Software Inc
+
+OUI:904E91C*
+ ID_OUI_FROM_DATABASE=Showtacle s.r.o.
+
+OUI:904E913*
+ ID_OUI_FROM_DATABASE=Teleepoch Ltd
+
+OUI:904E91A*
+ ID_OUI_FROM_DATABASE=Kaertech Limited
+
+OUI:904E919*
+ ID_OUI_FROM_DATABASE=CUTTER Systems spol. s r.o.
+
+OUI:2C279EE*
+ ID_OUI_FROM_DATABASE=Amaryllo International Inc.
+
+OUI:CC22374*
+ ID_OUI_FROM_DATABASE=SHANGHAI CARGOA M.&E.EQUIPMENT CO.LTD
+
+OUI:CC22376*
+ ID_OUI_FROM_DATABASE=Siemens AG Austria
+
+OUI:CC22370*
+ ID_OUI_FROM_DATABASE=MEDCOM sp. z o.o.
+
+OUI:CC22379*
+ ID_OUI_FROM_DATABASE=E Ink Corp
+
+OUI:CC22373*
+ ID_OUI_FROM_DATABASE=XConnect Professional Services
+
+OUI:CC2237E*
+ ID_OUI_FROM_DATABASE=MANUFACTURAS Y TRANSFORMADOS AB, S.L.
+
+OUI:741AE08*
+ ID_OUI_FROM_DATABASE=Broadcast Wireless Systems Ltd
+
+OUI:741AE06*
+ ID_OUI_FROM_DATABASE=Blocks Wearables Inc.
+
+OUI:741AE03*
+ ID_OUI_FROM_DATABASE=Philips Personal Health Solutions
+
OUI:E043DB*
ID_OUI_FROM_DATABASE=Shenzhen ViewAt Technology Co.,Ltd.
OUI:2405F5*
ID_OUI_FROM_DATABASE=Integrated Device Technology (Malaysia) Sdn. Bhd.
-OUI:2C3033*
- ID_OUI_FROM_DATABASE=NETGEAR
-
OUI:3CD92B*
ID_OUI_FROM_DATABASE=Hewlett Packard
@@ -10208,9 +11504,6 @@ OUI:348AAE*
OUI:BCEC23*
ID_OUI_FROM_DATABASE=SHENZHEN CHUANGWEI-RGB ELECTRONICS CO.,LTD
-OUI:8CE748*
- ID_OUI_FROM_DATABASE=Private
-
OUI:AC06C7*
ID_OUI_FROM_DATABASE=ServerNet S.r.l.
@@ -10397,15 +11690,6 @@ OUI:006057*
OUI:0007D8*
ID_OUI_FROM_DATABASE=Hitron Technologies. Inc
-OUI:0012F2*
- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
-
-OUI:001BED*
- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
-
-OUI:002438*
- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
-
OUI:84742A*
ID_OUI_FROM_DATABASE=zte corporation
@@ -11006,9 +12290,6 @@ OUI:70BF3E*
OUI:D848EE*
ID_OUI_FROM_DATABASE=Hangzhou Xueji Technology Co., Ltd.
-OUI:88947E*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
OUI:88C242*
ID_OUI_FROM_DATABASE=Poynt Co.
@@ -11060,9 +12341,6 @@ OUI:C8A9FC*
OUI:C49FF3*
ID_OUI_FROM_DATABASE=Mciao Technologies, Inc.
-OUI:80739F*
- ID_OUI_FROM_DATABASE=KYOCERA Corporation
-
OUI:7C2BE1*
ID_OUI_FROM_DATABASE=Shenzhen Ferex Electrical Co.,Ltd
@@ -11084,9 +12362,6 @@ OUI:2CA539*
OUI:FC335F*
ID_OUI_FROM_DATABASE=Polyera
-OUI:FCC233*
- ID_OUI_FROM_DATABASE=Private
-
OUI:A8C87F*
ID_OUI_FROM_DATABASE=Roqos, Inc.
@@ -11144,9 +12419,6 @@ OUI:DC3CF6*
OUI:3C3178*
ID_OUI_FROM_DATABASE=Qolsys Inc.
-OUI:F4573E*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
OUI:083A5C*
ID_OUI_FROM_DATABASE=Junilab, Inc.
@@ -11171,18 +12443,12 @@ OUI:6459F8*
OUI:082CB0*
ID_OUI_FROM_DATABASE=Network Instruments
-OUI:F0AB54*
- ID_OUI_FROM_DATABASE=MITSUMI ELECTRIC CO.,LTD.
-
OUI:485073*
ID_OUI_FROM_DATABASE=Microsoft Corporation
OUI:3CA31A*
ID_OUI_FROM_DATABASE=Oilfind International LLC
-OUI:ACFD93*
- ID_OUI_FROM_DATABASE=Weifang GoerTek Electronics Co., Ltd.
-
OUI:A424DD*
ID_OUI_FROM_DATABASE=Cambrionix Ltd
@@ -11330,9 +12596,6 @@ OUI:38C70A*
OUI:60E6BC*
ID_OUI_FROM_DATABASE=Sino-Telecom Technology Co.,Ltd.
-OUI:1CA532*
- ID_OUI_FROM_DATABASE=Shenzhen Gongjin Electronics Co.,Ltd
-
OUI:486EFB*
ID_OUI_FROM_DATABASE=Davit System Technology Co., Ltd.
@@ -11453,9 +12716,6 @@ OUI:8CDF9D*
OUI:F8E903*
ID_OUI_FROM_DATABASE=D-Link International
-OUI:F0B052*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:6828F6*
ID_OUI_FROM_DATABASE=Vubiq Networks, Inc.
@@ -11588,9 +12848,6 @@ OUI:74F413*
OUI:34F0CA*
ID_OUI_FROM_DATABASE=Shenzhen Linghangyuan Digital Technology Co.,Ltd.
-OUI:84183A*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:30B5F1*
ID_OUI_FROM_DATABASE=Aitexin Technology Co., Ltd
@@ -11678,9 +12935,6 @@ OUI:34E42A*
OUI:20A787*
ID_OUI_FROM_DATABASE=Bointec Taiwan Corporation Limited
-OUI:6CAAB3*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:A481EE*
ID_OUI_FROM_DATABASE=Nokia Corporation
@@ -11735,9 +12989,6 @@ OUI:9451BF*
OUI:4C7F62*
ID_OUI_FROM_DATABASE=Nokia Corporation
-OUI:841766*
- ID_OUI_FROM_DATABASE=Weifang GoerTek Electronics Co., Ltd
-
OUI:F03FF8*
ID_OUI_FROM_DATABASE=R L Drake
@@ -12029,9 +13280,6 @@ OUI:F42896*
OUI:1C7B21*
ID_OUI_FROM_DATABASE=Sony Mobile Communications AB
-OUI:BC9680*
- ID_OUI_FROM_DATABASE=Shenzhen Gongjin Electronics Co.,Ltd
-
OUI:9C2840*
ID_OUI_FROM_DATABASE=Discovery Technology,LTD..
@@ -12155,9 +13403,6 @@ OUI:C47F51*
OUI:E8D4E0*
ID_OUI_FROM_DATABASE=Beijing BenyWave Technology Co., Ltd.
-OUI:3889DC*
- ID_OUI_FROM_DATABASE=Opticon Sensors Europe B.V.
-
OUI:681D64*
ID_OUI_FROM_DATABASE=Sunwave Communications Co., Ltd
@@ -12167,9 +13412,6 @@ OUI:F4CD90*
OUI:E438F2*
ID_OUI_FROM_DATABASE=Advantage Controls
-OUI:24C9A1*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:C8F386*
ID_OUI_FROM_DATABASE=Shenzhen Xiaoniao Technology Co.,Ltd
@@ -12551,9 +13793,6 @@ OUI:58CF4B*
OUI:C4393A*
ID_OUI_FROM_DATABASE=SMC Networks Inc
-OUI:C4017C*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:D45C70*
ID_OUI_FROM_DATABASE=Wi-Fi Alliance
@@ -12773,9 +14012,6 @@ OUI:18F87A*
OUI:142DF5*
ID_OUI_FROM_DATABASE=Amphitech
-OUI:C08ADE*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:90F72F*
ID_OUI_FROM_DATABASE=Phillips Machine & Welding Co., Inc.
@@ -12917,9 +14153,6 @@ OUI:AC3FA4*
OUI:0C130B*
ID_OUI_FROM_DATABASE=Uniqoteq Ltd.
-OUI:14CF8D*
- ID_OUI_FROM_DATABASE=OHSUNG ELECTRONICS CO., LTD.
-
OUI:808698*
ID_OUI_FROM_DATABASE=Netronics Technologies Inc.
@@ -13307,9 +14540,6 @@ OUI:685E6B*
OUI:4C32D9*
ID_OUI_FROM_DATABASE=M Rutty Holdings Pty. Ltd.
-OUI:50A733*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:603FC5*
ID_OUI_FROM_DATABASE=COX CO., LTD
@@ -13472,9 +14702,6 @@ OUI:802275*
OUI:BC8199*
ID_OUI_FROM_DATABASE=BASIC Co.,Ltd.
-OUI:000726*
- ID_OUI_FROM_DATABASE=Shenzhen Gongjin Electronics Co., Ltd.
-
OUI:24470E*
ID_OUI_FROM_DATABASE=PentronicAB
@@ -13616,9 +14843,6 @@ OUI:707EDE*
OUI:CCBE71*
ID_OUI_FROM_DATABASE=OptiLogix BV
-OUI:D8B12A*
- ID_OUI_FROM_DATABASE=Panasonic Mobile Communications Co., Ltd.
-
OUI:7CDD90*
ID_OUI_FROM_DATABASE=Shenzhen Ogemray Technology Co., Ltd.
@@ -13880,9 +15104,6 @@ OUI:84DB2F*
OUI:A45055*
ID_OUI_FROM_DATABASE=busware.de
-OUI:2CD2E7*
- ID_OUI_FROM_DATABASE=Nokia Corporation
-
OUI:C89383*
ID_OUI_FROM_DATABASE=Embedded Automation, Inc.
@@ -14399,9 +15620,6 @@ OUI:0025EF*
OUI:0025E9*
ID_OUI_FROM_DATABASE=i-mate Development, Inc.
-OUI:0025DF*
- ID_OUI_FROM_DATABASE=Private
-
OUI:002690*
ID_OUI_FROM_DATABASE=I DO IT
@@ -14978,9 +16196,6 @@ OUI:00229A*
OUI:002299*
ID_OUI_FROM_DATABASE=SeaMicro Inc.
-OUI:002294*
- ID_OUI_FROM_DATABASE=Kyocera Corporation
-
OUI:0021FA*
ID_OUI_FROM_DATABASE=A4SP Technologies Ltd.
@@ -15146,9 +16361,6 @@ OUI:001F3E*
OUI:001F42*
ID_OUI_FROM_DATABASE=Etherstack plc
-OUI:001F41*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:001F39*
ID_OUI_FROM_DATABASE=Construcciones y Auxiliar de Ferrocarriles, S.A.
@@ -16151,9 +17363,6 @@ OUI:001890*
OUI:001884*
ID_OUI_FROM_DATABASE=Fon Technology S.L.
-OUI:00187D*
- ID_OUI_FROM_DATABASE=Armorlink shanghai Co. Ltd
-
OUI:00187F*
ID_OUI_FROM_DATABASE=ZODIANET
@@ -16181,9 +17390,6 @@ OUI:0016AB*
OUI:0016A6*
ID_OUI_FROM_DATABASE=Dovado FZ-LLC
-OUI:0017C8*
- ID_OUI_FROM_DATABASE=KYOCERA Document Solutions Inc.
-
OUI:0017CF*
ID_OUI_FROM_DATABASE=iMCA-GmbH
@@ -16241,9 +17447,6 @@ OUI:00175F*
OUI:001751*
ID_OUI_FROM_DATABASE=Online Corporation
-OUI:001753*
- ID_OUI_FROM_DATABASE=nFore Technology Inc.
-
OUI:001758*
ID_OUI_FROM_DATABASE=ThruVision Ltd
@@ -16499,9 +17702,6 @@ OUI:001531*
OUI:001538*
ID_OUI_FROM_DATABASE=RFID, Inc.
-OUI:00152A*
- ID_OUI_FROM_DATABASE=Nokia GmbH
-
OUI:00161D*
ID_OUI_FROM_DATABASE=Innovative Wireless Technologies, Inc.
@@ -17081,9 +18281,6 @@ OUI:001137*
OUI:00112D*
ID_OUI_FROM_DATABASE=iPulse Systems
-OUI:111111*
- ID_OUI_FROM_DATABASE=Private
-
OUI:001123*
ID_OUI_FROM_DATABASE=Appointech, Inc.
@@ -18776,9 +19973,6 @@ OUI:0004D1*
OUI:0004CB*
ID_OUI_FROM_DATABASE=Tdsoft Communication, Ltd.
-OUI:0004BF*
- ID_OUI_FROM_DATABASE=VersaLogic Corp.
-
OUI:0004C5*
ID_OUI_FROM_DATABASE=ASE Technologies, USA
@@ -19223,9 +20417,6 @@ OUI:00015A*
OUI:000166*
ID_OUI_FROM_DATABASE=TC GROUP A/S
-OUI:00016D*
- ID_OUI_FROM_DATABASE=CarrierComm Inc.
-
OUI:00015F*
ID_OUI_FROM_DATABASE=DIGITAL DESIGN GmbH
@@ -21083,9 +22274,6 @@ OUI:080076*
OUI:080072*
ID_OUI_FROM_DATABASE=XEROX CORP UNIV GRANT PROGRAM
-OUI:080070*
- ID_OUI_FROM_DATABASE=MITSUBISHI ELECTRIC CORP.
-
OUI:080068*
ID_OUI_FROM_DATABASE=RIDGE COMPUTERS
@@ -21227,9 +22415,6 @@ OUI:00004C*
OUI:00003B*
ID_OUI_FROM_DATABASE=i Controls, Inc.
-OUI:0000FE*
- ID_OUI_FROM_DATABASE=ANNAPOLIS MICRO SYSTEMS
-
OUI:080013*
ID_OUI_FROM_DATABASE=Exxon
@@ -21314,15 +22499,6 @@ OUI:C8CD72*
OUI:E8BE81*
ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
-OUI:28FAA0*
- ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
-
-OUI:3CA348*
- ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
-
-OUI:F42981*
- ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
-
OUI:C4282D*
ID_OUI_FROM_DATABASE=Embedded Intellect Pty Ltd
@@ -21479,9 +22655,6 @@ OUI:9C4E36*
OUI:541473*
ID_OUI_FROM_DATABASE=Wingtech Group (HongKong)Limited
-OUI:14144B*
- ID_OUI_FROM_DATABASE=FUJIAN STAR-NET COMMUNICATION CO.,LTD
-
OUI:001C50*
ID_OUI_FROM_DATABASE=TCL Technoly Electronics (Huizhou) Co., Ltd.
@@ -21674,12 +22847,6 @@ OUI:E839DF*
OUI:00138F*
ID_OUI_FROM_DATABASE=Asiarock Technology Limited
-OUI:2CB05D*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:00146C*
- ID_OUI_FROM_DATABASE=NETGEAR
-
OUI:1C69A5*
ID_OUI_FROM_DATABASE=BlackBerry RTS
@@ -21695,21 +22862,9 @@ OUI:002308*
OUI:880355*
ID_OUI_FROM_DATABASE=Arcadyan Technology Corporation
-OUI:A42B8C*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:04A151*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:28C68E*
- ID_OUI_FROM_DATABASE=NETGEAR
-
OUI:5CDC96*
ID_OUI_FROM_DATABASE=Arcadyan Technology Corporation
-OUI:504A6E*
- ID_OUI_FROM_DATABASE=NETGEAR
-
OUI:D0D04B*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
@@ -21827,9 +22982,6 @@ OUI:000B3B*
OUI:001D20*
ID_OUI_FROM_DATABASE=Comtrend Corporation
-OUI:6C38A1*
- ID_OUI_FROM_DATABASE=Ubee Interactive Corp.
-
OUI:140C76*
ID_OUI_FROM_DATABASE=FREEBOX SAS
@@ -21971,9 +23123,6 @@ OUI:000BA2*
OUI:30CBF8*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:2C4D79*
- ID_OUI_FROM_DATABASE=GoerTek Inc.
-
OUI:40D357*
ID_OUI_FROM_DATABASE=Ison Technology Co., Ltd.
@@ -22067,9 +23216,6 @@ OUI:349971*
OUI:24615A*
ID_OUI_FROM_DATABASE=China Mobile Group Device Co.,Ltd.
-OUI:B0E2E5*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
OUI:AC0D1B*
ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
@@ -22301,9 +23447,6 @@ OUI:045604*
OUI:10BD55*
ID_OUI_FROM_DATABASE=Q-Lab Corporation
-OUI:C449BB*
- ID_OUI_FROM_DATABASE=MITSUMI ELECTRIC CO.,LTD.
-
OUI:8C6D50*
ID_OUI_FROM_DATABASE=SHENZHEN MTC CO LTD
@@ -22346,9 +23489,6 @@ OUI:680715*
OUI:A09E1A*
ID_OUI_FROM_DATABASE=Polar Electro Oy
-OUI:3CB6B7*
- ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
-
OUI:D0B2C4*
ID_OUI_FROM_DATABASE=Technicolor CH USA Inc.
@@ -22472,9 +23612,6 @@ OUI:0050C2*
OUI:CC79CF*
ID_OUI_FROM_DATABASE=SHENZHEN RF-LINK TECHNOLOGY CO.,LTD.
-OUI:544E45*
- ID_OUI_FROM_DATABASE=Private
-
OUI:6CB9C5*
ID_OUI_FROM_DATABASE=Delta Networks, Inc.
@@ -22778,9 +23915,6 @@ OUI:98F058*
OUI:24E43F*
ID_OUI_FROM_DATABASE=Wenzhou Kunmei Communication Technology Co.,Ltd.
-OUI:A00460*
- ID_OUI_FROM_DATABASE=NETGEAR
-
OUI:240AC4*
ID_OUI_FROM_DATABASE=Espressif Inc.
@@ -23009,9 +24143,6 @@ OUI:C80E14*
OUI:E0686D*
ID_OUI_FROM_DATABASE=Raybased AB
-OUI:A45385*
- ID_OUI_FROM_DATABASE=Weifang GoerTek Electronics Co., Ltd.
-
OUI:98B039*
ID_OUI_FROM_DATABASE=Nokia
@@ -23099,9 +24230,6 @@ OUI:FCCAC4*
OUI:04BA36*
ID_OUI_FROM_DATABASE=Li Seng Technology Ltd
-OUI:DCF090*
- ID_OUI_FROM_DATABASE=Private
-
OUI:4409B8*
ID_OUI_FROM_DATABASE=Salcomp (Shenzhen) CO., LTD.
@@ -23180,9 +24308,6 @@ OUI:484D7E*
OUI:F4B549*
ID_OUI_FROM_DATABASE=Xiamen Yeastar Information Technology Co., Ltd.
-OUI:9C3DCF*
- ID_OUI_FROM_DATABASE=NETGEAR
-
OUI:28EED3*
ID_OUI_FROM_DATABASE=Shenzhen Super D Technology Co., Ltd
@@ -23318,9 +24443,6 @@ OUI:A03D6F*
OUI:40605A*
ID_OUI_FROM_DATABASE=Hawkeye Tech Co. Ltd
-OUI:5419C8*
- ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
-
OUI:C0210D*
ID_OUI_FROM_DATABASE=SHENZHEN RF-LINK TECHNOLOGY CO.,LTD.
@@ -23342,9 +24464,6 @@ OUI:1840A4*
OUI:9C50EE*
ID_OUI_FROM_DATABASE=Cambridge Industries(Group) Co.,Ltd.
-OUI:1077B0*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
OUI:F015B9*
ID_OUI_FROM_DATABASE=PlayFusion Limited
@@ -23450,9 +24569,6 @@ OUI:3407FB*
OUI:6CB4A7*
ID_OUI_FROM_DATABASE=Landauer, Inc.
-OUI:1C398A*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
OUI:F8A5C5*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
@@ -23537,9 +24653,6 @@ OUI:2C3311*
OUI:503A7D*
ID_OUI_FROM_DATABASE=AlphaTech PLC Int’l Co., Ltd.
-OUI:BC024A*
- ID_OUI_FROM_DATABASE=HMD Global Oy
-
OUI:9CFCD1*
ID_OUI_FROM_DATABASE=Aetheris Technology (Shanghai) Co., Ltd.
@@ -23969,9 +25082,6 @@ OUI:FC4D8C*
OUI:B01F29*
ID_OUI_FROM_DATABASE=Helvetia INC.
-OUI:CC0677*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
OUI:28070D*
ID_OUI_FROM_DATABASE=GUANGZHOU WINSOUND INFORMATION TECHNOLOGY CO.,LTD.
@@ -24011,6 +25121,486 @@ OUI:E0D848*
OUI:145BE1*
ID_OUI_FROM_DATABASE=nyantec UG (haftungsbeschränkt)
+OUI:00187D*
+ ID_OUI_FROM_DATABASE=Armorlink Co .Ltd
+
+OUI:F42981*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:3CA348*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:A40E2B*
+ ID_OUI_FROM_DATABASE=Facebook Inc
+
+OUI:28FAA0*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:3CB6B7*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:5419C8*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:F4B7B3*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:1C4D70*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:E43A6E*
+ ID_OUI_FROM_DATABASE=Shenzhen Zeroone Technology CO.,LTD
+
+OUI:60DA83*
+ ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited
+
+OUI:2C5731*
+ ID_OUI_FROM_DATABASE=Wingtech Group (HongKong)Limited
+
+OUI:F46BEF*
+ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
+
+OUI:085114*
+ ID_OUI_FROM_DATABASE=QINGDAO TOPSCOMM COMMUNICATION CO., LTD
+
+OUI:D05A00*
+ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc.
+
+OUI:70F11C*
+ ID_OUI_FROM_DATABASE=Shenzhen Ogemray Technology Co.,Ltd
+
+OUI:14144B*
+ ID_OUI_FROM_DATABASE=Ruijie Networks Co.,LTD
+
+OUI:70DF2F*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:6447E0*
+ ID_OUI_FROM_DATABASE=Feitian Technologies Co., Ltd
+
+OUI:001753*
+ ID_OUI_FROM_DATABASE=nFore Technology Inc.
+
+OUI:58C583*
+ ID_OUI_FROM_DATABASE=ITEL MOBILE LIMITED
+
+OUI:E86D65*
+ ID_OUI_FROM_DATABASE=AUDIO MOBIL Elektronik GmbH
+
+OUI:E86FF2*
+ ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc
+
+OUI:00016D*
+ ID_OUI_FROM_DATABASE=CarrierComm Inc.
+
+OUI:F0B052*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:84183A*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:6CAAB3*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:C4017C*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:70DEF9*
+ ID_OUI_FROM_DATABASE=FAI WAH INTERNATIONAL (HONG KONG) LIMITED
+
+OUI:001F41*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:C08ADE*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:50A733*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:24C9A1*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:245880*
+ ID_OUI_FROM_DATABASE=VIZEO
+
+OUI:000726*
+ ID_OUI_FROM_DATABASE=SHENZHEN GONGJIN ELECTRONICS CO.,LT
+
+OUI:BC9680*
+ ID_OUI_FROM_DATABASE=SHENZHEN GONGJIN ELECTRONICS CO.,LT
+
+OUI:1CA532*
+ ID_OUI_FROM_DATABASE=SHENZHEN GONGJIN ELECTRONICS CO.,LT
+
+OUI:0000FE*
+ ID_OUI_FROM_DATABASE=Annapolis Micro Systems, Inc.
+
+OUI:188090*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:BC024A*
+ ID_OUI_FROM_DATABASE=HMD Global Oy
+
+OUI:90A365*
+ ID_OUI_FROM_DATABASE=HMD Global Oy
+
+OUI:C444A0*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:F83441*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:5C0339*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:044F4C*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:1C151F*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:544E45*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:DCEB53*
+ ID_OUI_FROM_DATABASE=Wuhan QianXiao Elecronic Technology CO.,LTD
+
+OUI:94E36D*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:74819A*
+ ID_OUI_FROM_DATABASE=PT. Hartono Istana Teknologi
+
+OUI:0835B2*
+ ID_OUI_FROM_DATABASE=CoreEdge Networks Co., Ltd
+
+OUI:6C38A1*
+ ID_OUI_FROM_DATABASE=Ubee Interactive Co., Limited
+
+OUI:B40F3B*
+ ID_OUI_FROM_DATABASE=Tenda Technology Co.,Ltd.Dongguan branch
+
+OUI:1062D0*
+ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc.
+
+OUI:7802B1*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:309935*
+ ID_OUI_FROM_DATABASE=zte corporation
+
+OUI:94D9B3*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
+
+OUI:409BCD*
+ ID_OUI_FROM_DATABASE=D-Link International
+
+OUI:005C86*
+ ID_OUI_FROM_DATABASE=SHENZHEN FAST TECHNOLOGIES CO.,LTD
+
+OUI:1CAB34*
+ ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd
+
+OUI:5C0979*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:002EC7*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:488EEF*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:002438*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:001BED*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:0012F2*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:04A151*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:A42B8C*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:A00460*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:9C3DCF*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:2CB05D*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:504A6E*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:28C68E*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:2C3033*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:00146C*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:ACFD93*
+ ID_OUI_FROM_DATABASE=Weifang GoerTek Technology Co.,Ltd.
+
+OUI:A45385*
+ ID_OUI_FROM_DATABASE=Weifang GoerTek Technology Co.,Ltd.
+
+OUI:2C4D79*
+ ID_OUI_FROM_DATABASE=Weifang GoerTek Technology Co.,Ltd.
+
+OUI:841766*
+ ID_OUI_FROM_DATABASE=Weifang GoerTek Technology Co.,Ltd.
+
+OUI:741C27*
+ ID_OUI_FROM_DATABASE=ITEL MOBILE LIMITED
+
+OUI:111111*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:FCC233*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:2830AC*
+ ID_OUI_FROM_DATABASE=Frontiir Co. Ltd.
+
+OUI:9050CA*
+ ID_OUI_FROM_DATABASE=Hitron Technologies. Inc
+
+OUI:0004BF*
+ ID_OUI_FROM_DATABASE=VersaLogic Corp.
+
+OUI:D8B12A*
+ ID_OUI_FROM_DATABASE=Panasonic Mobile Communications Co.,Ltd.
+
+OUI:64B5C6*
+ ID_OUI_FROM_DATABASE=Nintendo Co.,Ltd
+
+OUI:A41115*
+ ID_OUI_FROM_DATABASE=Robert Bosch Engineering and Business Solutions pvt. Ltd.
+
+OUI:EC0441*
+ ID_OUI_FROM_DATABASE=ShenZhen TIGO Semiconductor Co., Ltd.
+
+OUI:BC88C3*
+ ID_OUI_FROM_DATABASE=Ningbo Dooya Mechanic & Electronic Technology Co., Ltd
+
+OUI:A8BE27*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:B8634D*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:6C96CF*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:3035AD*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:681F40*
+ ID_OUI_FROM_DATABASE=Blu Wireless Technology Ltd
+
+OUI:48C58D*
+ ID_OUI_FROM_DATABASE=Lear Corporation GmbH
+
+OUI:90ADF7*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:982D68*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co., Ltd
+
+OUI:2CD2E7*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:00152A*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:5CEA1D*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
+OUI:A43412*
+ ID_OUI_FROM_DATABASE=Thales Alenia Space
+
+OUI:ECD09F*
+ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd
+
+OUI:9C65EE*
+ ID_OUI_FROM_DATABASE=DASAN Network Solutions
+
+OUI:80739F*
+ ID_OUI_FROM_DATABASE=KYOCERA CORPORATION
+
+OUI:3889DC*
+ ID_OUI_FROM_DATABASE=Opticon Sensors Europe B.V.
+
+OUI:38E2DD*
+ ID_OUI_FROM_DATABASE=zte corporation
+
+OUI:74E5F9*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:0017C8*
+ ID_OUI_FROM_DATABASE=KYOCERA Display Corporation
+
+OUI:002294*
+ ID_OUI_FROM_DATABASE=KYOCERA CORPORATION
+
+OUI:3C11B2*
+ ID_OUI_FROM_DATABASE=Fraunhofer FIT
+
+OUI:080070*
+ ID_OUI_FROM_DATABASE=Mitsubishi Precision Co.,LTd.
+
+OUI:DCF090*
+ ID_OUI_FROM_DATABASE=Nubia Technology Co.,Ltd.
+
+OUI:DC6AEA*
+ ID_OUI_FROM_DATABASE=Infinix mobility limited
+
+OUI:0025DF*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:D8A01D*
+ ID_OUI_FROM_DATABASE=Espressif Inc.
+
+OUI:8CE38E*
+ ID_OUI_FROM_DATABASE=Toshiba Memory Corporation
+
+OUI:74EAC8*
+ ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd
+
+OUI:A434F1*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:C4F312*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:44EAD8*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:8C5F48*
+ ID_OUI_FROM_DATABASE=Continental Intelligent Transportation Systems LLC
+
+OUI:A0D86F*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:3890A5*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:4C1365*
+ ID_OUI_FROM_DATABASE=Emplus Technologies
+
+OUI:2054FA*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:989C57*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:E4A7C5*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:104400*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:88DA1A*
+ ID_OUI_FROM_DATABASE=Redpine Signals, Inc.
+
+OUI:14CF8D*
+ ID_OUI_FROM_DATABASE=OHSUNG
+
+OUI:8CE748*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:48D35D*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:E446DA*
+ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd
+
+OUI:500F80*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:F4F5DB*
+ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd
+
+OUI:38A6CE*
+ ID_OUI_FROM_DATABASE=BSkyB Ltd
+
+OUI:1077B0*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:1C398A*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:CC0677*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:C84029*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:28BF89*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:F4573E*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:88947E*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:B0E2E5*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:F0AB54*
+ ID_OUI_FROM_DATABASE=MITSUMI ELECTRIC CO.,LTD.
+
+OUI:C449BB*
+ ID_OUI_FROM_DATABASE=MITSUMI ELECTRIC CO.,LTD.
+
+OUI:B430C0*
+ ID_OUI_FROM_DATABASE=York Instruments Ltd
+
+OUI:C468D0*
+ ID_OUI_FROM_DATABASE=VTech Telecommunications Ltd.
+
+OUI:48D6D5*
+ ID_OUI_FROM_DATABASE=Google, Inc.
+
+OUI:F0BD2E*
+ ID_OUI_FROM_DATABASE=H+S Polatis Ltd
+
+OUI:842C80*
+ ID_OUI_FROM_DATABASE=Sichuan Changhong Electric Ltd.
+
+OUI:182D98*
+ ID_OUI_FROM_DATABASE=Jinwoo Industrial system
+
+OUI:0C1C20*
+ ID_OUI_FROM_DATABASE=Kakao Corp
+
+OUI:40498A*
+ ID_OUI_FROM_DATABASE=Synapticon GmbH
+
+OUI:D80831*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:24F27F*
+ ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise
+
+OUI:00B69F*
+ ID_OUI_FROM_DATABASE=Latch
+
+OUI:A88200*
+ ID_OUI_FROM_DATABASE=Hisense Electric Co.,Ltd
+
+OUI:F449EF*
+ ID_OUI_FROM_DATABASE=EMSTONE
+
OUI:0C6F9C*
ID_OUI_FROM_DATABASE=Shaw Communications Inc.
@@ -24245,18 +25835,6 @@ OUI:241EEB*
OUI:F431C3*
ID_OUI_FROM_DATABASE=Apple, Inc.
-OUI:C4F57C*
- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
-
-OUI:8C7CFF*
- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
-
-OUI:000CDB*
- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
-
-OUI:006069*
- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
-
OUI:C87B5B*
ID_OUI_FROM_DATABASE=zte corporation
@@ -24875,9 +26453,6 @@ OUI:74D7CA*
OUI:1CCDE5*
ID_OUI_FROM_DATABASE=Shanghai Wind Technologies Co.,Ltd
-OUI:20896F*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
OUI:D494E8*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
@@ -24896,9 +26471,6 @@ OUI:ECB870*
OUI:3095E3*
ID_OUI_FROM_DATABASE=SHANGHAI SIMCOM LIMITED
-OUI:401B5F*
- ID_OUI_FROM_DATABASE=Weifang GoerTek Electronics Co., Ltd.
-
OUI:4040A7*
ID_OUI_FROM_DATABASE=Sony Mobile Communications AB
@@ -24941,9 +26513,6 @@ OUI:B88687*
OUI:68F956*
ID_OUI_FROM_DATABASE=Objetivos y Servicio de Valor Añadido
-OUI:58B633*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:F4E926*
ID_OUI_FROM_DATABASE=Tianjin Zanpu Technology Inc.
@@ -25100,9 +26669,6 @@ OUI:64DB81*
OUI:C4BAA3*
ID_OUI_FROM_DATABASE=Beijing Winicssec Technologies Co., Ltd.
-OUI:A013CB*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
OUI:20635F*
ID_OUI_FROM_DATABASE=Abeeway
@@ -25142,9 +26708,6 @@ OUI:C43ABE*
OUI:18B169*
ID_OUI_FROM_DATABASE=Sonicwall
-OUI:D4684D*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:1CC72D*
ID_OUI_FROM_DATABASE=Shenzhen Huapu Digital CO.,Ltd
@@ -25565,9 +27128,6 @@ OUI:7C1A03*
OUI:481842*
ID_OUI_FROM_DATABASE=Shanghai Winaas Co. Equipment Co. Ltd.
-OUI:E817FC*
- ID_OUI_FROM_DATABASE=NIFTY Corporation
-
OUI:D09C30*
ID_OUI_FROM_DATABASE=Foster Electric Company, Limited
@@ -25898,9 +27458,6 @@ OUI:78CB33*
OUI:507691*
ID_OUI_FROM_DATABASE=Tekpea, Inc.
-OUI:C421C8*
- ID_OUI_FROM_DATABASE=KYOCERA Corporation
-
OUI:A4C0C7*
ID_OUI_FROM_DATABASE=ShenZhen Hitom Communication Technology Co..LTD
@@ -25997,9 +27554,6 @@ OUI:2C7B84*
OUI:540536*
ID_OUI_FROM_DATABASE=Vivago Oy
-OUI:2CE6CC*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:E0FAEC*
ID_OUI_FROM_DATABASE=Platan sp. z o.o. sp. k.
@@ -26408,9 +27962,6 @@ OUI:80D733*
OUI:8C3330*
ID_OUI_FROM_DATABASE=EmFirst Co., Ltd.
-OUI:8C0C90*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:08E5DA*
ID_OUI_FROM_DATABASE=NANJING FUJITSU COMPUTER PRODUCTS CO.,LTD.
@@ -26495,9 +28046,6 @@ OUI:9C3178*
OUI:48BE2D*
ID_OUI_FROM_DATABASE=Symanitron
-OUI:38E595*
- ID_OUI_FROM_DATABASE=Shenzhen Gongjin Electronics Co.,Ltd
-
OUI:B86091*
ID_OUI_FROM_DATABASE=Onnet Technologies and Innovations LLC
@@ -26588,9 +28136,6 @@ OUI:A4D18F*
OUI:0C565C*
ID_OUI_FROM_DATABASE=HyBroad Vision (Hong Kong) Technology Co Ltd
-OUI:647C34*
- ID_OUI_FROM_DATABASE=Ubee Interactive Corp.
-
OUI:649FF7*
ID_OUI_FROM_DATABASE=Kone OYj
@@ -26648,9 +28193,6 @@ OUI:1848D8*
OUI:702393*
ID_OUI_FROM_DATABASE=fos4X GmbH
-OUI:D8AFF1*
- ID_OUI_FROM_DATABASE=Panasonic Appliances Company
-
OUI:58ECE1*
ID_OUI_FROM_DATABASE=Newport Corporation
@@ -26867,9 +28409,6 @@ OUI:240917*
OUI:DC37D2*
ID_OUI_FROM_DATABASE=Hunan HKT Electronic Technology Co., Ltd
-OUI:048B42*
- ID_OUI_FROM_DATABASE=Skspruce Technology Limited
-
OUI:5076A6*
ID_OUI_FROM_DATABASE=Ecil Informatica Ind. Com. Ltda
@@ -26987,9 +28526,6 @@ OUI:94E0D0*
OUI:DCF858*
ID_OUI_FROM_DATABASE=Lorent Networks, Inc.
-OUI:589396*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:A05E6B*
ID_OUI_FROM_DATABASE=MELPER Co., Ltd.
@@ -27431,9 +28967,6 @@ OUI:6879ED*
OUI:9CC0D2*
ID_OUI_FROM_DATABASE=Conductix-Wampfler GmbH
-OUI:408BF6*
- ID_OUI_FROM_DATABASE=Shenzhen TCL New Technology Co; Ltd.
-
OUI:447E95*
ID_OUI_FROM_DATABASE=Alpha and Omega, Inc
@@ -27716,9 +29249,6 @@ OUI:E8757F*
OUI:C83EA7*
ID_OUI_FROM_DATABASE=KUNBUS GmbH
-OUI:A8D3C8*
- ID_OUI_FROM_DATABASE=Wachendorff Elektronik GmbH & Co. KG
-
OUI:E0CF2D*
ID_OUI_FROM_DATABASE=Gemintek Corporation
@@ -27758,9 +29288,6 @@ OUI:D46CDA*
OUI:C4F464*
ID_OUI_FROM_DATABASE=Spica international
-OUI:74911A*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:544A05*
ID_OUI_FROM_DATABASE=wenglor sensoric gmbh
@@ -28415,9 +29942,6 @@ OUI:002609*
OUI:00268C*
ID_OUI_FROM_DATABASE=StarLeaf Ltd.
-OUI:002692*
- ID_OUI_FROM_DATABASE=Mitsubishi Electric Co.
-
OUI:002686*
ID_OUI_FROM_DATABASE=Quantenna Communcations, Inc.
@@ -28535,9 +30059,6 @@ OUI:002489*
OUI:00248E*
ID_OUI_FROM_DATABASE=Infoware ZRt.
-OUI:002482*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:002476*
ID_OUI_FROM_DATABASE=TAP.tv
@@ -28742,9 +30263,6 @@ OUI:00228B*
OUI:002284*
ID_OUI_FROM_DATABASE=DESAY A&V SCIENCE AND TECHNOLOGY CO.,LTD
-OUI:00227F*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:002277*
ID_OUI_FROM_DATABASE=NEC Australia Pty Ltd
@@ -28814,9 +30332,6 @@ OUI:002385*
OUI:00237E*
ID_OUI_FROM_DATABASE=ELSTER GMBH
-OUI:00237F*
- ID_OUI_FROM_DATABASE=PLANTRONICS, INC.
-
OUI:002379*
ID_OUI_FROM_DATABASE=Union Business Machines Co. Ltd.
@@ -29630,9 +31145,6 @@ OUI:001BE6*
OUI:001BDF*
ID_OUI_FROM_DATABASE=Iskra Sistemi d.d.
-OUI:001BD3*
- ID_OUI_FROM_DATABASE=Panasonic Corp. AVC Company
-
OUI:001BD8*
ID_OUI_FROM_DATABASE=DVTel LTD
@@ -29699,9 +31211,6 @@ OUI:001B1E*
OUI:001B12*
ID_OUI_FROM_DATABASE=Apprion
-OUI:001B17*
- ID_OUI_FROM_DATABASE=Palo Alto Networks
-
OUI:001B0B*
ID_OUI_FROM_DATABASE=Phidgets Inc.
@@ -30386,9 +31895,6 @@ OUI:001534*
OUI:001440*
ID_OUI_FROM_DATABASE=ATOMIC Corporation
-OUI:001439*
- ID_OUI_FROM_DATABASE=Blonder Tongue Laboratories, Inc.
-
OUI:001434*
ID_OUI_FROM_DATABASE=Keri Systems, Inc
@@ -32087,9 +33593,6 @@ OUI:000903*
OUI:0008FE*
ID_OUI_FROM_DATABASE=UNIK C&C Co.,Ltd.
-OUI:0008FA*
- ID_OUI_FROM_DATABASE=Karl E.Brinkmann GmbH
-
OUI:0008EE*
ID_OUI_FROM_DATABASE=Logic Product Development
@@ -32144,9 +33647,6 @@ OUI:0008C0*
OUI:0008C5*
ID_OUI_FROM_DATABASE=Liontech Co., Ltd.
-OUI:0008C9*
- ID_OUI_FROM_DATABASE=TechniSat Digital GmbH
-
OUI:0008CA*
ID_OUI_FROM_DATABASE=TwinHan Technology Co.,Ltd
@@ -33419,9 +34919,6 @@ OUI:00302D*
OUI:003025*
ID_OUI_FROM_DATABASE=CHECKOUT COMPUTER SYSTEMS, LTD
-OUI:00D01F*
- ID_OUI_FROM_DATABASE=Senetas Security
-
OUI:003012*
ID_OUI_FROM_DATABASE=DIGITAL ENGINEERING LTD.
@@ -33956,9 +35453,6 @@ OUI:001032*
OUI:001025*
ID_OUI_FROM_DATABASE=Grayhill, Inc
-OUI:001009*
- ID_OUI_FROM_DATABASE=HORO QUARTZ
-
OUI:0010F8*
ID_OUI_FROM_DATABASE=TEXIO TECHNOLOGY CORPORATION
@@ -34223,9 +35717,6 @@ OUI:00601E*
OUI:0060F8*
ID_OUI_FROM_DATABASE=Loran International Technologies Inc.
-OUI:006088*
- ID_OUI_FROM_DATABASE=WHITE MOUNTAIN DSP, INC.
-
OUI:00609A*
ID_OUI_FROM_DATABASE=NJK TECHNO CO.
@@ -34625,9 +36116,6 @@ OUI:00C0DF*
OUI:00C0F6*
ID_OUI_FROM_DATABASE=CELAN TECHNOLOGY INC.
-OUI:00C08F*
- ID_OUI_FROM_DATABASE=Panasonic Electric Works Co., Ltd.
-
OUI:00C012*
ID_OUI_FROM_DATABASE=NETSPAN CORPORATION
@@ -35207,9 +36695,6 @@ OUI:00789E*
OUI:44E9DD*
ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
-OUI:10F681*
- ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
-
OUI:B888E3*
ID_OUI_FROM_DATABASE=COMPAL INFORMATION (KUNSHAN) CO., LTD.
@@ -35507,18 +36992,6 @@ OUI:FCB4E6*
OUI:F05C19*
ID_OUI_FROM_DATABASE=Aruba Networks
-OUI:C43DC7*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:000FB5*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:00095B*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:F87394*
- ID_OUI_FROM_DATABASE=NETGEAR
-
OUI:70AAB2*
ID_OUI_FROM_DATABASE=BlackBerry RTS
@@ -35540,15 +37013,6 @@ OUI:745AAA*
OUI:7C1CF1*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-OUI:C0FFD4*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:405D82*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:803773*
- ID_OUI_FROM_DATABASE=NETGEAR
-
OUI:00264D*
ID_OUI_FROM_DATABASE=Arcadyan Technology Corporation
@@ -35807,9 +37271,6 @@ OUI:3CBEE1*
OUI:047E4A*
ID_OUI_FROM_DATABASE=moobox CO., Ltd.
-OUI:F01B6C*
- ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
-
OUI:E0C767*
ID_OUI_FROM_DATABASE=Apple, Inc.
@@ -35876,9 +37337,6 @@ OUI:54D0B4*
OUI:D017C2*
ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
-OUI:10DA43*
- ID_OUI_FROM_DATABASE=NETGEAR
-
OUI:001625*
ID_OUI_FROM_DATABASE=Impinj, Inc.
@@ -35900,15 +37358,6 @@ OUI:2C2D48*
OUI:E4A471*
ID_OUI_FROM_DATABASE=Intel Corporate
-OUI:60B617*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
-OUI:18A3E8*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
-OUI:741E93*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
OUI:00A0F4*
ID_OUI_FROM_DATABASE=GE
@@ -35933,9 +37382,6 @@ OUI:0CBF3F*
OUI:84FEDC*
ID_OUI_FROM_DATABASE=Borqs Beijing Ltd.
-OUI:F03E90*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:D8D723*
ID_OUI_FROM_DATABASE=IDS, Inc
@@ -36128,9 +37574,6 @@ OUI:E8A7F2*
OUI:D8209F*
ID_OUI_FROM_DATABASE=Cubro Acronet GesmbH
-OUI:CC500A*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
OUI:A860B6*
ID_OUI_FROM_DATABASE=Apple, Inc.
@@ -36245,9 +37688,6 @@ OUI:588BF3*
OUI:D8B02E*
ID_OUI_FROM_DATABASE=Guangzhou Zonerich Business Machine Co., LTD.
-OUI:DC1AC5*
- ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
-
OUI:849D64*
ID_OUI_FROM_DATABASE=SMC Corporation
@@ -36458,9 +37898,6 @@ OUI:00C017*
OUI:D49B5C*
ID_OUI_FROM_DATABASE=Chongqing Miedu Technology Co., Ltd.
-OUI:EC8CA2*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:C411E0*
ID_OUI_FROM_DATABASE=Bull Group Co., Ltd
@@ -36623,9 +38060,6 @@ OUI:8CEA1B*
OUI:001650*
ID_OUI_FROM_DATABASE=Kratos EPD
-OUI:9CFBD5*
- ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
-
OUI:583112*
ID_OUI_FROM_DATABASE=DRUST
@@ -36755,12 +38189,6 @@ OUI:B08900*
OUI:640DCE*
ID_OUI_FROM_DATABASE=SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD.
-OUI:00A085*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:ACDE48*
- ID_OUI_FROM_DATABASE=Private
-
OUI:6063F9*
ID_OUI_FROM_DATABASE=Ciholas, Inc.
@@ -37058,9 +38486,6 @@ OUI:500959*
OUI:143365*
ID_OUI_FROM_DATABASE=TEM Mobile Limited
-OUI:205D47*
- ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
-
OUI:C0F945*
ID_OUI_FROM_DATABASE=Toshiba Toko Meter Systems Co., LTD.
@@ -37100,12 +38525,6 @@ OUI:C83DD4*
OUI:487B6B*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-OUI:3087D9*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
-OUI:A8E705*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
OUI:9C62AB*
ID_OUI_FROM_DATABASE=Sumavision Technologies Co.,Ltd
@@ -37544,9 +38963,6 @@ OUI:E442A6*
OUI:6045CB*
ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
-OUI:74C9A3*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
OUI:84AFEC*
ID_OUI_FROM_DATABASE=BUFFALO.INC
@@ -37580,9 +38996,6 @@ OUI:B03D96*
OUI:B02628*
ID_OUI_FROM_DATABASE=Broadcom Limited
-OUI:24792A*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:0080E7*
ID_OUI_FROM_DATABASE=Leonardo Tactical Systems.
@@ -37871,6 +39284,474 @@ OUI:A009ED*
OUI:90FB5B*
ID_OUI_FROM_DATABASE=Avaya Inc
+OUI:3C0CDB*
+ ID_OUI_FROM_DATABASE=UNIONMAN TECHNOLOGY CO.,LTD
+
+OUI:C81FEA*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:10F681*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:F01B6C*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:DC1AC5*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:205D47*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:9CFBD5*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:886AE3*
+ ID_OUI_FROM_DATABASE=Alpha Networks Inc.
+
+OUI:9061AE*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:A4F3E7*
+ ID_OUI_FROM_DATABASE=Integrated Device Technology (Malaysia) Sdn. Bhd.
+
+OUI:A0239F*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:D8DF7A*
+ ID_OUI_FROM_DATABASE=Quest Software, Inc.
+
+OUI:30B62D*
+ ID_OUI_FROM_DATABASE=Mojo Networks, Inc.
+
+OUI:001B17*
+ ID_OUI_FROM_DATABASE=Palo Alto Networks
+
+OUI:9828A6*
+ ID_OUI_FROM_DATABASE=COMPAL INFORMATION (KUNSHAN) CO., LTD.
+
+OUI:B0EABC*
+ ID_OUI_FROM_DATABASE=ASKEY COMPUTER CORP
+
+OUI:94C691*
+ ID_OUI_FROM_DATABASE=EliteGroup Computer Systems Co., LTD
+
+OUI:9C6F52*
+ ID_OUI_FROM_DATABASE=zte corporation
+
+OUI:A09D86*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent Shanghai Bell Co., Ltd
+
+OUI:E0CBBC*
+ ID_OUI_FROM_DATABASE=Cisco Meraki
+
+OUI:00D01F*
+ ID_OUI_FROM_DATABASE=Senetas Corporation Ltd
+
+OUI:A40450*
+ ID_OUI_FROM_DATABASE=nFore Technology Inc.
+
+OUI:4CB008*
+ ID_OUI_FROM_DATABASE=Shenzhen Gwelltimes Technology Co.,Ltd
+
+OUI:58B633*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:D4684D*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:2CE6CC*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:8C0C90*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:842096*
+ ID_OUI_FROM_DATABASE=SHENZHEN RF-LINK TECHNOLOGY CO.,LTD.
+
+OUI:3087D9*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:24792A*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:589396*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:74911A*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:00227F*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:002482*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:F03E90*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:EC8CA2*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:30F77F*
+ ID_OUI_FROM_DATABASE=S Mobile Devices Limited
+
+OUI:38E595*
+ ID_OUI_FROM_DATABASE=SHENZHEN GONGJIN ELECTRONICS CO.,LT
+
+OUI:5C5181*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:389AF6*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:E0AA96*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:507705*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:C4CB6B*
+ ID_OUI_FROM_DATABASE=Airista Flow, Inc.
+
+OUI:B05508*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:008BFC*
+ ID_OUI_FROM_DATABASE=mixi,Inc.
+
+OUI:2C4053*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:ACDE48*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:00A085*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:D09466*
+ ID_OUI_FROM_DATABASE=Dell Inc.
+
+OUI:F0EFD2*
+ ID_OUI_FROM_DATABASE=TF PAYMENT SERVICE CO., LTD
+
+OUI:30C01B*
+ ID_OUI_FROM_DATABASE=Shenzhen Jingxun Software Telecommunication Technology Co.,Ltd
+
+OUI:647C34*
+ ID_OUI_FROM_DATABASE=Ubee Interactive Co., Limited
+
+OUI:747D24*
+ ID_OUI_FROM_DATABASE=Phicomm (Shanghai) Co., Ltd.
+
+OUI:E817FC*
+ ID_OUI_FROM_DATABASE=Fujitsu Cloud Technologies Limited
+
+OUI:001009*
+ ID_OUI_FROM_DATABASE=HORANET
+
+OUI:6432A8*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:78BC1A*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:E4F004*
+ ID_OUI_FROM_DATABASE=Dell Inc.
+
+OUI:60F677*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:288CB8*
+ ID_OUI_FROM_DATABASE=zte corporation
+
+OUI:0C72D9*
+ ID_OUI_FROM_DATABASE=zte corporation
+
+OUI:602E20*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:E472E2*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:E86819*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:48BCA6*
+ ID_OUI_FROM_DATABASE=​ASUNG TECHNO CO.,Ltd
+
+OUI:8C7CFF*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:C4F57C*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:00237F*
+ ID_OUI_FROM_DATABASE=PLANTRONICS, INC.
+
+OUI:00095B*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:000FB5*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:006069*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:000CDB*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:803773*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:405D82*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:C0FFD4*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:10DA43*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:B03956*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:C43DC7*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:F87394*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:401B5F*
+ ID_OUI_FROM_DATABASE=Weifang GoerTek Technology Co.,Ltd.
+
+OUI:AC512C*
+ ID_OUI_FROM_DATABASE=Infinix mobility limited
+
+OUI:90B1E0*
+ ID_OUI_FROM_DATABASE=Beijing Nebula Link Technology Co., Ltd
+
+OUI:6C090A*
+ ID_OUI_FROM_DATABASE=GEMATICA SRL
+
+OUI:001439*
+ ID_OUI_FROM_DATABASE=Blonder Tongue Laboratories, Inc
+
+OUI:107B44*
+ ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
+
+OUI:9C4FCF*
+ ID_OUI_FROM_DATABASE=TCT mobile ltd
+
+OUI:001BD3*
+ ID_OUI_FROM_DATABASE=Panasonic Corporation AVC Networks Company
+
+OUI:00C08F*
+ ID_OUI_FROM_DATABASE=Panasonic Electric Works Co., Ltd.
+
+OUI:0008C9*
+ ID_OUI_FROM_DATABASE=TechniSat Digital GmbH Daun
+
+OUI:20A6CD*
+ ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise
+
+OUI:F4F3AA*
+ ID_OUI_FROM_DATABASE=JBL GmbH & Co. KG
+
+OUI:38CD07*
+ ID_OUI_FROM_DATABASE=Beijing FaceCam Technology Co., Ltd.
+
+OUI:B009DA*
+ ID_OUI_FROM_DATABASE=Ring Solutions
+
+OUI:444AB0*
+ ID_OUI_FROM_DATABASE=Zhejiang Moorgen Intelligence Technology Co., Ltd
+
+OUI:844167*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:B4F61C*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:ECFA03*
+ ID_OUI_FROM_DATABASE=FCA
+
+OUI:78E103*
+ ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
+
+OUI:90324B*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
+OUI:78A6E1*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:F4D7B2*
+ ID_OUI_FROM_DATABASE=LGS Innovations, LLC
+
+OUI:20040F*
+ ID_OUI_FROM_DATABASE=Dell Inc.
+
+OUI:2C7360*
+ ID_OUI_FROM_DATABASE=Earda Technologies co Ltd
+
+OUI:048B42*
+ ID_OUI_FROM_DATABASE=Skspruce Technologies
+
+OUI:C421C8*
+ ID_OUI_FROM_DATABASE=KYOCERA CORPORATION
+
+OUI:9C63ED*
+ ID_OUI_FROM_DATABASE=zte corporation
+
+OUI:002692*
+ ID_OUI_FROM_DATABASE=Mitsubishi Electric Corporation
+
+OUI:F03D03*
+ ID_OUI_FROM_DATABASE=TECNO MOBILE LIMITED
+
+OUI:006088*
+ ID_OUI_FROM_DATABASE=Analog Devices, Inc.
+
+OUI:084ACF*
+ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+
+OUI:1CDDEA*
+ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+
+OUI:ECEBB8*
+ ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise
+
+OUI:5CE8B7*
+ ID_OUI_FROM_DATABASE=Oraimo Technology Limited
+
+OUI:D89EF3*
+ ID_OUI_FROM_DATABASE=Dell Inc.
+
+OUI:CC66B2*
+ ID_OUI_FROM_DATABASE=Nokia
+
+OUI:C0742B*
+ ID_OUI_FROM_DATABASE=SHENZHEN XUNLONG SOFTWARE CO.,LIMITED
+
+OUI:D8AFF1*
+ ID_OUI_FROM_DATABASE=Panasonic Appliances Company
+
+OUI:7086C1*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:A072E4*
+ ID_OUI_FROM_DATABASE=NJ SYSTEM CO.,LTD
+
+OUI:A8E824*
+ ID_OUI_FROM_DATABASE=INIM ELECTRONICS S.R.L.
+
+OUI:6CB749*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:A0FE61*
+ ID_OUI_FROM_DATABASE=Vivint Wireless Inc.
+
+OUI:601803*
+ ID_OUI_FROM_DATABASE=Daikin Air-conditioning (Shanghai) Co., Ltd.
+
+OUI:08152F*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co., Ltd. ARTIK
+
+OUI:408BF6*
+ ID_OUI_FROM_DATABASE=Shenzhen TCL New Technology Co., Ltd
+
+OUI:F46E24*
+ ID_OUI_FROM_DATABASE=NEC Personal Computers, Ltd.
+
+OUI:888279*
+ ID_OUI_FROM_DATABASE=Shenzhen RB-LINK Intelligent Technology Co.Ltd
+
+OUI:78321B*
+ ID_OUI_FROM_DATABASE=D-Link International
+
+OUI:EC51BC*
+ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+
+OUI:F079E8*
+ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+
+OUI:741E93*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:18A3E8*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:60B617*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:CC500A*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:A8E705*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:74C9A3*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:A013CB*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:20896F*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:D8A534*
+ ID_OUI_FROM_DATABASE=Spectronix Corporation
+
+OUI:583879*
+ ID_OUI_FROM_DATABASE=RICOH COMPANY, LTD.
+
+OUI:94282E*
+ ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd
+
+OUI:887598*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:D0B128*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:FCEEE6*
+ ID_OUI_FROM_DATABASE=FORMIKE ELECTRONIC CO., LTD
+
+OUI:D843ED*
+ ID_OUI_FROM_DATABASE=Suzuken
+
+OUI:2C431A*
+ ID_OUI_FROM_DATABASE=Shenzhen YOUHUA Technology Co., Ltd
+
+OUI:A8D3C8*
+ ID_OUI_FROM_DATABASE=Topcon Electronics GmbH & Co. KG
+
+OUI:389F5A*
+ ID_OUI_FROM_DATABASE=C-Kur TV Inc.
+
+OUI:24B209*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:24E124*
+ ID_OUI_FROM_DATABASE=Xiamen Ursaconn Technology Co. , Ltd.
+
+OUI:DC68EB*
+ ID_OUI_FROM_DATABASE=Nintendo Co.,Ltd
+
+OUI:9441C1*
+ ID_OUI_FROM_DATABASE=Mini-Cam Limited
+
+OUI:E8D819*
+ ID_OUI_FROM_DATABASE=AzureWave Technology Inc.
+
+OUI:0008FA*
+ ID_OUI_FROM_DATABASE=KEB Automation KG
+
+OUI:18396E*
+ ID_OUI_FROM_DATABASE=SUNSEA TELECOMMUNICATIONS CO.,LTD.
+
+OUI:E8DF70*
+ ID_OUI_FROM_DATABASE=AVM Audiovisuelles Marketing und Computersysteme GmbH
+
OUI:5846E1*
ID_OUI_FROM_DATABASE=Baxter International Inc
@@ -38174,9 +40055,6 @@ OUI:808917*
OUI:5C899A*
ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
-OUI:E422A5*
- ID_OUI_FROM_DATABASE=PLANTRONICS, INC.
-
OUI:1C994C*
ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd.
@@ -38222,18 +40100,6 @@ OUI:44A7CF*
OUI:0013E0*
ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd.
-OUI:748EF8*
- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
-
-OUI:00E052*
- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
-
-OUI:000480*
- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
-
-OUI:000088*
- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
-
OUI:344B50*
ID_OUI_FROM_DATABASE=zte corporation
@@ -38399,12 +40265,6 @@ OUI:80E86F*
OUI:E4AA5D*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:000389*
- ID_OUI_FROM_DATABASE=PLANTRONICS, INC.
-
-OUI:0CE0E4*
- ID_OUI_FROM_DATABASE=PLANTRONICS, INC.
-
OUI:B0AA77*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
@@ -38900,9 +40760,6 @@ OUI:68EDA4*
OUI:B899B0*
ID_OUI_FROM_DATABASE=Cohere Technologies
-OUI:2CC5D3*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:80C5E6*
ID_OUI_FROM_DATABASE=Microsoft Corporation
@@ -38945,9 +40802,6 @@ OUI:BCF811*
OUI:A8827F*
ID_OUI_FROM_DATABASE=CIBN Oriental Network(Beijing) CO.,Ltd
-OUI:609C9F*
- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
-
OUI:900A39*
ID_OUI_FROM_DATABASE=Wiio, Inc.
@@ -39059,9 +40913,6 @@ OUI:60F189*
OUI:74A34A*
ID_OUI_FROM_DATABASE=ZIMI CORPORATION
-OUI:98F5A9*
- ID_OUI_FROM_DATABASE=OHSUNG ELECTRONICS CO.,LTD.
-
OUI:D89341*
ID_OUI_FROM_DATABASE=General Electric Global Research
@@ -39197,9 +41048,6 @@ OUI:B43934*
OUI:DCC622*
ID_OUI_FROM_DATABASE=BUHEUNG SYSTEM
-OUI:5C2BF5*
- ID_OUI_FROM_DATABASE=Vivint
-
OUI:D062A0*
ID_OUI_FROM_DATABASE=China Essence Technology (Zhumadian) Co., Ltd.
@@ -39254,9 +41102,6 @@ OUI:94B40F*
OUI:4C2C83*
ID_OUI_FROM_DATABASE=Zhejiang KaNong Network Technology Co.,Ltd.
-OUI:BCC342*
- ID_OUI_FROM_DATABASE=Panasonic System Networks Co., Ltd.
-
OUI:E89606*
ID_OUI_FROM_DATABASE=testo Instruments (Shenzhen) Co., Ltd.
@@ -39557,9 +41402,6 @@ OUI:387B47*
OUI:7CCD11*
ID_OUI_FROM_DATABASE=MS-Magnet
-OUI:94FBB2*
- ID_OUI_FROM_DATABASE=Shenzhen Gongjin Electronics Co.,Ltd
-
OUI:4CE1BB*
ID_OUI_FROM_DATABASE=Zhuhai HiFocus Technology Co., Ltd.
@@ -39665,9 +41507,6 @@ OUI:D46867*
OUI:68692E*
ID_OUI_FROM_DATABASE=Zycoo Co.,Ltd
-OUI:A875E2*
- ID_OUI_FROM_DATABASE=Aventura Technologies, Inc.
-
OUI:38BF2F*
ID_OUI_FROM_DATABASE=Espec Corp.
@@ -39812,9 +41651,6 @@ OUI:DC1792*
OUI:7C8306*
ID_OUI_FROM_DATABASE=Glen Dimplex Nordic as
-OUI:84253F*
- ID_OUI_FROM_DATABASE=Silex Technology, Inc
-
OUI:907A0A*
ID_OUI_FROM_DATABASE=Gebr. Bode GmbH & Co KG
@@ -39917,9 +41753,6 @@ OUI:A05B21*
OUI:50B8A2*
ID_OUI_FROM_DATABASE=ImTech Technologies LLC,
-OUI:A41566*
- ID_OUI_FROM_DATABASE=Wei Fang Goertek Electronics Co.,Ltd
-
OUI:B04C05*
ID_OUI_FROM_DATABASE=Fresenius Medical Care Deutschland GmbH
@@ -40376,9 +42209,6 @@ OUI:7093F8*
OUI:305D38*
ID_OUI_FROM_DATABASE=Beissbarth
-OUI:FCD6BD*
- ID_OUI_FROM_DATABASE=Robert Bosch GmbH
-
OUI:044A50*
ID_OUI_FROM_DATABASE=Ramaxel Technology (Shenzhen) limited company
@@ -40865,9 +42695,6 @@ OUI:64808B*
OUI:7C6B52*
ID_OUI_FROM_DATABASE=Tigaro Wireless
-OUI:48C1AC*
- ID_OUI_FROM_DATABASE=PLANTRONICS, INC.
-
OUI:046D42*
ID_OUI_FROM_DATABASE=Bryston Ltd.
@@ -40925,9 +42752,6 @@ OUI:FC2E2D*
OUI:E84E06*
ID_OUI_FROM_DATABASE=EDUP INTERNATIONAL (HK) CO., LTD
-OUI:70B921*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
OUI:E8C320*
ID_OUI_FROM_DATABASE=Austco Communication Systems Pty Ltd
@@ -41063,9 +42887,6 @@ OUI:040A83*
OUI:B42A39*
ID_OUI_FROM_DATABASE=ORBIT MERRET, spol. s r. o.
-OUI:B80B9D*
- ID_OUI_FROM_DATABASE=ROPEX Industrie-Elektronik GmbH
-
OUI:18AEBB*
ID_OUI_FROM_DATABASE=Siemens Convergence Creators GmbH&Co.KG
@@ -41117,9 +42938,6 @@ OUI:C0A26D*
OUI:205B2A*
ID_OUI_FROM_DATABASE=Private
-OUI:18B430*
- ID_OUI_FROM_DATABASE=Nest Labs Inc.
-
OUI:F8769B*
ID_OUI_FROM_DATABASE=Neopis Co., Ltd.
@@ -41195,9 +43013,6 @@ OUI:94E848*
OUI:AC5E8C*
ID_OUI_FROM_DATABASE=Utillink
-OUI:CC7EE7*
- ID_OUI_FROM_DATABASE=Panasonic AVC Networks Company
-
OUI:BC99BC*
ID_OUI_FROM_DATABASE=FonSee Technology Inc.
@@ -41324,9 +43139,6 @@ OUI:A036FA*
OUI:EC836C*
ID_OUI_FROM_DATABASE=RM Tech Co., Ltd.
-OUI:C0C520*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:6083B2*
ID_OUI_FROM_DATABASE=GkWare e.K.
@@ -41627,9 +43439,6 @@ OUI:389F83*
OUI:8C541D*
ID_OUI_FROM_DATABASE=LGE
-OUI:601283*
- ID_OUI_FROM_DATABASE=Soluciones Tecnologicas para la Salud y el Bienestar SA
-
OUI:003A9D*
ID_OUI_FROM_DATABASE=NEC Platforms, Ltd.
@@ -41816,9 +43625,6 @@ OUI:889821*
OUI:CC5076*
ID_OUI_FROM_DATABASE=Ocom Communications, Inc.
-OUI:705812*
- ID_OUI_FROM_DATABASE=Panasonic AVC Networks Company
-
OUI:7C2CF3*
ID_OUI_FROM_DATABASE=Secure Electrans Ltd
@@ -42785,9 +44591,6 @@ OUI:001DDA*
OUI:001DDF*
ID_OUI_FROM_DATABASE=Sunitec Enterprise Co., Ltd.
-OUI:001DCC*
- ID_OUI_FROM_DATABASE=Hetra Secure Solutions
-
OUI:001DC7*
ID_OUI_FROM_DATABASE=L-3 Communications Geneva Aerospace
@@ -43031,9 +44834,6 @@ OUI:001D07*
OUI:001D01*
ID_OUI_FROM_DATABASE=Neptune Digital
-OUI:001CFA*
- ID_OUI_FROM_DATABASE=Alarm.com
-
OUI:001CEE*
ID_OUI_FROM_DATABASE=SHARP Corporation
@@ -43418,9 +45218,6 @@ OUI:00198E*
OUI:001980*
ID_OUI_FROM_DATABASE=Gridpoint Systems
-OUI:001987*
- ID_OUI_FROM_DATABASE=Panasonic Mobile Communications Co., Ltd.
-
OUI:00197B*
ID_OUI_FROM_DATABASE=Picotest Corp.
@@ -43532,9 +45329,6 @@ OUI:001898*
OUI:001891*
ID_OUI_FROM_DATABASE=Zhongshan General K-mate Electronics Co., Ltd
-OUI:001885*
- ID_OUI_FROM_DATABASE=Avigilon Corporation
-
OUI:00188C*
ID_OUI_FROM_DATABASE=Mobile Action Technology Inc.
@@ -43745,9 +45539,6 @@ OUI:001741*
OUI:001733*
ID_OUI_FROM_DATABASE=SFR
-OUI:00173A*
- ID_OUI_FROM_DATABASE=Reach Systems Inc.
-
OUI:00172E*
ID_OUI_FROM_DATABASE=FXC Inc.
@@ -44039,9 +45830,6 @@ OUI:00152C*
OUI:00151F*
ID_OUI_FROM_DATABASE=Multivision Intelligent Surveillance (Hong Kong) Ltd
-OUI:001526*
- ID_OUI_FROM_DATABASE=Remote Technologies Inc
-
OUI:00151A*
ID_OUI_FROM_DATABASE=Hunter Engineering Company
@@ -44303,9 +46091,6 @@ OUI:001343*
OUI:00133D*
ID_OUI_FROM_DATABASE=Micro Memory Curtiss Wright Co
-OUI:00139D*
- ID_OUI_FROM_DATABASE=Marvell Hispana S.L.
-
OUI:00138B*
ID_OUI_FROM_DATABASE=Phantom Technologies LLC
@@ -44417,9 +46202,6 @@ OUI:00122B*
OUI:001212*
ID_OUI_FROM_DATABASE=PLUS Corporation
-OUI:001219*
- ID_OUI_FROM_DATABASE=Ahead Communication Systems Inc
-
OUI:0012D8*
ID_OUI_FROM_DATABASE=International Games System Co., Ltd.
@@ -46988,9 +48770,6 @@ OUI:00507C*
OUI:005065*
ID_OUI_FROM_DATABASE=TDK-Lambda Corporation
-OUI:0050C7*
- ID_OUI_FROM_DATABASE=Private
-
OUI:0050F4*
ID_OUI_FROM_DATABASE=SIGMATEK GMBH & CO. KG
@@ -47120,9 +48899,6 @@ OUI:00D06F*
OUI:00D04B*
ID_OUI_FROM_DATABASE=LA CIE GROUP S.A.
-OUI:00D060*
- ID_OUI_FROM_DATABASE=Panasonic Europe Ltd.
-
OUI:00D002*
ID_OUI_FROM_DATABASE=DITECH CORPORATION
@@ -48017,9 +49793,6 @@ OUI:00C083*
OUI:00C005*
ID_OUI_FROM_DATABASE=LIVINGSTON ENTERPRISES, INC.
-OUI:00C064*
- ID_OUI_FROM_DATABASE=GENERAL DATACOMM IND. INC.
-
OUI:00C0C8*
ID_OUI_FROM_DATABASE=MICRO BYTE PTY. LTD.
@@ -48356,9 +50129,6 @@ OUI:00405A*
OUI:00404C*
ID_OUI_FROM_DATABASE=HYPERTEC PTY LTD.
-OUI:00C0EE*
- ID_OUI_FROM_DATABASE=KYOCERA CORPORATION
-
OUI:00C0CB*
ID_OUI_FROM_DATABASE=CONTROL TECHNOLOGY CORPORATION
@@ -48728,9 +50498,6 @@ OUI:080053*
OUI:08004F*
ID_OUI_FROM_DATABASE=CYGNET SYSTEMS
-OUI:F8E71E*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:00194B*
ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
@@ -48746,12 +50513,6 @@ OUI:A01B29*
OUI:90013B*
ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
-OUI:ECDF3A*
- ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
-
-OUI:E45AA2*
- ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
-
OUI:00235A*
ID_OUI_FROM_DATABASE=COMPAL INFORMATION (KUNSHAN) CO., LTD.
@@ -49064,24 +50825,6 @@ OUI:000B6A*
OUI:40BA61*
ID_OUI_FROM_DATABASE=ARIMA Communications Corp.
-OUI:841B5E*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:204E7F*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:A021B7*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:0024B2*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:C03F0E*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:001F33*
- ID_OUI_FROM_DATABASE=NETGEAR
-
OUI:1883BF*
ID_OUI_FROM_DATABASE=Arcadyan Technology Corporation
@@ -49121,15 +50864,6 @@ OUI:002675*
OUI:001F3F*
ID_OUI_FROM_DATABASE=AVM GmbH
-OUI:506A03*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:6CB0CE*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:100D7F*
- ID_OUI_FROM_DATABASE=NETGEAR
-
OUI:0020D6*
ID_OUI_FROM_DATABASE=Breezecom, Ltd.
@@ -49487,9 +51221,6 @@ OUI:A89352*
OUI:AC5F3E*
ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO-MECHANICS(THAILAND)
-OUI:B07FB9*
- ID_OUI_FROM_DATABASE=NETGEAR
-
OUI:70661B*
ID_OUI_FROM_DATABASE=Sonova AG
@@ -49550,21 +51281,6 @@ OUI:405EE1*
OUI:10F005*
ID_OUI_FROM_DATABASE=Intel Corporate
-OUI:BC9889*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
-OUI:E42F26*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
-OUI:344B3D*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
-OUI:FCF647*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
-OUI:1088CE*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
OUI:D463FE*
ID_OUI_FROM_DATABASE=Arcadyan Corporation
@@ -49811,18 +51527,12 @@ OUI:042758*
OUI:3C92DC*
ID_OUI_FROM_DATABASE=Octopod Technology Co. Ltd.
-OUI:74CC39*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
OUI:6038E0*
ID_OUI_FROM_DATABASE=Belkin International Inc.
OUI:F0FDA0*
ID_OUI_FROM_DATABASE=Acurix Networks Pty Ltd
-OUI:1CB9C4*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:3876D1*
ID_OUI_FROM_DATABASE=Euronda SpA
@@ -50075,9 +51785,6 @@ OUI:A84E3F*
OUI:00A742*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:6CA858*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
OUI:001478*
ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
@@ -50984,56 +52691,50 @@ OUI:F87588*
OUI:BC3F8F*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-OUI:E4A749*
- ID_OUI_FROM_DATABASE=Palo Alto Networks
-
OUI:04DEF2*
ID_OUI_FROM_DATABASE=Shenzhen ECOM Technology Co. Ltd
OUI:00D071*
ID_OUI_FROM_DATABASE=ECHELON CORP.
+OUI:504061*
+ ID_OUI_FROM_DATABASE=Nokia
+
OUI:0030C5*
ID_OUI_FROM_DATABASE=CADENCE DESIGN SYSTEMS, INC.
-OUI:504061*
- ID_OUI_FROM_DATABASE=Nokia
+OUI:54E3F6*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent
OUI:7467F7*
ID_OUI_FROM_DATABASE=Extreme Networks
+OUI:B0C205*
+ ID_OUI_FROM_DATABASE=BIONIME
+
+OUI:0C61CF*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
OUI:B4C799*
ID_OUI_FROM_DATABASE=Extreme Networks
-OUI:54E3F6*
- ID_OUI_FROM_DATABASE=Alcatel-Lucent
-
OUI:5C0E8B*
ID_OUI_FROM_DATABASE=Extreme Networks
OUI:00E02B*
ID_OUI_FROM_DATABASE=Extreme Networks
-OUI:B0C205*
- ID_OUI_FROM_DATABASE=BIONIME
-
-OUI:0C61CF*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
OUI:7C2664*
ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
-OUI:E47DEB*
- ID_OUI_FROM_DATABASE=Shanghai Notion Information Technology CO.,LTD.
-
OUI:A002DC*
ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
OUI:0C47C9*
ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
-OUI:28EF01*
- ID_OUI_FROM_DATABASE=Private
+OUI:E47DEB*
+ ID_OUI_FROM_DATABASE=Shanghai Notion Information Technology CO.,LTD.
OUI:747548*
ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
@@ -51086,18 +52787,9 @@ OUI:4C82CF*
OUI:F49634*
ID_OUI_FROM_DATABASE=Intel Corporate
-OUI:F470AB*
- ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
-
-OUI:341A35*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
OUI:6C4B90*
ID_OUI_FROM_DATABASE=LiteON
-OUI:08028E*
- ID_OUI_FROM_DATABASE=NETGEAR
-
OUI:F8FF0B*
ID_OUI_FROM_DATABASE=Electronic Technology Inc.
@@ -51110,15 +52802,15 @@ OUI:90F305*
OUI:00093A*
ID_OUI_FROM_DATABASE=Molex
+OUI:C8F86D*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent Shanghai Bell Co., Ltd
+
OUI:B8D50B*
ID_OUI_FROM_DATABASE=Sunitec Enterprise Co.,Ltd
OUI:28A6DB*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-OUI:C8F86D*
- ID_OUI_FROM_DATABASE=Alcatel-Lucent Shanghai Bell Co., Ltd
-
OUI:D45F25*
ID_OUI_FROM_DATABASE=Shenzhen YOUHUA Technology Co., Ltd
@@ -51143,6 +52835,12 @@ OUI:F4DE0C*
OUI:BC8AE8*
ID_OUI_FROM_DATABASE=QING DAO HAIER TELECOM CO.,LTD.
+OUI:A81B5A*
+ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+
+OUI:DC6DCD*
+ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+
OUI:440444*
ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
@@ -51158,11 +52856,8 @@ OUI:38295A*
OUI:4C1A3D*
ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
-OUI:A81B5A*
- ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
-
-OUI:DC6DCD*
- ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+OUI:185207*
+ ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO., LTD
OUI:70D379*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
@@ -51170,9 +52865,6 @@ OUI:70D379*
OUI:7C4F7D*
ID_OUI_FROM_DATABASE=Sawwave
-OUI:185207*
- ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO., LTD
-
OUI:9874DA*
ID_OUI_FROM_DATABASE=Infinix mobility limited
@@ -51200,38 +52892,38 @@ OUI:EC363F*
OUI:54FA3E*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:0C8910*
+OUI:B8BBAF*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:FCF136*
+OUI:60C5AD*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:981DFA*
+OUI:28395E*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:84A466*
+OUI:C4AE12*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:1867B0*
- ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+OUI:10D07A*
+ ID_OUI_FROM_DATABASE=AMPAK Technology, Inc.
-OUI:CCB11A*
+OUI:0C8910*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:B8BBAF*
+OUI:FCF136*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:60C5AD*
+OUI:981DFA*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:28395E*
+OUI:84A466*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:C4AE12*
+OUI:1867B0*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:10D07A*
- ID_OUI_FROM_DATABASE=AMPAK Technology, Inc.
+OUI:CCB11A*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
OUI:80B234*
ID_OUI_FROM_DATABASE=Technicolor CH USA Inc.
@@ -51239,18 +52931,9 @@ OUI:80B234*
OUI:B877C3*
ID_OUI_FROM_DATABASE=METER Group
-OUI:003676*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:84E058*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
OUI:F07485*
ID_OUI_FROM_DATABASE=NGD Systems, Inc.
-OUI:347A60*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
OUI:BC644B*
ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
@@ -51275,24 +52958,6 @@ OUI:745612*
OUI:E46449*
ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-OUI:C005C2*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:6455B1*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:203D66*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:D404CD*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:446AB7*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:2C9924*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
OUI:001BDD*
ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
@@ -51380,11 +53045,35 @@ OUI:8C09F4*
OUI:3CDFA9*
ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-OUI:105611*
+OUI:003676*
ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-OUI:2C3AE8*
- ID_OUI_FROM_DATABASE=Espressif Inc.
+OUI:84E058*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:347A60*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:C005C2*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:6455B1*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:203D66*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:D404CD*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:446AB7*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:2C9924*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:105611*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
OUI:DC74A8*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
@@ -51392,30 +53081,33 @@ OUI:DC74A8*
OUI:C087EB*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+OUI:2C3AE8*
+ ID_OUI_FROM_DATABASE=Espressif Inc.
+
+OUI:74F61C*
+ ID_OUI_FROM_DATABASE=HTC Corporation
+
OUI:E8B6C2*
ID_OUI_FROM_DATABASE=Juniper Networks
OUI:B0DAF9*
ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-OUI:74F61C*
- ID_OUI_FROM_DATABASE=HTC Corporation
-
OUI:3438B7*
ID_OUI_FROM_DATABASE=HUMAX Co., Ltd.
OUI:5C1A6F*
ID_OUI_FROM_DATABASE=Cambridge Industries(Group) Co.,Ltd.
+OUI:487D2E*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
+
OUI:B089C2*
ID_OUI_FROM_DATABASE=Zyptonite
OUI:F0D4F6*
ID_OUI_FROM_DATABASE=Lars Thrane A/S
-OUI:487D2E*
- ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
-
OUI:0403D6*
ID_OUI_FROM_DATABASE=Nintendo Co.,Ltd
@@ -51431,14 +53123,14 @@ OUI:6C60EB*
OUI:AC4E2E*
ID_OUI_FROM_DATABASE=Shenzhen JingHanDa Electronics Co.Ltd
-OUI:B40016*
- ID_OUI_FROM_DATABASE=INGENICO TERMINALS SAS
-
OUI:0027E3*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:A0341B*
- ID_OUI_FROM_DATABASE=TrackR, Inc
+OUI:488D36*
+ ID_OUI_FROM_DATABASE=Arcadyan Corporation
+
+OUI:B40016*
+ ID_OUI_FROM_DATABASE=INGENICO TERMINALS SAS
OUI:FCA667*
ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
@@ -51446,8 +53138,8 @@ OUI:FCA667*
OUI:784501*
ID_OUI_FROM_DATABASE=Biamp Systems
-OUI:488D36*
- ID_OUI_FROM_DATABASE=Arcadyan Corporation
+OUI:A0341B*
+ ID_OUI_FROM_DATABASE=TrackR, Inc
OUI:986F60*
ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
@@ -51455,6 +53147,12 @@ OUI:986F60*
OUI:4C189A*
ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+OUI:6CA849*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:A4251B*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
OUI:E45D52*
ID_OUI_FROM_DATABASE=Avaya Inc
@@ -51473,7 +53171,7 @@ OUI:14612F*
OUI:707C69*
ID_OUI_FROM_DATABASE=Avaya Inc
-OUI:A47886*
+OUI:FC8399*
ID_OUI_FROM_DATABASE=Avaya Inc
OUI:44322A*
@@ -51482,17 +53180,488 @@ OUI:44322A*
OUI:048A15*
ID_OUI_FROM_DATABASE=Avaya Inc
-OUI:6CA849*
+OUI:00040D*
ID_OUI_FROM_DATABASE=Avaya Inc
-OUI:A4251B*
+OUI:A47886*
ID_OUI_FROM_DATABASE=Avaya Inc
-OUI:00040D*
- ID_OUI_FROM_DATABASE=Avaya Inc
+OUI:001CFA*
+ ID_OUI_FROM_DATABASE=Alarm.com
-OUI:FC8399*
- ID_OUI_FROM_DATABASE=Avaya Inc
+OUI:60313B*
+ ID_OUI_FROM_DATABASE=Sunnovo International Limited
+
+OUI:B4E62A*
+ ID_OUI_FROM_DATABASE=LG Innotek
+
+OUI:E45AA2*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:ECDF3A*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:F470AB*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:50184C*
+ ID_OUI_FROM_DATABASE=Platina Systems Inc.
+
+OUI:E4A749*
+ ID_OUI_FROM_DATABASE=Palo Alto Networks
+
+OUI:786D94*
+ ID_OUI_FROM_DATABASE=Palo Alto Networks
+
+OUI:CC4639*
+ ID_OUI_FROM_DATABASE=WAAV, Inc.
+
+OUI:30B164*
+ ID_OUI_FROM_DATABASE=Power Electronics International Inc.
+
+OUI:18B430*
+ ID_OUI_FROM_DATABASE=Nest Labs Inc.
+
+OUI:3CF591*
+ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+
+OUI:602101*
+ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+
+OUI:604762*
+ ID_OUI_FROM_DATABASE=Beijing Sensoro Technology Co.,Ltd.
+
+OUI:7CE2CA*
+ ID_OUI_FROM_DATABASE=Juniper Networks
+
+OUI:B0DFC1*
+ ID_OUI_FROM_DATABASE=Tenda Technology Co.,Ltd.Dongguan branch
+
+OUI:70788B*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:001DCC*
+ ID_OUI_FROM_DATABASE=Ayon Cyber Security, Inc
+
+OUI:7065A3*
+ ID_OUI_FROM_DATABASE=Kandao lightforge Co., Ltd.
+
+OUI:706E6D*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:FC2F6B*
+ ID_OUI_FROM_DATABASE=Everspin Technologies, Inc.
+
+OUI:B4C170*
+ ID_OUI_FROM_DATABASE=Yi chip Microelectronics (Hangzhou) Co., Ltd
+
+OUI:540237*
+ ID_OUI_FROM_DATABASE=Teltronic AG
+
+OUI:2CC5D3*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:F8E71E*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:1CB9C4*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:C0C520*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:A89675*
+ ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company
+
+OUI:94F128*
+ ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise
+
+OUI:94FBB2*
+ ID_OUI_FROM_DATABASE=SHENZHEN GONGJIN ELECTRONICS CO.,LT
+
+OUI:A47B9D*
+ ID_OUI_FROM_DATABASE=Espressif Inc.
+
+OUI:608E08*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:7C2EDD*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:3CF7A4*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:342D0D*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:EC3DFD*
+ ID_OUI_FROM_DATABASE=SHENZHEN BILIAN ELECTRONIC CO.,LTD
+
+OUI:001885*
+ ID_OUI_FROM_DATABASE=Avigilon Corporation
+
+OUI:18742E*
+ ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
+
+OUI:8886C2*
+ ID_OUI_FROM_DATABASE=STABILO International GmbH
+
+OUI:04FA3F*
+ ID_OUI_FROM_DATABASE=Opticore Inc.
+
+OUI:308454*
+ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+
+OUI:FC7F56*
+ ID_OUI_FROM_DATABASE=CoSyst Control Systems GmbH
+
+OUI:8C2505*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:94D029*
+ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+
+OUI:4C49E3*
+ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd
+
+OUI:28D436*
+ ID_OUI_FROM_DATABASE=Jiangsu dewosi electric co., LTD
+
+OUI:149346*
+ ID_OUI_FROM_DATABASE=PNI sensor corporation
+
+OUI:18B81F*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:00C064*
+ ID_OUI_FROM_DATABASE=General Datacomm LLC
+
+OUI:601283*
+ ID_OUI_FROM_DATABASE=TSB REAL TIME LOCATION SYSTEMS S.L.
+
+OUI:E06089*
+ ID_OUI_FROM_DATABASE=Cloudleaf, Inc.
+
+OUI:001219*
+ ID_OUI_FROM_DATABASE=General Datacomm LLC
+
+OUI:BC54FC*
+ ID_OUI_FROM_DATABASE=SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD.
+
+OUI:547595*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
+
+OUI:18BC5A*
+ ID_OUI_FROM_DATABASE=Zhejiang Tmall Technology Co., Ltd.
+
+OUI:00869C*
+ ID_OUI_FROM_DATABASE=Palo Alto Networks
+
+OUI:00139D*
+ ID_OUI_FROM_DATABASE=MaxLinear Hispania S.L.U.
+
+OUI:4C16FC*
+ ID_OUI_FROM_DATABASE=Juniper Networks
+
+OUI:609C9F*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:000088*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:000480*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:00E052*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:748EF8*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:48C1AC*
+ ID_OUI_FROM_DATABASE=PLANTRONICS, INC.
+
+OUI:0CE0E4*
+ ID_OUI_FROM_DATABASE=PLANTRONICS, INC.
+
+OUI:000389*
+ ID_OUI_FROM_DATABASE=PLANTRONICS, INC.
+
+OUI:E422A5*
+ ID_OUI_FROM_DATABASE=PLANTRONICS, INC.
+
+OUI:001F33*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:C03F0E*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:0024B2*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:A021B7*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:204E7F*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:841B5E*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:100D7F*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:6CB0CE*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:506A03*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:B07FB9*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:08028E*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:D8C497*
+ ID_OUI_FROM_DATABASE=Quanta Computer Inc.
+
+OUI:444E6D*
+ ID_OUI_FROM_DATABASE=AVM Audiovisuelles Marketing und Computersysteme GmbH
+
+OUI:A41566*
+ ID_OUI_FROM_DATABASE=Weifang GoerTek Technology Co.,Ltd.
+
+OUI:74E60F*
+ ID_OUI_FROM_DATABASE=TECNO MOBILE LIMITED
+
+OUI:0050C7*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:B80B9D*
+ ID_OUI_FROM_DATABASE=ROPEX Industrie-Elektronik GmbH
+
+OUI:001526*
+ ID_OUI_FROM_DATABASE=Remote Technologies Inc
+
+OUI:409922*
+ ID_OUI_FROM_DATABASE=AzureWave Technology Inc.
+
+OUI:B8DB1C*
+ ID_OUI_FROM_DATABASE=Integrated Device Technology (Malaysia) Sdn. Bhd.
+
+OUI:3C10E6*
+ ID_OUI_FROM_DATABASE=PHAZR Inc.
+
+OUI:001987*
+ ID_OUI_FROM_DATABASE=Panasonic Mobile Communications Co.,Ltd.
+
+OUI:BCC342*
+ ID_OUI_FROM_DATABASE=Panasonic Communications Co., Ltd.
+
+OUI:705812*
+ ID_OUI_FROM_DATABASE=Panasonic Corporation AVC Networks Company
+
+OUI:CC7EE7*
+ ID_OUI_FROM_DATABASE=Panasonic Corporation AVC Networks Company
+
+OUI:00D060*
+ ID_OUI_FROM_DATABASE=Panasonic Europe Ltd.
+
+OUI:84253F*
+ ID_OUI_FROM_DATABASE=silex technology, Inc.
+
+OUI:40017A*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:40D63C*
+ ID_OUI_FROM_DATABASE=Equitech Industrial(DongGuan)Co.,Ltd
+
+OUI:A4E975*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:C0A53E*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:9800C6*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:787B8A*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:3866F0*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:20EE28*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:08F4AB*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:8C8590*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:FC017C*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
+OUI:2CB21A*
+ ID_OUI_FROM_DATABASE=Phicomm (Shanghai) Co., Ltd.
+
+OUI:00C0EE*
+ ID_OUI_FROM_DATABASE=KYOCERA Display Corporation
+
+OUI:28840E*
+ ID_OUI_FROM_DATABASE=silicon valley immigration service
+
+OUI:CC5A53*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:BC2E48*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:940006*
+ ID_OUI_FROM_DATABASE=jinyoung
+
+OUI:5C6776*
+ ID_OUI_FROM_DATABASE=IDS Imaging Development Systems GmbH
+
+OUI:28EF01*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:A875E2*
+ ID_OUI_FROM_DATABASE=Aventura Technologies, Inc.
+
+OUI:DC0C2D*
+ ID_OUI_FROM_DATABASE=WEIFANG GOERTEK ELECTRONICS CO.,LTD
+
+OUI:00173A*
+ ID_OUI_FROM_DATABASE=Cloudastructure Inc
+
+OUI:38D620*
+ ID_OUI_FROM_DATABASE=Limidea Concept Pte. Ltd.
+
+OUI:745C4B*
+ ID_OUI_FROM_DATABASE=GN Audio A/S
+
+OUI:64FB50*
+ ID_OUI_FROM_DATABASE=RoomReady/Zdi, Inc.
+
+OUI:940E6B*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:38378B*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:5C2BF5*
+ ID_OUI_FROM_DATABASE=Vivint Wireless Inc.
+
+OUI:00FC8B*
+ ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
+
+OUI:10F163*
+ ID_OUI_FROM_DATABASE=TNK CO.,LTD
+
+OUI:98F5A9*
+ ID_OUI_FROM_DATABASE=OHSUNG
+
+OUI:5033F0*
+ ID_OUI_FROM_DATABASE=YICHEN (SHENZHEN) TECHNOLOGY CO.LTD
+
+OUI:50F722*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:90FD9F*
+ ID_OUI_FROM_DATABASE=Silicon Laboratories
+
+OUI:504EDC*
+ ID_OUI_FROM_DATABASE=Ping Communication
+
+OUI:344B3D*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:E42F26*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:BC9889*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:1088CE*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:FCF647*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:74CC39*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:6CA858*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:341A35*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:18D225*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:185282*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:BC4101*
+ ID_OUI_FROM_DATABASE=Shenzhen TINNO Mobile Technology Corp.
+
+OUI:5C8D2D*
+ ID_OUI_FROM_DATABASE=Shanghai Wellpay Information Technology Co., Ltd
+
+OUI:70B921*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:C850E9*
+ ID_OUI_FROM_DATABASE=Raisecom Technology CO., LTD
+
+OUI:BC825D*
+ ID_OUI_FROM_DATABASE=MITSUMI ELECTRIC CO.,LTD.
+
+OUI:5CA176*
+ ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO., LTD
+
+OUI:C8E7F0*
+ ID_OUI_FROM_DATABASE=Juniper Networks
+
+OUI:087808*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:D03169*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:BC5451*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:24F5A2*
+ ID_OUI_FROM_DATABASE=Belkin International Inc.
+
+OUI:782D7E*
+ ID_OUI_FROM_DATABASE=TRENDnet, Inc.
+
+OUI:BCC31B*
+ ID_OUI_FROM_DATABASE=Kygo Life AS
+
+OUI:FCD6BD*
+ ID_OUI_FROM_DATABASE=Robert Bosch GmbH
+
+OUI:48BA4E*
+ ID_OUI_FROM_DATABASE=Hewlett Packard
+
+OUI:FC65DE*
+ ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
+
+OUI:B06EBF*
+ ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
+
+OUI:28AD3E*
+ ID_OUI_FROM_DATABASE=Shenzhen TONG BO WEI Technology CO.,LTD
+
+OUI:F092B4*
+ ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO., LTD
OUI:D86CE9*
ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
@@ -51659,9 +53828,6 @@ OUI:94659C*
OUI:1002B5*
ID_OUI_FROM_DATABASE=Intel Corporate
-OUI:A468BC*
- ID_OUI_FROM_DATABASE=Private
-
OUI:441EA1*
ID_OUI_FROM_DATABASE=Hewlett Packard
@@ -51719,9 +53885,6 @@ OUI:403DEC*
OUI:E84DD0*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-OUI:D81FCC*
- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
-
OUI:140467*
ID_OUI_FROM_DATABASE=SNK Technologies Co.,Ltd.
@@ -51791,24 +53954,6 @@ OUI:ACE87B*
OUI:688F84*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-OUI:889471*
- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
-
-OUI:CC4E24*
- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
-
-OUI:50EB1A*
- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
-
-OUI:0027F8*
- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
-
-OUI:000533*
- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
-
-OUI:0060DF*
- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
-
OUI:4CAC0A*
ID_OUI_FROM_DATABASE=zte corporation
@@ -52349,12 +54494,6 @@ OUI:B4EF04*
OUI:049645*
ID_OUI_FROM_DATABASE=WUXI SKY CHIP INTERCONNECTION TECHNOLOGY CO.,LTD.
-OUI:5CE3B6*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
-OUI:9C88AD*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
OUI:C8C2C6*
ID_OUI_FROM_DATABASE=Shanghai Airm2m Communication Technology Co., Ltd
@@ -52394,9 +54533,6 @@ OUI:044169*
OUI:ACC51B*
ID_OUI_FROM_DATABASE=Zhuhai Pantum Electronics Co., Ltd.
-OUI:4473D6*
- ID_OUI_FROM_DATABASE=Logitech
-
OUI:E80734*
ID_OUI_FROM_DATABASE=Champion Optical Network Engineering, LLC
@@ -52424,9 +54560,6 @@ OUI:CC20E8*
OUI:E435C8*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-OUI:38FF36*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:D47208*
ID_OUI_FROM_DATABASE=Bragi GmbH
@@ -52598,12 +54731,6 @@ OUI:4CEEB0*
OUI:188EF9*
ID_OUI_FROM_DATABASE=G2C Co. Ltd.
-OUI:809FAB*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
-OUI:D00492*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
OUI:F4E9D4*
ID_OUI_FROM_DATABASE=QLogic Corporation
@@ -52874,9 +55001,6 @@ OUI:70FC8C*
OUI:902CC7*
ID_OUI_FROM_DATABASE=C-MAX Asia Limited
-OUI:1C965A*
- ID_OUI_FROM_DATABASE=Weifang goertek Electronics CO.,LTD
-
OUI:188219*
ID_OUI_FROM_DATABASE=Alibaba Cloud Computing Ltd.
@@ -53282,9 +55406,6 @@ OUI:38CA97*
OUI:84A783*
ID_OUI_FROM_DATABASE=Alcatel Lucent
-OUI:2C5D93*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:1CC11A*
ID_OUI_FROM_DATABASE=Wavetronix
@@ -53501,12 +55622,6 @@ OUI:B0793C*
OUI:20CEC4*
ID_OUI_FROM_DATABASE=Peraso Technologies
-OUI:04848A*
- ID_OUI_FROM_DATABASE=7INOVA TECHNOLOGY LIMITED
-
-OUI:20C6EB*
- ID_OUI_FROM_DATABASE=Panasonic Corporation AVC Networks Company
-
OUI:700FEC*
ID_OUI_FROM_DATABASE=Poindus Systems Corp.
@@ -53705,9 +55820,6 @@ OUI:E0C6B3*
OUI:FCDB96*
ID_OUI_FROM_DATABASE=ENERVALLEY CO., LTD
-OUI:FC8B97*
- ID_OUI_FROM_DATABASE=Shenzhen Gongjin Electronics Co.,Ltd
-
OUI:882E5A*
ID_OUI_FROM_DATABASE=storONE
@@ -53759,9 +55871,6 @@ OUI:D0CDE1*
OUI:94756E*
ID_OUI_FROM_DATABASE=QinetiQ North America
-OUI:543D37*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:0C5521*
ID_OUI_FROM_DATABASE=Axiros GmbH
@@ -53837,9 +55946,6 @@ OUI:E4EEFD*
OUI:105CBF*
ID_OUI_FROM_DATABASE=DuroByte Inc
-OUI:88A3CC*
- ID_OUI_FROM_DATABASE=Amatis Controls
-
OUI:EC89F5*
ID_OUI_FROM_DATABASE=Lenovo Mobile Communication Technology Ltd.
@@ -54110,12 +56216,6 @@ OUI:E804F3*
OUI:B85810*
ID_OUI_FROM_DATABASE=NUMERA, INC.
-OUI:2CAB25*
- ID_OUI_FROM_DATABASE=Shenzhen Gongjin Electronics Co.,Ltd
-
-OUI:AC6E1A*
- ID_OUI_FROM_DATABASE=Shenzhen Gongjin Electronics Co.,Ltd
-
OUI:9886B1*
ID_OUI_FROM_DATABASE=Flyaudio corporation (China)
@@ -54257,9 +56357,6 @@ OUI:04F17D*
OUI:A0DC04*
ID_OUI_FROM_DATABASE=Becker-Antriebe GmbH
-OUI:8CC121*
- ID_OUI_FROM_DATABASE=Panasonic Corporation AVC Networks Company
-
OUI:2CBE97*
ID_OUI_FROM_DATABASE=Ingenieurbuero Bickele und Buehler GmbH
@@ -54584,9 +56681,6 @@ OUI:902B34*
OUI:48E1AF*
ID_OUI_FROM_DATABASE=Vity
-OUI:245FDF*
- ID_OUI_FROM_DATABASE=KYOCERA Corporation
-
OUI:C0A0DE*
ID_OUI_FROM_DATABASE=Multi Touch Oy
@@ -54872,18 +56966,12 @@ OUI:0CE82F*
OUI:C0626B*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:74D0DC*
- ID_OUI_FROM_DATABASE=ERICSSON AB
-
OUI:B4B88D*
ID_OUI_FROM_DATABASE=Thuh Company
OUI:60F59C*
ID_OUI_FROM_DATABASE=CRU-Dataport
-OUI:C4108A*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:4C73A5*
ID_OUI_FROM_DATABASE=KOVE
@@ -55115,18 +57203,12 @@ OUI:64F987*
OUI:3C7437*
ID_OUI_FROM_DATABASE=RIM
-OUI:04209A*
- ID_OUI_FROM_DATABASE=Panasonic AVC Networks Company
-
OUI:64DC01*
ID_OUI_FROM_DATABASE=Static Systems Group PLC
OUI:1CF5E7*
ID_OUI_FROM_DATABASE=Turtle Industry Co., Ltd.
-OUI:9C4A7B*
- ID_OUI_FROM_DATABASE=Nokia Corporation
-
OUI:2C8065*
ID_OUI_FROM_DATABASE=HARTING Inc. of North America
@@ -55139,9 +57221,6 @@ OUI:E41C4B*
OUI:E0143E*
ID_OUI_FROM_DATABASE=Modoosis Inc.
-OUI:5C6984*
- ID_OUI_FROM_DATABASE=NUVICO
-
OUI:204AAA*
ID_OUI_FROM_DATABASE=Hanscan Spain S.A.
@@ -55202,9 +57281,6 @@ OUI:0006F6*
OUI:ACAB8D*
ID_OUI_FROM_DATABASE=Lyngso Marine A/S
-OUI:181456*
- ID_OUI_FROM_DATABASE=Nokia Corporation
-
OUI:E8995A*
ID_OUI_FROM_DATABASE=PiiGAB, Processinformation i Goteborg AB
@@ -55385,9 +57461,6 @@ OUI:DCFAD5*
OUI:D84606*
ID_OUI_FROM_DATABASE=Silicon Valley Global Marketing
-OUI:689234*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:D0E347*
ID_OUI_FROM_DATABASE=Yoga
@@ -55466,9 +57539,6 @@ OUI:30694B*
OUI:AC5135*
ID_OUI_FROM_DATABASE=MPI TECH
-OUI:E4EC10*
- ID_OUI_FROM_DATABASE=Nokia Corporation
-
OUI:00D38D*
ID_OUI_FROM_DATABASE=Hotel Technology Next Generation
@@ -55712,9 +57782,6 @@ OUI:64A837*
OUI:B4B5AF*
ID_OUI_FROM_DATABASE=Minsung Electronics
-OUI:044FAA*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:44568D*
ID_OUI_FROM_DATABASE=PNC Technologies Co., Ltd.
@@ -55880,9 +57947,6 @@ OUI:0025D1*
OUI:0025CB*
ID_OUI_FROM_DATABASE=Reiner SCT
-OUI:0025C4*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:0025BF*
ID_OUI_FROM_DATABASE=Wireless Cables Inc.
@@ -56837,9 +58901,6 @@ OUI:001EF1*
OUI:001F9E*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:001F92*
- ID_OUI_FROM_DATABASE=VideoIQ, Inc.
-
OUI:001F97*
ID_OUI_FROM_DATABASE=BERTANA srl
@@ -57014,9 +59075,6 @@ OUI:001D64*
OUI:001D5D*
ID_OUI_FROM_DATABASE=Control Dynamics Pty. Ltd.
-OUI:001D2E*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:001D21*
ID_OUI_FROM_DATABASE=Alcad SL
@@ -57929,9 +59987,6 @@ OUI:0016F4*
OUI:0016E8*
ID_OUI_FROM_DATABASE=Sigma Designs, Inc.
-OUI:0016ED*
- ID_OUI_FROM_DATABASE=Digital Safety Technologies, Inc
-
OUI:0016DC*
ID_OUI_FROM_DATABASE=ARCHOS
@@ -59312,9 +61367,6 @@ OUI:0009C9*
OUI:0009D0*
ID_OUI_FROM_DATABASE=Solacom Technologies Inc.
-OUI:0009BC*
- ID_OUI_FROM_DATABASE=Digital Safety Technologies, Inc
-
OUI:0009C1*
ID_OUI_FROM_DATABASE=PROCES-DATA A/S
@@ -61262,9 +63314,6 @@ OUI:005008*
OUI:005001*
ID_OUI_FROM_DATABASE=YAMASHITA SYSTEMS CORP.
-OUI:0050B5*
- ID_OUI_FROM_DATABASE=FICHET-BAUCHE
-
OUI:0050B0*
ID_OUI_FROM_DATABASE=TECHNOLOGY ATLANTA CORPORATION
@@ -61832,9 +63881,6 @@ OUI:00A07F*
OUI:00A03E*
ID_OUI_FROM_DATABASE=ATM FORUM
-OUI:00A050*
- ID_OUI_FROM_DATABASE=CYPRESS SEMICONDUCTOR
-
OUI:00A098*
ID_OUI_FROM_DATABASE=NetApp
@@ -62687,9 +64733,6 @@ OUI:5464D9*
OUI:00023F*
ID_OUI_FROM_DATABASE=COMPAL ELECTRONICS, INC.
-OUI:C46699*
- ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
-
OUI:383BC8*
ID_OUI_FROM_DATABASE=2Wire Inc
@@ -63005,21 +65048,6 @@ OUI:C0D962*
OUI:00150C*
ID_OUI_FROM_DATABASE=AVM GmbH
-OUI:744401*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:E091F5*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:001B2F*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:00223F*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:E0469A*
- ID_OUI_FROM_DATABASE=NETGEAR
-
OUI:F40B93*
ID_OUI_FROM_DATABASE=BlackBerry RTS
@@ -63053,24 +65081,6 @@ OUI:C02506*
OUI:0896D7*
ID_OUI_FROM_DATABASE=AVM GmbH
-OUI:008EF2*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:4494FC*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:20E52A*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:9CD36D*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:C40415*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:08BD43*
- ID_OUI_FROM_DATABASE=NETGEAR
-
OUI:4C09D4*
ID_OUI_FROM_DATABASE=Arcadyan Technology Corporation
@@ -63218,9 +65228,6 @@ OUI:78CB68*
OUI:001A7F*
ID_OUI_FROM_DATABASE=GCI Science & Technology Co.,LTD
-OUI:00054F*
- ID_OUI_FROM_DATABASE=Private
-
OUI:D04D2C*
ID_OUI_FROM_DATABASE=Roku, Inc.
@@ -63338,9 +65345,6 @@ OUI:84683E*
OUI:C88722*
ID_OUI_FROM_DATABASE=Lumenpulse
-OUI:FC1A11*
- ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
-
OUI:30A9DE*
ID_OUI_FROM_DATABASE=LG Innotek
@@ -63407,27 +65411,9 @@ OUI:8801F2*
OUI:FC084A*
ID_OUI_FROM_DATABASE=FUJITSU LIMITED
-OUI:D4AD2D*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
-OUI:48555F*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
OUI:847BEB*
ID_OUI_FROM_DATABASE=Dell Inc.
-OUI:F8C96C*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
-OUI:34BF90*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
-OUI:D467E7*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
-OUI:04C1B9*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
OUI:689361*
ID_OUI_FROM_DATABASE=Integrated Device Technology (Malaysia) Sdn. Bhd.
@@ -63671,9 +65657,6 @@ OUI:749D8F*
OUI:346AC2*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-OUI:8CD2E9*
- ID_OUI_FROM_DATABASE=NIPPON SMT Co.Ltd
-
OUI:C83DFC*
ID_OUI_FROM_DATABASE=Pioneer DJ Corporation
@@ -63806,9 +65789,6 @@ OUI:38BC1A*
OUI:0004A3*
ID_OUI_FROM_DATABASE=Microchip Technology Inc.
-OUI:E0DDC0*
- ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
-
OUI:982F3C*
ID_OUI_FROM_DATABASE=Sichuan Changhong Electric Ltd.
@@ -64004,9 +65984,6 @@ OUI:6CEFC6*
OUI:002A10*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:886AB1*
- ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
-
OUI:44D6E1*
ID_OUI_FROM_DATABASE=Snuza International Pty. Ltd.
@@ -64151,9 +66128,6 @@ OUI:08010F*
OUI:CCA260*
ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO.,LTD
-OUI:0015FF*
- ID_OUI_FROM_DATABASE=Novatel Wireless Solutions, Inc.
-
OUI:203CAE*
ID_OUI_FROM_DATABASE=Apple, Inc.
@@ -64166,9 +66140,6 @@ OUI:00D78F*
OUI:A03BE3*
ID_OUI_FROM_DATABASE=Apple, Inc.
-OUI:18E29F*
- ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
-
OUI:886B0F*
ID_OUI_FROM_DATABASE=Bluegiga Technologies OY
@@ -64271,15 +66242,9 @@ OUI:000BA1*
OUI:AC587B*
ID_OUI_FROM_DATABASE=JCT Healthcare
-OUI:B0B98A*
- ID_OUI_FROM_DATABASE=NETGEAR
-
OUI:30E171*
ID_OUI_FROM_DATABASE=Hewlett Packard
-OUI:D490E0*
- ID_OUI_FROM_DATABASE=Wachendorff Automation GmbH & Co KG
-
OUI:8C3C4A*
ID_OUI_FROM_DATABASE=NAKAYO Inc
@@ -64415,12 +66380,6 @@ OUI:54D272*
OUI:9CA3A9*
ID_OUI_FROM_DATABASE=Guangzhou Juan Optical and Electronical Tech Joint Stock Co., Ltd
-OUI:1100AA*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:002067*
- ID_OUI_FROM_DATABASE=Private
-
OUI:9893CC*
ID_OUI_FROM_DATABASE=LG ELECTRONICS INC
@@ -64715,9 +66674,6 @@ OUI:9CAED3*
OUI:341E6B*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-OUI:48F97C*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
OUI:B47447*
ID_OUI_FROM_DATABASE=CoreOS
@@ -64829,9 +66785,6 @@ OUI:C87324*
OUI:3CF862*
ID_OUI_FROM_DATABASE=Intel Corporate
-OUI:0823B2*
- ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
-
OUI:88C3B3*
ID_OUI_FROM_DATABASE=SOVICO
@@ -64895,15 +66848,15 @@ OUI:9800C1*
OUI:3034D2*
ID_OUI_FROM_DATABASE=Availink, Inc.
+OUI:40B034*
+ ID_OUI_FROM_DATABASE=Hewlett Packard
+
OUI:CCCE1E*
ID_OUI_FROM_DATABASE=AVM Audiovisuelles Marketing und Computersysteme GmbH
OUI:501E2D*
ID_OUI_FROM_DATABASE=StreamUnlimited Engineering GmbH
-OUI:40B034*
- ID_OUI_FROM_DATABASE=Hewlett Packard
-
OUI:FC0A81*
ID_OUI_FROM_DATABASE=Extreme Networks
@@ -64913,9 +66866,6 @@ OUI:C8B5AD*
OUI:88E628*
ID_OUI_FROM_DATABASE=Shenzhen Kezhonglong Optoelectronic Technology Co.,Ltd
-OUI:6091F3*
- ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
-
OUI:9CDA3E*
ID_OUI_FROM_DATABASE=Intel Corporate
@@ -64925,6 +66875,12 @@ OUI:3CA067*
OUI:D8325A*
ID_OUI_FROM_DATABASE=Shenzhen YOUHUA Technology Co., Ltd
+OUI:F04F7C*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:10AE60*
+ ID_OUI_FROM_DATABASE=Private
+
OUI:44650D*
ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
@@ -64940,18 +66896,9 @@ OUI:40B4CD*
OUI:2C86D2*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:F04F7C*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:10AE60*
- ID_OUI_FROM_DATABASE=Private
-
OUI:802689*
ID_OUI_FROM_DATABASE=D-Link International
-OUI:BC2F3D*
- ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
-
OUI:409F38*
ID_OUI_FROM_DATABASE=AzureWave Technology Inc.
@@ -64961,6 +66908,12 @@ OUI:C4D197*
OUI:58821D*
ID_OUI_FROM_DATABASE=H. Schomäcker GmbH
+OUI:B8D7AF*
+ ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd.
+
+OUI:3096FB*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
OUI:CCBE59*
ID_OUI_FROM_DATABASE=Calix Inc.
@@ -64970,23 +66923,14 @@ OUI:EC4F82*
OUI:000631*
ID_OUI_FROM_DATABASE=Calix Inc.
-OUI:B8D7AF*
- ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd.
-
-OUI:3096FB*
- ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-
OUI:F0EE10*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:A8A198*
- ID_OUI_FROM_DATABASE=TCT mobile ltd
-
OUI:107D1A*
ID_OUI_FROM_DATABASE=Dell Inc.
-OUI:C0D012*
- ID_OUI_FROM_DATABASE=Apple, Inc.
+OUI:A8A198*
+ ID_OUI_FROM_DATABASE=TCT mobile ltd
OUI:D4DCCD*
ID_OUI_FROM_DATABASE=Apple, Inc.
@@ -65000,6 +66944,9 @@ OUI:F80377*
OUI:14BD61*
ID_OUI_FROM_DATABASE=Apple, Inc.
+OUI:C0D012*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
OUI:0827CE*
ID_OUI_FROM_DATABASE=NAGANO KEIKI CO., LTD.
@@ -65018,33 +66965,33 @@ OUI:00143F*
OUI:F8BE0D*
ID_OUI_FROM_DATABASE=A2UICT Co.,Ltd.
+OUI:5CC6E9*
+ ID_OUI_FROM_DATABASE=Edifier International
+
OUI:08EA40*
ID_OUI_FROM_DATABASE=SHENZHEN BILIAN ELECTRONIC CO.,LTD
OUI:00E0DA*
ID_OUI_FROM_DATABASE=Alcatel-Lucent Enterprise
-OUI:5CC6E9*
- ID_OUI_FROM_DATABASE=Edifier International
+OUI:1868CB*
+ ID_OUI_FROM_DATABASE=Hangzhou Hikvision Digital Technology Co.,Ltd.
OUI:E8C1D7*
ID_OUI_FROM_DATABASE=Philips
-OUI:1868CB*
- ID_OUI_FROM_DATABASE=Hangzhou Hikvision Digital Technology Co.,Ltd.
-
OUI:F80BCB*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+OUI:24EA40*
+ ID_OUI_FROM_DATABASE=Helmholz GmbH & Co. KG
+
OUI:9CC8AE*
ID_OUI_FROM_DATABASE=Becton, Dickinson and Company
OUI:B0359F*
ID_OUI_FROM_DATABASE=Intel Corporate
-OUI:24EA40*
- ID_OUI_FROM_DATABASE=Helmholz GmbH & Co. KG
-
OUI:84A9C4*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
@@ -65081,24 +67028,18 @@ OUI:FC539E*
OUI:9CAF6F*
ID_OUI_FROM_DATABASE=ITEL MOBILE LIMITED
-OUI:105887*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+OUI:907065*
+ ID_OUI_FROM_DATABASE=Texas Instruments
OUI:9C061B*
ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited
-OUI:907065*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:C4ABB2*
- ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+OUI:A08E78*
+ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
OUI:B8FFB3*
ID_OUI_FROM_DATABASE=MitraStar Technology Corp.
-OUI:A08E78*
- ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
-
OUI:E0D55E*
ID_OUI_FROM_DATABASE=GIGA-BYTE TECHNOLOGY CO.,LTD.
@@ -65111,24 +67052,24 @@ OUI:90F1AA*
OUI:78BDBC*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:20F452*
- ID_OUI_FROM_DATABASE=Shanghai IUV Software Development Co. Ltd
-
OUI:D47AE2*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+OUI:20F452*
+ ID_OUI_FROM_DATABASE=Shanghai IUV Software Development Co. Ltd
+
OUI:88D274*
ID_OUI_FROM_DATABASE=zte corporation
OUI:986DC8*
ID_OUI_FROM_DATABASE=TOSHIBA MITSUBISHI-ELECTRIC INDUSTRIAL SYSTEMS CORPORATION
-OUI:982DBA*
- ID_OUI_FROM_DATABASE=Fibergate Inc.
-
OUI:0040AA*
ID_OUI_FROM_DATABASE=Valmet Automation
+OUI:982DBA*
+ ID_OUI_FROM_DATABASE=Fibergate Inc.
+
OUI:0080C2*
ID_OUI_FROM_DATABASE=IEEE 802.1 Working Group
@@ -65171,6 +67112,36 @@ OUI:145BD1*
OUI:6CC1D2*
ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+OUI:D82522*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:70B14E*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:14D4FE*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:707630*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:90C792*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:789684*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:CC65AD*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:986B3D*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:5CE30E*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:7823AE*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
OUI:F80BBE*
ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
@@ -65219,15 +67190,6 @@ OUI:001DD0*
OUI:5C571A*
ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-OUI:D82522*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:70B14E*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:14D4FE*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
OUI:002374*
ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
@@ -65258,39 +67220,18 @@ OUI:901ACA*
OUI:E8ED05*
ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-OUI:707630*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:90C792*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:789684*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:CC65AD*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:986B3D*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:5CE30E*
+OUI:2C7E81*
ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-OUI:7823AE*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+OUI:84C0EF*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
OUI:447F77*
ID_OUI_FROM_DATABASE=Connected Home
-OUI:2C7E81*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
OUI:009AD2*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:84C0EF*
- ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-
OUI:7C1C68*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
@@ -65306,15 +67247,15 @@ OUI:7C8BCA*
OUI:88B111*
ID_OUI_FROM_DATABASE=Intel Corporate
-OUI:54D751*
- ID_OUI_FROM_DATABASE=Proximus
-
OUI:D8F1F0*
ID_OUI_FROM_DATABASE=Pepxim International Limited
OUI:0019F0*
ID_OUI_FROM_DATABASE=UNIONMAN TECHNOLOGY CO.,LTD
+OUI:54D751*
+ ID_OUI_FROM_DATABASE=Proximus
+
OUI:506E92*
ID_OUI_FROM_DATABASE=Innocent Technology Co., Ltd.
@@ -65327,6 +67268,9 @@ OUI:900A1A*
OUI:CC03D9*
ID_OUI_FROM_DATABASE=Cisco Meraki
+OUI:BCADAB*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
OUI:506184*
ID_OUI_FROM_DATABASE=Avaya Inc
@@ -65336,18 +67280,522 @@ OUI:F81547*
OUI:A01290*
ID_OUI_FROM_DATABASE=Avaya Inc
-OUI:B4A95A*
+OUI:3C3A73*
ID_OUI_FROM_DATABASE=Avaya Inc
-OUI:BCADAB*
+OUI:B4A95A*
ID_OUI_FROM_DATABASE=Avaya Inc
-OUI:3C3A73*
- ID_OUI_FROM_DATABASE=Avaya Inc
+OUI:6CB227*
+ ID_OUI_FROM_DATABASE=Sony Video & Sound Products Inc.
OUI:60271C*
ID_OUI_FROM_DATABASE=VIDEOR E. Hartig GmbH
+OUI:C46699*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:FC1A11*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:E0DDC0*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:886AB1*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:18E29F*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:F81D90*
+ ID_OUI_FROM_DATABASE=Solidwintech
+
+OUI:0823B2*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:6091F3*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:BC2F3D*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:C4ABB2*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:C8DB26*
+ ID_OUI_FROM_DATABASE=Logitech
+
+OUI:4473D6*
+ ID_OUI_FROM_DATABASE=Logitech
+
+OUI:70F35A*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:EC42B4*
+ ID_OUI_FROM_DATABASE=ADC Corporation
+
+OUI:10CDB6*
+ ID_OUI_FROM_DATABASE=Essential Products, Inc.
+
+OUI:08306B*
+ ID_OUI_FROM_DATABASE=Palo Alto Networks
+
+OUI:6CF9D2*
+ ID_OUI_FROM_DATABASE=Chengdu Goods for the Road Electronic Technology C
+
+OUI:641666*
+ ID_OUI_FROM_DATABASE=Nest Labs Inc.
+
+OUI:3817E1*
+ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc.
+
+OUI:94147A*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:74D0DC*
+ ID_OUI_FROM_DATABASE=Ericsson AB
+
+OUI:88A3CC*
+ ID_OUI_FROM_DATABASE=Amatis Controls
+
+OUI:8C9F3B*
+ ID_OUI_FROM_DATABASE=Qingdao Hisense Communications Co.,Ltd.
+
+OUI:404229*
+ ID_OUI_FROM_DATABASE=Layer3TV, Inc
+
+OUI:B090D4*
+ ID_OUI_FROM_DATABASE=Shenzhen Hoin Internet Technology Co., Ltd
+
+OUI:348F27*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:001D2E*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:689234*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:044FAA*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:0025C4*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:38FF36*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:2C5D93*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:543D37*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:C4108A*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:D463C6*
+ ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company
+
+OUI:00A050*
+ ID_OUI_FROM_DATABASE=CYPRESS SEMICONDUCTOR
+
+OUI:54666C*
+ ID_OUI_FROM_DATABASE=Shenzhen YOUHUA Technology Co., Ltd
+
+OUI:A44CC8*
+ ID_OUI_FROM_DATABASE=Dell Inc.
+
+OUI:0840F3*
+ ID_OUI_FROM_DATABASE=Tenda Technology Co.,Ltd.Dongguan branch
+
+OUI:103034*
+ ID_OUI_FROM_DATABASE=Cara Systems
+
+OUI:FC8B97*
+ ID_OUI_FROM_DATABASE=SHENZHEN GONGJIN ELECTRONICS CO.,LT
+
+OUI:2CAB25*
+ ID_OUI_FROM_DATABASE=SHENZHEN GONGJIN ELECTRONICS CO.,LT
+
+OUI:AC6E1A*
+ ID_OUI_FROM_DATABASE=SHENZHEN GONGJIN ELECTRONICS CO.,LT
+
+OUI:24A534*
+ ID_OUI_FROM_DATABASE=SynTrust Tech International Ltd.
+
+OUI:F844E3*
+ ID_OUI_FROM_DATABASE=Taicang T&W Electronics
+
+OUI:001F92*
+ ID_OUI_FROM_DATABASE=Avigilon Corporation
+
+OUI:0C8FFF*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:54B121*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:786256*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:A80C63*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:5CC307*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:08A8A1*
+ ID_OUI_FROM_DATABASE=Cyclotronics Power Concepts, Inc
+
+OUI:887A31*
+ ID_OUI_FROM_DATABASE=Velankani Electronics Pvt. Ltd.
+
+OUI:8C0F6F*
+ ID_OUI_FROM_DATABASE=PEGATRON CORPORATION
+
+OUI:283545*
+ ID_OUI_FROM_DATABASE=SHENZHEN CHUANGWEI-RGB ELECTRONICS CO.,LTD
+
+OUI:A82BB5*
+ ID_OUI_FROM_DATABASE=Edgecore Networks Corporation
+
+OUI:88365F*
+ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
+
+OUI:0015FF*
+ ID_OUI_FROM_DATABASE=Novatel Wireless Solutions, Inc.
+
+OUI:788C4D*
+ ID_OUI_FROM_DATABASE=Indyme Solutions, LLC
+
+OUI:A8B2DA*
+ ID_OUI_FROM_DATABASE=FUJITSU LIMITED
+
+OUI:0CB937*
+ ID_OUI_FROM_DATABASE=Ubee Interactive Co., Limited
+
+OUI:2880A2*
+ ID_OUI_FROM_DATABASE=Novatel Wireless Solutions, Inc.
+
+OUI:0CB459*
+ ID_OUI_FROM_DATABASE=Marketech International Corp.
+
+OUI:84AA9C*
+ ID_OUI_FROM_DATABASE=MitraStar Technology Corp.
+
+OUI:0C4B54*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
+
+OUI:C47154*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
+
+OUI:44EA4B*
+ ID_OUI_FROM_DATABASE=Actlas Inc.
+
+OUI:5C6984*
+ ID_OUI_FROM_DATABASE=NUVICO
+
+OUI:F86EEE*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:E4FB5D*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:5C546D*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:508F4C*
+ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd
+
+OUI:0027F8*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:50EB1A*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:CC4E24*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:889471*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:D81FCC*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:002067*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:0060DF*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:000533*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:00223F*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:001B2F*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:E091F5*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:744401*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:E0469A*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:08BD43*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:C40415*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:9CD36D*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:20E52A*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:4494FC*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:008EF2*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:B0B98A*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:1100AA*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:1C965A*
+ ID_OUI_FROM_DATABASE=Weifang GoerTek Technology Co.,Ltd.
+
+OUI:104E89*
+ ID_OUI_FROM_DATABASE=Garmin International
+
+OUI:30053F*
+ ID_OUI_FROM_DATABASE=JTI Co.,Ltd.
+
+OUI:0050B5*
+ ID_OUI_FROM_DATABASE=FICHET SECURITE ELECTRONIQUE
+
+OUI:04209A*
+ ID_OUI_FROM_DATABASE=Panasonic Corporation AVC Networks Company
+
+OUI:8CC121*
+ ID_OUI_FROM_DATABASE=Panasonic Corporation AVC Networks Company
+
+OUI:20C6EB*
+ ID_OUI_FROM_DATABASE=Panasonic Corporation AVC Networks Company
+
+OUI:B0350B*
+ ID_OUI_FROM_DATABASE=MOBIWIRE MOBILES (NINGBO) CO.,LTD
+
+OUI:28A6AC*
+ ID_OUI_FROM_DATABASE=seca gmbh & co. kg
+
+OUI:00054F*
+ ID_OUI_FROM_DATABASE=Garmin International
+
+OUI:40CE24*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:24C42F*
+ ID_OUI_FROM_DATABASE=Philips Lifeline
+
+OUI:E048D3*
+ ID_OUI_FROM_DATABASE=MOBIWIRE MOBILES (NINGBO) CO.,LTD
+
+OUI:B8EE0E*
+ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
+
+OUI:78886D*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:A85C2C*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:00DB70*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:181456*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:E4EC10*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:9C4A7B*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:386EA2*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:58B42D*
+ ID_OUI_FROM_DATABASE=YSTen Technology Co.,Ltd
+
+OUI:48EC5B*
+ ID_OUI_FROM_DATABASE=Nokia
+
+OUI:D86162*
+ ID_OUI_FROM_DATABASE=Wistron Neweb Corporation
+
+OUI:80615F*
+ ID_OUI_FROM_DATABASE=Beijing Sinead Technology Co., Ltd.
+
+OUI:0009BC*
+ ID_OUI_FROM_DATABASE=Utility, Inc
+
+OUI:0016ED*
+ ID_OUI_FROM_DATABASE=Utility, Inc
+
+OUI:74F661*
+ ID_OUI_FROM_DATABASE=Schneider Electric Fire & Security Oy
+
+OUI:245FDF*
+ ID_OUI_FROM_DATABASE=KYOCERA CORPORATION
+
+OUI:885DFB*
+ ID_OUI_FROM_DATABASE=zte corporation
+
+OUI:608CE6*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:8CD2E9*
+ ID_OUI_FROM_DATABASE=YOKOTE SEIKO CO., LTD.
+
+OUI:186024*
+ ID_OUI_FROM_DATABASE=Hewlett Packard
+
+OUI:74F91A*
+ ID_OUI_FROM_DATABASE=Onface
+
+OUI:706BB9*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:6CC147*
+ ID_OUI_FROM_DATABASE=Xiamen Hanin Electronic Technology Co., Ltd
+
+OUI:8CFEB4*
+ ID_OUI_FROM_DATABASE=VSOONTECH ELECTRONICS CO., LIMITED
+
+OUI:CCF957*
+ ID_OUI_FROM_DATABASE=u-blox AG
+
+OUI:74373B*
+ ID_OUI_FROM_DATABASE=UNINET Co.,Ltd.
+
+OUI:7C6456*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:448F17*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co., Ltd. ARTIK
+
+OUI:0076B1*
+ ID_OUI_FROM_DATABASE=Somfy-Protect By Myfox SAS
+
+OUI:D0666D*
+ ID_OUI_FROM_DATABASE=Shenzhen Bus-Lan Technology Co., Ltd.
+
+OUI:B8D94D*
+ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
+
+OUI:10FCB6*
+ ID_OUI_FROM_DATABASE=mirusystems CO.,LTD
+
+OUI:04D6AA*
+ ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO-MECHANICS(THAILAND)
+
+OUI:08661F*
+ ID_OUI_FROM_DATABASE=Palo Alto Networks
+
+OUI:0C5842*
+ ID_OUI_FROM_DATABASE=DME Micro
+
+OUI:A468BC*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:80C755*
+ ID_OUI_FROM_DATABASE=Panasonic Appliances Company
+
+OUI:A0648F*
+ ID_OUI_FROM_DATABASE=ASKEY COMPUTER CORP
+
+OUI:D467E7*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:34BF90*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:F8C96C*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:48555F*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:D4AD2D*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:D00492*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:809FAB*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:9C88AD*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:48F97C*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:105887*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:5CE3B6*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:04C1B9*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:04848A*
+ ID_OUI_FROM_DATABASE=7INOVA TECHNOLOGY LIMITED
+
+OUI:E81DA8*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:3CC079*
+ ID_OUI_FROM_DATABASE=Shenzhen One-Nine Intelligent Electronic Science and Technology Co., Ltd
+
+OUI:746EE4*
+ ID_OUI_FROM_DATABASE=Asia Vital Components Co.,Ltd.
+
+OUI:F44C70*
+ ID_OUI_FROM_DATABASE=Skyworth Digital Technology(Shenzhen) Co.,Ltd
+
+OUI:98C5DB*
+ ID_OUI_FROM_DATABASE=Ericsson AB
+
+OUI:043A0D*
+ ID_OUI_FROM_DATABASE=SM Optics S.r.l.
+
+OUI:9CE063*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:9C9C40*
+ ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO., LTD
+
+OUI:D490E0*
+ ID_OUI_FROM_DATABASE=Topcon Electronics GmbH & Co. KG
+
+OUI:E8361D*
+ ID_OUI_FROM_DATABASE=Sense Labs, Inc.
+
+OUI:EC7D11*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
OUI:2C3996*
ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
@@ -65600,9 +68048,6 @@ OUI:20906F*
OUI:1C7839*
ID_OUI_FROM_DATABASE=Shenzhen Tencent Computer System Co., Ltd.
-OUI:D837BE*
- ID_OUI_FROM_DATABASE=Shanghai Gongjing Telecom Technology Co,LTD
-
OUI:A4516F*
ID_OUI_FROM_DATABASE=Microsoft Mobile Oy
@@ -65648,18 +68093,6 @@ OUI:0C96BF*
OUI:9CC172*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-OUI:0014C9*
- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
-
-OUI:00010F*
- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
-
-OUI:080088*
- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
-
-OUI:00051E*
- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
-
OUI:384608*
ID_OUI_FROM_DATABASE=zte corporation
@@ -66488,9 +68921,6 @@ OUI:9CB6D0*
OUI:D0C0BF*
ID_OUI_FROM_DATABASE=Actions Microelectronics Co., Ltd
-OUI:94F665*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:E04B45*
ID_OUI_FROM_DATABASE=Hi-P Electronics Pte Ltd
@@ -66668,9 +69098,6 @@ OUI:887033*
OUI:8C7967*
ID_OUI_FROM_DATABASE=zte corporation
-OUI:D083D4*
- ID_OUI_FROM_DATABASE=XTel ApS
-
OUI:78F944*
ID_OUI_FROM_DATABASE=Private
@@ -66734,9 +69161,6 @@ OUI:6CF5E8*
OUI:70FF5C*
ID_OUI_FROM_DATABASE=Cheerzing Communication(Xiamen)Technology Co.,Ltd
-OUI:E0107F*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:08115E*
ID_OUI_FROM_DATABASE=Bitel Co., Ltd.
@@ -66785,9 +69209,6 @@ OUI:D4EC86*
OUI:20A99B*
ID_OUI_FROM_DATABASE=Microsoft Corporation
-OUI:6C7660*
- ID_OUI_FROM_DATABASE=KYOCERA Corporation
-
OUI:A0A3E2*
ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc
@@ -66830,9 +69251,6 @@ OUI:7CB177*
OUI:8C5D60*
ID_OUI_FROM_DATABASE=UCI Corporation Co.,Ltd.
-OUI:104B46*
- ID_OUI_FROM_DATABASE=Mitsubishi Electric Corporation
-
OUI:4C0BBE*
ID_OUI_FROM_DATABASE=Microsoft
@@ -66926,9 +69344,6 @@ OUI:D05AF1*
OUI:481A84*
ID_OUI_FROM_DATABASE=Pointer Telocation Ltd
-OUI:E4F4C6*
- ID_OUI_FROM_DATABASE=NETGEAR
-
OUI:DC663A*
ID_OUI_FROM_DATABASE=Apacer Technology Inc.
@@ -67064,9 +69479,6 @@ OUI:4CF45B*
OUI:B06971*
ID_OUI_FROM_DATABASE=DEI Sales, Inc.
-OUI:58493B*
- ID_OUI_FROM_DATABASE=Palo Alto Networks
-
OUI:580528*
ID_OUI_FROM_DATABASE=LABRIS NETWORKS
@@ -67790,9 +70202,6 @@ OUI:20B5C6*
OUI:AC3CB4*
ID_OUI_FROM_DATABASE=Nilan A/S
-OUI:A830AD*
- ID_OUI_FROM_DATABASE=Wei Fang Goertek Electronics Co.,Ltd
-
OUI:8007A2*
ID_OUI_FROM_DATABASE=Esson Technology Inc.
@@ -68249,9 +70658,6 @@ OUI:00E8AB*
OUI:18421D*
ID_OUI_FROM_DATABASE=Private
-OUI:78617C*
- ID_OUI_FROM_DATABASE=MITSUMI ELECTRIC CO.,LTD
-
OUI:C401B1*
ID_OUI_FROM_DATABASE=SeekTech INC
@@ -68741,9 +71147,6 @@ OUI:DCA6BD*
OUI:58E808*
ID_OUI_FROM_DATABASE=AUTONICS CORPORATION
-OUI:B8C716*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
OUI:8058C5*
ID_OUI_FROM_DATABASE=NovaTec Kommunikationstechnik GmbH
@@ -68978,9 +71381,6 @@ OUI:5C9AD8*
OUI:144C1A*
ID_OUI_FROM_DATABASE=Max Communication GmbH
-OUI:FCE557*
- ID_OUI_FROM_DATABASE=Nokia Corporation
-
OUI:BC6E76*
ID_OUI_FROM_DATABASE=Green Energy Options Ltd
@@ -69095,9 +71495,6 @@ OUI:7076F0*
OUI:48C8B6*
ID_OUI_FROM_DATABASE=SysTec GmbH
-OUI:303855*
- ID_OUI_FROM_DATABASE=Nokia Corporation
-
OUI:9C4563*
ID_OUI_FROM_DATABASE=DIMEP Sistemas
@@ -69131,9 +71528,6 @@ OUI:64E8E6*
OUI:34A183*
ID_OUI_FROM_DATABASE=AWare, Inc
-OUI:740ABC*
- ID_OUI_FROM_DATABASE=JSJS Designs (Europe) Limited
-
OUI:588D09*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
@@ -69404,9 +71798,6 @@ OUI:0CC9C6*
OUI:B45861*
ID_OUI_FROM_DATABASE=CRemote, LLC
-OUI:AC6706*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:B8653B*
ID_OUI_FROM_DATABASE=Bolymin, Inc.
@@ -71312,9 +73703,6 @@ OUI:00198B*
OUI:00198D*
ID_OUI_FROM_DATABASE=Ocean Optics, Inc.
-OUI:00197F*
- ID_OUI_FROM_DATABASE=PLANTRONICS, INC.
-
OUI:001986*
ID_OUI_FROM_DATABASE=Cheng Hongjian
@@ -72197,9 +74585,6 @@ OUI:00139F*
OUI:001398*
ID_OUI_FROM_DATABASE=TrafficSim Co.,Ltd
-OUI:001392*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:00138C*
ID_OUI_FROM_DATABASE=Kumyoung.Co.Ltd
@@ -72980,9 +75365,6 @@ OUI:000BFC*
OUI:000BFE*
ID_OUI_FROM_DATABASE=CASTEL Broadband Limited
-OUI:000C03*
- ID_OUI_FROM_DATABASE=HDMI Licensing, LLC
-
OUI:000CA4*
ID_OUI_FROM_DATABASE=Prompttec Product Management GmbH
@@ -75452,9 +77834,6 @@ OUI:00A0AD*
OUI:00A0F6*
ID_OUI_FROM_DATABASE=AutoGas Systems Inc.
-OUI:00A096*
- ID_OUI_FROM_DATABASE=MITSUMI ELECTRIC CO., LTD.
-
OUI:00A006*
ID_OUI_FROM_DATABASE=IMAGE DATA PROCESSING SYSTEM GROUP
@@ -76961,36 +79340,12 @@ OUI:00040E*
OUI:0016E3*
ID_OUI_FROM_DATABASE=ASKEY COMPUTER CORP
-OUI:30469A*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:0026F2*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:00184D*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:001E2A*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:E8FCAF*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:4C60DE*
- ID_OUI_FROM_DATABASE=NETGEAR
-
OUI:00300A*
ID_OUI_FROM_DATABASE=Aztech Electronics Pte Ltd
-OUI:A06391*
- ID_OUI_FROM_DATABASE=NETGEAR
-
OUI:9CC7A6*
ID_OUI_FROM_DATABASE=AVM GmbH
-OUI:DCEF09*
- ID_OUI_FROM_DATABASE=NETGEAR
-
OUI:743170*
ID_OUI_FROM_DATABASE=Arcadyan Technology Corporation
@@ -77003,9 +79358,6 @@ OUI:7C4FB5*
OUI:0012BF*
ID_OUI_FROM_DATABASE=Arcadyan Technology Corporation
-OUI:200CC8*
- ID_OUI_FROM_DATABASE=NETGEAR
-
OUI:04FE8D*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
@@ -77306,9 +79658,6 @@ OUI:BC44B0*
OUI:7864E6*
ID_OUI_FROM_DATABASE=Green Motive Technology Limited
-OUI:743E2B*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:C0CCF8*
ID_OUI_FROM_DATABASE=Apple, Inc.
@@ -77393,9 +79742,6 @@ OUI:000594*
OUI:000AC2*
ID_OUI_FROM_DATABASE=Wuhan FiberHome Digital Technology Co.,Ltd.
-OUI:F08CFB*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
OUI:D4F207*
ID_OUI_FROM_DATABASE=DIAODIAO(Beijing)Technology CO.,Ltd
@@ -77474,9 +79820,6 @@ OUI:00208F*
OUI:9CDF03*
ID_OUI_FROM_DATABASE=Harman/Becker Automotive Systems GmbH
-OUI:F0407B*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
OUI:94885E*
ID_OUI_FROM_DATABASE=Surfilter Network Technology Co., Ltd.
@@ -78263,9 +80606,6 @@ OUI:0005CD*
OUI:8C9351*
ID_OUI_FROM_DATABASE=Jigowatts Inc.
-OUI:D838FC*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:00248D*
ID_OUI_FROM_DATABASE=Sony Interactive Entertainment Inc.
@@ -78284,12 +80624,6 @@ OUI:40D855*
OUI:48DF37*
ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise
-OUI:9C93E4*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:005079*
- ID_OUI_FROM_DATABASE=Private
-
OUI:0028F8*
ID_OUI_FROM_DATABASE=Intel Corporate
@@ -78350,9 +80684,6 @@ OUI:002597*
OUI:882BD7*
ID_OUI_FROM_DATABASE=ADDÉNERGIE TECHNOLOGIES
-OUI:9CA5C0*
- ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
-
OUI:B4A5EF*
ID_OUI_FROM_DATABASE=Sercomm Corporation.
@@ -78368,9 +80699,6 @@ OUI:38A28C*
OUI:58528A*
ID_OUI_FROM_DATABASE=Mitsubishi Electric Corporation
-OUI:BCC00F*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
OUI:B0C287*
ID_OUI_FROM_DATABASE=Technicolor CH USA Inc.
@@ -78779,9 +81107,6 @@ OUI:3805AC*
OUI:F8BBBF*
ID_OUI_FROM_DATABASE=eero inc.
-OUI:0CF4D5*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:000130*
ID_OUI_FROM_DATABASE=Extreme Networks
@@ -78848,9 +81173,6 @@ OUI:4827EA*
OUI:049573*
ID_OUI_FROM_DATABASE=zte corporation
-OUI:001D44*
- ID_OUI_FROM_DATABASE=Krohne
-
OUI:48BF6B*
ID_OUI_FROM_DATABASE=Apple, Inc.
@@ -78890,9 +81212,6 @@ OUI:64D154*
OUI:0020DA*
ID_OUI_FROM_DATABASE=Alcatel-Lucent Enterprise
-OUI:1CDA27*
- ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
-
OUI:345BBB*
ID_OUI_FROM_DATABASE=GD Midea Air-Conditioning Equipment Co.,Ltd.
@@ -78929,9 +81248,6 @@ OUI:C83A6B*
OUI:B4C6F8*
ID_OUI_FROM_DATABASE=Axilspot Communication
-OUI:70D923*
- ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
-
OUI:B83A08*
ID_OUI_FROM_DATABASE=Tenda Technology Co.,Ltd.Dongguan branch
@@ -79016,9 +81332,6 @@ OUI:E47DBD*
OUI:503DA1*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:A040A0*
- ID_OUI_FROM_DATABASE=NETGEAR
-
OUI:508569*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
@@ -79264,3 +81577,459 @@ OUI:78B28D*
OUI:000CAB*
ID_OUI_FROM_DATABASE=Commend International GmbH
+
+OUI:00EC0A*
+ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd
+
+OUI:A86B7C*
+ ID_OUI_FROM_DATABASE=SHENZHEN FENGLIAN TECHNOLOGY CO., LTD.
+
+OUI:9CA5C0*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:1CDA27*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:70D923*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:F430B9*
+ ID_OUI_FROM_DATABASE=Hewlett Packard
+
+OUI:2C9EEC*
+ ID_OUI_FROM_DATABASE=Jabil Circuit Penang
+
+OUI:943FC2*
+ ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise
+
+OUI:A06A44*
+ ID_OUI_FROM_DATABASE=Vizio, Inc
+
+OUI:B44F96*
+ ID_OUI_FROM_DATABASE=Zhejiang Xinzailing Technology co., ltd
+
+OUI:D822F4*
+ ID_OUI_FROM_DATABASE=Avnet Silica
+
+OUI:58493B*
+ ID_OUI_FROM_DATABASE=Palo Alto Networks
+
+OUI:D083D4*
+ ID_OUI_FROM_DATABASE=Xtel Wireless ApS
+
+OUI:7CEB7F*
+ ID_OUI_FROM_DATABASE=Dmet Products Corp.
+
+OUI:8C8580*
+ ID_OUI_FROM_DATABASE=Smart Innovation LLC
+
+OUI:C4571F*
+ ID_OUI_FROM_DATABASE=June Life Inc
+
+OUI:FC5A1D*
+ ID_OUI_FROM_DATABASE=Hitron Technologies. Inc
+
+OUI:287B09*
+ ID_OUI_FROM_DATABASE=zte corporation
+
+OUI:4859A4*
+ ID_OUI_FROM_DATABASE=zte corporation
+
+OUI:3894E0*
+ ID_OUI_FROM_DATABASE=Syrotech Networks. Ltd.
+
+OUI:34F64B*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:ACED5C*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:18204C*
+ ID_OUI_FROM_DATABASE=Kummler+Matter AG
+
+OUI:740ABC*
+ ID_OUI_FROM_DATABASE=LightwaveRF Technology Ltd
+
+OUI:54BD79*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:D86C63*
+ ID_OUI_FROM_DATABASE=Google, Inc.
+
+OUI:743E2B*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:D838FC*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:0CF4D5*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:AC6706*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:94F665*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:E0107F*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:001392*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:7811DC*
+ ID_OUI_FROM_DATABASE=XIAOMI Electronics,CO.,LTD
+
+OUI:D837BE*
+ ID_OUI_FROM_DATABASE=SHENZHEN GONGJIN ELECTRONICS CO.,LT
+
+OUI:DC44B6*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:1007B6*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:F4939F*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co., Ltd.
+
+OUI:000C03*
+ ID_OUI_FROM_DATABASE=HDMI Licensing, LLC
+
+OUI:CC2F71*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:F82819*
+ ID_OUI_FROM_DATABASE=Liteon Technology Corporation
+
+OUI:F4B520*
+ ID_OUI_FROM_DATABASE=Biostar Microtech international corp.
+
+OUI:9C93E4*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:D4B27A*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:F0F8F2*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:341513*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:64CFD9*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:24B2DE*
+ ID_OUI_FROM_DATABASE=Espressif Inc.
+
+OUI:50E971*
+ ID_OUI_FROM_DATABASE=Jibo, Inc.
+
+OUI:50642B*
+ ID_OUI_FROM_DATABASE=XIAOMI Electronics,CO.,LTD
+
+OUI:909D7D*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:84A1D1*
+ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
+
+OUI:783690*
+ ID_OUI_FROM_DATABASE=Yulong Computer Telecommunication Scientific (Shenzhen) Co.,Ltd
+
+OUI:788102*
+ ID_OUI_FROM_DATABASE=Sercomm Corporation.
+
+OUI:58A0CB*
+ ID_OUI_FROM_DATABASE=TrackNet, Inc
+
+OUI:586163*
+ ID_OUI_FROM_DATABASE=Quantum Networks (SG) Pte. Ltd.
+
+OUI:3C7843*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:A47758*
+ ID_OUI_FROM_DATABASE=Ningbo Freewings Technologies Co.,Ltd
+
+OUI:00051E*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:080088*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:00010F*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:00197F*
+ ID_OUI_FROM_DATABASE=PLANTRONICS, INC.
+
+OUI:E4F4C6*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:001E2A*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:0014C9*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:00184D*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:0026F2*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:30469A*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:4C60DE*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:E8FCAF*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:200CC8*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:DCEF09*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:A06391*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:A040A0*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:8C3BAD*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:005079*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:F86465*
+ ID_OUI_FROM_DATABASE=Anova Applied Electronics, Inc.
+
+OUI:A830AD*
+ ID_OUI_FROM_DATABASE=Weifang GoerTek Technology Co.,Ltd.
+
+OUI:70E1FD*
+ ID_OUI_FROM_DATABASE=FLEXTRONICS
+
+OUI:001D44*
+ ID_OUI_FROM_DATABASE=Krohne
+
+OUI:D4D2E5*
+ ID_OUI_FROM_DATABASE=BKAV Corporation
+
+OUI:C06D1A*
+ ID_OUI_FROM_DATABASE=Tianjin Henxinhuifeng Technology Co.,Ltd.
+
+OUI:3432E6*
+ ID_OUI_FROM_DATABASE=Panasonic Industrial Devices Europe GmbH
+
+OUI:40A3CC*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:E470B8*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:B019C6*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:58E28F*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:AC1F74*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:303855*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:FCE557*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:9C305B*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
+OUI:00289F*
+ ID_OUI_FROM_DATABASE=Semptian Co., Ltd.
+
+OUI:8C4500*
+ ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd.
+
+OUI:6C7660*
+ ID_OUI_FROM_DATABASE=KYOCERA CORPORATION
+
+OUI:104B46*
+ ID_OUI_FROM_DATABASE=Mitsubishi Electric Corporation
+
+OUI:903DBD*
+ ID_OUI_FROM_DATABASE=SECURE METERS LIMITED
+
+OUI:384F49*
+ ID_OUI_FROM_DATABASE=Juniper Networks
+
+OUI:A491B1*
+ ID_OUI_FROM_DATABASE=Technicolor
+
+OUI:8CD48E*
+ ID_OUI_FROM_DATABASE=ITEL MOBILE LIMITED
+
+OUI:642B8A*
+ ID_OUI_FROM_DATABASE=ALL BEST Industrial Co., Ltd.
+
+OUI:68ECC5*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:CC9891*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:1C7022*
+ ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd.
+
+OUI:947EB9*
+ ID_OUI_FROM_DATABASE=National Narrowband Network Communications Pty Ltd
+
+OUI:4CBD8F*
+ ID_OUI_FROM_DATABASE=Hangzhou Hikvision Digital Technology Co.,Ltd.
+
+OUI:B4D64E*
+ ID_OUI_FROM_DATABASE=Caldero Limited
+
+OUI:F89DBB*
+ ID_OUI_FROM_DATABASE=Tintri
+
+OUI:D4389C*
+ ID_OUI_FROM_DATABASE=Sony Mobile Communications AB
+
+OUI:104963*
+ ID_OUI_FROM_DATABASE=HARTING K.K.
+
+OUI:646E69*
+ ID_OUI_FROM_DATABASE=Liteon Technology Corporation
+
+OUI:BC3D85*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:B0E17E*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:74D21D*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:44C874*
+ ID_OUI_FROM_DATABASE=China Mobile Group Device Co.,Ltd.
+
+OUI:98EF9B*
+ ID_OUI_FROM_DATABASE=OHSUNG
+
+OUI:84E327*
+ ID_OUI_FROM_DATABASE=TAILYN TECHNOLOGIES INC
+
+OUI:7091F3*
+ ID_OUI_FROM_DATABASE=Universal Electronics, Inc.
+
+OUI:68C63A*
+ ID_OUI_FROM_DATABASE=Espressif Inc.
+
+OUI:F4E204*
+ ID_OUI_FROM_DATABASE=Traqueur
+
+OUI:3456FE*
+ ID_OUI_FROM_DATABASE=Cisco Meraki
+
+OUI:08674E*
+ ID_OUI_FROM_DATABASE=Hisense broadband multimedia technology Co.,Ltd
+
+OUI:F08CFB*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:F0407B*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:BCC00F*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:6405E9*
+ ID_OUI_FROM_DATABASE=Shenzhen WayOS Technology Crop., Ltd.
+
+OUI:B8C716*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:50A83A*
+ ID_OUI_FROM_DATABASE=S Mobile Devices Limited
+
+OUI:EC8AC7*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:E084F3*
+ ID_OUI_FROM_DATABASE=High Grade Controls Corporation
+
+OUI:74BBD3*
+ ID_OUI_FROM_DATABASE=Shenzhen xeme Communication Co., Ltd.
+
+OUI:D8ED1C*
+ ID_OUI_FROM_DATABASE=Magna Technology SL
+
+OUI:78617C*
+ ID_OUI_FROM_DATABASE=MITSUMI ELECTRIC CO.,LTD.
+
+OUI:00A096*
+ ID_OUI_FROM_DATABASE=MITSUMI ELECTRIC CO.,LTD.
+
+OUI:A07099*
+ ID_OUI_FROM_DATABASE=Beijing Huacan Electronics Co., Ltd
+
+OUI:B0935B*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:20F19E*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:389D92*
+ ID_OUI_FROM_DATABASE=Seiko Epson Corporation
+
+OUI:74860B*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:C0174D*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:A407B6*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:149F3C*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:149FB6*
+ ID_OUI_FROM_DATABASE=GUANGDONG GENIUS TECHNOLOGY CO.,LTD.
+
+OUI:7C1C4E*
+ ID_OUI_FROM_DATABASE=LG Innotek
+
+OUI:70708B*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:BC903A*
+ ID_OUI_FROM_DATABASE=Robert Bosch GmbH
+
+OUI:603D26*
+ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc.
+
+OUI:3820A8*
+ ID_OUI_FROM_DATABASE=ColorTokens, Inc.
+
+OUI:705896*
+ ID_OUI_FROM_DATABASE=InShow Technology
+
+OUI:D05995*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:54DF24*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:78870D*
+ ID_OUI_FROM_DATABASE=Unifiedgateways India Private Limited
+
+OUI:3CA616*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
diff --git a/hwdb/20-acpi-vendor.hwdb b/hwdb/20-acpi-vendor.hwdb
index 886e61aa38..64634478e6 100644
--- a/hwdb/20-acpi-vendor.hwdb
+++ b/hwdb/20-acpi-vendor.hwdb
@@ -42,6 +42,9 @@ acpi:ATML*:
acpi:AUTH*:
ID_VENDOR_FROM_DATABASE=AuthenTec
+acpi:BOOT*:
+ ID_VENDOR_FROM_DATABASE=Coreboot Project
+
acpi:BOSC*:
ID_VENDOR_FROM_DATABASE=Robert Bosch GmbH
@@ -72,6 +75,9 @@ acpi:ELAN*:
acpi:ESSX*:
ID_VENDOR_FROM_DATABASE=Everest Semiconductor Co., Ltd.
+acpi:EXAR*:
+ ID_VENDOR_FROM_DATABASE=Exar Corporation
+
acpi:FRSC*:
ID_VENDOR_FROM_DATABASE=Freescale, Inc
@@ -141,6 +147,9 @@ acpi:MCHP*:
acpi:MIPI*:
ID_VENDOR_FROM_DATABASE=MIPI Alliance
+acpi:MRVL*:
+ ID_VENDOR_FROM_DATABASE=Marvell Technology Group Ltd.
+
acpi:MSAY*:
ID_VENDOR_FROM_DATABASE=Microsoft Corporation
@@ -951,6 +960,9 @@ acpi:BBH*:
acpi:BBL*:
ID_VENDOR_FROM_DATABASE=Brain Boxes Limited
+acpi:BBX*:
+ ID_VENDOR_FROM_DATABASE=Black Box Corporation
+
acpi:BCC*:
ID_VENDOR_FROM_DATABASE=Beaver Computer Corporaton
@@ -1326,6 +1338,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
@@ -2721,6 +2736,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
@@ -3099,6 +3117,9 @@ acpi:HYC*:
acpi:HYD*:
ID_VENDOR_FROM_DATABASE=Hydis Technologies.Co.,LTD
+acpi:HYL*:
+ ID_VENDOR_FROM_DATABASE=Shanghai Chai Ming Huang Info&Tech Co, Ltd
+
acpi:HYO*:
ID_VENDOR_FROM_DATABASE=HYC CO., LTD.
@@ -4530,6 +4551,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
@@ -5220,6 +5244,9 @@ acpi:PMD*:
acpi:PMM*:
ID_VENDOR_FROM_DATABASE=Point Multimedia System
+acpi:PMS*:
+ ID_VENDOR_FROM_DATABASE=Pabian Embedded Systems
+
acpi:PMT*:
ID_VENDOR_FROM_DATABASE=Promate Electronic Co., Ltd.
@@ -5238,6 +5265,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.
@@ -6414,6 +6444,9 @@ acpi:TCD*:
acpi:TCE*:
ID_VENDOR_FROM_DATABASE=Century Corporation
+acpi:TCF*:
+ ID_VENDOR_FROM_DATABASE=Televic Conference
+
acpi:TCH*:
ID_VENDOR_FROM_DATABASE=Interaction Systems, Inc
@@ -6489,6 +6522,9 @@ 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
@@ -6570,6 +6606,9 @@ acpi:TLK*:
acpi:TLL*:
ID_VENDOR_FROM_DATABASE=Thinklogical
+acpi:TLN*:
+ ID_VENDOR_FROM_DATABASE=Techlogix Networx
+
acpi:TLS*:
ID_VENDOR_FROM_DATABASE=Teleste Educational OY
@@ -6696,6 +6735,9 @@ acpi:TRM*:
acpi:TRN*:
ID_VENDOR_FROM_DATABASE=Datacommunicatie Tron B.V.
+acpi:TRP*:
+ ID_VENDOR_FROM_DATABASE=TRAPEZE GROUP
+
acpi:TRS*:
ID_VENDOR_FROM_DATABASE=Torus Systems Ltd
diff --git a/hwdb/20-pci-vendor-model.hwdb b/hwdb/20-pci-vendor-model.hwdb
index 83ff9f3668..482853dbca 100644
--- a/hwdb/20-pci-vendor-model.hwdb
+++ b/hwdb/20-pci-vendor-model.hwdb
@@ -144,34 +144,34 @@ pci:v00000B0B*
ID_VENDOR_FROM_DATABASE=Rhino Equipment Corp.
pci:v00000B0Bd00000105*
- ID_MODEL_FROM_DATABASE=Rhino R1T1
+ ID_MODEL_FROM_DATABASE=R1T1
pci:v00000B0Bd00000205*
- ID_MODEL_FROM_DATABASE=Rhino R4FXO
+ ID_MODEL_FROM_DATABASE=R4FXO
pci:v00000B0Bd00000206*
ID_MODEL_FROM_DATABASE=RCB4FXO 4-channel FXO analog telphony card
pci:v00000B0Bd00000305*
- ID_MODEL_FROM_DATABASE=Rhino R4T1
+ ID_MODEL_FROM_DATABASE=R4T1
pci:v00000B0Bd00000405*
- ID_MODEL_FROM_DATABASE=Rhino R8FXX
+ ID_MODEL_FROM_DATABASE=R8FXX
pci:v00000B0Bd00000406*
ID_MODEL_FROM_DATABASE=RCB8FXX 8-channel modular analog telphony card
pci:v00000B0Bd00000505*
- ID_MODEL_FROM_DATABASE=Rhino R24FXX
+ ID_MODEL_FROM_DATABASE=R24FXX
pci:v00000B0Bd00000506*
ID_MODEL_FROM_DATABASE=RCB24FXS 24-Channel FXS analog telphony card
pci:v00000B0Bd00000605*
- ID_MODEL_FROM_DATABASE=Rhino R2T1
+ ID_MODEL_FROM_DATABASE=R2T1
pci:v00000B0Bd00000705*
- ID_MODEL_FROM_DATABASE=Rhino R24FXS
+ ID_MODEL_FROM_DATABASE=R24FXS
pci:v00000B0Bd00000706*
ID_MODEL_FROM_DATABASE=RCB24FXO 24-Channel FXO analog telphony card
@@ -659,6 +659,9 @@ pci:v00001000d00000014sv00001028sd00001FD4*
pci:v00001000d00000014sv00001D49sd00000602*
ID_MODEL_FROM_DATABASE=MegaRAID Tri-Mode SAS3516 (ThinkSystem RAID 930-16i 4GB Flash PCIe 12Gb Adapter)
+pci:v00001000d00000014sv00001D49sd00000604*
+ ID_MODEL_FROM_DATABASE=MegaRAID Tri-Mode SAS3516 (ThinkSystem RAID 930-8e 4GB Flash PCIe 12Gb Adapter)
+
pci:v00001000d00000015*
ID_MODEL_FROM_DATABASE=MegaRAID Tri-Mode SAS3416
@@ -1199,6 +1202,9 @@ pci:v00001000d00000062sv00001000sd00000062*
pci:v00001000d00000064*
ID_MODEL_FROM_DATABASE=SAS2116 PCI-Express Fusion-MPT SAS-2 [Meteor]
+pci:v00001000d00000064sv00001000sd000030C0*
+ ID_MODEL_FROM_DATABASE=SAS2116 PCI-Express Fusion-MPT SAS-2 [Meteor] (SAS 9201-16i)
+
pci:v00001000d00000065*
ID_MODEL_FROM_DATABASE=SAS2116 PCI-Express Fusion-MPT SAS-2 [Meteor]
@@ -1541,6 +1547,9 @@ pci:v00001000d00000097sv00001000sd00003090*
pci:v00001000d00000097sv00001000sd000030E0*
ID_MODEL_FROM_DATABASE=SAS3008 PCI-Express Fusion-MPT SAS-3 (SAS9300-8i)
+pci:v00001000d00000097sv00001000sd00003130*
+ ID_MODEL_FROM_DATABASE=SAS3008 PCI-Express Fusion-MPT SAS-3 (SAS 9300-16i)
+
pci:v00001000d00000097sv00001028sd00001F45*
ID_MODEL_FROM_DATABASE=SAS3008 PCI-Express Fusion-MPT SAS-3 (HBA330 Adapter)
@@ -1583,6 +1592,9 @@ pci:v00001000d000000AFsv00001D49sd00000200*
pci:v00001000d000000AFsv00001D49sd00000202*
ID_MODEL_FROM_DATABASE=SAS3408 Fusion-MPT Tri-Mode I/O Controller Chip (IOC) (ThinkSystem 430-8e SAS/SATA 12Gb HBA)
+pci:v00001000d000000AFsv00001D49sd00000204*
+ ID_MODEL_FROM_DATABASE=SAS3408 Fusion-MPT Tri-Mode I/O Controller Chip (IOC) (ThinkSystem 430-8i SAS/SATA 12Gb Dense HBA)
+
pci:v00001000d000000BE*
ID_MODEL_FROM_DATABASE=SAS3504 Fusion-MPT Tri-Mode RAID On Chip (ROC)
@@ -3207,7 +3219,7 @@ pci:v00001002d00004C46sv00001002sd00000155*
ID_MODEL_FROM_DATABASE=Rage Mobility 128 AGP 2X/Mobility M3 (IBM Thinkpad A22p)
pci:v00001002d00004C46sv00001014sd00000155*
- ID_MODEL_FROM_DATABASE=Rage Mobility 128 AGP 2X/Mobility M3 (IBM Thinkpad A22p)
+ ID_MODEL_FROM_DATABASE=Rage Mobility 128 AGP 2X/Mobility M3 (Thinkpad A22p)
pci:v00001002d00004C46sv00001028sd000000B1*
ID_MODEL_FROM_DATABASE=Rage Mobility 128 AGP 2X/Mobility M3 (Latitude C600)
@@ -6287,9 +6299,6 @@ pci:v00001002d00006798sv00001787sd00002317*
pci:v00001002d00006798sv00001787sd00003000*
ID_MODEL_FROM_DATABASE=Tahiti XT [Radeon HD 7970/8970 OEM / R9 280X] (Tahiti XT2 [Radeon HD 7970 GHz Edition])
-pci:v00001002d00006799*
- ID_MODEL_FROM_DATABASE=New Zealand [Radeon HD 7900 Series]
-
pci:v00001002d0000679A*
ID_MODEL_FROM_DATABASE=Tahiti PRO [Radeon HD 7950/8950 OEM / R9 280]
@@ -6306,19 +6315,19 @@ pci:v00001002d0000679Asv0000174Bsd0000A003*
ID_MODEL_FROM_DATABASE=Tahiti PRO [Radeon HD 7950/8950 OEM / R9 280] (Radeon R9 280)
pci:v00001002d0000679B*
- ID_MODEL_FROM_DATABASE=Malta [Radeon HD 7990]
+ ID_MODEL_FROM_DATABASE=Malta [Radeon HD 7990/8990 OEM]
pci:v00001002d0000679Bsv00001002sd00000B28*
- ID_MODEL_FROM_DATABASE=Malta [Radeon HD 7990] (Radeon HD 8990 OEM)
+ ID_MODEL_FROM_DATABASE=Malta [Radeon HD 7990/8990 OEM] (Radeon HD 8990 OEM)
pci:v00001002d0000679Bsv00001002sd00000B2A*
- ID_MODEL_FROM_DATABASE=Malta [Radeon HD 7990] (Radeon HD 7990)
+ ID_MODEL_FROM_DATABASE=Malta [Radeon HD 7990/8990 OEM] (Radeon HD 7990)
pci:v00001002d0000679Bsv00001462sd00008036*
- ID_MODEL_FROM_DATABASE=Malta [Radeon HD 7990] (Radeon HD 8990 OEM)
+ ID_MODEL_FROM_DATABASE=Malta [Radeon HD 7990/8990 OEM] (Radeon HD 8990 OEM)
pci:v00001002d0000679Bsv0000148Csd00008990*
- ID_MODEL_FROM_DATABASE=Malta [Radeon HD 7990] (Radeon HD 8990 OEM)
+ ID_MODEL_FROM_DATABASE=Malta [Radeon HD 7990/8990 OEM] (Radeon HD 8990 OEM)
pci:v00001002d0000679E*
ID_MODEL_FROM_DATABASE=Tahiti LE [Radeon HD 7870 XT]
@@ -6486,11 +6495,17 @@ pci:v00001002d000067BE*
ID_MODEL_FROM_DATABASE=Hawaii LE
pci:v00001002d000067C0*
- ID_MODEL_FROM_DATABASE=Ellesmere [Polaris10]
+ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon Pro WX 7100]
pci:v00001002d000067C4*
ID_MODEL_FROM_DATABASE=Ellesmere [Radeon Pro WX 7100]
+pci:v00001002d000067C4sv00001002sd00000336*
+ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon Pro WX 7100] (Radeon Pro Duo)
+
+pci:v00001002d000067C4sv00001002sd00001336*
+ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon Pro WX 7100] (Radeon Pro Duo)
+
pci:v00001002d000067C7*
ID_MODEL_FROM_DATABASE=Ellesmere [Radeon Pro WX 5100]
@@ -6504,49 +6519,64 @@ pci:v00001002d000067CF*
ID_MODEL_FROM_DATABASE=Ellesmere [Polaris10]
pci:v00001002d000067DF*
- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480]
+ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/580]
pci:v00001002d000067DFsv00001002sd00000B37*
- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480] (Radeon RX 480)
+ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/580] (Radeon RX 480)
pci:v00001002d000067DFsv00001043sd000004A8*
- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480] (Radeon RX 480)
+ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/580] (Radeon RX 480)
pci:v00001002d000067DFsv00001043sd000004B0*
- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480] (Radeon RX 470)
+ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/580] (Radeon RX 470)
pci:v00001002d000067DFsv00001043sd000004FB*
- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480] (Radeon RX 480)
+ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/580] (Radeon RX 480)
+
+pci:v00001002d000067DFsv00001043sd000004FD*
+ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/580] (Radeon RX 480 8GB)
+
+pci:v00001002d000067DFsv00001458sd000022F0*
+ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/580] (Radeon RX 570)
pci:v00001002d000067DFsv00001462sd00003411*
- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480] (Radeon RX 470)
+ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/580] (Radeon RX 470)
pci:v00001002d000067DFsv00001462sd00003413*
- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480] (Radeon RX 480)
+ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/580] (Radeon RX 480)
pci:v00001002d000067DFsv0000148Csd00002372*
- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480] (Radeon RX 480)
+ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/580] (Radeon RX 480)
pci:v00001002d000067DFsv0000148Csd00002373*
- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480] (Radeon RX 470)
+ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/580] (Radeon RX 470)
pci:v00001002d000067DFsv00001682sd00009470*
- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480] (Radeon RX 470)
+ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/580] (Radeon RX 470)
pci:v00001002d000067DFsv00001682sd00009480*
- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480] (Radeon RX 480)
+ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/580] (Radeon RX 480)
+
+pci:v00001002d000067DFsv00001682sd00009588*
+ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/580] (Radeon RX 580 XTR)
pci:v00001002d000067DFsv0000174Bsd0000E347*
- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480] (Radeon RX 470/480)
+ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/580] (Radeon RX 470/480)
pci:v00001002d000067DFsv0000174Bsd0000E349*
- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480] (Radeon RX 470)
+ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/580] (Radeon RX 470)
pci:v00001002d000067DFsv00001787sd0000A470*
- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480] (Radeon RX 470)
+ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/580] (Radeon RX 470)
pci:v00001002d000067DFsv00001787sd0000A480*
- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480] (Radeon RX 480)
+ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/580] (Radeon RX 480)
+
+pci:v00001002d000067DFsv00001DA2sd0000E353*
+ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/580] (Sapphire Radeon RX 580 Pulse 8GB)
+
+pci:v00001002d000067DFsv00001DA2sd0000E366*
+ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/580] (Radeon RX 570)
pci:v00001002d000067E0*
ID_MODEL_FROM_DATABASE=Baffin [Polaris11]
@@ -6570,7 +6600,7 @@ pci:v00001002d000067EF*
ID_MODEL_FROM_DATABASE=Baffin [Radeon RX 460]
pci:v00001002d000067FF*
- ID_MODEL_FROM_DATABASE=Baffin [Polaris11]
+ ID_MODEL_FROM_DATABASE=Baffin [Radeon RX 560]
pci:v00001002d00006800*
ID_MODEL_FROM_DATABASE=Wimbledon XT [Radeon HD 7970M]
@@ -7157,6 +7187,12 @@ pci:v00001002d00006842*
pci:v00001002d00006843*
ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7670M]
+pci:v00001002d00006863*
+ ID_MODEL_FROM_DATABASE=Vega 10 [Radeon Vega Frontier Edition]
+
+pci:v00001002d0000687F*
+ ID_MODEL_FROM_DATABASE=Vega [Radeon RX Vega]
+
pci:v00001002d00006888*
ID_MODEL_FROM_DATABASE=Cypress XT [FirePro V8800]
@@ -8676,7 +8712,7 @@ pci:v00001002d00006981*
ID_MODEL_FROM_DATABASE=Polaris12
pci:v00001002d00006985*
- ID_MODEL_FROM_DATABASE=Polaris12
+ ID_MODEL_FROM_DATABASE=Lexa XT [Radeon PRO WX 3100]
pci:v00001002d00006986*
ID_MODEL_FROM_DATABASE=Polaris12
@@ -8684,8 +8720,11 @@ pci:v00001002d00006986*
pci:v00001002d00006987*
ID_MODEL_FROM_DATABASE=Polaris12
+pci:v00001002d00006995*
+ ID_MODEL_FROM_DATABASE=Lexa XT [Radeon PRO WX 2100]
+
pci:v00001002d0000699F*
- ID_MODEL_FROM_DATABASE=Polaris12
+ ID_MODEL_FROM_DATABASE=Lexa PRO [Radeon RX 550]
pci:v00001002d0000700F*
ID_MODEL_FROM_DATABASE=RS100 AGP Bridge
@@ -11234,6 +11273,9 @@ pci:v00001014d00000302*
pci:v00001014d00000308*
ID_MODEL_FROM_DATABASE=CalIOC2 PCI-E Root Port
+pci:v00001014d00000311*
+ ID_MODEL_FROM_DATABASE=FC 5740/1954 4-Port 10/100/1000 Base-TX PCI-X Adapter for POWER
+
pci:v00001014d00000314*
ID_MODEL_FROM_DATABASE=ZISC 036 Neural accelerator card
@@ -11324,6 +11366,9 @@ pci:v00001014d0000034Asv00001014sd000004C8*
pci:v00001014d0000034Asv00001014sd000004C9*
ID_MODEL_FROM_DATABASE=PCI-E IPR SAS Adapter (ASIC) (PCIe3 x 8 Cache SAS RAID Internal Adapter 6GB(2CCD))
+pci:v00001014d000003DC*
+ ID_MODEL_FROM_DATABASE=POWER8 Host Bridge (PHB3)
+
pci:v00001014d0000044B*
ID_MODEL_FROM_DATABASE=GenWQE Accelerator Adapter
@@ -11693,6 +11738,9 @@ pci:v00001022d00001439*
pci:v00001022d0000145B*
ID_MODEL_FROM_DATABASE=Zeppelin Non-Transparent Bridge
+pci:v00001022d0000145C*
+ ID_MODEL_FROM_DATABASE=USB3 Host Controller
+
pci:v00001022d00001510*
ID_MODEL_FROM_DATABASE=Family 14h Processor Root Complex
@@ -11945,6 +11993,9 @@ pci:v00001022d000043A2*
pci:v00001022d000043A3*
ID_MODEL_FROM_DATABASE=Hudson PCI to PCI bridge (PCIE port 3)
+pci:v00001022d000043BB*
+ ID_MODEL_FROM_DATABASE=USB 3.1 XHCI Controller
+
pci:v00001022d00007006*
ID_MODEL_FROM_DATABASE=AMD-751 [Irongate] System Controller
@@ -13295,6 +13346,12 @@ pci:v0000102Bd00000533sv0000103Csd00003381*
pci:v0000102Bd00000534*
ID_MODEL_FROM_DATABASE=G200eR2
+pci:v0000102Bd00000538*
+ ID_MODEL_FROM_DATABASE=G200eH
+
+pci:v0000102Bd00000538sv00001590sd000000E4*
+ ID_MODEL_FROM_DATABASE=G200eH (iLO5 VGA)
+
pci:v0000102Bd00000540*
ID_MODEL_FROM_DATABASE=M91XX
@@ -14825,6 +14882,12 @@ pci:v0000103Cd00001302*
pci:v0000103Cd00001303*
ID_MODEL_FROM_DATABASE=RMP-3 (Remote Management Processor)
+pci:v0000103Cd000022F6*
+ ID_MODEL_FROM_DATABASE=iLO5 Virtual USB Controller
+
+pci:v0000103Cd000022F6sv00001590sd000000E4*
+ ID_MODEL_FROM_DATABASE=iLO5 Virtual USB Controller (iLO5 Standard Virtual USB Controller)
+
pci:v0000103Cd00002910*
ID_MODEL_FROM_DATABASE=E2910A PCIBus Exerciser
@@ -15971,6 +16034,9 @@ pci:v0000104Cd00008240*
pci:v0000104Cd00008241*
ID_MODEL_FROM_DATABASE=TUSB73x0 SuperSpeed USB 3.0 xHCI Host Controller
+pci:v0000104Cd00008241sv00001014sd000004B2*
+ ID_MODEL_FROM_DATABASE=TUSB73x0 SuperSpeed USB 3.0 xHCI Host Controller (S824 (8286-42A))
+
pci:v0000104Cd00008400*
ID_MODEL_FROM_DATABASE=ACX 100 22Mbps Wireless Interface
@@ -17807,6 +17873,9 @@ pci:v00001077d00001656sv00001077sd0000E4F6*
pci:v00001077d00001656sv00001077sd0000E4F7*
ID_MODEL_FROM_DATABASE=FastLinQ QL45000 Series 25GbE Controller (FastLinQ QL45212H 25GbE Adapter)
+pci:v00001077d00001656sv00001590sd00000223*
+ ID_MODEL_FROM_DATABASE=FastLinQ QL45000 Series 25GbE Controller (Synergy 6810C 25/50Gb Ethernet Adapter)
+
pci:v00001077d0000165C*
ID_MODEL_FROM_DATABASE=FastLinQ QL45000 Series 40GbE Controller (FCoE)
@@ -17856,13 +17925,13 @@ pci:v00001077d00002031*
ID_MODEL_FROM_DATABASE=ISP8324-based 16Gb Fibre Channel to PCI Express Adapter
pci:v00001077d00002031sv0000103Csd000017E7*
- ID_MODEL_FROM_DATABASE=ISP8324-based 16Gb Fibre Channel to PCI Express Adapter (HP SN1000Q 16Gb Single Port Fibre Channel Adapter)
+ ID_MODEL_FROM_DATABASE=ISP8324-based 16Gb Fibre Channel to PCI Express Adapter (SN1000Q 16Gb Single Port Fibre Channel Adapter)
pci:v00001077d00002031sv0000103Csd000017E8*
- ID_MODEL_FROM_DATABASE=ISP8324-based 16Gb Fibre Channel to PCI Express Adapter (HP SN1000Q 16Gb Dual Port Fibre Channel Adapter)
+ ID_MODEL_FROM_DATABASE=ISP8324-based 16Gb Fibre Channel to PCI Express Adapter (SN1000Q 16Gb Dual Port Fibre Channel Adapter)
pci:v00001077d00002031sv0000103Csd00001939*
- ID_MODEL_FROM_DATABASE=ISP8324-based 16Gb Fibre Channel to PCI Express Adapter (HP QMH2672 16Gb Dual Port Fibre Channel Adapter)
+ ID_MODEL_FROM_DATABASE=ISP8324-based 16Gb Fibre Channel to PCI Express Adapter (QMH2672 16Gb Dual Port Fibre Channel Adapter)
pci:v00001077d00002031sv0000103Csd00008002*
ID_MODEL_FROM_DATABASE=ISP8324-based 16Gb Fibre Channel to PCI Express Adapter (3830C 16G Fibre Channel Host Bus Adapter)
@@ -17922,16 +17991,16 @@ pci:v00001077d00002261sv00001077sd000002AC*
ID_MODEL_FROM_DATABASE=ISP2722-based 16/32Gb Fibre Channel to PCIe Adapter (QLE2742 Dual Port 32Gb FC to PCIe Gen3 x8 Adapter)
pci:v00001077d00002261sv00001590sd000000F9*
- ID_MODEL_FROM_DATABASE=ISP2722-based 16/32Gb Fibre Channel to PCIe Adapter (HPE StoreFabric SN1100Q 16Gb Single Port Fibre Channel Host Bus Adapter)
+ ID_MODEL_FROM_DATABASE=ISP2722-based 16/32Gb Fibre Channel to PCIe Adapter (StoreFabric SN1100Q 16Gb Single Port Fibre Channel Host Bus Adapter)
pci:v00001077d00002261sv00001590sd000000FA*
- ID_MODEL_FROM_DATABASE=ISP2722-based 16/32Gb Fibre Channel to PCIe Adapter (HPE StoreFabric SN1100Q 16Gb Dual Port Fibre Channel Host Bus Adapter)
+ ID_MODEL_FROM_DATABASE=ISP2722-based 16/32Gb Fibre Channel to PCIe Adapter (StoreFabric SN1100Q 16Gb Dual Port Fibre Channel Host Bus Adapter)
pci:v00001077d00002261sv00001590sd00000203*
- ID_MODEL_FROM_DATABASE=ISP2722-based 16/32Gb Fibre Channel to PCIe Adapter (HPE StoreFabric SN1600Q 32Gb Single Port Fibre Channel Host Bus Adapter)
+ ID_MODEL_FROM_DATABASE=ISP2722-based 16/32Gb Fibre Channel to PCIe Adapter (StoreFabric SN1600Q 32Gb Single Port Fibre Channel Host Bus Adapter)
pci:v00001077d00002261sv00001590sd00000204*
- ID_MODEL_FROM_DATABASE=ISP2722-based 16/32Gb Fibre Channel to PCIe Adapter (HPE StoreFabric SN1600Q 32Gb Dual Port Fibre Channel Host Bus Adapter)
+ ID_MODEL_FROM_DATABASE=ISP2722-based 16/32Gb Fibre Channel to PCIe Adapter (StoreFabric SN1600Q 32Gb Dual Port Fibre Channel Host Bus Adapter)
pci:v00001077d00002300*
ID_MODEL_FROM_DATABASE=QLA2300 64-bit Fibre Channel Adapter
@@ -17966,17 +18035,29 @@ pci:v00001077d00002432sv0000103Csd00007040*
pci:v00001077d00002532*
ID_MODEL_FROM_DATABASE=ISP2532-based 8Gb Fibre Channel to PCI Express HBA
+pci:v00001077d00002532sv00001014sd0000041E*
+ ID_MODEL_FROM_DATABASE=ISP2532-based 8Gb Fibre Channel to PCI Express HBA (FC EN0Y/EN12 PCIe2 LP 8 Gb 4-port Fibre Channel Adapter for POWER)
+
pci:v00001077d00002532sv0000103Csd00003262*
ID_MODEL_FROM_DATABASE=ISP2532-based 8Gb Fibre Channel to PCI Express HBA (StorageWorks 81Q)
pci:v00001077d00002532sv0000103Csd00003263*
ID_MODEL_FROM_DATABASE=ISP2532-based 8Gb Fibre Channel to PCI Express HBA (StorageWorks 82Q)
+pci:v00001077d00002532sv00001077sd0000015C*
+ ID_MODEL_FROM_DATABASE=ISP2532-based 8Gb Fibre Channel to PCI Express HBA (QLE2560 PCI Express to 8Gb FC Single Channel)
+
+pci:v00001077d00002532sv00001077sd0000015D*
+ ID_MODEL_FROM_DATABASE=ISP2532-based 8Gb Fibre Channel to PCI Express HBA (QLE2562 PCI Express to 8Gb FC Dual Channel)
+
+pci:v00001077d00002532sv00001077sd0000015E*
+ ID_MODEL_FROM_DATABASE=ISP2532-based 8Gb Fibre Channel to PCI Express HBA (QLE2564 PCI Express to 8Gb FC Quad Channel)
+
pci:v00001077d00002532sv00001077sd00000167*
ID_MODEL_FROM_DATABASE=ISP2532-based 8Gb Fibre Channel to PCI Express HBA (QME2572 Dual Port FC8 HBA Mezzanine)
pci:v00001077d00002532sv00001590sd000000FC*
- ID_MODEL_FROM_DATABASE=ISP2532-based 8Gb Fibre Channel to PCI Express HBA (HPE StoreFabric 84Q 8Gb Quad Port Fibre Channel Host Bus Adapter)
+ ID_MODEL_FROM_DATABASE=ISP2532-based 8Gb Fibre Channel to PCI Express HBA (StoreFabric 84Q 8Gb Quad Port Fibre Channel Host Bus Adapter)
pci:v00001077d00003022*
ID_MODEL_FROM_DATABASE=ISP4022-based Ethernet NIC
@@ -18014,6 +18095,9 @@ pci:v00001077d00008000*
pci:v00001077d00008001*
ID_MODEL_FROM_DATABASE=10GbE Converged Network Adapter (FCoE)
+pci:v00001077d00008001sv00001014sd000003AF*
+ ID_MODEL_FROM_DATABASE=10GbE Converged Network Adapter (FCoE) (FC 5708/5270 10 Gb FCoE PCIe Dual Port Adapter for POWER)
+
pci:v00001077d00008020*
ID_MODEL_FROM_DATABASE=cLOM8214 1/10GbE Controller
@@ -18083,6 +18167,15 @@ pci:v00001077d00008032*
pci:v00001077d00008070*
ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller
+pci:v00001077d00008070sv00001077sd00000001*
+ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (10GE 2P QL41162HxRJ-DE Adapter)
+
+pci:v00001077d00008070sv00001077sd00000002*
+ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (10GE 2P QL41112HxCU-DE Adapter)
+
+pci:v00001077d00008070sv00001077sd0000000B*
+ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (25GE 2P QL41262HxCU-DE Adapter)
+
pci:v00001077d00008070sv00001077sd00000011*
ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (FastLinQ QL41212H 25GbE Adapter)
@@ -18092,6 +18185,15 @@ pci:v00001077d00008070sv00001077sd00000012*
pci:v00001077d00008080*
ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (FCoE)
+pci:v00001077d00008080sv00001077sd00000001*
+ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (FCoE) (10GE 2P QL41162HxRJ-DE Adapter)
+
+pci:v00001077d00008080sv00001077sd00000002*
+ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (FCoE) (10GE 2P QL41112HxCU-DE Adapter)
+
+pci:v00001077d00008080sv00001077sd0000000B*
+ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (FCoE) (25GE 2P QL41262HxCU-DE Adapter)
+
pci:v00001077d00008080sv00001077sd0000000D*
ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (FCoE) (FastLinQ QL41262H 25GbE FCoE Adapter)
@@ -18101,6 +18203,15 @@ pci:v00001077d00008080sv00001077sd0000000E*
pci:v00001077d00008084*
ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (iSCSI)
+pci:v00001077d00008084sv00001077sd00000001*
+ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (iSCSI) (10GE 2P QL41162HxRJ-DE Adapter)
+
+pci:v00001077d00008084sv00001077sd00000002*
+ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (iSCSI) (10GE 2P QL41112HxCU-DE Adapter)
+
+pci:v00001077d00008084sv00001077sd0000000B*
+ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (iSCSI) (25GE 2P QL41262HxCU-DE Adapter)
+
pci:v00001077d00008084sv00001077sd0000000D*
ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (iSCSI) (FastLinQ QL41262H 25GbE iSCSI Adapter)
@@ -18110,6 +18221,15 @@ pci:v00001077d00008084sv00001077sd0000000E*
pci:v00001077d00008090*
ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series Gigabit Ethernet Controller (SR-IOV VF)
+pci:v00001077d00008090sv00001077sd00000001*
+ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series Gigabit Ethernet Controller (SR-IOV VF) (25GE 2P QL41262HxCU-DE Adapter)
+
+pci:v00001077d00008090sv00001077sd00000002*
+ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series Gigabit Ethernet Controller (SR-IOV VF) (10GE 2P QL41112HxCU-DE Adapter)
+
+pci:v00001077d00008090sv00001077sd0000000B*
+ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series Gigabit Ethernet Controller (SR-IOV VF) (25GE 2P QL41262HxCU-DE Adapter)
+
pci:v00001077d00008090sv00001077sd0000000D*
ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series Gigabit Ethernet Controller (SR-IOV VF) (FastLinQ QL41262H 25GbE FCoE Adapter (SR-IOV VF))
@@ -26553,7 +26673,7 @@ pci:v000010DEd00000398*
ID_MODEL_FROM_DATABASE=G73M [GeForce Go 7600]
pci:v000010DEd00000398sv00001025sd0000006C*
- ID_MODEL_FROM_DATABASE=G73M [GeForce Go 7600] (Acer 9814 WKMI)
+ ID_MODEL_FROM_DATABASE=G73M [GeForce Go 7600] (Aspire 9814WKMi)
pci:v000010DEd00000399*
ID_MODEL_FROM_DATABASE=G73M [GeForce Go 7600 GT]
@@ -29417,6 +29537,9 @@ pci:v000010DEd00000DFC*
pci:v000010DEd00000E08*
ID_MODEL_FROM_DATABASE=GF119 HDMI Audio Controller
+pci:v000010DEd00000E08sv00001043sd000083A0*
+ ID_MODEL_FROM_DATABASE=GF119 HDMI Audio Controller (ENGT520 SILENT)
+
pci:v000010DEd00000E08sv000010B0sd0000104A*
ID_MODEL_FROM_DATABASE=GF119 HDMI Audio Controller (Gainward GeForce GT 610)
@@ -29498,6 +29621,12 @@ pci:v000010DEd00000F06*
pci:v000010DEd00000FB0*
ID_MODEL_FROM_DATABASE=GM200 High Definition Audio
+pci:v000010DEd00000FB8*
+ ID_MODEL_FROM_DATABASE=GP108 High Definition Audio Controller
+
+pci:v000010DEd00000FB9*
+ ID_MODEL_FROM_DATABASE=GP107GL High Definition Audio Controller
+
pci:v000010DEd00000FBB*
ID_MODEL_FROM_DATABASE=GM204 High Definition Audio Controller
@@ -29789,6 +29918,9 @@ pci:v000010DEd0000103C*
pci:v000010DEd00001040*
ID_MODEL_FROM_DATABASE=GF119 [GeForce GT 520]
+pci:v000010DEd00001040sv00001043sd000083A0*
+ ID_MODEL_FROM_DATABASE=GF119 [GeForce GT 520] (ENGT520 SILENT)
+
pci:v000010DEd00001042*
ID_MODEL_FROM_DATABASE=GF119 [GeForce 510]
@@ -29996,6 +30128,9 @@ pci:v000010DEd000010EF*
pci:v000010DEd000010F0*
ID_MODEL_FROM_DATABASE=GP104 High Definition Audio Controller
+pci:v000010DEd000010F1*
+ ID_MODEL_FROM_DATABASE=GP106 High Definition Audio Controller
+
pci:v000010DEd00001140*
ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/810M/820M / GT 620M/625M/630M/720M]
@@ -31478,6 +31613,9 @@ pci:v000010DEd0000137A*
pci:v000010DEd0000137Asv000017AAsd0000505A*
ID_MODEL_FROM_DATABASE=GM108GLM [Quadro K620M / Quadro M500M] (Quadro M500M)
+pci:v000010DEd0000137B*
+ ID_MODEL_FROM_DATABASE=GM108GLM [Quadro M520 Mobile]
+
pci:v000010DEd0000137D*
ID_MODEL_FROM_DATABASE=GM108M [GeForce 940A]
@@ -31613,6 +31751,9 @@ pci:v000010DEd000013D9*
pci:v000010DEd000013DA*
ID_MODEL_FROM_DATABASE=GM204M [GeForce GTX 980]
+pci:v000010DEd000013E7*
+ ID_MODEL_FROM_DATABASE=GM204 [GeForce GTX 980 Engineering Sample]
+
pci:v000010DEd000013F0*
ID_MODEL_FROM_DATABASE=GM204GL [Quadro M5000]
@@ -31665,7 +31806,7 @@ pci:v000010DEd00001436*
ID_MODEL_FROM_DATABASE=GM206GLM [Quadro M2200 Mobile]
pci:v000010DEd000015F0*
- ID_MODEL_FROM_DATABASE=GP100GL
+ ID_MODEL_FROM_DATABASE=GP100GL [Quadro GP100]
pci:v000010DEd000015F1*
ID_MODEL_FROM_DATABASE=GP100GL
@@ -31689,7 +31830,7 @@ pci:v000010DEd00001619*
ID_MODEL_FROM_DATABASE=GM204M [GeForce GTX 965M]
pci:v000010DEd0000161A*
- ID_MODEL_FROM_DATABASE=GM204M [GeForce GTX 980]
+ ID_MODEL_FROM_DATABASE=GM204M [GeForce GTX 980 Mobile]
pci:v000010DEd00001667*
ID_MODEL_FROM_DATABASE=GM204M [GeForce GTX 965M]
@@ -31724,6 +31865,12 @@ pci:v000010DEd00001B00*
pci:v000010DEd00001B01*
ID_MODEL_FROM_DATABASE=GP102
+pci:v000010DEd00001B02*
+ ID_MODEL_FROM_DATABASE=GP102 [TITAN Xp]
+
+pci:v000010DEd00001B06*
+ ID_MODEL_FROM_DATABASE=GP102 [GeForce GTX 1080 Ti]
+
pci:v000010DEd00001B30*
ID_MODEL_FROM_DATABASE=GP102GL [Quadro P6000]
@@ -31761,7 +31908,7 @@ pci:v000010DEd00001BB0*
ID_MODEL_FROM_DATABASE=GP104GL [Quadro P5000]
pci:v000010DEd00001BB1*
- ID_MODEL_FROM_DATABASE=GP104GL
+ ID_MODEL_FROM_DATABASE=GP104GL [Quadro P4000]
pci:v000010DEd00001BB3*
ID_MODEL_FROM_DATABASE=GP104GL [Tesla P4]
@@ -31800,7 +31947,7 @@ pci:v000010DEd00001C20*
ID_MODEL_FROM_DATABASE=GP106M [GeForce GTX 1060 Mobile]
pci:v000010DEd00001C30*
- ID_MODEL_FROM_DATABASE=GP106GL
+ ID_MODEL_FROM_DATABASE=GP106GL [Quadro P2000]
pci:v000010DEd00001C35*
ID_MODEL_FROM_DATABASE=GP106
@@ -31808,6 +31955,12 @@ pci:v000010DEd00001C35*
pci:v000010DEd00001C60*
ID_MODEL_FROM_DATABASE=GP106M [GeForce GTX 1060 Mobile]
+pci:v000010DEd00001C61*
+ ID_MODEL_FROM_DATABASE=GP106M [GeForce GTX 1050 Ti Mobile]
+
+pci:v000010DEd00001C62*
+ ID_MODEL_FROM_DATABASE=GP106M [GeForce GTX 1050 Mobile]
+
pci:v000010DEd00001C70*
ID_MODEL_FROM_DATABASE=GP106GL
@@ -31838,8 +31991,23 @@ pci:v000010DEd00001CA8*
pci:v000010DEd00001CAA*
ID_MODEL_FROM_DATABASE=GP107GL
+pci:v000010DEd00001CB1*
+ ID_MODEL_FROM_DATABASE=GP107GL [Quadro P1000]
+
+pci:v000010DEd00001CB2*
+ ID_MODEL_FROM_DATABASE=GP107GL [Quadro P600]
+
+pci:v000010DEd00001CB3*
+ ID_MODEL_FROM_DATABASE=GP107GL [Quadro P400]
+
pci:v000010DEd00001D01*
- ID_MODEL_FROM_DATABASE=GP108
+ ID_MODEL_FROM_DATABASE=GP108 [GeForce GT 1030]
+
+pci:v000010DEd00001D10*
+ ID_MODEL_FROM_DATABASE=GP108 [GeForce MX150]
+
+pci:v000010DEd00001D81*
+ ID_MODEL_FROM_DATABASE=GV100
pci:v000010DF*
ID_VENDOR_FROM_DATABASE=Emulex Corporation
@@ -31908,7 +32076,10 @@ pci:v000010DFd0000E180*
ID_MODEL_FROM_DATABASE=Proteus-X: LightPulse IOV Fibre Channel Host Adapter
pci:v000010DFd0000E200*
- ID_MODEL_FROM_DATABASE=Lancer-X: LightPulse Fibre Channel Host Adapter
+ ID_MODEL_FROM_DATABASE=LightPulse LPe16002
+
+pci:v000010DFd0000E200sv00001014sd000003F1*
+ ID_MODEL_FROM_DATABASE=LightPulse LPe16002 (PCIe2 16 Gb 2-port Fibre Channel Adapter (FC EL5B; CCIN 577F))
pci:v000010DFd0000E208*
ID_MODEL_FROM_DATABASE=LightPulse 16Gb Fibre Channel Host Adapter (Lancer-VF)
@@ -31934,6 +32105,24 @@ pci:v000010DFd0000E268*
pci:v000010DFd0000E300*
ID_MODEL_FROM_DATABASE=Lancer Gen6: LPe32000 Fibre Channel Host Adapter
+pci:v000010DFd0000E300sv000010DFsd0000E310*
+ ID_MODEL_FROM_DATABASE=Lancer Gen6: LPe32000 Fibre Channel Host Adapter (Lancer Gen6: LPe31000 Fibre Channel Host Adapter)
+
+pci:v000010DFd0000E300sv000010DFsd0000E311*
+ ID_MODEL_FROM_DATABASE=Lancer Gen6: LPe32000 Fibre Channel Host Adapter (Lancer Gen6: LPe31000 Fibre Channel Host Adapter)
+
+pci:v000010DFd0000E300sv000010DFsd0000E312*
+ ID_MODEL_FROM_DATABASE=Lancer Gen6: LPe32000 Fibre Channel Host Adapter (Lancer Gen6: LPe31000 Fibre Channel Host Adapter)
+
+pci:v000010DFd0000E300sv000010DFsd0000E322*
+ ID_MODEL_FROM_DATABASE=Lancer Gen6: LPe32000 Fibre Channel Host Adapter (Lancer Gen6: LPe31000 Fibre Channel Host Adapter)
+
+pci:v000010DFd0000E300sv000010DFsd0000E323*
+ ID_MODEL_FROM_DATABASE=Lancer Gen6: LPe32000 Fibre Channel Host Adapter (Lancer Gen6: LPe31000 Fibre Channel Host Adapter)
+
+pci:v000010DFd0000E300sv000010DFsd0000E325*
+ ID_MODEL_FROM_DATABASE=Lancer Gen6: LPe32000 Fibre Channel Host Adapter (Lancer Gen6: LPe31000 Fibre Channel Host Adapter)
+
pci:v000010DFd0000F011*
ID_MODEL_FROM_DATABASE=Saturn: LightPulse Fibre Channel Host Adapter
@@ -31976,6 +32165,9 @@ pci:v000010DFd0000F0F5*
pci:v000010DFd0000F100*
ID_MODEL_FROM_DATABASE=Saturn-X: LightPulse Fibre Channel Host Adapter
+pci:v000010DFd0000F100sv00001014sd0000038A*
+ ID_MODEL_FROM_DATABASE=Saturn-X: LightPulse Fibre Channel Host Adapter (8Gb PCI Express Dual Port FC Adapter for POWER)
+
pci:v000010DFd0000F100sv0000103Csd00003282*
ID_MODEL_FROM_DATABASE=Saturn-X: LightPulse Fibre Channel Host Adapter (8Gb Dual-port PCI-e FC HBA)
@@ -32042,6 +32234,9 @@ pci:v000010DFd0000FC50*
pci:v000010DFd0000FD00*
ID_MODEL_FROM_DATABASE=Helios-X LightPulse Fibre Channel Host Adapter
+pci:v000010DFd0000FD00sv000010DFsd0000FD02*
+ ID_MODEL_FROM_DATABASE=Helios-X LightPulse Fibre Channel Host Adapter (LightPulse LP11002 Dual-port 4Gigabit PCI Fibre Channel Adapter)
+
pci:v000010DFd0000FD11*
ID_MODEL_FROM_DATABASE=Helios-X LightPulse Fibre Channel Host Adapter
@@ -32342,6 +32537,9 @@ pci:v000010ECd00005250*
pci:v000010ECd0000525A*
ID_MODEL_FROM_DATABASE=RTS525A PCI Express Card Reader
+pci:v000010ECd0000525Asv000017AAsd0000224F*
+ ID_MODEL_FROM_DATABASE=RTS525A PCI Express Card Reader (ThinkPad X1 Carbon 5th Gen)
+
pci:v000010ECd00005286*
ID_MODEL_FROM_DATABASE=RTS5286 PCI Express Card Reader
@@ -32657,6 +32855,9 @@ pci:v000010ECd00008168sv00001849sd00008168*
pci:v000010ECd00008168sv00007470sd00003468*
ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (TG-3468 Gigabit PCI Express Network Adapter)
+pci:v000010ECd00008168sv00008086sd00002055*
+ ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (NUC Kit DN2820FYKH)
+
pci:v000010ECd00008168sv00008086sd0000D615*
ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (Desktop Board D510MO/D525MW)
@@ -32795,6 +32996,9 @@ pci:v000010ECd00008821*
pci:v000010ECd0000B723*
ID_MODEL_FROM_DATABASE=RTL8723BE PCIe Wireless Network Adapter
+pci:v000010ECd0000B723sv000010ECsd00008739*
+ ID_MODEL_FROM_DATABASE=RTL8723BE PCIe Wireless Network Adapter (Dell Wireless 1801)
+
pci:v000010ED*
ID_VENDOR_FROM_DATABASE=Ascii Corporation
@@ -34263,10 +34467,10 @@ pci:v00001106d00003059sv00001043sd000080B0*
ID_MODEL_FROM_DATABASE=VT8233/A/8235/8237 AC97 Audio Controller (A7V600/K8V-X/K8V Deluxe motherboard (ADI AD1980 codec [SoundMAX]))
pci:v00001106d00003059sv00001043sd000080F3*
- ID_MODEL_FROM_DATABASE=VT8233/A/8235/8237 AC97 Audio Controller (ASUSTek SK8V motherboard)
+ ID_MODEL_FROM_DATABASE=VT8233/A/8235/8237 AC97 Audio Controller (SK8V motherboard)
pci:v00001106d00003059sv00001043sd0000810D*
- ID_MODEL_FROM_DATABASE=VT8233/A/8235/8237 AC97 Audio Controller (Asus P5VD1-X (AD1888 codec [SoundMax]))
+ ID_MODEL_FROM_DATABASE=VT8233/A/8235/8237 AC97 Audio Controller (P5VD1-X (AD1888 codec [SoundMax]))
pci:v00001106d00003059sv00001043sd0000812A*
ID_MODEL_FROM_DATABASE=VT8233/A/8235/8237 AC97 Audio Controller (A8V Deluxe motherboard (Realtek ALC850 codec))
@@ -36291,7 +36495,7 @@ pci:v00001131d00007133sv00001043sd00000210*
ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (FlyTV mini Asus Digimatrix)
pci:v00001131d00007133sv00001043sd00004843*
- ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (ASUS TV-FM 7133)
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (TV-FM 7133)
pci:v00001131d00007133sv00001043sd00004845*
ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (TV-FM 7135)
@@ -36513,7 +36717,7 @@ pci:v00001131d00007134sv00001043sd00000210*
ID_MODEL_FROM_DATABASE=SAA7134/SAA7135HL Video Broadcast Decoder (Digimatrix TV)
pci:v00001131d00007134sv00001043sd00004840*
- ID_MODEL_FROM_DATABASE=SAA7134/SAA7135HL Video Broadcast Decoder (ASUS TV-FM 7134)
+ ID_MODEL_FROM_DATABASE=SAA7134/SAA7135HL Video Broadcast Decoder (TV-FM 7134)
pci:v00001131d00007134sv00001043sd00004842*
ID_MODEL_FROM_DATABASE=SAA7134/SAA7135HL Video Broadcast Decoder (TV-FM 7134)
@@ -38649,7 +38853,7 @@ pci:v00001180d00000476sv00001043sd00001967*
ID_MODEL_FROM_DATABASE=RL5c476 II (V6800V)
pci:v00001180d00000476sv00001043sd00001987*
- ID_MODEL_FROM_DATABASE=RL5c476 II (Asus A4K and Z81K notebooks, possibly others ( mid-2005 machines ))
+ ID_MODEL_FROM_DATABASE=RL5c476 II (A4K and Z81K notebooks, possibly others ( mid-2005 machines ))
pci:v00001180d00000476sv0000104Dsd000080DF*
ID_MODEL_FROM_DATABASE=RL5c476 II (Vaio PCG-FX403)
@@ -38676,7 +38880,7 @@ pci:v00001180d00000476sv000017AAsd0000201C*
ID_MODEL_FROM_DATABASE=RL5c476 II (ThinkPad X60/X60s)
pci:v00001180d00000476sv000017AAsd000020C4*
- ID_MODEL_FROM_DATABASE=RL5c476 II (ThinkPad T61)
+ ID_MODEL_FROM_DATABASE=RL5c476 II (ThinkPad T61/R61)
pci:v00001180d00000476sv000017AAsd000020C6*
ID_MODEL_FROM_DATABASE=RL5c476 II (ThinkPad R61)
@@ -38826,7 +39030,7 @@ pci:v00001180d00000822sv00001043sd00001237*
ID_MODEL_FROM_DATABASE=R5C822 SD/SDIO/MMC/MS/MSPro Host Adapter (A6J-Q008)
pci:v00001180d00000822sv00001043sd00001967*
- ID_MODEL_FROM_DATABASE=R5C822 SD/SDIO/MMC/MS/MSPro Host Adapter (ASUS V6800V)
+ ID_MODEL_FROM_DATABASE=R5C822 SD/SDIO/MMC/MS/MSPro Host Adapter (V6800V)
pci:v00001180d00000822sv000010F7sd00008338*
ID_MODEL_FROM_DATABASE=R5C822 SD/SDIO/MMC/MS/MSPro Host Adapter (Panasonic CF-Y5 laptop)
@@ -38873,6 +39077,9 @@ pci:v00001180d00000832sv0000103Csd000030CC*
pci:v00001180d00000832sv0000103Csd000030CF*
ID_MODEL_FROM_DATABASE=R5C832 IEEE 1394 Controller (Pavilion dv9668eg Laptop)
+pci:v00001180d00000832sv000017AAsd000020C5*
+ ID_MODEL_FROM_DATABASE=R5C832 IEEE 1394 Controller (ThinkPad R61)
+
pci:v00001180d00000832sv000017AAsd000020C7*
ID_MODEL_FROM_DATABASE=R5C832 IEEE 1394 Controller (ThinkPad R61)
@@ -38892,10 +39099,10 @@ pci:v00001180d00000843sv00001028sd000001F3*
ID_MODEL_FROM_DATABASE=R5C843 MMC Host Controller (Inspiron 1420)
pci:v00001180d00000843sv00001028sd000001F5*
- ID_MODEL_FROM_DATABASE=R5C843 MMC Host Controller (Dell Inspiron 1501)
+ ID_MODEL_FROM_DATABASE=R5C843 MMC Host Controller (Inspiron 1501)
pci:v00001180d00000843sv00001028sd0000024F*
- ID_MODEL_FROM_DATABASE=R5C843 MMC Host Controller (Dell Latitude e6500)
+ ID_MODEL_FROM_DATABASE=R5C843 MMC Host Controller (Latitude e6500)
pci:v00001180d00000843sv0000103Csd000003B5*
ID_MODEL_FROM_DATABASE=R5C843 MMC Host Controller (Presario V3242AU)
@@ -38963,6 +39170,9 @@ pci:v00001180d0000E822sv00001028sd0000040B*
pci:v00001180d0000E823*
ID_MODEL_FROM_DATABASE=PCIe SDXC/MMC Host Controller
+pci:v00001180d0000E823sv000017AAsd000021CF*
+ ID_MODEL_FROM_DATABASE=PCIe SDXC/MMC Host Controller (ThinkPad T520)
+
pci:v00001180d0000E832*
ID_MODEL_FROM_DATABASE=R5C832 PCIe IEEE 1394 Controller
@@ -38972,6 +39182,9 @@ pci:v00001180d0000E832sv00001028sd0000040A*
pci:v00001180d0000E832sv00001028sd0000040B*
ID_MODEL_FROM_DATABASE=R5C832 PCIe IEEE 1394 Controller (Latitude E6510)
+pci:v00001180d0000E832sv000017AAsd000021CF*
+ ID_MODEL_FROM_DATABASE=R5C832 PCIe IEEE 1394 Controller (ThinkPad T520)
+
pci:v00001180d0000E852*
ID_MODEL_FROM_DATABASE=PCIe xD-Picture Card Controller
@@ -43734,7 +43947,7 @@ pci:v000012D8*
ID_VENDOR_FROM_DATABASE=Pericom Semiconductor
pci:v000012D8d000001A7*
- ID_MODEL_FROM_DATABASE=PI7C21P100 PCI to PCI Bridge
+ ID_MODEL_FROM_DATABASE=7C21P100 2-port PCI-X to PCI-X Bridge
pci:v000012D8d0000400A*
ID_MODEL_FROM_DATABASE=PI7C9X442SL PCI Express Bridge Port
@@ -44651,6 +44864,12 @@ pci:v00001344d00005161*
pci:v00001344d00005163*
ID_MODEL_FROM_DATABASE=RealSSD P425m
+pci:v00001344d00005180*
+ ID_MODEL_FROM_DATABASE=9100 PRO NVMe SSD
+
+pci:v00001344d00005181*
+ ID_MODEL_FROM_DATABASE=9100 MAX NVMe SSD
+
pci:v00001345*
ID_VENDOR_FROM_DATABASE=Arescom Inc
@@ -44889,7 +45108,7 @@ pci:v00001360d00000208*
ID_MODEL_FROM_DATABASE=GPS180AMC GPS Receiver (PCI Express / MicroTCA / AdvancedMC)
pci:v00001360d00000209*
- ID_MODEL_FROM_DATABASE=GRC181PEX GPS/GLONASS/BEIDOU receiver (PCI Express)
+ ID_MODEL_FROM_DATABASE=GNS181PEX GPS/Galileo/GLONASS/BEIDOU receiver (PCI Express)
pci:v00001360d00000301*
ID_MODEL_FROM_DATABASE=TCR510PCI IRIG Timecode Reader
@@ -46680,7 +46899,7 @@ pci:v0000140A*
ID_VENDOR_FROM_DATABASE=DSP Research Inc
pci:v0000140B*
- ID_VENDOR_FROM_DATABASE=GE Intelligent Platforms
+ ID_VENDOR_FROM_DATABASE=Abaco Systems, Inc.
pci:v0000140C*
ID_VENDOR_FROM_DATABASE=Elmic Systems Inc
@@ -47618,6 +47837,12 @@ pci:v00001425d0000509F*
pci:v00001425d000050A0*
ID_MODEL_FROM_DATABASE=T540-50A0 Unified Wire Ethernet Controller
+pci:v00001425d000050A1*
+ ID_MODEL_FROM_DATABASE=T540-50A1 Unified Wire Ethernet Controller
+
+pci:v00001425d000050A2*
+ ID_MODEL_FROM_DATABASE=T580-50A2 Unified Wire Ethernet Controller
+
pci:v00001425d00005401*
ID_MODEL_FROM_DATABASE=T520-CR Unified Wire Ethernet Controller
@@ -47771,6 +47996,12 @@ pci:v00001425d0000549F*
pci:v00001425d000054A0*
ID_MODEL_FROM_DATABASE=T540-50A0 Unified Wire Ethernet Controller
+pci:v00001425d000054A1*
+ ID_MODEL_FROM_DATABASE=T540-50A1 Unified Wire Ethernet Controller
+
+pci:v00001425d000054A2*
+ ID_MODEL_FROM_DATABASE=T580-50A2 Unified Wire Ethernet Controller
+
pci:v00001425d00005501*
ID_MODEL_FROM_DATABASE=T520-CR Unified Wire Storage Controller
@@ -47924,6 +48155,12 @@ pci:v00001425d0000559F*
pci:v00001425d000055A0*
ID_MODEL_FROM_DATABASE=T540-50A0 Unified Wire Storage Controller
+pci:v00001425d000055A1*
+ ID_MODEL_FROM_DATABASE=T540-50A1 Unified Wire Storage Controller
+
+pci:v00001425d000055A2*
+ ID_MODEL_FROM_DATABASE=T580-50A2 Unified Wire Storage Controller
+
pci:v00001425d00005601*
ID_MODEL_FROM_DATABASE=T520-CR Unified Wire Storage Controller
@@ -48077,6 +48314,12 @@ pci:v00001425d0000569F*
pci:v00001425d000056A0*
ID_MODEL_FROM_DATABASE=T540-50A0 Unified Wire Storage Controller
+pci:v00001425d000056A1*
+ ID_MODEL_FROM_DATABASE=T540-50A1 Unified Wire Storage Controller
+
+pci:v00001425d000056A2*
+ ID_MODEL_FROM_DATABASE=T580-50A2 Unified Wire Storage Controller
+
pci:v00001425d00005701*
ID_MODEL_FROM_DATABASE=T520-CR Unified Wire Ethernet Controller
@@ -48347,6 +48590,12 @@ pci:v00001425d0000589F*
pci:v00001425d000058A0*
ID_MODEL_FROM_DATABASE=T540-50A0 Unified Wire Ethernet Controller [VF]
+pci:v00001425d000058A1*
+ ID_MODEL_FROM_DATABASE=T540-50A1 Unified Wire Ethernet Controller [VF]
+
+pci:v00001425d000058A2*
+ ID_MODEL_FROM_DATABASE=T580-50A2 Unified Wire Ethernet Controller [VF]
+
pci:v00001425d00006001*
ID_MODEL_FROM_DATABASE=T6225-CR Unified Wire Ethernet Controller
@@ -48392,6 +48641,15 @@ pci:v00001425d00006080*
pci:v00001425d00006081*
ID_MODEL_FROM_DATABASE=T62100-6081 Unified Wire Ethernet Controller
+pci:v00001425d00006082*
+ ID_MODEL_FROM_DATABASE=T6225-6082 Unified Wire Ethernet Controller
+
+pci:v00001425d00006083*
+ ID_MODEL_FROM_DATABASE=T62100-6083 Unified Wire Ethernet Controller
+
+pci:v00001425d00006084*
+ ID_MODEL_FROM_DATABASE=T64100-6084 Unified Wire Ethernet Controller
+
pci:v00001425d00006401*
ID_MODEL_FROM_DATABASE=T6225-CR Unified Wire Ethernet Controller
@@ -48437,6 +48695,15 @@ pci:v00001425d00006480*
pci:v00001425d00006481*
ID_MODEL_FROM_DATABASE=T62100-6081 Unified Wire Ethernet Controller
+pci:v00001425d00006482*
+ ID_MODEL_FROM_DATABASE=T6225-6082 Unified Wire Ethernet Controller
+
+pci:v00001425d00006483*
+ ID_MODEL_FROM_DATABASE=T62100-6083 Unified Wire Ethernet Controller
+
+pci:v00001425d00006484*
+ ID_MODEL_FROM_DATABASE=T64100-6084 Unified Wire Ethernet Controller
+
pci:v00001425d00006501*
ID_MODEL_FROM_DATABASE=T6225-CR Unified Wire Storage Controller
@@ -48482,6 +48749,15 @@ pci:v00001425d00006580*
pci:v00001425d00006581*
ID_MODEL_FROM_DATABASE=T62100-6081 Unified Wire Storage Controller
+pci:v00001425d00006582*
+ ID_MODEL_FROM_DATABASE=T6225-6082 Unified Wire Storage Controller
+
+pci:v00001425d00006583*
+ ID_MODEL_FROM_DATABASE=T62100-6083 Unified Wire Storage Controller
+
+pci:v00001425d00006584*
+ ID_MODEL_FROM_DATABASE=T64100-6084 Unified Wire Storage Controller
+
pci:v00001425d00006601*
ID_MODEL_FROM_DATABASE=T6225-CR Unified Wire Storage Controller
@@ -48527,6 +48803,15 @@ pci:v00001425d00006680*
pci:v00001425d00006681*
ID_MODEL_FROM_DATABASE=T62100-6081 Unified Wire Storage Controller
+pci:v00001425d00006682*
+ ID_MODEL_FROM_DATABASE=T6225-6082 Unified Wire Storage Controller
+
+pci:v00001425d00006683*
+ ID_MODEL_FROM_DATABASE=T62100-6083 Unified Wire Storage Controller
+
+pci:v00001425d00006684*
+ ID_MODEL_FROM_DATABASE=T64100-6084 Unified Wire Storage Controller
+
pci:v00001425d00006801*
ID_MODEL_FROM_DATABASE=T6225-CR Unified Wire Ethernet Controller [VF]
@@ -48572,6 +48857,15 @@ pci:v00001425d00006880*
pci:v00001425d00006881*
ID_MODEL_FROM_DATABASE=T62100-6081 Unified Wire Ethernet Controller [VF]
+pci:v00001425d00006882*
+ ID_MODEL_FROM_DATABASE=T6225-6082 Unified Wire Ethernet Controller [VF]
+
+pci:v00001425d00006883*
+ ID_MODEL_FROM_DATABASE=T62100-6083 Unified Wire Ethernet Controller [VF]
+
+pci:v00001425d00006884*
+ ID_MODEL_FROM_DATABASE=T64100-6084 Unified Wire Ethernet Controller [VF]
+
pci:v00001425d0000A000*
ID_MODEL_FROM_DATABASE=PE10K Unified Wire Ethernet Controller
@@ -48830,6 +49124,36 @@ pci:v0000144Dd0000A821sv00001028sd00001FC2*
pci:v0000144Dd0000A821sv00001028sd00001FC4*
ID_MODEL_FROM_DATABASE=NVMe SSD Controller 172X (Express Flash NVMe PM1725 1.6TB AIC)
+pci:v0000144Dd0000A822*
+ ID_MODEL_FROM_DATABASE=NVMe SSD Controller 172Xa
+
+pci:v0000144Dd0000A822sv00001014sd00000621*
+ ID_MODEL_FROM_DATABASE=NVMe SSD Controller 172Xa (PCIe3 1.6TB NVMe Flash Adapter II x8)
+
+pci:v0000144Dd0000A822sv00001014sd00000622*
+ ID_MODEL_FROM_DATABASE=NVMe SSD Controller 172Xa (PCIe3 3.2TB NVMe Flash Adapter II x8)
+
+pci:v0000144Dd0000A822sv00001028sd00001FD9*
+ ID_MODEL_FROM_DATABASE=NVMe SSD Controller 172Xa (Express Flash PM1725a 800GB SFF)
+
+pci:v0000144Dd0000A822sv00001028sd00001FDA*
+ ID_MODEL_FROM_DATABASE=NVMe SSD Controller 172Xa (Express Flash PM1725a 1.6TB SFF)
+
+pci:v0000144Dd0000A822sv00001028sd00001FDB*
+ ID_MODEL_FROM_DATABASE=NVMe SSD Controller 172Xa (Express Flash PM1725a 3.2TB SFF)
+
+pci:v0000144Dd0000A822sv00001028sd00001FDC*
+ ID_MODEL_FROM_DATABASE=NVMe SSD Controller 172Xa (Express Flash PM1725a 6.4TB SFF)
+
+pci:v0000144Dd0000A822sv00001028sd00001FDD*
+ ID_MODEL_FROM_DATABASE=NVMe SSD Controller 172Xa (Express Flash PM1725a 1.6TB AIC)
+
+pci:v0000144Dd0000A822sv00001028sd00001FDE*
+ ID_MODEL_FROM_DATABASE=NVMe SSD Controller 172Xa (Express Flash PM1725a 3.2TB AIC)
+
+pci:v0000144Dd0000A822sv00001028sd00001FDF*
+ ID_MODEL_FROM_DATABASE=NVMe SSD Controller 172Xa (Express Flash PM1725a 6.4TB AIC)
+
pci:v0000144E*
ID_VENDOR_FROM_DATABASE=OLITEC
@@ -49371,7 +49695,16 @@ pci:v000014CC*
ID_VENDOR_FROM_DATABASE=NAKAYO Telecommunications Inc
pci:v000014CD*
- ID_VENDOR_FROM_DATABASE=Universal Scientific Ind.
+ ID_VENDOR_FROM_DATABASE=Universal Global Scientific Industrial Co.,Ltd
+
+pci:v000014CDd00000001*
+ ID_MODEL_FROM_DATABASE=USI-1514-1GbaseT [OCP1]
+
+pci:v000014CDd00000002*
+ ID_MODEL_FROM_DATABASE=USI-4227-SFP [OCP2]
+
+pci:v000014CDd00000003*
+ ID_MODEL_FROM_DATABASE=USI-X557-10GbaseT [OCP3]
pci:v000014CE*
ID_VENDOR_FROM_DATABASE=Whistle Communications
@@ -49676,6 +50009,9 @@ pci:v000014E4d0000163C*
pci:v000014E4d0000163D*
ID_MODEL_FROM_DATABASE=NetXtreme II BCM57811 10-Gigabit Ethernet
+pci:v000014E4d0000163Dsv00001043sd0000858A*
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM57811 10-Gigabit Ethernet (PEB-10G/57811-1S)
+
pci:v000014E4d0000163E*
ID_MODEL_FROM_DATABASE=NetXtreme II BCM57811 10 Gigabit Ethernet Multi Function
@@ -50049,7 +50385,7 @@ pci:v000014E4d0000165A*
ID_MODEL_FROM_DATABASE=NetXtreme BCM5722 Gigabit Ethernet PCI Express
pci:v000014E4d0000165Asv00001014sd00000378*
- ID_MODEL_FROM_DATABASE=NetXtreme BCM5722 Gigabit Ethernet PCI Express (IBM System x3350 (Machine type 4192))
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5722 Gigabit Ethernet PCI Express (System x3350 (Machine type 4192))
pci:v000014E4d0000165Asv00001028sd0000020F*
ID_MODEL_FROM_DATABASE=NetXtreme BCM5722 Gigabit Ethernet PCI Express (PowerEdge R300 Broadcom NetXtreme 5722)
@@ -50291,6 +50627,9 @@ pci:v000014E4d0000168D*
pci:v000014E4d0000168E*
ID_MODEL_FROM_DATABASE=NetXtreme II BCM57810 10 Gigabit Ethernet
+pci:v000014E4d0000168Esv00001014sd00000492*
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM57810 10 Gigabit Ethernet (PCIe2 2-port 10 GbE BaseT RJ45 Adapter (FC EN0W; CCIN 2CC4))
+
pci:v000014E4d0000168Esv0000103Csd00001798*
ID_MODEL_FROM_DATABASE=NetXtreme II BCM57810 10 Gigabit Ethernet (Flex-10 10Gb 2-port 530FLB Adapter [Meru])
@@ -50345,6 +50684,9 @@ pci:v000014E4d00001693sv00001025sd00000121*
pci:v000014E4d00001693sv0000103Csd000030C0*
ID_MODEL_FROM_DATABASE=NetLink BCM5787M Gigabit Ethernet PCI Express (6710b)
+pci:v000014E4d00001693sv000017AAsd000020D5*
+ ID_MODEL_FROM_DATABASE=NetLink BCM5787M Gigabit Ethernet PCI Express (ThinkPad R61)
+
pci:v000014E4d00001694*
ID_MODEL_FROM_DATABASE=NetLink BCM57790 Gigabit Ethernet PCIe
@@ -50712,7 +51054,7 @@ pci:v000014E4d000016CA*
ID_MODEL_FROM_DATABASE=BCM57304 NetXtreme-C 10Gb/25Gb/40Gb/50Gb Ethernet Controller
pci:v000014E4d000016CB*
- ID_MODEL_FROM_DATABASE=BCM57304 NetXtreme-C Ethernet Virtual Function
+ ID_MODEL_FROM_DATABASE=NetXtreme-C Ethernet Virtual Function
pci:v000014E4d000016CC*
ID_MODEL_FROM_DATABASE=BCM57417 NetXtreme-E Ethernet Partition
@@ -50733,7 +51075,7 @@ pci:v000014E4d000016D2*
ID_MODEL_FROM_DATABASE=BCM57406 NetXtreme-E 10GBASE-T Ethernet Controller
pci:v000014E4d000016D3*
- ID_MODEL_FROM_DATABASE=BCM57404 NetXtreme-E Ethernet Virtual Function
+ ID_MODEL_FROM_DATABASE=NetXtreme-E Ethernet Virtual Function
pci:v000014E4d000016D4*
ID_MODEL_FROM_DATABASE=BCM57402 NetXtreme-E Ethernet Partition
@@ -50747,6 +51089,12 @@ pci:v000014E4d000016D6*
pci:v000014E4d000016D7*
ID_MODEL_FROM_DATABASE=BCM57414 NetXtreme-E 10Gb/25Gb RDMA Ethernet Controller
+pci:v000014E4d000016D7sv000014E4sd00001202*
+ ID_MODEL_FROM_DATABASE=BCM57414 NetXtreme-E 10Gb/25Gb RDMA Ethernet Controller (BCM957412M4122 OCP 1x25G Type1 wRoCE)
+
+pci:v000014E4d000016D7sv000014E4sd00001404*
+ ID_MODEL_FROM_DATABASE=BCM57414 NetXtreme-E 10Gb/25Gb RDMA Ethernet Controller (BCM957414M4142 OCP 2x25G Type1 wRoCE)
+
pci:v000014E4d000016D7sv00001590sd0000020E*
ID_MODEL_FROM_DATABASE=BCM57414 NetXtreme-E 10Gb/25Gb RDMA Ethernet Controller (Ethernet 25Gb 2-port 631SFP28 Adapter)
@@ -50769,7 +51117,7 @@ pci:v000014E4d000016D9sv0000108Esd00004866*
ID_MODEL_FROM_DATABASE=BCM57417 NetXtreme-E 10GBASE-T RDMA Ethernet Controller (Dual Port 10GBase-T Ethernet Controller)
pci:v000014E4d000016DC*
- ID_MODEL_FROM_DATABASE=BCM57414 NetXtreme-E Ethernet Virtual Function
+ ID_MODEL_FROM_DATABASE=NetXtreme-E Ethernet Virtual Function
pci:v000014E4d000016DD*
ID_MODEL_FROM_DATABASE=NetLink BCM5781 Gigabit Ethernet PCI Express
@@ -50781,7 +51129,7 @@ pci:v000014E4d000016DF*
ID_MODEL_FROM_DATABASE=BCM57314 NetXtreme-C 10Gb/25Gb/40Gb/50Gb RDMA Ethernet Controller
pci:v000014E4d000016E1*
- ID_MODEL_FROM_DATABASE=BCM57314 NetXtreme-C Ethernet Virtual Function
+ ID_MODEL_FROM_DATABASE=NetXtreme-C Ethernet Virtual Function
pci:v000014E4d000016E2*
ID_MODEL_FROM_DATABASE=BCM57417 NetXtreme-E 10Gb/25Gb RDMA Ethernet Controller
@@ -50792,6 +51140,9 @@ pci:v000014E4d000016E2sv0000108Esd00004866*
pci:v000014E4d000016E3*
ID_MODEL_FROM_DATABASE=BCM57416 NetXtreme-E 10Gb RDMA Ethernet Controller
+pci:v000014E4d000016E5*
+ ID_MODEL_FROM_DATABASE=NetXtreme-C RDMA Virtual Function
+
pci:v000014E4d000016E7*
ID_MODEL_FROM_DATABASE=BCM57404 NetXtreme-E Ethernet Partition
@@ -51644,6 +51995,12 @@ pci:v000014E4d0000B800*
pci:v000014E4d0000B842*
ID_MODEL_FROM_DATABASE=BCM56842 Trident 10GE Switch Controller
+pci:v000014E4d0000B850*
+ ID_MODEL_FROM_DATABASE=Broadcom BCM56850 Switch ASIC
+
+pci:v000014E4d0000B960*
+ ID_MODEL_FROM_DATABASE=Broadcom BCM56960 Switch ASIC
+
pci:v000014E5*
ID_VENDOR_FROM_DATABASE=Pixelfusion Ltd
@@ -52209,7 +52566,7 @@ pci:v000014F1d00008800sv00001002sd0000A101*
ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (HDTV Wonder)
pci:v000014F1d00008800sv00001043sd00004823*
- ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (ASUS PVR-416)
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (PVR-416)
pci:v000014F1d00008800sv0000107Dsd00006611*
ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (Winfast TV 2000XP Expert)
@@ -52347,7 +52704,7 @@ pci:v000014F1d00008802sv00000070sd00009600*
ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [MPEG Port] (WinTV 88x MPEG Encoder)
pci:v000014F1d00008802sv00001043sd00004823*
- ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [MPEG Port] (ASUS PVR-416)
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [MPEG Port] (PVR-416)
pci:v000014F1d00008802sv0000107Dsd0000663C*
ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [MPEG Port] (Leadtek PVR 2000)
@@ -53025,7 +53382,7 @@ pci:v00001541*
ID_VENDOR_FROM_DATABASE=MACHONE Communications
pci:v00001542*
- ID_VENDOR_FROM_DATABASE=Concurrent Computer Corporation
+ ID_VENDOR_FROM_DATABASE=Concurrent Real-Time
pci:v00001542d00009260*
ID_MODEL_FROM_DATABASE=RCIM-II Real-Time Clock & Interrupt Module
@@ -53621,6 +53978,39 @@ pci:v000015B3d00001003sv0000103Csd000018CF*
pci:v000015B3d00001003sv0000103Csd000018D6*
ID_MODEL_FROM_DATABASE=MT27500 Family [ConnectX-3] (InfiniBand FDR/EN 10/40Gb Dual Port 544QSFP Adapter)
+pci:v000015B3d00001003sv000015B3sd00000025*
+ ID_MODEL_FROM_DATABASE=MT27500 Family [ConnectX-3] (ConnectX-3 IB QDR Dual Port Mezzanine Card)
+
+pci:v000015B3d00001003sv000015B3sd00000026*
+ ID_MODEL_FROM_DATABASE=MT27500 Family [ConnectX-3] (ConnectX-3 IB FDR Dual Port Mezzanine Card)
+
+pci:v000015B3d00001003sv000015B3sd00000028*
+ ID_MODEL_FROM_DATABASE=MT27500 Family [ConnectX-3] (ConnectX-3 VPI Dual QSFP+ Port QDR Infiniband 40Gb/s or 10Gb Ethernet)
+
+pci:v000015B3d00001003sv000015B3sd00000059*
+ ID_MODEL_FROM_DATABASE=MT27500 Family [ConnectX-3] (ConnectX-3 VPI IB FDR/40 GbE Single Port QSFP+ Mezzanine Card)
+
+pci:v000015B3d00001003sv000015B3sd00000065*
+ ID_MODEL_FROM_DATABASE=MT27500 Family [ConnectX-3] (ConnectX-3 VPI IB FDR/40 GbE Dual Port QSFP+ Adapter)
+
+pci:v000015B3d00001003sv000015B3sd00000066*
+ ID_MODEL_FROM_DATABASE=MT27500 Family [ConnectX-3] (ConnectX-3 IB FDR10 Dual Port Mezzanine Card)
+
+pci:v000015B3d00001003sv000015B3sd00000067*
+ ID_MODEL_FROM_DATABASE=MT27500 Family [ConnectX-3] (ConnectX-3 VPI IB FDR/40 GbE Single Port QSFP+ Adapter)
+
+pci:v000015B3d00001003sv000015B3sd00000071*
+ ID_MODEL_FROM_DATABASE=MT27500 Family [ConnectX-3] (ConnectX-3 VPI IB FDR/40 GbE Dual Port QSFP+ Mezzanine Card)
+
+pci:v000015B3d00001003sv000015B3sd00000078*
+ ID_MODEL_FROM_DATABASE=MT27500 Family [ConnectX-3] (ConnectX-3 10 GbE Dual Port KR Mezzanine Card)
+
+pci:v000015B3d00001003sv000015B3sd00000079*
+ ID_MODEL_FROM_DATABASE=MT27500 Family [ConnectX-3] (ConnectX-3 40 GbE Dual Port QSFP+ Adapter)
+
+pci:v000015B3d00001003sv000015B3sd00000080*
+ ID_MODEL_FROM_DATABASE=MT27500 Family [ConnectX-3] (ConnectX-3 10 GbE Dual Port SFP+ Adapter)
+
pci:v000015B3d00001004*
ID_MODEL_FROM_DATABASE=MT27500/MT27520 Family [ConnectX-3/ConnectX-3 Pro Virtual Function]
@@ -53657,6 +54047,15 @@ pci:v000015B3d00001007sv0000117Csd00000092*
pci:v000015B3d00001007sv0000117Csd00000093*
ID_MODEL_FROM_DATABASE=MT27520 Family [ConnectX-3 Pro] (FastFrame NQ12)
+pci:v000015B3d00001007sv000015B3sd00000078*
+ ID_MODEL_FROM_DATABASE=MT27520 Family [ConnectX-3 Pro] (ConnectX-3 Pro 10 GbE Dual Port KR Mezzanine Card)
+
+pci:v000015B3d00001007sv000015B3sd00000079*
+ ID_MODEL_FROM_DATABASE=MT27520 Family [ConnectX-3 Pro] (ConnectX-3 Pro 40 GbE Dual Port QSFP+ Adapter)
+
+pci:v000015B3d00001007sv000015B3sd00000080*
+ ID_MODEL_FROM_DATABASE=MT27520 Family [ConnectX-3 Pro] (ConnectX-3 Pro 10 GbE Dual Port SFP+ Adapter)
+
pci:v000015B3d00001009*
ID_MODEL_FROM_DATABASE=MT27530 Family
@@ -53690,12 +54089,36 @@ pci:v000015B3d00001012*
pci:v000015B3d00001013*
ID_MODEL_FROM_DATABASE=MT27700 Family [ConnectX-4]
+pci:v000015B3d00001013sv000015B3sd00000006*
+ ID_MODEL_FROM_DATABASE=MT27700 Family [ConnectX-4] (MCX416A-BCAT, ConnectX-4 EN, 40/56GbE 2P, PCIe3.0 x16)
+
+pci:v000015B3d00001013sv000015B3sd00000033*
+ ID_MODEL_FROM_DATABASE=MT27700 Family [ConnectX-4] (ConnectX-4 VPI IB EDR/100 GbE Single Port QSFP28 Adapter)
+
+pci:v000015B3d00001013sv000015B3sd00000034*
+ ID_MODEL_FROM_DATABASE=MT27700 Family [ConnectX-4] (ConnectX-4 VPI IB EDR/100 GbE Dual Port QSFP28 Adapter)
+
+pci:v000015B3d00001013sv000015B3sd00000050*
+ ID_MODEL_FROM_DATABASE=MT27700 Family [ConnectX-4] (ConnectX-4 100 GbE Dual Port QSFP28 Adapter)
+
pci:v000015B3d00001014*
ID_MODEL_FROM_DATABASE=MT27700 Family [ConnectX-4 Virtual Function]
pci:v000015B3d00001015*
ID_MODEL_FROM_DATABASE=MT27710 Family [ConnectX-4 Lx]
+pci:v000015B3d00001015sv000015B3sd00000016*
+ ID_MODEL_FROM_DATABASE=MT27710 Family [ConnectX-4 Lx] (ConnectX-4 Lx 25 GbE Dual Port SFP28 Adapter)
+
+pci:v000015B3d00001015sv000015B3sd00000020*
+ ID_MODEL_FROM_DATABASE=MT27710 Family [ConnectX-4 Lx] (MCX4411A-ACQN, ConnectX-4 Lx EN OCP, 1x25Gb)
+
+pci:v000015B3d00001015sv000015B3sd00000021*
+ ID_MODEL_FROM_DATABASE=MT27710 Family [ConnectX-4 Lx] (MCX4421A-ACQN ConnectX-4 Lx EN OCP,2x25G)
+
+pci:v000015B3d00001015sv000015B3sd00000025*
+ ID_MODEL_FROM_DATABASE=MT27710 Family [ConnectX-4 Lx] (ConnectX-4 Lx 25 GbE Dual Port SFP28 rNDC)
+
pci:v000015B3d00001016*
ID_MODEL_FROM_DATABASE=MT27710 Family [ConnectX-4 Lx Virtual Function]
@@ -53786,6 +54209,9 @@ pci:v000015B3d00006732*
pci:v000015B3d0000673C*
ID_MODEL_FROM_DATABASE=MT26428 [ConnectX VPI PCIe 2.0 5GT/s - IB QDR / 10GigE]
+pci:v000015B3d0000673Csv00001014sd00000487*
+ ID_MODEL_FROM_DATABASE=MT26428 [ConnectX VPI PCIe 2.0 5GT/s - IB QDR / 10GigE] (GX++ 1-port 4X IB QDR Adapter for Power 795)
+
pci:v000015B3d0000673Csv0000103Csd00001782*
ID_MODEL_FROM_DATABASE=MT26428 [ConnectX VPI PCIe 2.0 5GT/s - IB QDR / 10GigE] (4X QDR InfiniBand Mezzanine HCA for c-Class BladeSystem)
@@ -53810,6 +54236,9 @@ pci:v000015B3d00006750sv00001014sd00000461*
pci:v000015B3d00006750sv000015B3sd00000018*
ID_MODEL_FROM_DATABASE=MT26448 [ConnectX EN 10GigE, PCIe 2.0 5GT/s] (HP 10 GbE PCI-e G2 Dual-Port NIC (rev C1))
+pci:v000015B3d00006750sv000015B3sd00006572*
+ ID_MODEL_FROM_DATABASE=MT26448 [ConnectX EN 10GigE, PCIe 2.0 5GT/s] (IBM Flex System EN4132 2-port 10Gb RoCE Adapter)
+
pci:v000015B3d0000675A*
ID_MODEL_FROM_DATABASE=MT25408 [ConnectX EN 10GigE 10GBaseT, PCIe Gen2 5GT/s]
@@ -53849,6 +54278,9 @@ pci:v000015B3d0000A2D0*
pci:v000015B3d0000A2D1*
ID_MODEL_FROM_DATABASE=MT416842 BlueField SoC Crypto disabled
+pci:v000015B3d0000A2D2*
+ ID_MODEL_FROM_DATABASE=MT416842 BlueField integrated ConnectX-5 network controller
+
pci:v000015B3d0000A2D3*
ID_MODEL_FROM_DATABASE=MT416842 BlueField multicore SoC family VF
@@ -55424,6 +55856,9 @@ pci:v0000168Cd00000033sv0000168Csd0000A120*
pci:v0000168Cd00000034*
ID_MODEL_FROM_DATABASE=AR9462 Wireless Network Adapter
+pci:v0000168Cd00000034sv00001028sd0000020B*
+ ID_MODEL_FROM_DATABASE=AR9462 Wireless Network Adapter (Wireless 1601 802.11abgn Adapter)
+
pci:v0000168Cd00000034sv00001028sd00000300*
ID_MODEL_FROM_DATABASE=AR9462 Wireless Network Adapter (Wireless 1802 802.11abgn Adapter)
@@ -58245,31 +58680,31 @@ pci:v00001924d00000A03*
ID_MODEL_FROM_DATABASE=SFC9220 10/40G Ethernet Controller
pci:v00001924d00000A03sv00001924sd00008011*
- ID_MODEL_FROM_DATABASE=SFC9220 10/40G Ethernet Controller (SFN8022-R1 Flareon 8000 Series 10G Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9220 10/40G Ethernet Controller (SFN8022-R1 8000 Series 10G Adapter)
pci:v00001924d00000A03sv00001924sd00008012*
- ID_MODEL_FROM_DATABASE=SFC9220 10/40G Ethernet Controller (SFN8522-R1 Flareon Ultra 8000 Series 10G Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9220 10/40G Ethernet Controller (SFN8522-R1 8000 Series 10G Adapter)
pci:v00001924d00000A03sv00001924sd00008013*
- ID_MODEL_FROM_DATABASE=SFC9220 10/40G Ethernet Controller (SFN8042-R1 Flareon 8000 Series 10/40G Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9220 10/40G Ethernet Controller (SFN8042-R1 8000 Series 10/40G Adapter)
pci:v00001924d00000A03sv00001924sd00008014*
- ID_MODEL_FROM_DATABASE=SFC9220 10/40G Ethernet Controller (SFN8542-R1 Flareon Ultra 8000 Series 10/40G Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9220 10/40G Ethernet Controller (SFN8542-R1 8000 Series 10/40G Adapter)
pci:v00001924d00000A03sv00001924sd00008016*
- ID_MODEL_FROM_DATABASE=SFC9220 10/40G Ethernet Controller (SFN8022-R2 Flareon 8000 Series 10G Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9220 10/40G Ethernet Controller (SFN8022-R2 8000 Series 10G Adapte)
pci:v00001924d00000A03sv00001924sd00008017*
- ID_MODEL_FROM_DATABASE=SFC9220 10/40G Ethernet Controller (SFN8522-R2 Flareon Ultra 8000 Series 10G Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9220 10/40G Ethernet Controller (SFN8522-R2 8000 Series 10G Adapter)
pci:v00001924d00000A03sv00001924sd00008018*
- ID_MODEL_FROM_DATABASE=SFC9220 10/40G Ethernet Controller (SFN8042-R2 Flareon 8000 Series 10/40G Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9220 10/40G Ethernet Controller (SFN8042-R2 8000 Series 10/40G Adapter)
pci:v00001924d00000A03sv00001924sd00008019*
- ID_MODEL_FROM_DATABASE=SFC9220 10/40G Ethernet Controller (SFN8542-R2 Flareon Ultra 8000 Series 10/40G Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9220 10/40G Ethernet Controller (SFN8542-R2 8000 Series 10/40G Adapter)
pci:v00001924d00000A03sv00001924sd0000801A*
- ID_MODEL_FROM_DATABASE=SFC9220 10/40G Ethernet Controller (SFN8722-R1 Flareon Ultra 8000 Series OCP 10G Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9220 10/40G Ethernet Controller (SFN8722-R1 8000 Series OCP 10G Adapter)
pci:v00001924d00001803*
ID_MODEL_FROM_DATABASE=SFC9020 10G Ethernet Controller (Virtual Function)
@@ -59013,32 +59448,50 @@ pci:v000019A2d00000222*
ID_MODEL_FROM_DATABASE=BladeEngine3 10Gb Gen2 PCIe iSCSI Adapter
pci:v000019A2d00000700*
- ID_MODEL_FROM_DATABASE=OneConnect 10Gb NIC
+ ID_MODEL_FROM_DATABASE=OneConnect OCe10100/OCe10102 Series 10 GbE
pci:v000019A2d00000700sv0000103Csd00001747*
- ID_MODEL_FROM_DATABASE=OneConnect 10Gb NIC (NC550SFP DualPort 10GbE Server Adapter)
+ ID_MODEL_FROM_DATABASE=OneConnect OCe10100/OCe10102 Series 10 GbE (NC550SFP DualPort 10GbE Server Adapter)
pci:v000019A2d00000700sv0000103Csd00001749*
- ID_MODEL_FROM_DATABASE=OneConnect 10Gb NIC (NC550SFP Dual Port Server Adapter)
+ ID_MODEL_FROM_DATABASE=OneConnect OCe10100/OCe10102 Series 10 GbE (NC550SFP Dual Port Server Adapter)
pci:v000019A2d00000700sv0000103Csd0000174A*
- ID_MODEL_FROM_DATABASE=OneConnect 10Gb NIC (NC551m Dual Port FlexFabric 10Gb Adapter)
+ ID_MODEL_FROM_DATABASE=OneConnect OCe10100/OCe10102 Series 10 GbE (NC551m Dual Port FlexFabric 10Gb Adapter)
pci:v000019A2d00000700sv0000103Csd0000174B*
- ID_MODEL_FROM_DATABASE=OneConnect 10Gb NIC (StorageWorks NC550 DualPort Converged Network Adapter)
+ ID_MODEL_FROM_DATABASE=OneConnect OCe10100/OCe10102 Series 10 GbE (StorageWorks NC550 DualPort Converged Network Adapter)
pci:v000019A2d00000700sv0000103Csd00003314*
- ID_MODEL_FROM_DATABASE=OneConnect 10Gb NIC (NC551i Dual Port FlexFabric 10Gb Adapter)
+ ID_MODEL_FROM_DATABASE=OneConnect OCe10100/OCe10102 Series 10 GbE (NC551i Dual Port FlexFabric 10Gb Adapter)
pci:v000019A2d00000702*
ID_MODEL_FROM_DATABASE=OneConnect 10Gb iSCSI Initiator
pci:v000019A2d00000704*
- ID_MODEL_FROM_DATABASE=OneConnect 10Gb FCoE Initiator
+ ID_MODEL_FROM_DATABASE=OneConnect OCe10100/OCe10102 Series 10 GbE CNA
+
+pci:v000019A2d00000704sv000010DFsd0000E602*
+ ID_MODEL_FROM_DATABASE=OneConnect OCe10100/OCe10102 Series 10 GbE CNA (OneConnect OCe10100 10Gb CNA)
+
+pci:v000019A2d00000704sv000010DFsd0000E630*
+ ID_MODEL_FROM_DATABASE=OneConnect OCe10100/OCe10102 Series 10 GbE CNA (OneConnect OCe10102-FM-E / OCe10102-FX-E for EMC VNX Symmetrix)
pci:v000019A2d00000710*
ID_MODEL_FROM_DATABASE=OneConnect 10Gb NIC (be3)
+pci:v000019A2d00000710sv00001014sd000003D0*
+ ID_MODEL_FROM_DATABASE=OneConnect 10Gb NIC (be3) (PCIe2 2-port 10GbE SR Adapter for POWER)
+
+pci:v000019A2d00000710sv00001014sd000003D1*
+ ID_MODEL_FROM_DATABASE=OneConnect 10Gb NIC (be3) (PCIe2 2-port 10GbE SFP+ Copper Adapter for POWER)
+
+pci:v000019A2d00000710sv00001014sd00000409*
+ ID_MODEL_FROM_DATABASE=OneConnect 10Gb NIC (be3) (Integrated Multifunction Card with Dual 10GbE SR Optical + Dual 1GbE for Power 750/760)
+
+pci:v000019A2d00000710sv00001014sd0000040A*
+ ID_MODEL_FROM_DATABASE=OneConnect 10Gb NIC (be3) (Integrated Multifunction Card with Dual 10GbE SR Copper + Dual 1GbE for Power 750/760)
+
pci:v000019A2d00000710sv0000103Csd00003315*
ID_MODEL_FROM_DATABASE=OneConnect 10Gb NIC (be3) (NC553i 10Gb 2-port FlexFabric Converged Network Adapter)
@@ -59054,6 +59507,9 @@ pci:v000019A2d00000710sv0000103Csd00003345*
pci:v000019A2d00000710sv0000103Csd0000337B*
ID_MODEL_FROM_DATABASE=OneConnect 10Gb NIC (be3) (NC554FLB 10Gb 2-port FlexFabric Converged Network Adapter)
+pci:v000019A2d00000710sv000010DFsd0000E733*
+ ID_MODEL_FROM_DATABASE=OneConnect 10Gb NIC (be3) (Flex System EN4054 4-port 10Gb Ethernet Mezzanine Adapter)
+
pci:v000019A2d00000712*
ID_MODEL_FROM_DATABASE=OneConnect 10Gb iSCSI Initiator (be3)
@@ -59774,9 +60230,24 @@ pci:v00001B36d00000006*
pci:v00001B36d00000007*
ID_MODEL_FROM_DATABASE=PCI SD Card Host Controller Interface
+pci:v00001B36d00000008*
+ ID_MODEL_FROM_DATABASE=QEMU PCIe Host bridge
+
+pci:v00001B36d00000009*
+ ID_MODEL_FROM_DATABASE=QEMU PCI Expander bridge
+
pci:v00001B36d0000000A*
ID_MODEL_FROM_DATABASE=PCI-PCI bridge (multiseat)
+pci:v00001B36d0000000B*
+ ID_MODEL_FROM_DATABASE=QEMU PCIe Expander bridge
+
+pci:v00001B36d0000000C*
+ ID_MODEL_FROM_DATABASE=QEMU PCIe Root port
+
+pci:v00001B36d0000000D*
+ ID_MODEL_FROM_DATABASE=QEMU XHCI Host Controller
+
pci:v00001B36d00000100*
ID_MODEL_FROM_DATABASE=QXL paravirtual graphic card
@@ -59822,6 +60293,9 @@ pci:v00001B37d0000001F*
pci:v00001B37d00000020*
ID_MODEL_FROM_DATABASE=ADQ14
+pci:v00001B37d00000023*
+ ID_MODEL_FROM_DATABASE=ADQ7
+
pci:v00001B37d00002014*
ID_MODEL_FROM_DATABASE=TX320
@@ -60014,6 +60488,9 @@ pci:v00001B85*
pci:v00001B85d00001041*
ID_MODEL_FROM_DATABASE=RevoDrive 3 X2 PCI-Express SSD 240 GB (Marvell Controller)
+pci:v00001B85d00006018*
+ ID_MODEL_FROM_DATABASE=RD400/400A SSD
+
pci:v00001B85d00008788*
ID_MODEL_FROM_DATABASE=RevoDrive Hybrid
@@ -60398,12 +60875,21 @@ pci:v00001CE4d00000005*
pci:v00001CE4d00000006*
ID_MODEL_FROM_DATABASE=ExaNIC X10-HPT
+pci:v00001CE4d00000007*
+ ID_MODEL_FROM_DATABASE=ExaNIC X40
+
pci:v00001CF7*
ID_VENDOR_FROM_DATABASE=Subspace Dynamics
pci:v00001D00*
ID_VENDOR_FROM_DATABASE=Pure Storage
+pci:v00001D18*
+ ID_VENDOR_FROM_DATABASE=RME
+
+pci:v00001D18d00000001*
+ ID_MODEL_FROM_DATABASE=Fireface UFX+
+
pci:v00001D1D*
ID_VENDOR_FROM_DATABASE=CNEX Labs
@@ -60443,6 +60929,9 @@ pci:v00001D44d0000A400*
pci:v00001D49*
ID_VENDOR_FROM_DATABASE=Lenovo
+pci:v00001D4C*
+ ID_VENDOR_FROM_DATABASE=Diamanti, Inc.
+
pci:v00001D5C*
ID_VENDOR_FROM_DATABASE=Fantasia Trading LLC
@@ -60518,6 +61007,9 @@ pci:v00001D78*
pci:v00001D7C*
ID_VENDOR_FROM_DATABASE=Aerotech, Inc.
+pci:v00001D87*
+ ID_VENDOR_FROM_DATABASE=Rockchip Inc. RK3399 PCI Express Root Port
+
pci:v00001D8F*
ID_VENDOR_FROM_DATABASE=Enyx
@@ -60527,6 +61019,9 @@ pci:v00001D95*
pci:v00001DA1*
ID_VENDOR_FROM_DATABASE=Teko Telecom S.r.l.
+pci:v00001DA2*
+ ID_VENDOR_FROM_DATABASE=Sapphire Technology Limited
+
pci:v00001DE1*
ID_VENDOR_FROM_DATABASE=Tekram Technology Co.,Ltd.
@@ -60677,6 +61172,9 @@ pci:v00001FC9d00004026*
pci:v00001FC9d00004027*
ID_MODEL_FROM_DATABASE=TN9710P 10GBase-T/NBASE-T Ethernet Adapter
+pci:v00001FC9d00004027sv00001154sd00000368*
+ ID_MODEL_FROM_DATABASE=TN9710P 10GBase-T/NBASE-T Ethernet Adapter (LGY-PCIE-MG)
+
pci:v00001FC9d00004027sv00001432sd00008104*
ID_MODEL_FROM_DATABASE=TN9710P 10GBase-T/NBASE-T Ethernet Adapter (10 Gigabit Ethernet PCI Express Adapter)
@@ -62489,6 +62987,9 @@ pci:v00005555*
pci:v00005555d00000003*
ID_MODEL_FROM_DATABASE=TURBOstor HFP-832 [HiPPI NIC]
+pci:v00005555d00003B00*
+ ID_MODEL_FROM_DATABASE=Epiphan DVI2PCIe video capture card
+
pci:v00005646*
ID_VENDOR_FROM_DATABASE=Vector Fabrics BV
@@ -62501,6 +63002,9 @@ pci:v00005678*
pci:v00005700*
ID_VENDOR_FROM_DATABASE=Netpower
+pci:v00005845*
+ ID_VENDOR_FROM_DATABASE=X-ES, Inc.
+
pci:v0000584D*
ID_VENDOR_FROM_DATABASE=AuzenTech Co., Ltd.
@@ -62817,7 +63321,7 @@ pci:v00008086d00000085*
ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6205 [Taylor Peak]
pci:v00008086d00000085sv00008086sd00001311*
- ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6205 [Taylor Peak] (Centrino Advanced-N 6205 AGN)
+ ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6205 [Taylor Peak] (Centrino Advanced-N 6205 (802.11a/b/g/n))
pci:v00008086d00000085sv00008086sd00001316*
ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6205 [Taylor Peak] (Centrino Advanced-N 6205 ABG)
@@ -62954,6 +63458,9 @@ pci:v00008086d00000104sv0000106Bsd000000DC*
pci:v00008086d00000104sv0000144Dsd0000C652*
ID_MODEL_FROM_DATABASE=2nd Generation Core Processor Family DRAM Controller (NP300E5C series laptop)
+pci:v00008086d00000104sv000017AAsd000021CF*
+ ID_MODEL_FROM_DATABASE=2nd Generation Core Processor Family DRAM Controller (ThinkPad T520)
+
pci:v00008086d00000105*
ID_MODEL_FROM_DATABASE=Xeon E3-1200/2nd Generation Core Processor Family PCI Express Root Port
@@ -63005,6 +63512,9 @@ pci:v00008086d00000126*
pci:v00008086d00000126sv00001028sd000004CC*
ID_MODEL_FROM_DATABASE=2nd Generation Core Processor Family Integrated Graphics Controller (Vostro 3350)
+pci:v00008086d00000126sv000017AAsd000021CF*
+ ID_MODEL_FROM_DATABASE=2nd Generation Core Processor Family Integrated Graphics Controller (ThinkPad T520)
+
pci:v00008086d00000150*
ID_MODEL_FROM_DATABASE=Xeon E3-1200 v2/3rd Gen Core processor DRAM Controller
@@ -65945,6 +66455,9 @@ pci:v00008086d000010BB*
pci:v00008086d000010BC*
ID_MODEL_FROM_DATABASE=82571EB Gigabit Ethernet Controller (Copper)
+pci:v00008086d000010BCsv00001014sd00000368*
+ ID_MODEL_FROM_DATABASE=82571EB Gigabit Ethernet Controller (Copper) (4-Port 10/100/1000 Base-TX PCI Express Adapter for POWER)
+
pci:v00008086d000010BCsv0000103Csd0000704B*
ID_MODEL_FROM_DATABASE=82571EB Gigabit Ethernet Controller (Copper) (NC364T PCI Express Quad Port Gigabit Server Adapter)
@@ -67077,13 +67590,16 @@ pci:v00008086d00001501*
ID_MODEL_FROM_DATABASE=82567V-3 Gigabit Network Connection
pci:v00008086d00001502*
- ID_MODEL_FROM_DATABASE=82579LM Gigabit Network Connection
+ ID_MODEL_FROM_DATABASE=82579LM Gigabit Network Connection (Lewisville)
pci:v00008086d00001502sv00001028sd000004A3*
- ID_MODEL_FROM_DATABASE=82579LM Gigabit Network Connection (Precision M4600)
+ ID_MODEL_FROM_DATABASE=82579LM Gigabit Network Connection (Lewisville) (Precision M4600)
+
+pci:v00008086d00001502sv000017AAsd000021CE*
+ ID_MODEL_FROM_DATABASE=82579LM Gigabit Network Connection (Lewisville) (ThinkPad T520)
pci:v00008086d00001502sv00008086sd0000357A*
- ID_MODEL_FROM_DATABASE=82579LM Gigabit Network Connection (Server Board S1200BTS)
+ ID_MODEL_FROM_DATABASE=82579LM Gigabit Network Connection (Lewisville) (Server Board S1200BTS)
pci:v00008086d00001503*
ID_MODEL_FROM_DATABASE=82579V Gigabit Network Connection
@@ -67451,6 +67967,9 @@ pci:v00008086d0000152A*
pci:v00008086d0000152E*
ID_MODEL_FROM_DATABASE=82599 Virtual Function
+pci:v00008086d0000152F*
+ ID_MODEL_FROM_DATABASE=I350 Virtual Function
+
pci:v00008086d00001530*
ID_MODEL_FROM_DATABASE=X540 Virtual Function
@@ -67496,6 +68015,12 @@ pci:v00008086d00001537sv00001059sd00000120*
pci:v00008086d00001537sv00001059sd00000130*
ID_MODEL_FROM_DATABASE=I210 Gigabit Backplane Connection (T4009 1GbE interface)
+pci:v00008086d00001537sv00001059sd00000140*
+ ID_MODEL_FROM_DATABASE=I210 Gigabit Backplane Connection (T2035 1GbE interface)
+
+pci:v00008086d00001537sv00001059sd00000150*
+ ID_MODEL_FROM_DATABASE=I210 Gigabit Backplane Connection (RD-01068 1GbE interface)
+
pci:v00008086d00001538*
ID_MODEL_FROM_DATABASE=I210 Gigabit Network Connection
@@ -67619,6 +68144,12 @@ pci:v00008086d00001563sv00008086sd00000001*
pci:v00008086d00001563sv00008086sd0000001A*
ID_MODEL_FROM_DATABASE=Ethernet Controller 10G X550T (Ethernet Converged Network Adapter X550-T2)
+pci:v00008086d00001563sv00008086sd0000001B*
+ ID_MODEL_FROM_DATABASE=Ethernet Controller 10G X550T (Ethernet Server Adapter X550-T2 for OCP)
+
+pci:v00008086d00001563sv00008086sd0000001D*
+ ID_MODEL_FROM_DATABASE=Ethernet Controller 10G X550T (Ethernet 10G 2P X550-t Adapter)
+
pci:v00008086d00001563sv00008086sd00000022*
ID_MODEL_FROM_DATABASE=Ethernet Controller 10G X550T (Ethernet Converged Network Adapter X550-T2)
@@ -67677,10 +68208,10 @@ pci:v00008086d00001572sv0000103Csd00000000*
ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (Ethernet 10Gb 562SFP+ Adapter)
pci:v00008086d00001572sv0000103Csd000022FC*
- ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (HP Ethernet 10Gb 2-port 562FLR-SFP+ Adapter)
+ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (Ethernet 10Gb 2-port 562FLR-SFP+ Adapter)
pci:v00008086d00001572sv0000103Csd000022FD*
- ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (HP Ethernet 10Gb 2-port 562SFP+ Adapter)
+ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (Ethernet 10Gb 2-port 562SFP+ Adapter)
pci:v00008086d00001572sv00001137sd00000000*
ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (Ethernet Converged NIC X710-DA)
@@ -67745,6 +68276,9 @@ pci:v00008086d00001572sv00008086sd0000000B*
pci:v00008086d00001572sv00008086sd0000000D*
ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+
+pci:v00008086d00001572sv00008086sd0000000E*
+ 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)
@@ -67754,6 +68288,9 @@ pci:v00008086d00001572sv00008086sd00004005*
pci:v00008086d00001572sv00008086sd00004006*
ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+
+pci:v00008086d00001572sv00008086sd00004007*
+ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+
+
pci:v00008086d00001575*
ID_MODEL_FROM_DATABASE=DSL6340 Thunderbolt 3 NHI [Alpine Ridge 2C 2015]
@@ -67793,6 +68330,9 @@ pci:v00008086d00001581sv00001028sd00001F98*
pci:v00008086d00001581sv00001028sd00001F9E*
ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE backplane (Ethernet 10G 2P X710-k bNDC)
+pci:v00008086d00001581sv00001059sd00000150*
+ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE backplane (RD-01068 10GbE-KR interface)
+
pci:v00008086d00001581sv00001590sd00000000*
ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE backplane (Ethernet 2-port 563i Adapter)
@@ -67875,10 +68415,10 @@ pci:v00008086d00001587*
ID_MODEL_FROM_DATABASE=Ethernet Controller XL710 for 20GbE backplane
pci:v00008086d00001587sv0000103Csd00000000*
- ID_MODEL_FROM_DATABASE=Ethernet Controller XL710 for 20GbE backplane (HPE Ethernet 10/20Gb 2-port 660FLB Adapter)
+ ID_MODEL_FROM_DATABASE=Ethernet Controller XL710 for 20GbE backplane (Ethernet 10/20Gb 2-port 660FLB Adapter)
pci:v00008086d00001587sv0000103Csd000022FE*
- ID_MODEL_FROM_DATABASE=Ethernet Controller XL710 for 20GbE backplane (HPE Ethernet 10/20Gb 2-port 660FLB Adapter)
+ ID_MODEL_FROM_DATABASE=Ethernet Controller XL710 for 20GbE backplane (Ethernet 10/20Gb 2-port 660FLB Adapter)
pci:v00008086d00001588*
ID_MODEL_FROM_DATABASE=Ethernet Controller XL710 for 20GbE backplane
@@ -67907,6 +68447,12 @@ pci:v00008086d00001589sv00008086sd00000001*
pci:v00008086d00001589sv00008086sd00000002*
ID_MODEL_FROM_DATABASE=Ethernet Controller X710/X557-AT 10GBASE-T (Ethernet Converged Network Adapter X710-T4)
+pci:v00008086d00001589sv00008086sd00000003*
+ ID_MODEL_FROM_DATABASE=Ethernet Controller X710/X557-AT 10GBASE-T (Ethernet Converged Network Adapter X710-T)
+
+pci:v00008086d00001589sv00008086sd000000A0*
+ ID_MODEL_FROM_DATABASE=Ethernet Controller X710/X557-AT 10GBASE-T (Ethernet Converged Network Adapter X710-T4)
+
pci:v00008086d00001589sv00008086sd00001003*
ID_MODEL_FROM_DATABASE=Ethernet Controller X710/X557-AT 10GBASE-T (Ethernet Converged Network Adapter X710-T)
@@ -67943,6 +68489,9 @@ pci:v00008086d0000158Bsv00008086sd00000007*
pci:v00008086d0000158Bsv00008086sd00000008*
ID_MODEL_FROM_DATABASE=Ethernet Controller XXV710 for 25GbE SFP28 (Ethernet Network Adapter OCP XXV710-1)
+pci:v00008086d0000158Bsv00008086sd00004001*
+ ID_MODEL_FROM_DATABASE=Ethernet Controller XXV710 for 25GbE SFP28 (Ethernet Network Adapter XXV710-2)
+
pci:v00008086d000015A0*
ID_MODEL_FROM_DATABASE=Ethernet Connection (2) I218-LM
@@ -67973,6 +68522,9 @@ pci:v00008086d000015AA*
pci:v00008086d000015AAsv00001059sd00000120*
ID_MODEL_FROM_DATABASE=Ethernet Connection X552 10 GbE Backplane (T4008 10GbE interface)
+pci:v00008086d000015AAsv00001059sd00000150*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection X552 10 GbE Backplane (RD-01068 10GbE interface)
+
pci:v00008086d000015AB*
ID_MODEL_FROM_DATABASE=Ethernet Connection X552 10 GbE Backplane
@@ -68024,9 +68576,30 @@ pci:v00008086d000015BF*
pci:v00008086d000015C0*
ID_MODEL_FROM_DATABASE=JHL6240 Thunderbolt 3 Bridge (Low Power) [Alpine Ridge LP 2016]
+pci:v00008086d000015C2*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection X553 Backplane
+
+pci:v00008086d000015C3*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection X553 Backplane
+
+pci:v00008086d000015C4*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection X553 10 GbE SFP+
+
pci:v00008086d000015C5*
ID_MODEL_FROM_DATABASE=X553 Virtual Function
+pci:v00008086d000015C6*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection X553 1GbE
+
+pci:v00008086d000015C7*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection X553 1GbE
+
+pci:v00008086d000015C8*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection X553/X557-AT 10GBASE-T
+
+pci:v00008086d000015CE*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection X553 10 GbE SFP+
+
pci:v00008086d000015D0*
ID_MODEL_FROM_DATABASE=Ethernet SDI Adapter FM10420-100GbE-QDA2
@@ -68036,6 +68609,9 @@ pci:v00008086d000015D1*
pci:v00008086d000015D1sv00008086sd00000002*
ID_MODEL_FROM_DATABASE=Ethernet Controller 10G X550T (Ethernet Converged Network Adapter X550-T1)
+pci:v00008086d000015D1sv00008086sd0000001B*
+ ID_MODEL_FROM_DATABASE=Ethernet Controller 10G X550T (Ethernet Server Adapter X550-T1 for OCP)
+
pci:v00008086d000015D1sv00008086sd00000021*
ID_MODEL_FROM_DATABASE=Ethernet Controller 10G X550T (Ethernet Converged Network Adapter X550-T1)
@@ -68048,6 +68624,9 @@ pci:v00008086d000015D2*
pci:v00008086d000015D3*
ID_MODEL_FROM_DATABASE=JHL6540 Thunderbolt 3 Bridge (C step) [Alpine Ridge 4C 2016]
+pci:v00008086d000015D4*
+ ID_MODEL_FROM_DATABASE=JHL6540 Thunderbolt 3 USB Controller (C step) [Alpine Ridge 4C 2016]
+
pci:v00008086d000015D5*
ID_MODEL_FROM_DATABASE=Ethernet SDI Adapter FM10420-25GbE-DA2
@@ -68063,15 +68642,36 @@ pci:v00008086d000015D7*
pci:v00008086d000015D8*
ID_MODEL_FROM_DATABASE=Ethernet Connection (4) I219-V
+pci:v00008086d000015D8sv000017AAsd0000224F*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection (4) I219-V (ThinkPad X1 Carbon 5th Gen)
+
pci:v00008086d000015D9*
ID_MODEL_FROM_DATABASE=JHL6340 Thunderbolt 3 NHI (C step) [Alpine Ridge 2C 2016]
pci:v00008086d000015DA*
ID_MODEL_FROM_DATABASE=JHL6340 Thunderbolt 3 Bridge (C step) [Alpine Ridge 2C 2016]
+pci:v00008086d000015DF*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection (8) I219-LM
+
+pci:v00008086d000015E0*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection (8) I219-V
+
+pci:v00008086d000015E1*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection (9) I219-LM
+
+pci:v00008086d000015E2*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection (9) I219-V
+
pci:v00008086d000015E3*
ID_MODEL_FROM_DATABASE=Ethernet Connection (5) I219-LM
+pci:v00008086d000015E4*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection X553 1GbE
+
+pci:v00008086d000015E5*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection X553 1GbE
+
pci:v00008086d00001600*
ID_MODEL_FROM_DATABASE=Broadwell-U Host Bridge -OPI
@@ -68186,6 +68786,9 @@ pci:v00008086d0000163D*
pci:v00008086d0000163E*
ID_MODEL_FROM_DATABASE=Broadwell-U Integrated Graphics
+pci:v00008086d00001889*
+ ID_MODEL_FROM_DATABASE=Ethernet Adaptive Virtual Function
+
pci:v00008086d00001900*
ID_MODEL_FROM_DATABASE=Skylake Host Bridge/DRAM Registers
@@ -68234,6 +68837,9 @@ pci:v00008086d00001910*
pci:v00008086d00001911*
ID_MODEL_FROM_DATABASE=Skylake Gaussian Mixture Model
+pci:v00008086d00001911sv000017AAsd0000224F*
+ ID_MODEL_FROM_DATABASE=Skylake Gaussian Mixture Model (ThinkPad X1 Carbon 5th Gen)
+
pci:v00008086d00001912*
ID_MODEL_FROM_DATABASE=HD Graphics 530
@@ -68493,52 +69099,58 @@ pci:v00008086d00001B48sv00008086sd0000A11F*
ID_MODEL_FROM_DATABASE=82597EX 10GbE Ethernet Controller (PRO/10GbE LR Server Adapter)
pci:v00008086d00001C00*
- ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family 4 port SATA IDE Controller
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family Desktop SATA Controller (IDE mode, ports 0-3)
pci:v00008086d00001C01*
- ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family 4 port SATA IDE Controller
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family Mobile SATA Controller (IDE mode, ports 0-3)
pci:v00008086d00001C02*
- ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family SATA AHCI Controller
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family 6 port Desktop SATA AHCI Controller
pci:v00008086d00001C02sv00001028sd000004AA*
- ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family SATA AHCI Controller (XPS 8300)
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family 6 port Desktop SATA AHCI Controller (XPS 8300)
pci:v00008086d00001C02sv00001043sd0000844D*
- ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family SATA AHCI Controller (P8 series motherboard)
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family 6 port Desktop SATA AHCI Controller (P8 series motherboard)
pci:v00008086d00001C02sv00008086sd00007270*
- ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family SATA AHCI Controller (Server Board S1200BTS)
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family 6 port Desktop SATA AHCI Controller (Server Board S1200BTS)
pci:v00008086d00001C03*
- ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family 6 port SATA AHCI Controller
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family 6 port Mobile SATA AHCI Controller
pci:v00008086d00001C03sv00001028sd000004A3*
- ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family 6 port SATA AHCI Controller (Precision M4600)
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family 6 port Mobile SATA AHCI Controller (Precision M4600)
pci:v00008086d00001C03sv00001028sd000004B2*
- ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family 6 port SATA AHCI Controller (Vostro 3350)
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family 6 port Mobile SATA AHCI Controller (Vostro 3350)
pci:v00008086d00001C03sv00001028sd000004DA*
- ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family 6 port SATA AHCI Controller (Vostro 3750)
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family 6 port Mobile SATA AHCI Controller (Vostro 3750)
+
+pci:v00008086d00001C03sv000017AAsd000021CF*
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family 6 port Mobile SATA AHCI Controller (ThinkPad T520)
pci:v00008086d00001C03sv00008086sd00007270*
- ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family 6 port SATA AHCI Controller (Apple MacBookPro8,2 [Core i7, 15", 2011])
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family 6 port Mobile SATA AHCI Controller (Apple MacBookPro8,2 [Core i7, 15", 2011])
pci:v00008086d00001C04*
- ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family SATA RAID Controller
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Desktop SATA RAID Controller
pci:v00008086d00001C04sv0000103Csd00003118*
- ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family SATA RAID Controller (Smart Array B110i SATA RAID Controller)
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Desktop SATA RAID Controller (Smart Array B110i SATA RAID Controller)
pci:v00008086d00001C05*
- ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family SATA RAID Controller
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Mobile SATA RAID Controller
+
+pci:v00008086d00001C06*
+ ID_MODEL_FROM_DATABASE=Z68 Express Chipset SATA RAID Controller
pci:v00008086d00001C08*
- ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family 2 port SATA IDE Controller
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family Desktop SATA Controller (IDE mode, ports 4-5)
pci:v00008086d00001C09*
- ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family 2 port SATA IDE Controller
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family Mobile SATA Controller (IDE mode, ports 4-5)
pci:v00008086d00001C10*
ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 1
@@ -68552,6 +69164,9 @@ pci:v00008086d00001C10sv00001028sd000004DA*
pci:v00008086d00001C10sv00001043sd0000844D*
ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 1 (P8 series motherboard)
+pci:v00008086d00001C10sv000017AAsd000021CF*
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 1 (ThinkPad T520)
+
pci:v00008086d00001C10sv00008086sd00007270*
ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 1 (Server Board S1200BTS / Apple MacBook Pro 8,1/8,2)
@@ -68561,6 +69176,9 @@ pci:v00008086d00001C12*
pci:v00008086d00001C12sv00001028sd000004AA*
ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 2 (XPS 8300)
+pci:v00008086d00001C12sv000017AAsd000021CF*
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 2 (ThinkPad T520)
+
pci:v00008086d00001C12sv00008086sd00007270*
ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 2 (Apple MacBookPro8,2 [Core i7, 15", 2011])
@@ -68579,12 +69197,18 @@ pci:v00008086d00001C16*
pci:v00008086d00001C16sv00001028sd000004AA*
ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 4 (XPS 8300)
+pci:v00008086d00001C16sv000017AAsd000021CF*
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 4 (ThinkPad T520)
+
pci:v00008086d00001C18*
ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 5
pci:v00008086d00001C18sv00001028sd000004DA*
ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 5 (Vostro 3750)
+pci:v00008086d00001C18sv000017AAsd000021CF*
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 5 (ThinkPad T520)
+
pci:v00008086d00001C18sv00008086sd00007270*
ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 5 (Server Board S1200BTS)
@@ -68630,6 +69254,9 @@ pci:v00008086d00001C20sv00001043sd00008418*
pci:v00008086d00001C20sv00001043sd0000841B*
ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family High Definition Audio Controller (P8H67 Series Motherboard)
+pci:v00008086d00001C20sv000017AAsd000021CF*
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family High Definition Audio Controller (ThinkPad T520)
+
pci:v00008086d00001C20sv00008086sd00002008*
ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family High Definition Audio Controller (DQ67SW board)
@@ -68654,6 +69281,9 @@ pci:v00008086d00001C22sv00001028sd000004DA*
pci:v00008086d00001C22sv00001043sd0000844D*
ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family SMBus Controller (P8 series motherboard)
+pci:v00008086d00001C22sv000017AAsd000021CF*
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family SMBus Controller (ThinkPad T520)
+
pci:v00008086d00001C22sv00008086sd00007270*
ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family SMBus Controller (Server Board S1200BTS / Apple MacBook Pro 8,1/8,2)
@@ -68681,6 +69311,9 @@ pci:v00008086d00001C26sv00001028sd000004DA*
pci:v00008086d00001C26sv00001043sd0000844D*
ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family USB Enhanced Host Controller #1 (P8 series motherboard)
+pci:v00008086d00001C26sv000017AAsd000021CF*
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family USB Enhanced Host Controller #1 (ThinkPad T520)
+
pci:v00008086d00001C26sv00008086sd00007270*
ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family USB Enhanced Host Controller #1 (Server Board S1200BTS / Apple MacBook Pro 8,1/8,2)
@@ -68714,6 +69347,9 @@ pci:v00008086d00001C2Dsv00001028sd000004DA*
pci:v00008086d00001C2Dsv00001043sd0000844D*
ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family USB Enhanced Host Controller #2 (P8 series motherboard)
+pci:v00008086d00001C2Dsv000017AAsd000021CF*
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family USB Enhanced Host Controller #2 (ThinkPad T520)
+
pci:v00008086d00001C2Dsv00008086sd00007270*
ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family USB Enhanced Host Controller #2 (Server Board S1200BTS / Apple MacBook Pro 8,1/8,2)
@@ -68741,6 +69377,9 @@ pci:v00008086d00001C3Asv00001028sd000004DA*
pci:v00008086d00001C3Asv00001043sd0000844D*
ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family MEI Controller #1 (P8 series motherboard)
+pci:v00008086d00001C3Asv000017AAsd000021CF*
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family MEI Controller #1 (ThinkPad T520)
+
pci:v00008086d00001C3Asv00008086sd00007270*
ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family MEI Controller #1 (Apple MacBookPro8,2 [Core i7, 15", 2011])
@@ -68822,6 +69461,9 @@ pci:v00008086d00001C4F*
pci:v00008086d00001C4Fsv00001028sd000004A3*
ID_MODEL_FROM_DATABASE=QM67 Express Chipset Family LPC Controller (Precision M4600)
+pci:v00008086d00001C4Fsv000017AAsd000021CF*
+ ID_MODEL_FROM_DATABASE=QM67 Express Chipset Family LPC Controller (ThinkPad T520)
+
pci:v00008086d00001C50*
ID_MODEL_FROM_DATABASE=B65 Express Chipset Family LPC Controller
@@ -69204,7 +69846,7 @@ pci:v00008086d00001E20*
ID_MODEL_FROM_DATABASE=7 Series/C216 Chipset Family High Definition Audio Controller
pci:v00008086d00001E20sv00001028sd0000054B*
- ID_MODEL_FROM_DATABASE=7 Series/C216 Chipset Family High Definition Audio Controller (Dell XPS One 2710)
+ ID_MODEL_FROM_DATABASE=7 Series/C216 Chipset Family High Definition Audio Controller (XPS One 2710)
pci:v00008086d00001E20sv00001043sd0000108D*
ID_MODEL_FROM_DATABASE=7 Series/C216 Chipset Family High Definition Audio Controller (VivoBook X202EV)
@@ -69219,7 +69861,7 @@ pci:v00008086d00001E20sv00001043sd00008415*
ID_MODEL_FROM_DATABASE=7 Series/C216 Chipset Family High Definition Audio Controller (P8H77-I Motherboard)
pci:v00008086d00001E20sv00001043sd00008445*
- ID_MODEL_FROM_DATABASE=7 Series/C216 Chipset Family High Definition Audio Controller (ASUS P8Z77-V LX Motherboard)
+ ID_MODEL_FROM_DATABASE=7 Series/C216 Chipset Family High Definition Audio Controller (P8Z77-V LX Motherboard)
pci:v00008086d00001E20sv0000144Dsd0000C652*
ID_MODEL_FROM_DATABASE=7 Series/C216 Chipset Family High Definition Audio Controller (NP300E5C series laptop)
@@ -69663,16 +70305,16 @@ pci:v00008086d00002024*
ID_MODEL_FROM_DATABASE=Sky Lake-E MM/Vt-d Configuration Registers
pci:v00008086d00002030*
- ID_MODEL_FROM_DATABASE=Sky Lake-E PCI Express Root Port 1A
+ ID_MODEL_FROM_DATABASE=Sky Lake-E PCI Express Root Port A
pci:v00008086d00002031*
- ID_MODEL_FROM_DATABASE=Sky Lake-E PCI Express Root Port 1B
+ ID_MODEL_FROM_DATABASE=Sky Lake-E PCI Express Root Port B
pci:v00008086d00002032*
- ID_MODEL_FROM_DATABASE=Sky Lake-E PCI Express Root Port 1C
+ ID_MODEL_FROM_DATABASE=Sky Lake-E PCI Express Root Port C
pci:v00008086d00002033*
- ID_MODEL_FROM_DATABASE=Sky Lake-E PCI Express Root Port 1D
+ ID_MODEL_FROM_DATABASE=Sky Lake-E PCI Express Root Port D
pci:v00008086d00002035*
ID_MODEL_FROM_DATABASE=Sky Lake-E RAS Configuration Registers
@@ -71912,6 +72554,9 @@ pci:v00008086d000024FD*
pci:v00008086d000024FDsv00008086sd00000010*
ID_MODEL_FROM_DATABASE=Wireless 8265 / 8275 (Dual Band Wireless-AC 8265)
+pci:v00008086d000024FDsv00008086sd00001130*
+ ID_MODEL_FROM_DATABASE=Wireless 8265 / 8275 (Dual Band Wireless-AC 8265)
+
pci:v00008086d00002500*
ID_MODEL_FROM_DATABASE=82820 820 (Camino) Chipset Host Bridge (MCH)
@@ -72192,7 +72837,7 @@ pci:v00008086d00002590sv00001014sd00000575*
ID_MODEL_FROM_DATABASE=Mobile 915GM/PM/GMS/910GML Express Processor to DRAM Controller (ThinkPad X41 / Z60t)
pci:v00008086d00002590sv00001028sd00000182*
- ID_MODEL_FROM_DATABASE=Mobile 915GM/PM/GMS/910GML Express Processor to DRAM Controller (Dell Latitude C610)
+ ID_MODEL_FROM_DATABASE=Mobile 915GM/PM/GMS/910GML Express Processor to DRAM Controller (Latitude C610)
pci:v00008086d00002590sv0000103Csd00000934*
ID_MODEL_FROM_DATABASE=Mobile 915GM/PM/GMS/910GML Express Processor to DRAM Controller (Compaq nw8240/nx8220)
@@ -73056,7 +73701,7 @@ pci:v00008086d00002668sv0000103Csd00002A09*
ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) High Definition Audio Controller (PufferM-UL8E)
pci:v00008086d00002668sv00001043sd00001173*
- ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) High Definition Audio Controller (Asus A6VC)
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) High Definition Audio Controller (A6VC)
pci:v00008086d00002668sv00001043sd0000814E*
ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) High Definition Audio Controller (P5GD1-VW Mainboard)
@@ -73134,7 +73779,7 @@ pci:v00008086d0000266Esv00001028sd00000182*
ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) AC'97 Audio Controller (Latitude D610 Laptop)
pci:v00008086d0000266Esv00001028sd00000187*
- ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) AC'97 Audio Controller (Dell Precision M70 Laptop)
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) AC'97 Audio Controller (Precision M70 Laptop)
pci:v00008086d0000266Esv00001028sd00000188*
ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) AC'97 Audio Controller (Inspiron 6000 laptop)
@@ -74256,7 +74901,7 @@ pci:v00008086d000027D8sv00001043sd00001123*
ID_MODEL_FROM_DATABASE=NM10/ICH7 Family High Definition Audio Controller (A6J-Q008)
pci:v00008086d000027D8sv00001043sd000013C4*
- ID_MODEL_FROM_DATABASE=NM10/ICH7 Family High Definition Audio Controller (Asus G2P)
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family High Definition Audio Controller (G2P)
pci:v00008086d000027D8sv00001043sd0000817F*
ID_MODEL_FROM_DATABASE=NM10/ICH7 Family High Definition Audio Controller (P5LD2-VM Mainboard (Realtek ALC 882 codec))
@@ -74310,7 +74955,7 @@ pci:v00008086d000027D8sv000017AAsd00002010*
ID_MODEL_FROM_DATABASE=NM10/ICH7 Family High Definition Audio Controller (ThinkPad R60/T60/X60 series)
pci:v00008086d000027D8sv000017AAsd00003802*
- ID_MODEL_FROM_DATABASE=NM10/ICH7 Family High Definition Audio Controller (Lenovo 3000 C200 audio [Realtek ALC861VD])
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family High Definition Audio Controller (3000 C200 audio [Realtek ALC861VD])
pci:v00008086d000027D8sv00008086sd00001112*
ID_MODEL_FROM_DATABASE=NM10/ICH7 Family High Definition Audio Controller (DeskTop Board D945GTP)
@@ -74522,6 +75167,9 @@ pci:v00008086d00002815sv0000104Dsd00009005*
pci:v00008086d00002815sv0000104Dsd0000902D*
ID_MODEL_FROM_DATABASE=82801HM (ICH8M) LPC Interface Controller (VAIO VGN-NR120E)
+pci:v00008086d00002815sv000017AAsd000020A5*
+ ID_MODEL_FROM_DATABASE=82801HM (ICH8M) LPC Interface Controller (ThinkPad R61)
+
pci:v00008086d00002815sv000017C0sd00004083*
ID_MODEL_FROM_DATABASE=82801HM (ICH8M) LPC Interface Controller (Medion WIM 2210 Notebook PC [MD96850])
@@ -74600,6 +75248,9 @@ pci:v00008086d00002828sv00001028sd000001F3*
pci:v00008086d00002828sv0000103Csd000030C0*
ID_MODEL_FROM_DATABASE=82801HM/HEM (ICH8M/ICH8M-E) SATA Controller [IDE mode] (Compaq 6710b)
+pci:v00008086d00002828sv000017AAsd000020A8*
+ ID_MODEL_FROM_DATABASE=82801HM/HEM (ICH8M/ICH8M-E) SATA Controller [IDE mode] (ThinkPad R61)
+
pci:v00008086d00002828sv0000E4BFsd0000CC47*
ID_MODEL_FROM_DATABASE=82801HM/HEM (ICH8M/ICH8M-E) SATA Controller [IDE mode] (CCG-RUMBA)
@@ -74649,7 +75300,7 @@ pci:v00008086d00002830*
ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #1
pci:v00008086d00002830sv00001025sd00000121*
- ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #1 (Acer Aspire 5920G)
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #1 (Aspire 5920G)
pci:v00008086d00002830sv00001028sd000001DA*
ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #1 (OptiPlex 745)
@@ -74829,7 +75480,7 @@ pci:v00008086d00002835*
ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #5
pci:v00008086d00002835sv00001025sd00000121*
- ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #5 (Acer Aspire 5920G)
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #5 (Aspire 5920G)
pci:v00008086d00002835sv00001028sd000001DA*
ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #5 (OptiPlex 745)
@@ -74913,7 +75564,7 @@ pci:v00008086d0000283A*
ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB2 EHCI Controller #2
pci:v00008086d0000283Asv00001025sd00000121*
- ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB2 EHCI Controller #2 (Acer Aspire 5920G)
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB2 EHCI Controller #2 (Aspire 5920G)
pci:v00008086d0000283Asv00001028sd000001DA*
ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB2 EHCI Controller #2 (OptiPlex 745)
@@ -75078,10 +75729,10 @@ pci:v00008086d0000284Bsv00001028sd000001F3*
ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) HD Audio Controller (Inspiron 1420)
pci:v00008086d0000284Bsv00001028sd000001F9*
- ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) HD Audio Controller (Dell Latitude D630)
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) HD Audio Controller (Latitude D630)
pci:v00008086d0000284Bsv00001028sd000001FF*
- ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) HD Audio Controller (Dell Precision M4300)
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) HD Audio Controller (Precision M4300)
pci:v00008086d0000284Bsv00001028sd00000256*
ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) HD Audio Controller (Studio 1735)
@@ -75099,7 +75750,7 @@ pci:v00008086d0000284Bsv0000103Csd000030CC*
ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) HD Audio Controller (Pavilion dv6700)
pci:v00008086d0000284Bsv00001043sd00001339*
- ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) HD Audio Controller (Asus M51S series)
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) HD Audio Controller (M51S series)
pci:v00008086d0000284Bsv00001043sd000081EC*
ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) HD Audio Controller (P5B)
@@ -76104,7 +76755,7 @@ pci:v00008086d00002A00*
ID_MODEL_FROM_DATABASE=Mobile PM965/GM965/GL960 Memory Controller Hub
pci:v00008086d00002A00sv00001025sd00000121*
- ID_MODEL_FROM_DATABASE=Mobile PM965/GM965/GL960 Memory Controller Hub (Acer Aspire 5920G)
+ ID_MODEL_FROM_DATABASE=Mobile PM965/GM965/GL960 Memory Controller Hub (Aspire 5920G)
pci:v00008086d00002A00sv00001028sd000001F3*
ID_MODEL_FROM_DATABASE=Mobile PM965/GM965/GL960 Memory Controller Hub (Inspiron 1420)
@@ -76161,10 +76812,10 @@ pci:v00008086d00002A02sv0000104Dsd0000902D*
ID_MODEL_FROM_DATABASE=Mobile GM965/GL960 Integrated Graphics Controller (primary) (VAIO VGN-NR120E)
pci:v00008086d00002A02sv000017AAsd000020B5*
- ID_MODEL_FROM_DATABASE=Mobile GM965/GL960 Integrated Graphics Controller (primary) (ThinkPad T61/R61)
+ ID_MODEL_FROM_DATABASE=Mobile GM965/GL960 Integrated Graphics Controller (primary) (GM965 [X3100] on ThinkPad T61/R61)
pci:v00008086d00002A02sv000017C0sd00004082*
- ID_MODEL_FROM_DATABASE=Mobile GM965/GL960 Integrated Graphics Controller (primary) (Medion WIM 2210 Notebook PC [MD96850])
+ ID_MODEL_FROM_DATABASE=Mobile GM965/GL960 Integrated Graphics Controller (primary) (GM965 on Medion WIM 2210 Notebook PC [MD96850])
pci:v00008086d00002A02sv0000E4BFsd0000CC47*
ID_MODEL_FROM_DATABASE=Mobile GM965/GL960 Integrated Graphics Controller (primary) (CCG-RUMBA)
@@ -76185,10 +76836,10 @@ pci:v00008086d00002A03sv0000104Dsd0000902D*
ID_MODEL_FROM_DATABASE=Mobile GM965/GL960 Integrated Graphics Controller (secondary) (VAIO VGN-NR120E)
pci:v00008086d00002A03sv000017AAsd000020B5*
- ID_MODEL_FROM_DATABASE=Mobile GM965/GL960 Integrated Graphics Controller (secondary) (ThinkPad T61/R61)
+ ID_MODEL_FROM_DATABASE=Mobile GM965/GL960 Integrated Graphics Controller (secondary) (GM965 [X3100] on ThinkPad T61/R61)
pci:v00008086d00002A03sv000017C0sd00004082*
- ID_MODEL_FROM_DATABASE=Mobile GM965/GL960 Integrated Graphics Controller (secondary) (Medion WIM 2210 Notebook PC [MD96850])
+ ID_MODEL_FROM_DATABASE=Mobile GM965/GL960 Integrated Graphics Controller (secondary) (GM965 on Medion WIM 2210 Notebook PC [MD96850])
pci:v00008086d00002A03sv0000E4BFsd0000CC47*
ID_MODEL_FROM_DATABASE=Mobile GM965/GL960 Integrated Graphics Controller (secondary) (CCG-RUMBA)
@@ -76797,7 +77448,7 @@ pci:v00008086d00002E20*
ID_MODEL_FROM_DATABASE=4 Series Chipset DRAM Controller
pci:v00008086d00002E20sv00001028sd00000283*
- ID_MODEL_FROM_DATABASE=4 Series Chipset DRAM Controller (Dell Vostro 220)
+ ID_MODEL_FROM_DATABASE=4 Series Chipset DRAM Controller (Vostro 220)
pci:v00008086d00002E20sv00001043sd000082D3*
ID_MODEL_FROM_DATABASE=4 Series Chipset DRAM Controller (P5Q Deluxe Motherboard)
@@ -78323,6 +78974,9 @@ pci:v00008086d000037D1sv00001590sd00000216*
pci:v00008086d000037D1sv00001590sd00000217*
ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 1GbE (Ethernet 1Gb 2-port 368FLR-MMT Adapter)
+pci:v00008086d000037D1sv00001590sd00000247*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 1GbE (Ethernet 1Gb 4-port 369i Adapter)
+
pci:v00008086d000037D1sv000017AAsd00004020*
ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 1GbE (Intel Ethernet Connection X722 for 1GbE)
@@ -78335,14 +78989,17 @@ pci:v00008086d000037D1sv000017AAsd00004022*
pci:v00008086d000037D2*
ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 10GBASE-T
+pci:v00008086d000037D2sv000014CDsd00000030*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 10GBASE-T (Ethernet OCP 2x10G RJ45 Phy Card [USI-X557-10GbaseT])
+
pci:v00008086d000037D2sv00001590sd00000218*
ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 10GBASE-T (Ethernet 10Gb 2-port 568FLR-MMT Adapter)
pci:v00008086d000037D2sv000017AAsd00004020*
- ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 10GBASE-T (Intel Ethernet Connection X722 for 10GBASE)
+ ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 10GBASE-T
pci:v00008086d000037D2sv000017AAsd00004021*
- ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 10GBASE-T (Intel Ethernet Connection X722 for 10GBASE)
+ ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 10GBASE-T
pci:v00008086d000037D2sv000017AAsd00004022*
ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 10GBASE-T
@@ -78353,6 +79010,12 @@ pci:v00008086d000037D3*
pci:v00008086d000037D3sv00001590sd00000219*
ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 10GbE SFP+ (Ethernet 10Gb 2-port 568FLR-MMSFP+ Adapter)
+pci:v00008086d000037D3sv000017AAsd00004020*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 10GbE SFP+
+
+pci:v00008086d000037D3sv000017AAsd00004021*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 10GbE SFP+
+
pci:v00008086d000037D4*
ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 10GbE QSFP+
@@ -79164,7 +79827,7 @@ pci:v00008086d00003B56sv00001028sd0000040B*
ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset High Definition Audio (Latitude E6510)
pci:v00008086d00003B56sv00001043sd00001373*
- ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset High Definition Audio (ASUSTek G73-series gaming laptop)
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset High Definition Audio (G73-series gaming laptop)
pci:v00008086d00003B56sv0000144Dsd0000C06A*
ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset High Definition Audio (R730 Laptop)
@@ -79595,8 +80258,8 @@ pci:v00008086d00004223sv00001002sd00008086*
pci:v00008086d00004223sv00001003sd00008086*
ID_MODEL_FROM_DATABASE=PRO/Wireless 2915ABG [Calexico2] Network Connection (mPCI 3B High-Band ZZH)
-pci:v00008086d00004223sv00001351sd0000103C*
- ID_MODEL_FROM_DATABASE=PRO/Wireless 2915ABG [Calexico2] Network Connection (Compaq NC6220)
+pci:v00008086d00004223sv0000103Csd00001351*
+ ID_MODEL_FROM_DATABASE=PRO/Wireless 2915ABG [Calexico2] Network Connection (Compaq nc6220)
pci:v00008086d00004224*
ID_MODEL_FROM_DATABASE=PRO/Wireless 2915ABG [Calexico2] Network Connection
@@ -79608,7 +80271,7 @@ pci:v00008086d00004227sv00008086sd00001010*
ID_MODEL_FROM_DATABASE=PRO/Wireless 3945ABG [Golan] Network Connection (ThinkPad R60e)
pci:v00008086d00004227sv00008086sd00001011*
- ID_MODEL_FROM_DATABASE=PRO/Wireless 3945ABG [Golan] Network Connection (ThinkPad T60/R60e/X60s)
+ ID_MODEL_FROM_DATABASE=PRO/Wireless 3945ABG [Golan] Network Connection (ThinkPad T60/R60e/X60s/R61)
pci:v00008086d00004227sv00008086sd00001014*
ID_MODEL_FROM_DATABASE=PRO/Wireless 3945ABG [Golan] Network Connection (PRO/Wireless 3945BG Network Connection)
@@ -79961,6 +80624,30 @@ pci:v00008086d00005845*
pci:v00008086d00005845sv00001AF4sd00001100*
ID_MODEL_FROM_DATABASE=QEMU NVM Express Controller (QEMU Virtual Machine)
+pci:v00008086d00005902*
+ ID_MODEL_FROM_DATABASE=HD Graphics 610
+
+pci:v00008086d00005904*
+ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v6/7th Gen Core Processor Host Bridge/DRAM Registers
+
+pci:v00008086d00005904sv000017AAsd0000224F*
+ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v6/7th Gen Core Processor Host Bridge/DRAM Registers (ThinkPad X1 Carbon 5th Gen)
+
+pci:v00008086d0000590F*
+ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v6/7th Gen Core Processor Host Bridge/DRAM Registers
+
+pci:v00008086d00005910*
+ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v6/7th Gen Core Processor Host Bridge/DRAM Registers
+
+pci:v00008086d00005912*
+ ID_MODEL_FROM_DATABASE=HD Graphics 630
+
+pci:v00008086d00005916*
+ ID_MODEL_FROM_DATABASE=HD Graphics 620
+
+pci:v00008086d00005916sv000017AAsd0000224F*
+ ID_MODEL_FROM_DATABASE=HD Graphics 620 (ThinkPad X1 Carbon 5th Gen)
+
pci:v00008086d00005A84*
ID_MODEL_FROM_DATABASE=Celeron N3350/Pentium N4200/Atom E3900 Series Integrated Graphics Controller
@@ -81989,6 +82676,12 @@ pci:v00008086d00009D03sv00001028sd000006F3*
pci:v00008086d00009D03sv000017AAsd0000382A*
ID_MODEL_FROM_DATABASE=Sunrise Point-LP SATA Controller [AHCI mode] (B51-80 Laptop)
+pci:v00008086d00009D10*
+ ID_MODEL_FROM_DATABASE=Sunrise Point-LP PCI Express Root Port #1
+
+pci:v00008086d00009D12*
+ ID_MODEL_FROM_DATABASE=Sunrise Point-LP PCI Express Root Port #3
+
pci:v00008086d00009D14*
ID_MODEL_FROM_DATABASE=Sunrise Point-LP PCI Express Root Port #5
@@ -82019,6 +82712,9 @@ pci:v00008086d00009D21*
pci:v00008086d00009D21sv00001028sd000006F3*
ID_MODEL_FROM_DATABASE=Sunrise Point-LP PMC (Latitude 3570)
+pci:v00008086d00009D21sv000017AAsd0000224F*
+ ID_MODEL_FROM_DATABASE=Sunrise Point-LP PMC (ThinkPad X1 Carbon 5th Gen)
+
pci:v00008086d00009D21sv000017AAsd0000382A*
ID_MODEL_FROM_DATABASE=Sunrise Point-LP PMC (B51-80 Laptop)
@@ -82028,6 +82724,9 @@ pci:v00008086d00009D23*
pci:v00008086d00009D23sv00001028sd000006F3*
ID_MODEL_FROM_DATABASE=Sunrise Point-LP SMBus (Latitude 3570)
+pci:v00008086d00009D23sv000017AAsd0000224F*
+ ID_MODEL_FROM_DATABASE=Sunrise Point-LP SMBus (ThinkPad X1 Carbon 5th Gen)
+
pci:v00008086d00009D23sv000017AAsd0000382A*
ID_MODEL_FROM_DATABASE=Sunrise Point-LP SMBus (B51-80 Laptop)
@@ -82061,6 +82760,9 @@ pci:v00008086d00009D31*
pci:v00008086d00009D31sv00001028sd000006F3*
ID_MODEL_FROM_DATABASE=Sunrise Point-LP Thermal subsystem (Latitude 3570)
+pci:v00008086d00009D31sv000017AAsd0000224F*
+ ID_MODEL_FROM_DATABASE=Sunrise Point-LP Thermal subsystem (ThinkPad X1 Carbon 5th Gen)
+
pci:v00008086d00009D31sv000017AAsd0000382A*
ID_MODEL_FROM_DATABASE=Sunrise Point-LP Thermal subsystem (B51-80 Laptop)
@@ -82070,6 +82772,9 @@ pci:v00008086d00009D3A*
pci:v00008086d00009D3Asv00001028sd000006F3*
ID_MODEL_FROM_DATABASE=Sunrise Point-LP CSME HECI #1 (Latitude 3570)
+pci:v00008086d00009D3Asv000017AAsd0000224F*
+ ID_MODEL_FROM_DATABASE=Sunrise Point-LP CSME HECI #1 (ThinkPad X1 Carbon 5th Gen)
+
pci:v00008086d00009D3Asv000017AAsd0000382A*
ID_MODEL_FROM_DATABASE=Sunrise Point-LP CSME HECI #1 (B51-80 Laptop)
@@ -82085,6 +82790,12 @@ pci:v00008086d00009D48*
pci:v00008086d00009D48sv00001028sd000006F3*
ID_MODEL_FROM_DATABASE=Sunrise Point-LP LPC Controller (Latitude 3570)
+pci:v00008086d00009D58*
+ ID_MODEL_FROM_DATABASE=Sunrise Point-LP LPC Controller
+
+pci:v00008086d00009D58sv000017AAsd0000224F*
+ ID_MODEL_FROM_DATABASE=Sunrise Point-LP LPC Controller (ThinkPad X1 Carbon 5th Gen)
+
pci:v00008086d00009D60*
ID_MODEL_FROM_DATABASE=Sunrise Point-LP Serial IO I2C Controller #0
@@ -82592,9 +83303,57 @@ pci:v00008086d0000A256*
pci:v00008086d0000A282*
ID_MODEL_FROM_DATABASE=200 Series PCH SATA controller [AHCI mode]
-pci:v00008086d0000A294*
+pci:v00008086d0000A286*
+ ID_MODEL_FROM_DATABASE=200 Series PCH SATA controller [RAID mode]
+
+pci:v00008086d0000A290*
ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #1
+pci:v00008086d0000A291*
+ ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #2
+
+pci:v00008086d0000A292*
+ ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #3
+
+pci:v00008086d0000A293*
+ ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #4
+
+pci:v00008086d0000A294*
+ ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #5
+
+pci:v00008086d0000A295*
+ ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #6
+
+pci:v00008086d0000A296*
+ ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #7
+
+pci:v00008086d0000A297*
+ ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #8
+
+pci:v00008086d0000A298*
+ ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #9
+
+pci:v00008086d0000A299*
+ ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #10
+
+pci:v00008086d0000A29A*
+ ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #11
+
+pci:v00008086d0000A29B*
+ ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #12
+
+pci:v00008086d0000A29C*
+ ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #13
+
+pci:v00008086d0000A29D*
+ ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #14
+
+pci:v00008086d0000A29E*
+ ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #15
+
+pci:v00008086d0000A29F*
+ ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #16
+
pci:v00008086d0000A2A1*
ID_MODEL_FROM_DATABASE=200 Series PCH PMC
@@ -82625,8 +83384,20 @@ pci:v00008086d0000A2BA*
pci:v00008086d0000A2BB*
ID_MODEL_FROM_DATABASE=200 Series PCH CSME HECI #2
+pci:v00008086d0000A2C4*
+ ID_MODEL_FROM_DATABASE=200 Series PCH LPC Controller (H270)
+
+pci:v00008086d0000A2C5*
+ ID_MODEL_FROM_DATABASE=200 Series PCH LPC Controller (Z270)
+
pci:v00008086d0000A2C6*
- ID_MODEL_FROM_DATABASE=200 Series PCH LPC Controller
+ ID_MODEL_FROM_DATABASE=200 Series PCH LPC Controller (Q270)
+
+pci:v00008086d0000A2C7*
+ ID_MODEL_FROM_DATABASE=200 Series PCH LPC Controller (Q250)
+
+pci:v00008086d0000A2C8*
+ ID_MODEL_FROM_DATABASE=200 Series PCH LPC Controller (B250)
pci:v00008086d0000A2E0*
ID_MODEL_FROM_DATABASE=200 Series PCH Serial IO I2C Controller #0
@@ -82643,6 +83414,30 @@ pci:v00008086d0000A2E3*
pci:v00008086d0000A2E6*
ID_MODEL_FROM_DATABASE=200 Series PCH Serial IO UART Controller #2
+pci:v00008086d0000A2E7*
+ ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #17
+
+pci:v00008086d0000A2E8*
+ ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #18
+
+pci:v00008086d0000A2E9*
+ ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #19
+
+pci:v00008086d0000A2EA*
+ ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #20
+
+pci:v00008086d0000A2EB*
+ ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #21
+
+pci:v00008086d0000A2EC*
+ ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #22
+
+pci:v00008086d0000A2ED*
+ ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #23
+
+pci:v00008086d0000A2EE*
+ ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #24
+
pci:v00008086d0000A2F0*
ID_MODEL_FROM_DATABASE=200 Series PCH HD Audio
@@ -83726,6 +84521,48 @@ pci:v00009005d0000028Dsv00009005sd00000553*
pci:v00009005d0000028Dsv00009005sd00000554*
ID_MODEL_FROM_DATABASE=Series 8 12G SAS/PCIe 3 (Series 8 - ASR-8885 - 8 internal 8 external 12G SAS Port/PCIe 3.0)
+pci:v00009005d0000028F*
+ ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3
+
+pci:v00009005d0000028Fsv0000103Csd00000600*
+ ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (Smart Array P408i-p SR Gen10)
+
+pci:v00009005d0000028Fsv0000103Csd00000601*
+ ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (Smart Array P408e-p SR Gen10)
+
+pci:v00009005d0000028Fsv0000103Csd00000602*
+ ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (Smart Array P408i-a SR Gen10)
+
+pci:v00009005d0000028Fsv0000103Csd00000603*
+ ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (Smart Array P408i-c SR Gen10)
+
+pci:v00009005d0000028Fsv0000103Csd00000650*
+ ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (Smart Array E208i-p SR Gen10)
+
+pci:v00009005d0000028Fsv0000103Csd00000651*
+ ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (Smart Array E208e-p SR Gen10)
+
+pci:v00009005d0000028Fsv0000103Csd00000652*
+ ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (Smart Array E208i-c SR Gen10)
+
+pci:v00009005d0000028Fsv0000103Csd00000654*
+ ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (Smart Array E208i-a SR Gen10)
+
+pci:v00009005d0000028Fsv0000103Csd00000655*
+ ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (Smart Array P408e-m SR Gen10)
+
+pci:v00009005d0000028Fsv0000103Csd00000700*
+ ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (Smart Array P204i-c SR Gen10)
+
+pci:v00009005d0000028Fsv0000103Csd00000701*
+ ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (Smart Array P204i-b SR Gen10)
+
+pci:v00009005d0000028Fsv0000103Csd00001100*
+ ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (Smart Array P816i-a SR Gen10)
+
+pci:v00009005d0000028Fsv0000103Csd00001101*
+ ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (Smart Array P416ie-m SR G10)
+
pci:v00009005d00000410*
ID_MODEL_FROM_DATABASE=AIC-9410W SAS (Razor HBA RAID)
@@ -84923,6 +85760,9 @@ pci:v0000F1D0d0000CFEE*
pci:v0000F1D0d0000DAFF*
ID_MODEL_FROM_DATABASE=KONA LHi
+pci:v0000F1D0d0000DB01*
+ ID_MODEL_FROM_DATABASE=Corvid22
+
pci:v0000F1D0d0000DB09*
ID_MODEL_FROM_DATABASE=Corvid 24
@@ -84932,6 +85772,9 @@ pci:v0000F1D0d0000DCAF*
pci:v0000F1D0d0000DFEE*
ID_MODEL_FROM_DATABASE=Xena HD-DA
+pci:v0000F1D0d0000EB0E*
+ ID_MODEL_FROM_DATABASE=Corvid 44
+
pci:v0000F1D0d0000EFAC*
ID_MODEL_FROM_DATABASE=Xena SD-MM/SD-22-MM
diff --git a/hwdb/20-usb-vendor-model.hwdb b/hwdb/20-usb-vendor-model.hwdb
index 6acb51bb1c..7583253777 100644
--- a/hwdb/20-usb-vendor-model.hwdb
+++ b/hwdb/20-usb-vendor-model.hwdb
@@ -3812,6 +3812,9 @@ usb:v041Ep3121*
usb:v041Ep3220*
ID_MODEL_FROM_DATABASE=Sound Blaster Tactic(3D) Sigma sound card
+usb:v041Ep3232*
+ ID_MODEL_FROM_DATABASE=Sound Blaster Premium HD [SBX]
+
usb:v041Ep3F00*
ID_MODEL_FROM_DATABASE=E-Mu Xboard 25 MIDI Controller
@@ -4787,6 +4790,15 @@ usb:v0430pA102*
usb:v0430pA103*
ID_MODEL_FROM_DATABASE=remote storage for P3 chip
+usb:v0430pA111*
+ ID_MODEL_FROM_DATABASE=remote keyboard for P4 chip
+
+usb:v0430pA112*
+ ID_MODEL_FROM_DATABASE=remote mouse for P4 chip
+
+usb:v0430pA113*
+ ID_MODEL_FROM_DATABASE=remote storage for P4 chip
+
usb:v0430pA4A2*
ID_MODEL_FROM_DATABASE=Ethernet (RNDIS and CDC ethernet)
@@ -5285,6 +5297,12 @@ usb:v043E*
usb:v043Ep3001*
ID_MODEL_FROM_DATABASE=AN-WF100 802.11abgn Wireless Adapter [Broadcom BCM4323]
+usb:v043Ep3004*
+ ID_MODEL_FROM_DATABASE=TWFM-B003D 802.11abgn Wireless Module [Broadcom BCM43236B]
+
+usb:v043Ep3101*
+ ID_MODEL_FROM_DATABASE=AN-WF500 802.11abgn + BT Wireless Adapter [Broadcom BCM43242]
+
usb:v043Ep42BD*
ID_MODEL_FROM_DATABASE=Flatron 795FT Plus Monitor
@@ -6884,6 +6902,9 @@ usb:v045Ep075D*
usb:v045Ep0761*
ID_MODEL_FROM_DATABASE=LifeCam VX-2000
+usb:v045Ep0765*
+ ID_MODEL_FROM_DATABASE=Xbox360 Slim Internal Wireless Module (1400) [Marvell 88W8786U]
+
usb:v045Ep0766*
ID_MODEL_FROM_DATABASE=LifeCam VX-800
@@ -7319,6 +7340,9 @@ usb:v046Dp0828*
usb:v046Dp082B*
ID_MODEL_FROM_DATABASE=Webcam C170
+usb:v046Dp082C*
+ ID_MODEL_FROM_DATABASE=HD Webcam C615
+
usb:v046Dp082D*
ID_MODEL_FROM_DATABASE=HD Pro Webcam C920
@@ -7889,6 +7913,9 @@ usb:v046DpC07D*
usb:v046DpC07E*
ID_MODEL_FROM_DATABASE=G402 Gaming Mouse
+usb:v046DpC083*
+ ID_MODEL_FROM_DATABASE=G403 Prodigy Gaming Mouse
+
usb:v046DpC101*
ID_MODEL_FROM_DATABASE=UltraX Media Remote
@@ -8174,9 +8201,15 @@ usb:v046DpC31C*
usb:v046DpC31D*
ID_MODEL_FROM_DATABASE=Media Keyboard K200
+usb:v046DpC31F*
+ ID_MODEL_FROM_DATABASE=Comfort Keyboard K290
+
usb:v046DpC332*
ID_MODEL_FROM_DATABASE=G502 Proteus Spectrum Optical Mouse
+usb:v046DpC335*
+ ID_MODEL_FROM_DATABASE=G910 Orion Spectrum Mechanical Keyboard
+
usb:v046DpC401*
ID_MODEL_FROM_DATABASE=TrackMan Marble Wheel
@@ -9446,6 +9479,9 @@ usb:v048Dp9503*
usb:v048Dp9507*
ID_MODEL_FROM_DATABASE=ITE it9507 full featured DVB-T transmission chip [ccHDtv]
+usb:v048Dp9910*
+ ID_MODEL_FROM_DATABASE=IT9910 chipset based grabber
+
usb:v048F*
ID_VENDOR_FROM_DATABASE=Eicon Tech.
@@ -10466,6 +10502,9 @@ usb:v04A9p1607*
usb:v04A9p1608*
ID_MODEL_FROM_DATABASE=DR-2580C Scanner
+usb:v04A9p1609*
+ ID_MODEL_FROM_DATABASE=DR-3080CII
+
usb:v04A9p1700*
ID_MODEL_FROM_DATABASE=PIXMA MP110 Scanner
@@ -10485,10 +10524,10 @@ usb:v04A9p1706*
ID_MODEL_FROM_DATABASE=PIXMA MP750 Scanner
usb:v04A9p1707*
- ID_MODEL_FROM_DATABASE=PIXMA MP780 Scanner
+ ID_MODEL_FROM_DATABASE=PIXMA MP780/MP790
usb:v04A9p1708*
- ID_MODEL_FROM_DATABASE=PIXMA MP760 Scanner
+ ID_MODEL_FROM_DATABASE=PIXMA MP760/MP770
usb:v04A9p1709*
ID_MODEL_FROM_DATABASE=PIXMA MP150 Scanner
@@ -10506,13 +10545,13 @@ usb:v04A9p170D*
ID_MODEL_FROM_DATABASE=PIXMA MP800 Scanner
usb:v04A9p170E*
- ID_MODEL_FROM_DATABASE=MP800R
+ ID_MODEL_FROM_DATABASE=PIXMA MP800R
usb:v04A9p1710*
ID_MODEL_FROM_DATABASE=MP950
usb:v04A9p1712*
- ID_MODEL_FROM_DATABASE=MP530
+ ID_MODEL_FROM_DATABASE=PIXMA MP530
usb:v04A9p1713*
ID_MODEL_FROM_DATABASE=PIXMA MP830 Scanner
@@ -10521,73 +10560,259 @@ usb:v04A9p1714*
ID_MODEL_FROM_DATABASE=MP160
usb:v04A9p1715*
- ID_MODEL_FROM_DATABASE=MP180 Storage
+ ID_MODEL_FROM_DATABASE=PIXMA MP180
usb:v04A9p1716*
- ID_MODEL_FROM_DATABASE=MP460 Composite
+ ID_MODEL_FROM_DATABASE=PIXMA MP460
usb:v04A9p1717*
- ID_MODEL_FROM_DATABASE=MP510
+ ID_MODEL_FROM_DATABASE=PIXMA MP510
usb:v04A9p1718*
- ID_MODEL_FROM_DATABASE=MP600 Storage
+ ID_MODEL_FROM_DATABASE=PIXMA MP600
+
+usb:v04A9p1719*
+ ID_MODEL_FROM_DATABASE=PIXMA MP600R
usb:v04A9p171A*
- ID_MODEL_FROM_DATABASE=MP810 Storage
+ ID_MODEL_FROM_DATABASE=PIXMA MP810
usb:v04A9p171B*
- ID_MODEL_FROM_DATABASE=MP960
+ ID_MODEL_FROM_DATABASE=PIXMA MP960
+
+usb:v04A9p171C*
+ ID_MODEL_FROM_DATABASE=PIXMA MX7600
usb:v04A9p1721*
- ID_MODEL_FROM_DATABASE=MP210 ser
+ ID_MODEL_FROM_DATABASE=PIXMA MP210
+
+usb:v04A9p1722*
+ ID_MODEL_FROM_DATABASE=PIXMA MP220
usb:v04A9p1723*
- ID_MODEL_FROM_DATABASE=MP470 ser
+ ID_MODEL_FROM_DATABASE=PIXMA MP470
usb:v04A9p1724*
ID_MODEL_FROM_DATABASE=PIXMA MP520 series
usb:v04A9p1725*
- ID_MODEL_FROM_DATABASE=MP610 ser
+ ID_MODEL_FROM_DATABASE=PIXMA MP610
usb:v04A9p1726*
- ID_MODEL_FROM_DATABASE=MP970 ser
+ ID_MODEL_FROM_DATABASE=PIXMA MP970
usb:v04A9p1727*
- ID_MODEL_FROM_DATABASE=MX300 ser
+ ID_MODEL_FROM_DATABASE=PIXMA MX300
usb:v04A9p1728*
ID_MODEL_FROM_DATABASE=PIXMA MX310 series
usb:v04A9p1729*
- ID_MODEL_FROM_DATABASE=MX700 ser
+ ID_MODEL_FROM_DATABASE=PIXMA MX700
usb:v04A9p172B*
ID_MODEL_FROM_DATABASE=MP140 ser
+usb:v04A9p172C*
+ ID_MODEL_FROM_DATABASE=PIXMA MX850
+
+usb:v04A9p172D*
+ ID_MODEL_FROM_DATABASE=PIXMA MP980
+
+usb:v04A9p172E*
+ ID_MODEL_FROM_DATABASE=PIXMA MP630
+
+usb:v04A9p172F*
+ ID_MODEL_FROM_DATABASE=PIXMA MP620
+
+usb:v04A9p1730*
+ ID_MODEL_FROM_DATABASE=PIXMA MP540
+
+usb:v04A9p1731*
+ ID_MODEL_FROM_DATABASE=PIXMA MP480
+
+usb:v04A9p1732*
+ ID_MODEL_FROM_DATABASE=PIXMA MP240
+
+usb:v04A9p1733*
+ ID_MODEL_FROM_DATABASE=PIXMA MP260
+
+usb:v04A9p1734*
+ ID_MODEL_FROM_DATABASE=PIXMA MP190
+
+usb:v04A9p1735*
+ ID_MODEL_FROM_DATABASE=PIXMA MX860
+
usb:v04A9p1736*
ID_MODEL_FROM_DATABASE=PIXMA MX320 series
+usb:v04A9p1737*
+ ID_MODEL_FROM_DATABASE=PIXMA MX330
+
usb:v04A9p173A*
- ID_MODEL_FROM_DATABASE=MP250 series printer
+ ID_MODEL_FROM_DATABASE=PIXMA MP250
usb:v04A9p173B*
ID_MODEL_FROM_DATABASE=PIXMA MP270 All-In-One Printer
+usb:v04A9p173C*
+ ID_MODEL_FROM_DATABASE=PIXMA MP490
+
+usb:v04A9p173D*
+ ID_MODEL_FROM_DATABASE=PIXMA MP550
+
usb:v04A9p173E*
- ID_MODEL_FROM_DATABASE=MP560
+ ID_MODEL_FROM_DATABASE=PIXMA MP560
usb:v04A9p173F*
- ID_MODEL_FROM_DATABASE=Pixma MP640 Multifunction device
+ ID_MODEL_FROM_DATABASE=PIXMA MP640
+
+usb:v04A9p1740*
+ ID_MODEL_FROM_DATABASE=PIXMA MP990
+
+usb:v04A9p1741*
+ ID_MODEL_FROM_DATABASE=PIXMA MX340
+
+usb:v04A9p1742*
+ ID_MODEL_FROM_DATABASE=PIXMA MX350
+
+usb:v04A9p1743*
+ ID_MODEL_FROM_DATABASE=PIXMA MX870
+
+usb:v04A9p1746*
+ ID_MODEL_FROM_DATABASE=PIXMA MP280
+
+usb:v04A9p1747*
+ ID_MODEL_FROM_DATABASE=PIXMA MP495
usb:v04A9p1748*
- ID_MODEL_FROM_DATABASE=Pixma MG5150
+ ID_MODEL_FROM_DATABASE=PIXMA MG5100 Series
+
+usb:v04A9p1749*
+ ID_MODEL_FROM_DATABASE=PIXMA MG5200 Series
+
+usb:v04A9p174A*
+ ID_MODEL_FROM_DATABASE=PIXMA MG6100 Series
+
+usb:v04A9p174B*
+ ID_MODEL_FROM_DATABASE=PIXMA MG8100 Series
usb:v04A9p174D*
- ID_MODEL_FROM_DATABASE=MX360 ser
+ ID_MODEL_FROM_DATABASE=PIXMA MX360
+
+usb:v04A9p174E*
+ ID_MODEL_FROM_DATABASE=PIXMA MX410
+
+usb:v04A9p174F*
+ ID_MODEL_FROM_DATABASE=PIXMA MX420
+
+usb:v04A9p1750*
+ ID_MODEL_FROM_DATABASE=PIXMA MX880 Series
+
+usb:v04A9p1752*
+ ID_MODEL_FROM_DATABASE=PIXMA MG3100 Series
+
+usb:v04A9p1753*
+ ID_MODEL_FROM_DATABASE=PIXMA MG4100 Series
+
+usb:v04A9p1754*
+ ID_MODEL_FROM_DATABASE=PIXMA MG5300 Series
+
+usb:v04A9p1755*
+ ID_MODEL_FROM_DATABASE=PIXMA MG6200 Series
+
+usb:v04A9p1756*
+ ID_MODEL_FROM_DATABASE=PIXMA MG8200 Series
+
+usb:v04A9p1757*
+ ID_MODEL_FROM_DATABASE=PIXMA MP493
+
+usb:v04A9p1759*
+ ID_MODEL_FROM_DATABASE=PIXMA MX370 Series
+
+usb:v04A9p175B*
+ ID_MODEL_FROM_DATABASE=PIXMA MX430 Series
+
+usb:v04A9p175C*
+ ID_MODEL_FROM_DATABASE=PIXMA MX510 Series
+
+usb:v04A9p175D*
+ ID_MODEL_FROM_DATABASE=PIXMA MX710 Series
+
+usb:v04A9p175E*
+ ID_MODEL_FROM_DATABASE=PIXMA MX890 Series
+
+usb:v04A9p175F*
+ ID_MODEL_FROM_DATABASE=PIXMA MP230
+
+usb:v04A9p1762*
+ ID_MODEL_FROM_DATABASE=PIXMA MG3200 Series
+
+usb:v04A9p1763*
+ ID_MODEL_FROM_DATABASE=PIXMA MG4200 Series
+
+usb:v04A9p1764*
+ ID_MODEL_FROM_DATABASE=PIXMA MG5400 Series
+
+usb:v04A9p1765*
+ ID_MODEL_FROM_DATABASE=PIXMA MG6300 Series
+
+usb:v04A9p1766*
+ ID_MODEL_FROM_DATABASE=PIXMA MX390 Series
+
+usb:v04A9p1768*
+ ID_MODEL_FROM_DATABASE=PIXMA MX450 Series
+
+usb:v04A9p1769*
+ ID_MODEL_FROM_DATABASE=PIXMA MX520 Series
+
+usb:v04A9p176A*
+ ID_MODEL_FROM_DATABASE=PIXMA MX720 Series
+
+usb:v04A9p176B*
+ ID_MODEL_FROM_DATABASE=PIXMA MX920 Series
usb:v04A9p176D*
- ID_MODEL_FROM_DATABASE=PIXMA MG2550
+ ID_MODEL_FROM_DATABASE=PIXMA MG2500 Series
+
+usb:v04A9p176E*
+ ID_MODEL_FROM_DATABASE=PIXMA MG3500 Series
+
+usb:v04A9p176F*
+ ID_MODEL_FROM_DATABASE=PIXMA MG6500 Series
+
+usb:v04A9p1770*
+ ID_MODEL_FROM_DATABASE=PIXMA MG6400 Series
+
+usb:v04A9p1771*
+ ID_MODEL_FROM_DATABASE=PIXMA MG5500 Series
+
+usb:v04A9p1772*
+ ID_MODEL_FROM_DATABASE=PIXMA MG7100 Series
+
+usb:v04A9p1774*
+ ID_MODEL_FROM_DATABASE=PIXMA MX470 Series
+
+usb:v04A9p1775*
+ ID_MODEL_FROM_DATABASE=PIXMA MX530 Series
+
+usb:v04A9p177C*
+ ID_MODEL_FROM_DATABASE=PIXMA MG7500 Series
+
+usb:v04A9p177E*
+ ID_MODEL_FROM_DATABASE=PIXMA MG6600 Series
+
+usb:v04A9p177F*
+ ID_MODEL_FROM_DATABASE=PIXMA MG5600 Series
+
+usb:v04A9p1780*
+ ID_MODEL_FROM_DATABASE=PIXMA MG2900 Series
+
+usb:v04A9p1787*
+ ID_MODEL_FROM_DATABASE=PIXMA MX490 Series
+
+usb:v04A9p178A*
+ ID_MODEL_FROM_DATABASE=PIXMA MG3600 Series
usb:v04A9p178D*
ID_MODEL_FROM_DATABASE=PIXMA MG6853
@@ -10773,10 +10998,10 @@ usb:v04A9p262D*
ID_MODEL_FROM_DATABASE=iR C3200
usb:v04A9p262F*
- ID_MODEL_FROM_DATABASE=MultiPASS MP730
+ ID_MODEL_FROM_DATABASE=PIXMA MP730
usb:v04A9p2630*
- ID_MODEL_FROM_DATABASE=MultiPASS MP700
+ ID_MODEL_FROM_DATABASE=PIXMA MP700
usb:v04A9p2631*
ID_MODEL_FROM_DATABASE=LASER CLASS 700
@@ -10794,16 +11019,16 @@ usb:v04A9p2638*
ID_MODEL_FROM_DATABASE=iR C3100
usb:v04A9p263C*
- ID_MODEL_FROM_DATABASE=Smartbase MP360
+ ID_MODEL_FROM_DATABASE=PIXMA MP360
usb:v04A9p263D*
- ID_MODEL_FROM_DATABASE=MP370
+ ID_MODEL_FROM_DATABASE=PIXMA MP370
usb:v04A9p263E*
- ID_MODEL_FROM_DATABASE=MP390 FAX
+ ID_MODEL_FROM_DATABASE=PIXMA MP390
usb:v04A9p263F*
- ID_MODEL_FROM_DATABASE=MP375
+ ID_MODEL_FROM_DATABASE=PIXMA MP375R
usb:v04A9p2646*
ID_MODEL_FROM_DATABASE=MF5530 Scanner Device V1.9.1
@@ -10811,6 +11036,9 @@ usb:v04A9p2646*
usb:v04A9p2647*
ID_MODEL_FROM_DATABASE=MF5550 Composite
+usb:v04A9p264C*
+ ID_MODEL_FROM_DATABASE=PIXMA MP740
+
usb:v04A9p264D*
ID_MODEL_FROM_DATABASE=PIXMA MP710
@@ -11831,6 +12059,9 @@ usb:v04A9p3278*
usb:v04A9p327A*
ID_MODEL_FROM_DATABASE=SELPHY CP910
+usb:v04A9p327B*
+ ID_MODEL_FROM_DATABASE=SELPHY CP820
+
usb:v04A9p327D*
ID_MODEL_FROM_DATABASE=Powershot ELPH 115 IS / IXUS 132
@@ -11903,12 +12134,18 @@ usb:v04A9p32B2*
usb:v04A9p32BB*
ID_MODEL_FROM_DATABASE=EOS M5
+usb:v04A9p32BF*
+ ID_MODEL_FROM_DATABASE=PowerShot SX420 IS
+
usb:v04A9p32C1*
ID_MODEL_FROM_DATABASE=PowerShot ELPH 180 / IXUS 175
usb:v04A9p32C2*
ID_MODEL_FROM_DATABASE=PowerShot SX720 HS
+usb:v04A9p32D5*
+ ID_MODEL_FROM_DATABASE=PowerShot SX430 IS
+
usb:v04AA*
ID_VENDOR_FROM_DATABASE=DaeWoo Telecom, Ltd
@@ -12137,6 +12374,9 @@ usb:v04B0p0429*
usb:v04B0p042A*
ID_MODEL_FROM_DATABASE=D800 (ptp)
+usb:v04B0p043F*
+ ID_MODEL_FROM_DATABASE=D5600
+
usb:v04B0p0F03*
ID_MODEL_FROM_DATABASE=PD-10 Wireless Printer Adapter
@@ -13871,6 +14111,9 @@ usb:v04D9p048E*
usb:v04D9p0499*
ID_MODEL_FROM_DATABASE=Optical Mouse
+usb:v04D9p1135*
+ ID_MODEL_FROM_DATABASE=Mouse [MGK-15BU/MLK-15BU]
+
usb:v04D9p1203*
ID_MODEL_FROM_DATABASE=Keyboard
@@ -13922,6 +14165,9 @@ usb:v04D9pA050*
usb:v04D9pA055*
ID_MODEL_FROM_DATABASE=Keyboard
+usb:v04D9pA100*
+ ID_MODEL_FROM_DATABASE=Mouse [HV-MS735]
+
usb:v04D9pA11B*
ID_MODEL_FROM_DATABASE=Mouse [MX-3200]
@@ -14033,6 +14279,9 @@ usb:v04DAp250D*
usb:v04DAp3904*
ID_MODEL_FROM_DATABASE=N5HBZ0000055 802.11abgn Wireless Adapter [Atheros AR7010+AR9280]
+usb:v04DAp3908*
+ ID_MODEL_FROM_DATABASE=N5HBZ0000062 802.11abgn Wireless Adapter [Atheros AR9374v1.1]
+
usb:v04DAp3C04*
ID_MODEL_FROM_DATABASE=JT-P100MR-20 [ePassport Reader]
@@ -14393,6 +14642,9 @@ usb:v04E6p5410*
usb:v04E6p5591*
ID_MODEL_FROM_DATABASE=SCL3711-NFC&RW
+usb:v04E6p5810*
+ ID_MODEL_FROM_DATABASE=uTrust 2700 R Smart Card Reader
+
usb:v04E6pE000*
ID_MODEL_FROM_DATABASE=SCRx31 Reader
@@ -14627,6 +14879,9 @@ usb:v04E8p3301*
usb:v04E8p330C*
ID_MODEL_FROM_DATABASE=ML-1865
+usb:v04E8p330F*
+ ID_MODEL_FROM_DATABASE=ML-216x Series Laser Printer
+
usb:v04E8p3310*
ID_MODEL_FROM_DATABASE=ML-331x Series Laser Printer
@@ -15443,6 +15698,9 @@ usb:v04F2pB354*
usb:v04F2pB394*
ID_MODEL_FROM_DATABASE=Integrated Camera
+usb:v04F2pB3EB*
+ ID_MODEL_FROM_DATABASE=HP 720p HD Monitor Webcam
+
usb:v04F2pB3F6*
ID_MODEL_FROM_DATABASE=HD WebCam (Acer)
@@ -18152,6 +18410,9 @@ usb:v0547p2810*
usb:v0547p4D90*
ID_MODEL_FROM_DATABASE=AmScope MD1900 camera
+usb:v0547p6010*
+ ID_MODEL_FROM_DATABASE=AmScope MU1000 camera
+
usb:v0547p6510*
ID_MODEL_FROM_DATABASE=Touptek UCMOS05100KPA
@@ -18401,6 +18662,9 @@ usb:v054Cp014D*
usb:v054Cp0154*
ID_MODEL_FROM_DATABASE=Eyetoy Audio Device
+usb:v054Cp0155*
+ ID_MODEL_FROM_DATABASE=Eyetoy Video Device
+
usb:v054Cp015F*
ID_MODEL_FROM_DATABASE=IC Recorder (BM)
@@ -18683,6 +18947,9 @@ usb:v054Cp0387*
usb:v054Cp03BC*
ID_MODEL_FROM_DATABASE=Webbie HD - MHS-CM1
+usb:v054Cp03CC*
+ ID_MODEL_FROM_DATABASE=SD Card Reader
+
usb:v054Cp03D1*
ID_MODEL_FROM_DATABASE=DPF-X95
@@ -18714,7 +18981,7 @@ usb:v054Cp0541*
ID_MODEL_FROM_DATABASE=DSC-HX100V [Cybershot Digital Still Camera]
usb:v054Cp05C4*
- ID_MODEL_FROM_DATABASE=DualShock 4
+ ID_MODEL_FROM_DATABASE=DualShock 4 [CUH-ZCT1E]
usb:v054Cp0689*
ID_MODEL_FROM_DATABASE=Walkman NWZ-B173F
@@ -18740,6 +19007,9 @@ usb:v054Cp094E*
usb:v054Cp0994*
ID_MODEL_FROM_DATABASE=ILCE-6000 (aka Alpha-6000) in charging mode
+usb:v054Cp09CC*
+ ID_MODEL_FROM_DATABASE=DualShock 4 [CUH-ZCT2E]
+
usb:v054Cp0BB5*
ID_MODEL_FROM_DATABASE=Headset MDR-1000X
@@ -19622,6 +19892,24 @@ usb:v056Ap034D*
usb:v056Ap034E*
ID_MODEL_FROM_DATABASE=DTH-W1620 [MobileStudio Pro 16] tablet
+usb:v056Ap034F*
+ ID_MODEL_FROM_DATABASE=DTH-1320 [Cintiq Pro 13] tablet
+
+usb:v056Ap0350*
+ ID_MODEL_FROM_DATABASE=DTH-1620 [Cintiq Pro 16] tablet
+
+usb:v056Ap0353*
+ ID_MODEL_FROM_DATABASE=DTH-1320 [Cintiq Pro 13] touchscreen
+
+usb:v056Ap0354*
+ ID_MODEL_FROM_DATABASE=DTH-1620 [Cintiq Pro 16] touchscreen
+
+usb:v056Ap0357*
+ ID_MODEL_FROM_DATABASE=PTH-660 [Intuos Pro (M)]
+
+usb:v056Ap0358*
+ ID_MODEL_FROM_DATABASE=PTH-860 [Intuos Pro (L)]
+
usb:v056Ap0400*
ID_MODEL_FROM_DATABASE=PenPartner 4x5
@@ -20067,7 +20355,7 @@ usb:v057Cp2300*
ID_MODEL_FROM_DATABASE=Teledat X130 DSL
usb:v057Cp2800*
- ID_MODEL_FROM_DATABASE=ISDN-Connector TA
+ ID_MODEL_FROM_DATABASE=Teledat 2a/b / X120 / NetXXL ISDN Terminal Adapter
usb:v057Cp3200*
ID_MODEL_FROM_DATABASE=Teledat X130 DSL
@@ -20091,7 +20379,7 @@ usb:v057Cp3C00*
ID_MODEL_FROM_DATABASE=FRITZ!Box WLAN
usb:v057Cp3D00*
- ID_MODEL_FROM_DATABASE=Fritz!Box
+ ID_MODEL_FROM_DATABASE=FRITZ!Box Fon WLAN 7050/7140/7170/IAD3331
usb:v057Cp3E01*
ID_MODEL_FROM_DATABASE=FRITZ!Box (Annex A)
@@ -20153,6 +20441,12 @@ usb:v057Ep0305*
usb:v057Ep0306*
ID_MODEL_FROM_DATABASE=Wii Remote Controller RVL-003
+usb:v057Ep2006*
+ ID_MODEL_FROM_DATABASE=Joy-Con L
+
+usb:v057Ep2007*
+ ID_MODEL_FROM_DATABASE=Joy-Con R
+
usb:v057F*
ID_VENDOR_FROM_DATABASE=QuickShot, Ltd
@@ -21488,6 +21782,9 @@ usb:v059Fp0641*
usb:v059Fp0829*
ID_MODEL_FROM_DATABASE=BigDisk Extreme+
+usb:v059Fp1004*
+ ID_MODEL_FROM_DATABASE=Little Disk 20 GB
+
usb:v059Fp100C*
ID_MODEL_FROM_DATABASE=Rugged Triple Interface Mobile Hard Drive
@@ -21518,6 +21815,9 @@ usb:v059Fp1049*
usb:v059Fp1052*
ID_MODEL_FROM_DATABASE=P'9220 Mobile Drive
+usb:v059Fp1061*
+ ID_MODEL_FROM_DATABASE=Rugged USB3-FW
+
usb:v059Fp1064*
ID_MODEL_FROM_DATABASE=Rugged 16 and 32 GB
@@ -23387,6 +23687,9 @@ usb:v05DCpA813*
usb:v05DCpA815*
ID_MODEL_FROM_DATABASE=JumpDrive V10
+usb:v05DCpA81D*
+ ID_MODEL_FROM_DATABASE=LJDTT16G [JumpDrive 16GB]
+
usb:v05DCpA833*
ID_MODEL_FROM_DATABASE=JumpDrive S23 64GB
@@ -23876,6 +24179,9 @@ usb:v05FC*
usb:v05FCp0001*
ID_MODEL_FROM_DATABASE=Soundcraft Si Multi Digital Card
+usb:v05FCp0010*
+ ID_MODEL_FROM_DATABASE=Soundcraft Si MADI combo card
+
usb:v05FCp7849*
ID_MODEL_FROM_DATABASE=Harman/Kardon SoundSticks
@@ -24219,7 +24525,7 @@ usb:v0629*
ID_VENDOR_FROM_DATABASE=Zida Technologies, Ltd
usb:v062A*
- ID_VENDOR_FROM_DATABASE=Creative Labs
+ ID_VENDOR_FROM_DATABASE=MosArt Semiconductor Corp.
usb:v062Ap0000*
ID_MODEL_FROM_DATABASE=Optical mouse
@@ -24519,19 +24825,28 @@ usb:v064F*
ID_VENDOR_FROM_DATABASE=WIBU-Systems AG
usb:v064Fp03E9*
- ID_MODEL_FROM_DATABASE=CmStick (article no. 1001)
+ ID_MODEL_FROM_DATABASE=CmStick (MSD, article no. 1001-xx-xxx)
usb:v064Fp03F2*
- ID_MODEL_FROM_DATABASE=CmStick/M (article no. 1010)
+ ID_MODEL_FROM_DATABASE=CmStick/M (MSD, article no. 1010-xx-xxx)
usb:v064Fp03F3*
- ID_MODEL_FROM_DATABASE=CmStick/M (article no. 1011)
+ ID_MODEL_FROM_DATABASE=CmStick/M (MSD, article no. 1011-xx-xxx)
usb:v064Fp0BD7*
- ID_MODEL_FROM_DATABASE=BOX/U
+ ID_MODEL_FROM_DATABASE=Wibu-Box/U (article no. 3031-xx-xxx)
usb:v064Fp0BD8*
- ID_MODEL_FROM_DATABASE=BOX/RU
+ ID_MODEL_FROM_DATABASE=Wibu-Box/RU (article no. 3032-xx-xxx)
+
+usb:v064Fp2AF9*
+ ID_MODEL_FROM_DATABASE=CmStick (HID, article no. 1001-xx-xxx)
+
+usb:v064Fp2B03*
+ ID_MODEL_FROM_DATABASE=CmStick/M (HID, article no. 1011-xx-xxx)
+
+usb:v064Fp5213*
+ ID_MODEL_FROM_DATABASE=CmStick/M (COMPOSITE, article no. 1011-xx-xxx)
usb:v0650*
ID_VENDOR_FROM_DATABASE=Dynapro Systems
@@ -26384,6 +26699,9 @@ usb:v06D3p0393*
usb:v06D3p0394*
ID_MODEL_FROM_DATABASE=CP9000D/DW Port
+usb:v06D3p0398*
+ ID_MODEL_FROM_DATABASE=P93D
+
usb:v06D3p03A1*
ID_MODEL_FROM_DATABASE=CP9550D/DW Port
@@ -26397,7 +26715,7 @@ usb:v06D3p03AA*
ID_MODEL_FROM_DATABASE=CP3020DA
usb:v06D3p03AD*
- ID_MODEL_FROM_DATABASE=CP-9800DW-S
+ ID_MODEL_FROM_DATABASE=CP-9800D/DW
usb:v06D3p03AE*
ID_MODEL_FROM_DATABASE=CP-9800DW-S
@@ -26405,12 +26723,24 @@ usb:v06D3p03AE*
usb:v06D3p3B10*
ID_MODEL_FROM_DATABASE=P95D
+usb:v06D3p3B21*
+ ID_MODEL_FROM_DATABASE=CP-9810D/DW
+
usb:v06D3p3B30*
ID_MODEL_FROM_DATABASE=CP-D70DW / CP-D707DW
usb:v06D3p3B31*
ID_MODEL_FROM_DATABASE=CP-K60DW-S
+usb:v06D3p3B36*
+ ID_MODEL_FROM_DATABASE=CP-D80DW
+
+usb:v06D3p3B50*
+ ID_MODEL_FROM_DATABASE=CP-W5000DW
+
+usb:v06D3p3B60*
+ ID_MODEL_FROM_DATABASE=CP-D90DW
+
usb:v06D4*
ID_VENDOR_FROM_DATABASE=Cisco Systems
@@ -27173,6 +27503,12 @@ usb:v071Dp2000*
usb:v071E*
ID_VENDOR_FROM_DATABASE=Ariston Technologies
+usb:v0720*
+ ID_VENDOR_FROM_DATABASE=Keyence Corp.
+
+usb:v0720p8001*
+ ID_MODEL_FROM_DATABASE=LJ-V7001
+
usb:v0723*
ID_VENDOR_FROM_DATABASE=Centillium Communications Corp.
@@ -27605,6 +27941,9 @@ usb:v0755*
usb:v0757*
ID_VENDOR_FROM_DATABASE=Network Technologies, Inc.
+usb:v0758*
+ ID_VENDOR_FROM_DATABASE=Carl Zeiss Microscopy GmbH
+
usb:v075B*
ID_VENDOR_FROM_DATABASE=Sophisticated Circuits, Inc.
@@ -27612,7 +27951,7 @@ usb:v075Bp0001*
ID_MODEL_FROM_DATABASE=Kick-off! Watchdog
usb:v0763*
- ID_VENDOR_FROM_DATABASE=Midiman
+ ID_VENDOR_FROM_DATABASE=M-Audio
usb:v0763p0115*
ID_MODEL_FROM_DATABASE=O2 / KeyRig 25
@@ -29073,7 +29412,7 @@ usb:v07B8p5301*
ID_MODEL_FROM_DATABASE=GW-US54ZGL 802.11bg
usb:v07B8p6001*
- ID_MODEL_FROM_DATABASE=802.11bg
+ ID_MODEL_FROM_DATABASE=WUG2690 802.11bg Wireless Module [ZyDAS ZD1211+AL2230]
usb:v07B8p8188*
ID_MODEL_FROM_DATABASE=AboCom Systems Inc [WN2001 Prolink Wireless-N Nano Adapter]
@@ -30083,6 +30422,9 @@ usb:v0810p0002*
usb:v0810p0003*
ID_MODEL_FROM_DATABASE=PlayStation Gamepad
+usb:v0810pE001*
+ ID_MODEL_FROM_DATABASE=Twin controller
+
usb:v0810pE501*
ID_MODEL_FROM_DATABASE=SNES Gamepad
@@ -30611,6 +30953,9 @@ usb:v0846p9043*
usb:v0846p9050*
ID_MODEL_FROM_DATABASE=A6200 802.11a/b/g/n/ac Wireless Adapter [Broadcom BCM43526]
+usb:v0846p9051*
+ ID_MODEL_FROM_DATABASE=A6200v2 802.11a/b/g/n/ac (2x2) Wireless Adapter [Realtek RTL8812AU]
+
usb:v0846p9052*
ID_MODEL_FROM_DATABASE=A6100 AC600 DB Wireless Adapter [Realtek RTL8811AU]
@@ -31043,9 +31388,18 @@ usb:v0894p0010*
usb:v0897*
ID_VENDOR_FROM_DATABASE=Lauterbach
+usb:v0897p0001*
+ ID_MODEL_FROM_DATABASE=ICE In-Circuit Emulator
+
usb:v0897p0002*
ID_MODEL_FROM_DATABASE=Power Debug/Power Debug II
+usb:v0897p0004*
+ ID_MODEL_FROM_DATABASE=PowerDebug
+
+usb:v0897p0005*
+ ID_MODEL_FROM_DATABASE=PowerDebug PRO
+
usb:v089C*
ID_VENDOR_FROM_DATABASE=United Technologies Research Cntr.
@@ -32012,6 +32366,12 @@ usb:v0908p04B1*
usb:v0908p04B2*
ID_MODEL_FROM_DATABASE=NC interface
+usb:v0908p04B3*
+ ID_MODEL_FROM_DATABASE=keyboard front panel Cockpit
+
+usb:v0908p04B4*
+ ID_MODEL_FROM_DATABASE=SCR_CCID
+
usb:v0908p2701*
ID_MODEL_FROM_DATABASE=ShenZhen SANZHAI Technology Co.,Ltd Spy Pen VGA
@@ -32519,6 +32879,9 @@ usb:v0930p0A07*
usb:v0930p0A08*
ID_MODEL_FROM_DATABASE=WLM-20U2/GN-1080 802.11abgn Wireless Adapter [Atheros AR7010+AR9280]
+usb:v0930p0A0B*
+ ID_MODEL_FROM_DATABASE=WLU5053 802.11abgn Wireless Module [Broadcom BCM43236B]
+
usb:v0930p0A13*
ID_MODEL_FROM_DATABASE=AX88179 Gigabit Ethernet [Toshiba]
@@ -32999,6 +33362,9 @@ usb:v0951p1625*
usb:v0951p162A*
ID_MODEL_FROM_DATABASE=DataTraveler 112 4GB Pen Drive
+usb:v0951p162B*
+ ID_MODEL_FROM_DATABASE=DataTraveler HyperX 3.0
+
usb:v0951p162D*
ID_MODEL_FROM_DATABASE=DataTraveler 102
@@ -33039,22 +33405,34 @@ usb:v0954*
ID_VENDOR_FROM_DATABASE=RPM Systems Corp.
usb:v0955*
- ID_VENDOR_FROM_DATABASE=NVidia Corp.
+ ID_VENDOR_FROM_DATABASE=NVIDIA Corp.
usb:v0955p7018*
- ID_MODEL_FROM_DATABASE=APX
+ ID_MODEL_FROM_DATABASE=T186 [Tegra Parker]
+
+usb:v0955p701A*
+ ID_MODEL_FROM_DATABASE=U-Boot running on Tegra
+
+usb:v0955p7020*
+ ID_MODEL_FROM_DATABASE=L4T (Linux for Tegra) running on Tegra
usb:v0955p7030*
- ID_MODEL_FROM_DATABASE=Tegra 3 (recovery mode)
+ ID_MODEL_FROM_DATABASE=T30 [Tegra 3] recovery mode
usb:v0955p7100*
ID_MODEL_FROM_DATABASE=Tegra Device
+usb:v0955p7140*
+ ID_MODEL_FROM_DATABASE=T124 [Tegra K1/Logan 32-bit]
+
usb:v0955p7210*
ID_MODEL_FROM_DATABASE=SHIELD Controller
+usb:v0955p7721*
+ ID_MODEL_FROM_DATABASE=T210 [Tegra Erista]
+
usb:v0955p7820*
- ID_MODEL_FROM_DATABASE=Tegra 2 AC100 developer mode
+ ID_MODEL_FROM_DATABASE=T20 [Tegra 2] recovery mode
usb:v0955pB400*
ID_MODEL_FROM_DATABASE=SHIELD (debug)
@@ -33137,6 +33515,9 @@ usb:v095D*
usb:v095Dp0001*
ID_MODEL_FROM_DATABASE=Polycom ViaVideo
+usb:v0964*
+ ID_VENDOR_FROM_DATABASE=BITRAN
+
usb:v0967*
ID_VENDOR_FROM_DATABASE=Acer NeWeb Corp.
@@ -34428,7 +34809,10 @@ usb:v0A5Cp6410*
ID_MODEL_FROM_DATABASE=BCM20703A1 Bluetooth 4.1 + LE
usb:v0A5CpBD11*
- ID_MODEL_FROM_DATABASE=TiVo AG0100 802.11bg Wireless Adapter [Broadcom BCM4320]
+ ID_MODEL_FROM_DATABASE=BCM4320 802.11bg Wireless Adapter
+
+usb:v0A5CpBD12*
+ ID_MODEL_FROM_DATABASE=BCM4326U 802.11bg Wireless Adapter
usb:v0A5CpBD13*
ID_MODEL_FROM_DATABASE=BCM4323 802.11abgn Wireless Adapter
@@ -34439,6 +34823,15 @@ usb:v0A5CpBD16*
usb:v0A5CpBD17*
ID_MODEL_FROM_DATABASE=BCM43236 802.11abgn Wireless Adapter
+usb:v0A5CpBD1D*
+ ID_MODEL_FROM_DATABASE=BCM43526 802.11a/b/g/n/ac (2x2) Wireless Adapter
+
+usb:v0A5CpBD1E*
+ ID_MODEL_FROM_DATABASE=BCM43143 802.11bgn (1x1) Wireless Adapter
+
+usb:v0A5CpBD1F*
+ ID_MODEL_FROM_DATABASE=BCM43242 802.11abgn Wireless Adapter
+
usb:v0A5CpD11B*
ID_MODEL_FROM_DATABASE=Eminent EM4045 [Broadcom 4320 USB]
@@ -35366,6 +35759,9 @@ usb:v0B05*
usb:v0B05p0001*
ID_MODEL_FROM_DATABASE=MeMO Pad HD 7 (CD-ROM mode)
+usb:v0B05p0301*
+ ID_MODEL_FROM_DATABASE=MyPal A696 GPS PDA
+
usb:v0B05p1101*
ID_MODEL_FROM_DATABASE=Mass Storage (UISDMC4S)
@@ -35382,7 +35778,7 @@ usb:v0B05p170B*
ID_MODEL_FROM_DATABASE=Multi card reader
usb:v0B05p170C*
- ID_MODEL_FROM_DATABASE=WL-159g 802.11bg
+ ID_MODEL_FROM_DATABASE=WL-159g 802.11bg [ZyDAS ZD1211B+AL2230]
usb:v0B05p170D*
ID_MODEL_FROM_DATABASE=802.11b/g Wireless Network Adapter
@@ -35418,7 +35814,7 @@ usb:v0B05p1726*
ID_MODEL_FROM_DATABASE=Laptop OLED Display
usb:v0B05p172A*
- ID_MODEL_FROM_DATABASE=ASUS 802.11n Network Adapter
+ ID_MODEL_FROM_DATABASE=802.11n Network Adapter
usb:v0B05p172B*
ID_MODEL_FROM_DATABASE=802.11n Network Adapter
@@ -35430,7 +35826,7 @@ usb:v0B05p1732*
ID_MODEL_FROM_DATABASE=802.11n Network Adapter
usb:v0B05p1734*
- ID_MODEL_FROM_DATABASE=ASUS AF-200
+ ID_MODEL_FROM_DATABASE=AF-200
usb:v0B05p173C*
ID_MODEL_FROM_DATABASE=BT-183 Bluetooth 2.0
@@ -35508,11 +35904,29 @@ usb:v0B05p17CB*
ID_MODEL_FROM_DATABASE=Broadcom BCM20702A0 Bluetooth
usb:v0B05p17D1*
- ID_MODEL_FROM_DATABASE=AC51 802.11a/b/g/n/ac Wireless Adapter [Mediatek MT7610/Ralink RT2870]
+ ID_MODEL_FROM_DATABASE=AC51 802.11a/b/g/n/ac Wireless Adapter [Mediatek MT7610U]
+
+usb:v0B05p17D2*
+ ID_MODEL_FROM_DATABASE=USB-AC56 802.11a/b/g/n/ac Wireless Adapter [Realtek RTL8812AU]
+
+usb:v0B05p17D3*
+ ID_MODEL_FROM_DATABASE=USB-N10 v2 802.11b/g/n Wireless Adapter [MediaTek MT7601U]
+
+usb:v0B05p17DB*
+ ID_MODEL_FROM_DATABASE=USB-AC50 802.11a/b/g/n/ac (1x1) Wireless Adapter [MediaTek MT7610U]
+
+usb:v0B05p17E8*
+ ID_MODEL_FROM_DATABASE=USB-N14 802.11b/g/n (2x2) Wireless Adapter [Ralink RT5372]
+
+usb:v0B05p17EB*
+ ID_MODEL_FROM_DATABASE=USB-AC55 802.11a/b/g/n/ac Wireless Adapter [MediaTek MT7612U]
usb:v0B05p180A*
ID_MODEL_FROM_DATABASE=Broadcom BCM20702 Single-Chip Bluetooth 4.0 + LE
+usb:v0B05p1817*
+ ID_MODEL_FROM_DATABASE=USB-AC68 802.11a/b/g/n/ac (4x4) Wireless Adapter [Realtek RTL8814AU]
+
usb:v0B05p1825*
ID_MODEL_FROM_DATABASE=Qualcomm Bluetooth 4.1
@@ -35556,22 +35970,22 @@ usb:v0B05p620A*
ID_MODEL_FROM_DATABASE=Remote NDIS Device
usb:v0B05p7772*
- ID_MODEL_FROM_DATABASE=ASUS Zenfone GO (ZB500KL) (MTP mode)
+ ID_MODEL_FROM_DATABASE=Zenfone GO (ZB500KL) (MTP mode)
usb:v0B05p7773*
- ID_MODEL_FROM_DATABASE=ASUS Zenfone GO (ZB500KL) (Debug, MTP mode)
+ ID_MODEL_FROM_DATABASE=Zenfone GO (ZB500KL) (Debug, MTP mode)
usb:v0B05p7774*
- ID_MODEL_FROM_DATABASE=ASUS Zenfone GO (ZB500KL) (RNDIS mode)
+ ID_MODEL_FROM_DATABASE=Zenfone GO (ZB500KL) (RNDIS mode)
usb:v0B05p7775*
- ID_MODEL_FROM_DATABASE=ASUS Zenfone GO (ZB500KL) (Debug, RNDIS mode)
+ ID_MODEL_FROM_DATABASE=Zenfone GO (ZB500KL) (Debug, RNDIS mode)
usb:v0B05p7776*
- ID_MODEL_FROM_DATABASE=ASUS Zenfone GO (ZB500KL) (PTP mode)
+ ID_MODEL_FROM_DATABASE=Zenfone GO (ZB500KL) (PTP mode)
usb:v0B05p7777*
- ID_MODEL_FROM_DATABASE=ASUS Zenfone GO (ZB500KL) (Debug, PTP mode)
+ ID_MODEL_FROM_DATABASE=Zenfone GO (ZB500KL) (Debug, PTP mode)
usb:v0B05pB700*
ID_MODEL_FROM_DATABASE=Broadcom Bluetooth 2.1
@@ -35702,6 +36116,9 @@ usb:v0B33p0020*
usb:v0B33p0030*
ID_MODEL_FROM_DATABASE=ShuttlePro v2
+usb:v0B33p0401*
+ ID_MODEL_FROM_DATABASE=RollerMouse Free 2
+
usb:v0B33p0700*
ID_MODEL_FROM_DATABASE=RollerMouse Pro
@@ -36935,6 +37352,9 @@ usb:v0BC2p3312*
usb:v0BC2p3320*
ID_MODEL_FROM_DATABASE=SRD00F2 [Expansion Desktop Drive]
+usb:v0BC2p3322*
+ ID_MODEL_FROM_DATABASE=SRD0NF2 [Expansion Desktop Drive]
+
usb:v0BC2p3332*
ID_MODEL_FROM_DATABASE=Expansion
@@ -36971,6 +37391,12 @@ usb:v0BC2p5121*
usb:v0BC2p5161*
ID_MODEL_FROM_DATABASE=FreeAgent GoFlex dock
+usb:v0BC2p6126*
+ ID_MODEL_FROM_DATABASE=Maxtor D3 Station 5TB
+
+usb:v0BC2p61B6*
+ ID_MODEL_FROM_DATABASE=Maxtor HX-M101TCB/GM [M3 Portable 1TB]
+
usb:v0BC2p61B7*
ID_MODEL_FROM_DATABASE=Maxtor M3 Portable
@@ -36986,6 +37412,9 @@ usb:v0BC2pA0A4*
usb:v0BC2pAB00*
ID_MODEL_FROM_DATABASE=Slim Portable Drive
+usb:v0BC2pAB1E*
+ ID_MODEL_FROM_DATABASE=Backup Plus Portable Drive
+
usb:v0BC2pAB20*
ID_MODEL_FROM_DATABASE=Backup Plus Portable Drive
@@ -36995,6 +37424,9 @@ usb:v0BC2pAB21*
usb:v0BC2pAB24*
ID_MODEL_FROM_DATABASE=Backup Plus Portable Drive
+usb:v0BC2pAB26*
+ ID_MODEL_FROM_DATABASE=Backup Plus Slim Portable Drive 1 TB
+
usb:v0BC2pAB31*
ID_MODEL_FROM_DATABASE=Backup Plus Desktop Drive (5TB)
@@ -37190,6 +37622,9 @@ usb:v0BDAp0301*
usb:v0BDAp0307*
ID_MODEL_FROM_DATABASE=Card Reader
+usb:v0BDAp0326*
+ ID_MODEL_FROM_DATABASE=Card reader
+
usb:v0BDAp1724*
ID_MODEL_FROM_DATABASE=RTL8723AU 802.11n WLAN Adapter
@@ -37223,6 +37658,9 @@ usb:v0BDAp57B3*
usb:v0BDAp57DA*
ID_MODEL_FROM_DATABASE=Built-In Video Camera
+usb:v0BDAp58C8*
+ ID_MODEL_FROM_DATABASE=Integrated Webcam HD
+
usb:v0BDAp8150*
ID_MODEL_FROM_DATABASE=RTL8150 Fast Ethernet Adapter
@@ -37263,7 +37701,7 @@ usb:v0BDAp8189*
ID_MODEL_FROM_DATABASE=RTL8187B Wireless 802.11g 54Mbps Network Adapter
usb:v0BDAp818B*
- ID_MODEL_FROM_DATABASE=ACT-WNP-UA-005 802.11b/g/n WLAN Adapter
+ ID_MODEL_FROM_DATABASE=RTL8192EU 802.11b/g/n WLAN Adapter
usb:v0BDAp8192*
ID_MODEL_FROM_DATABASE=RTL8191SU 802.11n Wireless Adapter
@@ -37281,7 +37719,13 @@ usb:v0BDAp8199*
ID_MODEL_FROM_DATABASE=RTL8187SU 802.11g WLAN Adapter
usb:v0BDAp8812*
- ID_MODEL_FROM_DATABASE=RTL8812AU 802.11a/b/g/n/ac WLAN Adapter
+ ID_MODEL_FROM_DATABASE=RTL8812AU 802.11a/b/g/n/ac 2T2R DB WLAN Adapter
+
+usb:v0BDAp8813*
+ ID_MODEL_FROM_DATABASE=RTL8814AU 802.11a/b/g/n/ac Wireless Adapter
+
+usb:v0BDApA811*
+ ID_MODEL_FROM_DATABASE=RTL8811AU 802.11a/b/g/n/ac WLAN Adapter
usb:v0BDB*
ID_VENDOR_FROM_DATABASE=Ericsson Business Mobile Networks BV
@@ -37682,6 +38126,12 @@ usb:v0C2Ep0B6A*
usb:v0C2Ep0B81*
ID_MODEL_FROM_DATABASE=Barcode scanner Voyager 1400g Series
+usb:v0C30*
+ ID_VENDOR_FROM_DATABASE=Mutoh Industries Ltd
+
+usb:v0C30p6010*
+ ID_MODEL_FROM_DATABASE=Kona 1400 Cutting Plotter
+
usb:v0C35*
ID_VENDOR_FROM_DATABASE=Eagletron, Inc.
@@ -38126,6 +38576,9 @@ usb:v0C45p6419*
usb:v0C45p641D*
ID_MODEL_FROM_DATABASE=1.3 MPixel Integrated Webcam
+usb:v0C45p6433*
+ ID_MODEL_FROM_DATABASE=Laptop Integrated Webcam HD (Composite Device)
+
usb:v0C45p643F*
ID_MODEL_FROM_DATABASE=Dell Integrated HD Webcam
@@ -38672,6 +39125,9 @@ usb:v0CAD*
usb:v0CADp1007*
ID_MODEL_FROM_DATABASE=APX Series Consolette
+usb:v0CADp1020*
+ ID_MODEL_FROM_DATABASE=MOTOTRBO Series Radio (Portable)
+
usb:v0CADp1030*
ID_MODEL_FROM_DATABASE=APX Series Radio (Portable)
@@ -39309,7 +39765,7 @@ usb:v0D28*
ID_VENDOR_FROM_DATABASE=NXP
usb:v0D28p0204*
- ID_MODEL_FROM_DATABASE=LPC1768
+ ID_MODEL_FROM_DATABASE=ARM mbed
usb:v0D32*
ID_VENDOR_FROM_DATABASE=Leo Hui Electric Wire & Cable Co., Ltd
@@ -39371,6 +39827,9 @@ usb:v0D46p2012*
usb:v0D46p3003*
ID_MODEL_FROM_DATABASE=mIDentity Light / KAAN SIM III
+usb:v0D46p3014*
+ ID_MODEL_FROM_DATABASE=Smart Token
+
usb:v0D46p4000*
ID_MODEL_FROM_DATABASE=mIDentity (mass storage)
@@ -39593,6 +40052,9 @@ usb:v0D64p3105*
usb:v0D64p3108*
ID_MODEL_FROM_DATABASE=Digicam Mass Storage Device
+usb:v0D64p5566*
+ ID_MODEL_FROM_DATABASE=Contour Roam Model 1600
+
usb:v0D65*
ID_VENDOR_FROM_DATABASE=KMJP Co., Ltd
@@ -39749,6 +40211,9 @@ usb:v0D8Cp0002*
usb:v0D8Cp0003*
ID_MODEL_FROM_DATABASE=Sound Device
+usb:v0D8Cp0005*
+ ID_MODEL_FROM_DATABASE=Blue Snowball
+
usb:v0D8Cp0006*
ID_MODEL_FROM_DATABASE=Storm HP-USB500 5.1 Headset
@@ -40088,6 +40553,12 @@ usb:v0DB0p3713*
usb:v0DB0p3801*
ID_MODEL_FROM_DATABASE=Motorola Bluetooth 2.1+EDR Device
+usb:v0DB0p3870*
+ ID_MODEL_FROM_DATABASE=MS-3870 802.11bgn Wireless Module [Ralink RT3070]
+
+usb:v0DB0p3871*
+ ID_MODEL_FROM_DATABASE=MS-3871 802.11bgn Wireless Module [Ralink RT8070]
+
usb:v0DB0p4011*
ID_MODEL_FROM_DATABASE=Medion Flash XL V2.0 Card Reader
@@ -40949,6 +41420,9 @@ usb:v0E4Cp7288*
usb:v0E50*
ID_VENDOR_FROM_DATABASE=TechnoData Interware
+usb:v0E50p0001*
+ ID_MODEL_FROM_DATABASE=Matrix USB-Key
+
usb:v0E50p0002*
ID_MODEL_FROM_DATABASE=Matrixlock Dongle (HID)
@@ -41048,6 +41522,9 @@ usb:v0E6Ap030C*
usb:v0E6Ap6001*
ID_MODEL_FROM_DATABASE=GEMBIRD Flexible keyboard KB-109F-B-DE
+usb:v0E6Ap7F5C*
+ ID_MODEL_FROM_DATABASE=BPF-015 Key Chain Photo Frame
+
usb:v0E6F*
ID_VENDOR_FROM_DATABASE=Logic3
@@ -41183,6 +41660,9 @@ usb:v0E8Fp0022*
usb:v0E8Fp0201*
ID_MODEL_FROM_DATABASE=SmartJoy Frag Xpad/PS2 adaptor
+usb:v0E8Fp300A*
+ ID_MODEL_FROM_DATABASE=steering Wheel
+
usb:v0E90*
ID_VENDOR_FROM_DATABASE=WiebeTech, LLC
@@ -43226,6 +43706,21 @@ usb:v1058p259D*
usb:v1058p259F*
ID_MODEL_FROM_DATABASE=My Passport Ultra (WD10JMVW)
+usb:v1058p25A1*
+ ID_MODEL_FROM_DATABASE=Elements / My Passport (WD20NMVW)
+
+usb:v1058p25A2*
+ ID_MODEL_FROM_DATABASE=Elements 25A2
+
+usb:v1058p25A3*
+ ID_MODEL_FROM_DATABASE=Elements Desktop (WDBWLG)
+
+usb:v1058p25E2*
+ ID_MODEL_FROM_DATABASE=My Passport (WD40NMZW)
+
+usb:v1058p30A0*
+ ID_MODEL_FROM_DATABASE=SATA adapter cable
+
usb:v1059*
ID_VENDOR_FROM_DATABASE=Giesecke & Devrient GmbH
@@ -43271,6 +43766,12 @@ usb:v1065p0020*
usb:v1065p2136*
ID_MODEL_FROM_DATABASE=EasyDisk ED1064
+usb:v1068*
+ ID_VENDOR_FROM_DATABASE=Micropi Elettronica
+
+usb:v1068p0001*
+ ID_MODEL_FROM_DATABASE=CPUSB - V 1.8 - software-rights management key
+
usb:v106A*
ID_VENDOR_FROM_DATABASE=Loyal Legend, Ltd
@@ -43541,12 +44042,99 @@ usb:v1082*
usb:v1083*
ID_VENDOR_FROM_DATABASE=Canon Electronics, Inc.
+usb:v1083p160C*
+ ID_MODEL_FROM_DATABASE=CR-55
+
+usb:v1083p160F*
+ ID_MODEL_FROM_DATABASE=DR-1210C
+
+usb:v1083p1614*
+ ID_MODEL_FROM_DATABASE=DR-4010C
+
+usb:v1083p1617*
+ ID_MODEL_FROM_DATABASE=DR-2510C
+
+usb:v1083p1618*
+ ID_MODEL_FROM_DATABASE=DR-X10C
+
+usb:v1083p161A*
+ ID_MODEL_FROM_DATABASE=CR-25
+
usb:v1083p161B*
ID_MODEL_FROM_DATABASE=DR-2010C Scanner
+usb:v1083p161D*
+ ID_MODEL_FROM_DATABASE=DR-3010C
+
+usb:v1083p1620*
+ ID_MODEL_FROM_DATABASE=DR-7090C
+
+usb:v1083p1622*
+ ID_MODEL_FROM_DATABASE=DR-9050C
+
+usb:v1083p1623*
+ ID_MODEL_FROM_DATABASE=DR-7550C
+
+usb:v1083p1624*
+ ID_MODEL_FROM_DATABASE=DR-6050C
+
+usb:v1083p1626*
+ ID_MODEL_FROM_DATABASE=DR-6010C
+
usb:v1083p162C*
ID_MODEL_FROM_DATABASE=P-150 Scanner
+usb:v1083p1638*
+ ID_MODEL_FROM_DATABASE=DR-6030C
+
+usb:v1083p1639*
+ ID_MODEL_FROM_DATABASE=CR-135i
+
+usb:v1083p163E*
+ ID_MODEL_FROM_DATABASE=DR-M160
+
+usb:v1083p163F*
+ ID_MODEL_FROM_DATABASE=DR-M140
+
+usb:v1083p1640*
+ ID_MODEL_FROM_DATABASE=DR-C125
+
+usb:v1083p1641*
+ ID_MODEL_FROM_DATABASE=DR-P215
+
+usb:v1083p1648*
+ ID_MODEL_FROM_DATABASE=FSU-201
+
+usb:v1083p164A*
+ ID_MODEL_FROM_DATABASE=DR-C130
+
+usb:v1083p164B*
+ ID_MODEL_FROM_DATABASE=DR-P208
+
+usb:v1083p164F*
+ ID_MODEL_FROM_DATABASE=DR-G1130
+
+usb:v1083p1650*
+ ID_MODEL_FROM_DATABASE=DR-G1100
+
+usb:v1083p1651*
+ ID_MODEL_FROM_DATABASE=DR-C120
+
+usb:v1083p1654*
+ ID_MODEL_FROM_DATABASE=DR-F120
+
+usb:v1083p1657*
+ ID_MODEL_FROM_DATABASE=DR-M1060
+
+usb:v1083p1658*
+ ID_MODEL_FROM_DATABASE=DR-C225
+
+usb:v1083p1659*
+ ID_MODEL_FROM_DATABASE=DR-P215II
+
+usb:v1083p165D*
+ ID_MODEL_FROM_DATABASE=DR-P208II
+
usb:v1084*
ID_VENDOR_FROM_DATABASE=Pantech Co., Ltd
@@ -43565,6 +44153,12 @@ usb:v108C*
usb:v108E*
ID_VENDOR_FROM_DATABASE=Lotes Co., Ltd.
+usb:v1091*
+ ID_VENDOR_FROM_DATABASE=Numerik Jena
+
+usb:v1091p8101*
+ ID_MODEL_FROM_DATABASE=Absoflex
+
usb:v1099*
ID_VENDOR_FROM_DATABASE=Surface Optics Corp.
@@ -43764,16 +44358,16 @@ usb:v10B8*
ID_VENDOR_FROM_DATABASE=DiBcom
usb:v10B8p0BB8*
- ID_MODEL_FROM_DATABASE=DiBcom USB DVB-T reference design (MOD300) (cold)
+ ID_MODEL_FROM_DATABASE=DVB-T reference design (MOD300) (cold)
usb:v10B8p0BB9*
- ID_MODEL_FROM_DATABASE=DiBcom USB DVB-T reference design (MOD300) (warm)
+ ID_MODEL_FROM_DATABASE=DVB-T reference design (MOD300) (warm)
usb:v10B8p0BC6*
- ID_MODEL_FROM_DATABASE=DiBcom USB2.0 DVB-T reference design (MOD3000P) (cold)
+ ID_MODEL_FROM_DATABASE=DVB-T reference design (MOD3000P) (cold)
usb:v10B8p0BC7*
- ID_MODEL_FROM_DATABASE=DiBcom USB2.0 DVB-T reference design (MOD3000P) (warm)
+ ID_MODEL_FROM_DATABASE=DVB-T reference design (MOD3000P) (warm)
usb:v10BB*
ID_VENDOR_FROM_DATABASE=TM Technology, Inc.
@@ -43811,6 +44405,12 @@ usb:v10C4p0002*
usb:v10C4p0003*
ID_MODEL_FROM_DATABASE=CommandIR
+usb:v10C4p800A*
+ ID_MODEL_FROM_DATABASE=SPORTident
+
+usb:v10C4p800B*
+ ID_MODEL_FROM_DATABASE=AES
+
usb:v10C4p8030*
ID_MODEL_FROM_DATABASE=K4JRG Ham Radio devices
@@ -43823,6 +44423,9 @@ usb:v10C4p804E*
usb:v10C4p80A9*
ID_MODEL_FROM_DATABASE=CP210x to UART Bridge Controller
+usb:v10C4p80C4*
+ ID_MODEL_FROM_DATABASE=Infrared Thermometer Adapter
+
usb:v10C4p80CA*
ID_MODEL_FROM_DATABASE=ATM2400 Sensor Device
@@ -43844,12 +44447,21 @@ usb:v10C4p818A*
usb:v10C4p81E8*
ID_MODEL_FROM_DATABASE=Zephyr BioHarness
+usb:v10C4p834B*
+ ID_MODEL_FROM_DATABASE=Infrared Online Sensor Adapter
+
+usb:v10C4p834E*
+ ID_MODEL_FROM_DATABASE=Infrared Sensor Adapter
+
usb:v10C4p8460*
ID_MODEL_FROM_DATABASE=Sangoma Wanpipe VoiceTime
usb:v10C4p8461*
ID_MODEL_FROM_DATABASE=Sangoma U100
+usb:v10C4p8470*
+ ID_MODEL_FROM_DATABASE=Juniper Networks BX Series System Console
+
usb:v10C4p8477*
ID_MODEL_FROM_DATABASE=Balluff RFID Reader
@@ -43859,9 +44471,18 @@ usb:v10C4p8496*
usb:v10C4p8497*
ID_MODEL_FROM_DATABASE=SiLabs Cypress EVB
+usb:v10C4p84FB*
+ ID_MODEL_FROM_DATABASE=Infrared Blackbody Adapter
+
+usb:v10C4p8508*
+ ID_MODEL_FROM_DATABASE=RS485 Adapter
+
usb:v10C4p8605*
ID_MODEL_FROM_DATABASE=dilitronics ESoLUX solar lighting controller
+usb:v10C4p8660*
+ ID_MODEL_FROM_DATABASE=Netronics CANdoISO
+
usb:v10C4p86BC*
ID_MODEL_FROM_DATABASE=C8051F34x AudioDelay [AD-340]
@@ -43877,17 +44498,23 @@ usb:v10C4p8863*
usb:v10C4p8897*
ID_MODEL_FROM_DATABASE=C8051F38x HDMI Splitter [UHBX]
+usb:v10C4p88C9*
+ ID_MODEL_FROM_DATABASE=AES HID device
+
usb:v10C4p8918*
ID_MODEL_FROM_DATABASE=C8051F38x HDMI Audio Extractor [VSA-HA-DP]
usb:v10C4p8973*
ID_MODEL_FROM_DATABASE=C8051F38x HDMI Extender [UHBX-8X]
+usb:v10C4p89C6*
+ ID_MODEL_FROM_DATABASE=SPORTident HID device
+
usb:v10C4p89E1*
ID_MODEL_FROM_DATABASE=C8051F38x HDMI Extender [UHBX-SW3-WP]
usb:v10C4pEA60*
- ID_MODEL_FROM_DATABASE=CP210x UART Bridge / myAVR mySmartUSB light
+ ID_MODEL_FROM_DATABASE=CP2102/CP2109 UART Bridge Controller [CP210x family]
usb:v10C4pEA61*
ID_MODEL_FROM_DATABASE=CP210x UART Bridge
@@ -43898,6 +44525,12 @@ usb:v10C4pEA70*
usb:v10C4pEA80*
ID_MODEL_FROM_DATABASE=CP210x UART Bridge
+usb:v10C4pEAC9*
+ ID_MODEL_FROM_DATABASE=EFM8UB1 Bootloader
+
+usb:v10C4pEACA*
+ ID_MODEL_FROM_DATABASE=EFM8UB2 Bootloader
+
usb:v10C5*
ID_VENDOR_FROM_DATABASE=Sanei Electric, Inc.
@@ -43922,9 +44555,21 @@ usb:v10CD*
usb:v10CE*
ID_VENDOR_FROM_DATABASE=Silicon Labs
+usb:v10CEp0007*
+ ID_MODEL_FROM_DATABASE=Shinko/Sinfonia CHC-S1245
+
usb:v10CEp000E*
ID_MODEL_FROM_DATABASE=Shinko/Sinfonia CHC-S2145
+usb:v10CEp0019*
+ ID_MODEL_FROM_DATABASE=Shinko/Sinfonia CHC-S6145
+
+usb:v10CEp001D*
+ ID_MODEL_FROM_DATABASE=Shinko/Sinfonia CHC-S6245
+
+usb:v10CEp001E*
+ ID_MODEL_FROM_DATABASE=Ciaat Brava 21
+
usb:v10CEpEA6A*
ID_MODEL_FROM_DATABASE=MobiData EDGE USB Modem
@@ -44048,6 +44693,9 @@ usb:v10F1p1A1E*
usb:v10F1p1A2A*
ID_MODEL_FROM_DATABASE=Laptop Integrated Webcam
+usb:v10F1p1A2E*
+ ID_MODEL_FROM_DATABASE=HP Truevision HD Integrated Webcam
+
usb:v10F5*
ID_VENDOR_FROM_DATABASE=Turtle Beach
@@ -44213,6 +44861,9 @@ usb:v1130p6604*
usb:v1130p660C*
ID_MODEL_FROM_DATABASE=Foot Pedal/Thermometer
+usb:v1130p6626*
+ ID_MODEL_FROM_DATABASE=Key
+
usb:v1130p6806*
ID_MODEL_FROM_DATABASE=Keychain photo frame
@@ -44273,6 +44924,15 @@ usb:v113C*
usb:v113D*
ID_VENDOR_FROM_DATABASE=Mapower Electronics Co., Ltd
+usb:v113F*
+ ID_VENDOR_FROM_DATABASE=Integrated Biometrics, LLC
+
+usb:v113Fp1020*
+ ID_MODEL_FROM_DATABASE=Watson Two-Finger Roll Scanner
+
+usb:v113Fp1100*
+ ID_MODEL_FROM_DATABASE=Columbo Single-Finger Scanner
+
usb:v1141*
ID_VENDOR_FROM_DATABASE=V One Multimedia, Pte., Ltd
@@ -44573,6 +45233,9 @@ usb:v1199p9009*
usb:v1199p900A*
ID_MODEL_FROM_DATABASE=Gobi 2000 Wireless Modem
+usb:v1199p9013*
+ ID_MODEL_FROM_DATABASE=Sierra Wireless Gobi 3000 Modem device (MC8355)
+
usb:v1199p9055*
ID_MODEL_FROM_DATABASE=Gobi 9x15 Multimode 3G/4G LTE Modem (NAT mode)
@@ -44630,6 +45293,12 @@ usb:v11BE*
usb:v11BEpF0A0*
ID_MODEL_FROM_DATABASE=Martin Maxxyz DMX
+usb:v11C0*
+ ID_VENDOR_FROM_DATABASE=Betop
+
+usb:v11C0p5506*
+ ID_MODEL_FROM_DATABASE=Gamepad
+
usb:v11C5*
ID_VENDOR_FROM_DATABASE=Inmax
@@ -44717,6 +45386,9 @@ usb:v1209p1005*
usb:v1209p1006*
ID_MODEL_FROM_DATABASE=Mini IO-Board
+usb:v1209p1AB5*
+ ID_MODEL_FROM_DATABASE=Arachnid Labs Tsunami
+
usb:v1209p2000*
ID_MODEL_FROM_DATABASE=Zygmunt Krynicki Lantern Brightness Sensor
@@ -44732,6 +45404,12 @@ usb:v1209p2300*
usb:v1209p2301*
ID_MODEL_FROM_DATABASE=Keyboardio Keyboardio Model 01
+usb:v1209p2327*
+ ID_MODEL_FROM_DATABASE=K.T.E.C.Bootloader Device
+
+usb:v1209p2328*
+ ID_MODEL_FROM_DATABASE=K.T.E.C. Keyboard Device
+
usb:v1209p2337*
ID_MODEL_FROM_DATABASE=/Dev or SlashDev /Net
@@ -44744,15 +45422,33 @@ usb:v1209p3333*
usb:v1209p5222*
ID_MODEL_FROM_DATABASE=telavivmakers attami
+usb:v1209p53C0*
+ ID_MODEL_FROM_DATABASE=SatoshiLabs TREZOR Bootloader
+
+usb:v1209p53C1*
+ ID_MODEL_FROM_DATABASE=SatoshiLabs TREZOR
+
usb:v1209p5A22*
ID_MODEL_FROM_DATABASE=ikari_01 sd2snes
+usb:v1209p7530*
+ ID_MODEL_FROM_DATABASE=Refflion - IoT Board - Bootloader
+
+usb:v1209p7531*
+ ID_MODEL_FROM_DATABASE=Refflion - IoT Board - Sketch
+
usb:v1209p7BD0*
ID_MODEL_FROM_DATABASE=pokey9000 Tiny Bit Dingus
usb:v1209pABD0*
ID_MODEL_FROM_DATABASE=tibounise ADB converter
+usb:v1209pACED*
+ ID_MODEL_FROM_DATABASE=Open Lighting Project - Ja Rule Device
+
+usb:v1209pACEE*
+ ID_MODEL_FROM_DATABASE=Open Lighting Project - Ja Rule Bootloader
+
usb:v1209pBEEF*
ID_MODEL_FROM_DATABASE=Modal MC-USB
@@ -44810,6 +45506,21 @@ usb:v121E*
usb:v121Ep3403*
ID_MODEL_FROM_DATABASE=Muzio JM250 Audio Player
+usb:v1220*
+ ID_VENDOR_FROM_DATABASE=TC Electronic
+
+usb:v1220p000A*
+ ID_MODEL_FROM_DATABASE=Hall of Fame Reverb
+
+usb:v1220p002A*
+ ID_MODEL_FROM_DATABASE=Polytune
+
+usb:v1220p0032*
+ ID_MODEL_FROM_DATABASE=Ditto X2 Looper
+
+usb:v1220p0039*
+ ID_MODEL_FROM_DATABASE=Alter Ego X4 Vintage Echo
+
usb:v1221*
ID_VENDOR_FROM_DATABASE=Unknown manufacturer
@@ -44960,6 +45671,15 @@ usb:v1235p8012*
usb:v1235p8014*
ID_MODEL_FROM_DATABASE=Scarlett 18i8
+usb:v1235p8016*
+ ID_MODEL_FROM_DATABASE=Focusrite Scarlett 2i2
+
+usb:v1235p8203*
+ ID_MODEL_FROM_DATABASE=Focusrite Scarlett 6i6
+
+usb:v1235p8204*
+ ID_MODEL_FROM_DATABASE=Scarlett 18i8 2nd Gen
+
usb:v1241*
ID_VENDOR_FROM_DATABASE=Belkin
@@ -45056,6 +45776,9 @@ usb:v125FpC96A*
usb:v125FpCB10*
ID_MODEL_FROM_DATABASE=Dash Drive UV100
+usb:v125FpCB20*
+ ID_MODEL_FROM_DATABASE=DashDrive UV110
+
usb:v1260*
ID_VENDOR_FROM_DATABASE=Standard Microsystems Corp.
@@ -45078,7 +45801,7 @@ usb:v1267p0103*
ID_MODEL_FROM_DATABASE=G-720 Keyboard
usb:v1267p0201*
- ID_MODEL_FROM_DATABASE=A4Tech SWOP-3 Mouse
+ ID_MODEL_FROM_DATABASE=Mouse
usb:v1267p0210*
ID_MODEL_FROM_DATABASE=LG Optical Mouse 3D-310
@@ -45227,6 +45950,9 @@ usb:v1286p2001*
usb:v1286p2006*
ID_MODEL_FROM_DATABASE=88W8362 802.11n WLAN
+usb:v1286p203C*
+ ID_MODEL_FROM_DATABASE=K30326 802.11bgn Wireless Module [Marvell 88W8786U]
+
usb:v1286p8001*
ID_MODEL_FROM_DATABASE=BLOB boot loader firmware
@@ -45245,6 +45971,9 @@ usb:v1292*
usb:v1292p0258*
ID_MODEL_FROM_DATABASE=Creative Labs VoIP Blaster
+usb:v1292p4154*
+ ID_MODEL_FROM_DATABASE=Retro Link Atari cable
+
usb:v1293*
ID_VENDOR_FROM_DATABASE=Belkin Components [hex]
@@ -45260,6 +45989,12 @@ usb:v1294*
usb:v1294p1320*
ID_MODEL_FROM_DATABASE=Webmail Notifier
+usb:v1297*
+ ID_VENDOR_FROM_DATABASE=DekTec
+
+usb:v1297p020F*
+ ID_MODEL_FROM_DATABASE=DTU-215 Multi-Standard Modulator
+
usb:v129B*
ID_VENDOR_FROM_DATABASE=CyberTAN Technology
@@ -45293,6 +46028,12 @@ usb:v12B9*
usb:v12BA*
ID_VENDOR_FROM_DATABASE=Licensed by Sony Computer Entertainment America
+usb:v12BAp0032*
+ ID_MODEL_FROM_DATABASE=Wireless Stereo Headset
+
+usb:v12BAp0042*
+ ID_MODEL_FROM_DATABASE=Wireless Stereo Headset
+
usb:v12BAp00FF*
ID_MODEL_FROM_DATABASE=Rocksmith Guitar Adapter
@@ -45314,6 +46055,9 @@ usb:v12BD*
usb:v12BDpD012*
ID_MODEL_FROM_DATABASE=JPD Shockforce gamepad
+usb:v12BDpD015*
+ ID_MODEL_FROM_DATABASE=Generic 4-button NES USB Controller
+
usb:v12C4*
ID_VENDOR_FROM_DATABASE=Autocue Group Ltd
@@ -45329,11 +46073,14 @@ usb:v12CF*
usb:v12CFp0170*
ID_MODEL_FROM_DATABASE=Tt eSPORTS BLACK Gaming mouse
+usb:v12CFp600B*
+ ID_MODEL_FROM_DATABASE=Cougar 600M Gaming Mouse
+
usb:v12D1*
ID_VENDOR_FROM_DATABASE=Huawei Technologies Co., Ltd.
usb:v12D1p1001*
- ID_MODEL_FROM_DATABASE=E169/E620/E800 HSDPA Modem
+ ID_MODEL_FROM_DATABASE=E161/E169/E620/E800 HSDPA Modem
usb:v12D1p1003*
ID_MODEL_FROM_DATABASE=E220 HSDPA Modem / E230/E270/E870 HSDPA/HSUPA Modem
@@ -45362,6 +46109,9 @@ usb:v12D1p1038*
usb:v12D1p1039*
ID_MODEL_FROM_DATABASE=Ideos (tethering mode)
+usb:v12D1p1052*
+ ID_MODEL_FROM_DATABASE=MT7-L09
+
usb:v12D1p1404*
ID_MODEL_FROM_DATABASE=EM770W miniPCI WCDMA Modem
@@ -45381,11 +46131,14 @@ usb:v12D1p1436*
ID_MODEL_FROM_DATABASE=Broadband stick
usb:v12D1p1446*
- ID_MODEL_FROM_DATABASE=Broadband stick (modem on)
+ ID_MODEL_FROM_DATABASE=HSPA modem
usb:v12D1p1465*
ID_MODEL_FROM_DATABASE=K3765 HSPA
+usb:v12D1p14AC*
+ ID_MODEL_FROM_DATABASE=E815
+
usb:v12D1p14C3*
ID_MODEL_FROM_DATABASE=K5005 Vodafone LTE/UMTS/GSM Modem/Networkcard
@@ -45494,6 +46247,12 @@ usb:v12EF*
usb:v12EFp0100*
ID_MODEL_FROM_DATABASE=Tapwave Handheld [Tapwave Zodiac]
+usb:v12F2*
+ ID_VENDOR_FROM_DATABASE=ViewPlus Technologies, Inc.
+
+usb:v12F2p000A*
+ ID_MODEL_FROM_DATABASE=Braille embosser [SpotDot Emprint]
+
usb:v12F5*
ID_VENDOR_FROM_DATABASE=Dynamic System Electronics Corp.
@@ -45531,7 +46290,7 @@ usb:v1307p0190*
ID_MODEL_FROM_DATABASE=Ut190 8 GB Flash Drive with MicroSD reader
usb:v1307p0310*
- ID_MODEL_FROM_DATABASE=SD/MicroSD CardReader [hama]
+ ID_MODEL_FROM_DATABASE=SD/MicroSD CardReader [hama]/IT1327E [Basic Line flash drive]
usb:v1307p0330*
ID_MODEL_FROM_DATABASE=63-in-1 Multi-Card Reader/Writer
@@ -45614,6 +46373,15 @@ usb:v1313p8030*
usb:v1313p8070*
ID_MODEL_FROM_DATABASE=PM100D
+usb:v1313p8072*
+ ID_MODEL_FROM_DATABASE=PM100USB Power and Energy Meter Interface
+
+usb:v1313p8078*
+ ID_MODEL_FROM_DATABASE=PM100D Compact Power and Energy Meter Console
+
+usb:v1313p8080*
+ ID_MODEL_FROM_DATABASE=CCS100 - Compact Spectrometer
+
usb:v131D*
ID_VENDOR_FROM_DATABASE=Natural Point
@@ -45623,6 +46391,12 @@ usb:v131Dp0155*
usb:v131Dp0156*
ID_MODEL_FROM_DATABASE=TrackIR 4 Pro Head Tracker
+usb:v131Dp0158*
+ ID_MODEL_FROM_DATABASE=TrackIR 5 Pro Head Tracker
+
+usb:v1325*
+ ID_VENDOR_FROM_DATABASE=ams AG
+
usb:v132A*
ID_VENDOR_FROM_DATABASE=Envara Inc.
diff --git a/hwdb/60-evdev.hwdb b/hwdb/60-evdev.hwdb
index fd9078393b..4f01d88c35 100644
--- a/hwdb/60-evdev.hwdb
+++ b/hwdb/60-evdev.hwdb
@@ -115,6 +115,13 @@ evdev:name:ETPS/2 Elantech Touchpad:dmi:*:svnASUSTeKCOMPUTERINC.:pn?550C?:*
EVDEV_ABS_35=::31
EVDEV_ABS_36=::30
+# Asus UX301L
+evdev:name:Elan Touchpad:dmi:*:svnASUSTeKCOMPUTERINC.:pnUX301LAA:*
+ EVDEV_ABS_00=::30
+ EVDEV_ABS_01=::29
+ EVDEV_ABS_35=::30
+ EVDEV_ABS_36=::29
+
# Asus UX305
evdev:name:Elan Touchpad:dmi:*:svnASUSTeKCOMPUTERINC.:pnUX305UA:*
EVDEV_ABS_00=0:3097:32
@@ -152,6 +159,13 @@ evdev:name:AlpsPS/2 ALPS DualPoint TouchPad:dmi:bvn*:bvr*:bd*:svnDellInc.:pnLati
EVDEV_ABS_35=79:1841:22
EVDEV_ABS_36=140:1325:29
+# 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
+
# Dell Precision 5510
evdev:name:SynPS/2 Synaptics TouchPad:dmi:bvn*:bvr*:bd*:svnDellInc.:pnPrecision5510*
EVDEV_ABS_00=::42
@@ -178,6 +192,15 @@ evdev:name:AlpsPS/2 ALPS GlidePoint:dmi:bvn*:bvr*:bd*:svnDellInc.:pnXPSM1530*
EVDEV_ABS_00=85:947:15
EVDEV_ABS_01=154:726:18
+#####
+# Sun
+#####
+
+# Fujitsu Component - USB Touch Panel
+evdev:input:b0003v0430p0530*
+ EVDEV_ABS_00=0:4096:16
+ EVDEV_ABS_01=0:4096:16
+
#########################################
# Google
#########################################
@@ -268,6 +291,20 @@ evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO*:pvrThinkPadX1Carbon4th*
EVDEV_ABS_35=1262:5679:44
EVDEV_ABS_36=1101:4824:65
+# Lenovo Thinkpad Carbon X1 5th gen.
+evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO*:pvrThinkPadX1Carbon5th*
+ EVDEV_ABS_00=::44
+ EVDEV_ABS_01=::65
+ EVDEV_ABS_35=::44
+ EVDEV_ABS_36=::65
+
+# Lenovo Thinkpad Carbon X1 5th gen. (rmi4)
+evdev:name:Synaptics TM3289-002:dmi:*svnLENOVO*:pvrThinkPadX1Carbon5th*
+ EVDEV_ABS_00=::19
+ EVDEV_ABS_01=::19
+ EVDEV_ABS_35=::19
+ EVDEV_ABS_36=::19
+
# Lenovo T460
evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO*:pn*ThinkPad*T460*
EVDEV_ABS_00=1266:5677:44
@@ -338,6 +375,13 @@ evdev:name:ETPS/2 Elantech Touchpad:dmi:*svnSAMSUNGELECTRONICSCO.,LTD.:pn305V4A/
EVDEV_ABS_35=0:2480:28
EVDEV_ABS_36=0:1116:24
+# Samsung 880Z5E
+evdev:name:ETPS/2 Elantech Touchpad:dmi:*svnSAMSUNGELECTRONICSCO.,LTD.:pn870Z5E/880Z5E/680Z5E*
+ EVDEV_ABS_00=::30
+ EVDEV_ABS_01=::29
+ EVDEV_ABS_35=::30
+ EVDEV_ABS_36=::29
+
#########################################
# Toshiba
#########################################
@@ -346,3 +390,12 @@ evdev:name:ETPS/2 Elantech Touchpad:dmi:*svnSAMSUNGELECTRONICSCO.,LTD.:pn305V4A/
evdev:name:AlpsPS/2 ALPS DualPoint TouchPad:dmi:*svnTOSHIBA:pnTECRAM11*
EVDEV_ABS_00=90:962:11
EVDEV_ABS_01=51:681:14
+
+#########################################
+# Waltop
+#########################################
+
+# WALTOP International Corp. Slim Tablet
+evdev:input:b0003v172Fp0031*
+ EVDEV_ABS_00=0:10000:400
+ EVDEV_ABS_01=0:6250:400
diff --git a/hwdb/60-keyboard.hwdb b/hwdb/60-keyboard.hwdb
index 1aa729f047..881a531b67 100644
--- a/hwdb/60-keyboard.hwdb
+++ b/hwdb/60-keyboard.hwdb
@@ -1,7 +1,14 @@
# This file is part of systemd.
#
-# Keyboard mapping of scan codes to key codes, and
-# scan codes to add to the AT keyboard's 'force-release' list.
+# This file contains 3 types of metadata to apply to keyboards and
+# keyboard-like input devices:
+# - Key mapping
+# - Hard-coded layouts
+# - Absence of modifier LEDs
+#
+# The matching process is the same for the different types of metadata.
+#
+# ########################### MATCHING #######################################
#
# The lookup keys are composed in:
# 60-evdev.rules
@@ -40,11 +47,19 @@
# /sys/class/input/input?/capabilities/ev" and <vendor> is the
# firmware-provided string exported by the kernel DMI modalias,
# see /sys/class/dmi/id/modalias
+
+
+# ######################### KEY MAPPING ######################################
+#
+# Keyboard mapping of scan codes to key codes, and
+# scan codes to add to the AT keyboard's 'force-release' list.
#
# Scan codes are specified as:
# KEYBOARD_KEY_<hex scan code>=<key code identifier>
# The scan code should be expressed in hex lowercase. The key codes
# are retrieved and normalized from the kernel input API header.
+# Keycodes are either KEY_* defines in lowercase with the key_ prefix
+# optionally removed or BTN_ defines in lowercase with btn_ preserved.
#
# An '!' as the first character of the key identifier string
# will add the scan code to the AT keyboard's list of scan codes
@@ -67,7 +82,8 @@
# systemd-hwdb update
# udevadm trigger /dev/input/eventXX
# where /dev/input/eventXX is the keyboard in question. If in
-# doubt, simply use /dev/input/event* to reload all input rules.
+# doubt, simply reload all input rules
+# udevadm trigger --verbose --sysname-match="event*"
#
# If your changes are generally applicable, preferably send them as a pull
# request to
@@ -84,6 +100,7 @@
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pn*
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnGateway*:pnA0A1*:pvr*
evdev:atkbd:dmi:bvn*:bvr*:bd*:svneMachines:pneMachines*E725:pvr*
+ KEYBOARD_KEY_86=wlan # Fn+F3 or Fn+Q for comunication key
KEYBOARD_KEY_a5=help # Fn+F1
KEYBOARD_KEY_a6=setup # Fn+F2 Acer eSettings
KEYBOARD_KEY_a7=battery # Fn+F3 Power Management
@@ -105,6 +122,7 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svneMachines:pneMachines*E725:pvr*
KEYBOARD_KEY_f3=prog2 # "P2" programmable button
KEYBOARD_KEY_f4=prog1 # "P1" programmable button
KEYBOARD_KEY_f5=presentation
+ KEYBOARD_KEY_f6=power # Power button
KEYBOARD_KEY_f8=fn
KEYBOARD_KEY_f9=prog1 # Launch NTI shadow
@@ -144,6 +162,10 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMate*C3[01]0*:pvr*
KEYBOARD_KEY_6b=fn
KEYBOARD_KEY_6c=screenlock # FIXME: lock tablet device/buttons
+# Travelmate P648-G2-MG
+evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMate*P648-G2-MG*:pvr*
+ KEYBOARD_KEY_8a=f20 # Microphone mute button; should be micmute
+
# on some models this isn't brightnessup
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pn*5210*:pvr*
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pn*5220*:pvr*
@@ -158,6 +180,10 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnAspire*1640:*
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnAOA*:pvr*
KEYBOARD_KEY_a9=!switchvideomode # Fn+F5
+# Easynote models
+evdev:atkbd:dmi:bvn*:bvr*:bd*:svnPackard*Bell*:pnEasynote*:pvr*
+ KEYBOARD_KEY_86=wlan # Fn+F3 or Fn+Q for comunication key
+
###########################################################
# Alienware
###########################################################
@@ -222,7 +248,7 @@ evdev:input:b0003v049Fp0051*
###########################################################
evdev:name:gpio-keys:phys:gpio-keys/input0:ev:3:dmi:bvn*:bvr*:bd*:svncube:pni1-TF:*
- KEYBOARD_KEY_0=home
+ KEYBOARD_KEY_0=leftmeta
KEYBOARD_KEY_1=power
###########################################################
@@ -291,6 +317,10 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDell*:pnPrecision*:pvr*
KEYBOARD_KEY_88=! # wireless switch
KEYBOARD_KEY_9e=!f21
+# Dell Latitude E7*
+evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDell*:pnLatitude*E7*:pvr*
+ KEYBOARD_KEY_88=unknown # Fn-PrtScr rfkill - handled in HW
+
# Dell XPS
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDell*:pnXPS*:pvr*
KEYBOARD_KEY_8c=!unknown
@@ -831,6 +861,7 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMAXDATA:pnPro*7000*:pvr*
###########################################################
# Akoya
+evdev:atkbd:dmi:bvn*:bvr*:svnMEDION*:pnS3409*:pvr*
evdev:atkbd:dmi:bvn*:bvr*:svnMedion*:pnAkoya*:pvr*
KEYBOARD_KEY_a0=!mute
KEYBOARD_KEY_ae=!volumedown
@@ -1274,9 +1305,13 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDIXONSP:pnDIXON*:pvr*
KEYBOARD_KEY_ae=! # volume down
KEYBOARD_KEY_b0=! # volume up
-###########################################################
-# Fixed layout devices
-###########################################################
+######################### FIXED LAYOUT DEVICES #############################
+# This section lists devices for which only one keyboard layout is possible
+# or useful such as devices which "type" expecting the user's keymap to match
+# a particular one. For example, barcode readers and OTP keys.
+#
+# The layout must be an xkb compatible layout (defined with XKB_FIXED_LAYOUT),
+# with an accompanying variant (defined with XKB_FIXED_VARIANT) if necessary.
# Yubico Yubico Yubikey II"
evdev:input:b0003v1050p0010*
@@ -1288,3 +1323,16 @@ evdev:input:b0003v1050p0116*
evdev:input:b0003v05FEp1010*
XKB_FIXED_LAYOUT="us"
XKB_FIXED_VARIANT=""
+
+######################### LACK OF MODIFIER LEDS ############################
+# This section lists keyboard which do not have their own LEDs for some
+# modifiers. Only Caps-Lock (KEYBOARD_LED_CAPSLOCK) and Num-Lock
+# (KEYBOARD_LED_CAPSLOCK) are currently handled and need their values set
+# to "0" to indicate the absence of LED.
+#
+# Presence of a LED is implicit when the property is absent.
+
+# Logitech K750
+evdev:input:b0003v046Dp4002*
+ KEYBOARD_LED_NUMLOCK=0
+ KEYBOARD_LED_CAPSLOCK=0
diff --git a/hwdb/60-sensor.hwdb b/hwdb/60-sensor.hwdb
index fcbdcabf30..dab22dc643 100644
--- a/hwdb/60-sensor.hwdb
+++ b/hwdb/60-sensor.hwdb
@@ -47,8 +47,31 @@
sensor:modalias:acpi:SMO8500*:dmi:*svn*ASUSTeK*:*pn*TP500LB*
ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 0
+sensor:modalias:acpi:SMO8500*:dmi:*svn*ASUSTeK*:*pn*TP300LJ*
+ ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1
+
+#########################################
+# Endless
+#########################################
+sensor:modalias:acpi:ACCE0001*:dmi:*svnEndless*:*pnELT-NL3*
+ ACCEL_MOUNT_MATRIX=0, 1, 0; 0, 0, -1; -1, 0, 0
+
+#########################################
+# HP
+#########################################
+sensor:modalias:platform:lis3lv02d:dmi:*svn*Hewlett-Packard*:*pn*HPEliteBook8540w*
+sensor:modalias:platform:lis3lv02d:dmi:*svn*Hewlett-Packard*:*pn*HPEliteBook8560w*
+ ACCEL_MOUNT_MATRIX=1, 0, 0; 0, 0, -1; 0, 1, 0
+
#########################################
# Winbook
#########################################
sensor:modalias:acpi:BMA250*:dmi:*svn*WinBook*:*pn*TW100*
ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 0
+
+#########################################
+# Cytrix (Mytrix)
+#########################################
+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-joystick.hwdb b/hwdb/70-joystick.hwdb
new file mode 100644
index 0000000000..9d5c4fc069
--- /dev/null
+++ b/hwdb/70-joystick.hwdb
@@ -0,0 +1,50 @@
+# This file is part of systemd.
+#
+# Database for joystick device information that cannot be queried directly.
+#
+# The lookup keys are composed in:
+# 70-joystick.rules
+#
+# Note: The format of the "joystick:" 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 format:
+# joystick:<bustype>:v<vid>p<pid>:name:<name>:
+#
+# vid/pid as 4-digit hex lowercase vendor/product
+#
+# To add local entries, create a new file
+# /etc/udev/hwdb.d/71-joystick-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 joystick 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.
+#
+# Permitted keys:
+# Specify if a joystick is a built-in one or external:
+# ID_INPUT_JOYSTICK_INTEGRATION=internal|external
+#
+# If the property is missing, user-space can assume:
+# ID_INPUT_JOYSTICK_INTEGRATION=external
+
+joystick:bluetooth:*
+ ID_INPUT_JOYSTICK_INTEGRATION=external
+
+###########################################################
+# GPD
+###########################################################
+
+# GPD Win, Classic and XBox 360 compat modes
+joystick:usb:v11c5p5507*
+joystick:usb:v045ep028e*
+ ID_INPUT_JOYSTICK_INTEGRATION=internal
diff --git a/hwdb/70-mouse.hwdb b/hwdb/70-mouse.hwdb
index 772534f495..d5cccb9bdb 100644
--- a/hwdb/70-mouse.hwdb
+++ b/hwdb/70-mouse.hwdb
@@ -214,6 +214,14 @@ mouse:usb:v0461p4d16:name:USB Optical Mouse:
MOUSE_DPI=500@125
##########################################
+# Future Technology Devices International
+##########################################
+
+# SNES Mouse plugged into a Retrode 2
+mouse:usb:v0403p97c1:name:Retrode SNES Mouse:
+ MOUSE_DPI=235@126
+
+##########################################
# HandShoe Mouse
##########################################
@@ -244,6 +252,14 @@ mouse:usb:v093ap2510:name:PIXART USB OPTICAL MOUSE:
MOUSE_DPI=1000@125
##########################################
+# IBM
+##########################################
+
+# IBM USB Travel Mouse (MO32BO)
+mouse:usb:v04b3p3107:name:*
+ MOUSE_DPI=800@125
+
+##########################################
# Lenovo
##########################################
diff --git a/hwdb/70-pointingstick.hwdb b/hwdb/70-pointingstick.hwdb
index 65c87aeac7..f1a86ff20b 100644
--- a/hwdb/70-pointingstick.hwdb
+++ b/hwdb/70-pointingstick.hwdb
@@ -126,10 +126,16 @@ evdev:name:TPPS/2 IBM TrackPoint:dmi:bvn*:bvr*:bd*:svnLENOVO:pn*:pvrThinkPadX1Ta
POINTINGSTICK_SENSITIVITY=200
POINTINGSTICK_CONST_ACCEL=1.0
-# Lenovo Thinkpad X200s / X201s
+# Lenovo Thinkpad X200/X201/X200s/X201s
# Note these come with 2 revisions of keyboard, with the trackpoints having a
# different sensitivity in the different revisions. 1.25 is a bit slow for the
# least sensitive revision, but it is better to be a bit slow than too fast.
-evdev:name:TPPS/2 IBM TrackPoint:dmi:bvn*:bvr*:bd*:svnLENOVO:pn*:pvrThinkPadX20?s:*
+evdev:name:TPPS/2 IBM TrackPoint:dmi:bvn*:bvr*:bd*:svnLENOVO:pn*:pvrThinkPadX20?:*
+evdev:name:TPPS/2 IBM TrackPoint:dmi:bvn*:bvr*:bd*:svnLENOVO:pn*:pvrThinkPadX20??:*
POINTINGSTICK_SENSITIVITY=200
POINTINGSTICK_CONST_ACCEL=1.25
+
+# Lenovo UltraNav SK-8845 (USB keyboard)
+evdev:input:b0003v06CBp0009*
+ POINTINGSTICK_CONST_ACCEL=2.5
+ POINTINGSTICK_SENSITIVITY=200
diff --git a/hwdb/70-touchpad.hwdb b/hwdb/70-touchpad.hwdb
index 82a4b7a575..12d97de69b 100644
--- a/hwdb/70-touchpad.hwdb
+++ b/hwdb/70-touchpad.hwdb
@@ -53,3 +53,10 @@ touchpad:usb:v05ac*
###########################################################
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-update.py b/hwdb/acpi-update.py
index 50da531dc6..2c23b057fb 100755
--- a/hwdb/acpi-update.py
+++ b/hwdb/acpi-update.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python3
+#!/usr/bin/env python3
from html.parser import HTMLParser
from enum import Enum
diff --git a/hwdb/meson.build b/hwdb/meson.build
new file mode 100644
index 0000000000..6fceff2b3b
--- /dev/null
+++ b/hwdb/meson.build
@@ -0,0 +1,44 @@
+hwdb_files = files('''
+ 20-pci-vendor-model.hwdb
+ 20-pci-classes.hwdb
+ 20-usb-vendor-model.hwdb
+ 20-usb-classes.hwdb
+ 20-sdio-vendor-model.hwdb
+ 20-sdio-classes.hwdb
+ 20-bluetooth-vendor-product.hwdb
+ 20-acpi-vendor.hwdb
+ 20-OUI.hwdb
+ 20-net-ifname.hwdb
+ 60-evdev.hwdb
+ 60-keyboard.hwdb
+ 60-sensor.hwdb
+ 70-joystick.hwdb
+ 70-mouse.hwdb
+ 70-pointingstick.hwdb
+ 70-touchpad.hwdb
+'''.split())
+
+if conf.get('ENABLE_HWDB', false)
+ install_data(hwdb_files,
+ install_dir : udevhwdbdir)
+
+ meson.add_install_script('sh', '-c',
+ mkdir_p.format(join_paths(sysconfdir, 'udev/hwdb.d')))
+
+ meson.add_install_script('sh', '-c',
+ 'test -n "$DESTDIR" || @0@/systemd-hwdb update'
+ .format(rootbindir))
+endif
+
+############################################################
+
+parse_hwdb_py = find_program('parse_hwdb.py')
+test('parse-hwdb',
+ parse_hwdb_py,
+ timeout : 90)
+
+############################################################
+
+run_target(
+ 'update',
+ command : [hwdb_update_sh, meson.current_source_dir()])
diff --git a/hwdb/parse_hwdb.py b/hwdb/parse_hwdb.py
index b57e6f75aa..c7b49b83df 100755
--- a/hwdb/parse_hwdb.py
+++ b/hwdb/parse_hwdb.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python3
+#!/usr/bin/env python3
# -*- Mode: python; coding: utf-8; indent-tabs-mode: nil -*- */
#
# This file is part of systemd. It is distrubuted under the MIT license, see
@@ -66,6 +66,7 @@ UDEV_TAG = Word(string.ascii_uppercase, alphanums + '_')
TYPES = {'mouse': ('usb', 'bluetooth', 'ps2', '*'),
'evdev': ('name', 'atkbd', 'input'),
'touchpad': ('i8042', 'rmi', 'bluetooth', 'usb'),
+ 'joystick': ('i8042', 'rmi', 'bluetooth', 'usb'),
'keyboard': ('name', ),
'sensor': ('modalias', ),
}
@@ -109,9 +110,12 @@ def property_grammar():
('MOUSE_WHEEL_TILT_VERTICAL', Literal('1')),
('POINTINGSTICK_SENSITIVITY', INTEGER),
('POINTINGSTICK_CONST_ACCEL', REAL),
+ ('ID_INPUT_JOYSTICK_INTEGRATION', Or(('internal', 'external'))),
('ID_INPUT_TOUCHPAD_INTEGRATION', Or(('internal', 'external'))),
('XKB_FIXED_LAYOUT', STRING),
('XKB_FIXED_VARIANT', STRING),
+ ('KEYBOARD_LED_NUMLOCK', Literal('0')),
+ ('KEYBOARD_LED_CAPSLOCK', Literal('0')),
('ACCEL_MOUNT_MATRIX', mount_matrix),
)
fixed_props = [Literal(name)('NAME') - Suppress('=') - val('VALUE')
@@ -168,7 +172,9 @@ def check_one_keycode(prop, value):
if value != '!' and ecodes is not None:
key = 'KEY_' + value.upper()
if key not in ecodes:
- error('Keycode {} unknown', key)
+ key = value.upper()
+ if key not in ecodes:
+ error('Keycode {} unknown', key)
def check_properties(groups):
grammar = property_grammar()
diff --git a/man/90-rearrange-path.py b/man/90-rearrange-path.py
index c6ff32210f..7537d5e915 100755
--- a/man/90-rearrange-path.py
+++ b/man/90-rearrange-path.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python3
+#!/usr/bin/env python3
"""
diff --git a/man/custom-entities.ent.in b/man/custom-entities.ent.in
new file mode 100644
index 0000000000..0257c2a94f
--- /dev/null
+++ b/man/custom-entities.ent.in
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!ENTITY MOUNT_PATH @MOUNT_PATH@>
+<!ENTITY UMOUNT_PATH @UMOUNT_PATH@>
+<!ENTITY systemgeneratordir @SYSTEM_GENERATOR_PATH@>
+<!ENTITY usergeneratordir @USER_GENERATOR_PATH@>
+<!ENTITY systemenvgeneratordir @SYSTEM_ENV_GENERATOR_PATH@>
+<!ENTITY userenvgeneratordir @USER_ENV_GENERATOR_PATH@>
diff --git a/man/environment.d.xml b/man/environment.d.xml
index be7758a2f9..ad9db1666f 100644
--- a/man/environment.d.xml
+++ b/man/environment.d.xml
@@ -20,7 +20,8 @@
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="environment.d" xmlns:xi="http://www.w3.org/2001/XInclude">
+<refentry id="environment.d" conditional='ENABLE_ENVIRONMENT_D'
+ xmlns:xi="http://www.w3.org/2001/XInclude">
<refentryinfo>
<title>environment.d</title>
@@ -103,7 +104,7 @@
<programlisting>
FOO_DEBUG=force-software-gl,log-verbose
PATH=/opt/foo/bin:$PATH
- LD_LIBRARY_PATH=${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}/opt/foo/lib
+ LD_LIBRARY_PATH=/opt/foo/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}
XDG_DATA_DIRS=/opt/foo/share:${XDG_DATA_DIRS:-/usr/local/share/:/usr/share/}
</programlisting>
</example>
diff --git a/man/journalctl.xml b/man/journalctl.xml
index cae5312db2..444b916073 100644
--- a/man/journalctl.xml
+++ b/man/journalctl.xml
@@ -272,16 +272,26 @@
<varlistentry>
<term>
- <option>short-precise</option>
+ <option>short-iso-precise</option>
</term>
<listitem>
- <para>is very similar, but shows timestamps with full
+ <para>as for <option>short-iso</option> but includes full
microsecond precision.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
+ <option>short-precise</option>
+ </term>
+ <listitem>
+ <para>is very similar, but shows classic syslog timestamps
+ with full microsecond precision.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
<option>short-monotonic</option>
</term>
<listitem>
diff --git a/man/kernel-command-line.xml b/man/kernel-command-line.xml
index f02ca3e7bc..00fb6f6c0d 100644
--- a/man/kernel-command-line.xml
+++ b/man/kernel-command-line.xml
@@ -59,8 +59,8 @@
kernel command line arguments.</para>
<para>For command line parameters understood by the kernel, please
- see <ulink
- url="https://www.kernel.org/doc/Documentation/kernel-parameters.txt"><filename>kernel-parameters.txt</filename></ulink>
+ see
+ <ulink url="https://www.kernel.org/doc/html/latest/admin-guide/kernel-parameters.html"><filename>kernel-parameters.html</filename></ulink>
and
<citerefentry project='man-pages'><refentrytitle>bootparam</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
diff --git a/man/less-variables.xml b/man/less-variables.xml
index 1f34cbc1bf..396481c937 100644
--- a/man/less-variables.xml
+++ b/man/less-variables.xml
@@ -12,8 +12,8 @@
<listitem><para>Pager to use when <option>--no-pager</option> is not given; overrides
<varname>$PAGER</varname>. If neither <varname>$SYSTEMD_PAGER</varname> nor <varname>$PAGER</varname> are set, a
set of well-known pager implementations are tried in turn, including
- <citerefentry><refentrytitle>less</refentrytitle><manvolnum>1</manvolnum></citerefentry> and
- <citerefentry><refentrytitle>more</refentrytitle><manvolnum>1</manvolnum></citerefentry>, until one is found. If
+ <citerefentry project='man-pages'><refentrytitle>less</refentrytitle><manvolnum>1</manvolnum></citerefentry> and
+ <citerefentry project='man-pages'><refentrytitle>more</refentrytitle><manvolnum>1</manvolnum></citerefentry>, until one is found. If
no pager implementation is discovered no pager is invoked. Setting this environment variable to an empty string
or the value <literal>cat</literal> is equivalent to passing <option>--no-pager</option>.</para></listitem>
</varlistentry>
diff --git a/man/locale.conf.xml b/man/locale.conf.xml
index 2fe731113a..1405dda3fd 100644
--- a/man/locale.conf.xml
+++ b/man/locale.conf.xml
@@ -91,12 +91,14 @@
might be checked for locale configuration as well, however only as
fallback.</para>
- <para><citerefentry project='man-pages'><refentrytitle>localectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+ <para><filename>/etc/vconsole.conf</filename> is usually created and updated
+ using
+ <citerefentry><refentrytitle>systemd-localed.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
+ <citerefentry project='man-pages'><refentrytitle>localectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
may be used to alter the settings in this file during runtime from
the command line. Use
<citerefentry><refentrytitle>systemd-firstboot</refentrytitle><manvolnum>1</manvolnum></citerefentry>
- to initialize them on mounted (but not booted) system
- images.</para>
+ to initialize them on mounted (but not booted) system images.</para>
</refsect1>
<refsect1>
diff --git a/man/logind.conf.xml b/man/logind.conf.xml
index 994e0e1140..16f51af72c 100644
--- a/man/logind.conf.xml
+++ b/man/logind.conf.xml
@@ -244,8 +244,9 @@
<para>A different application may disable logind's handling of system power and
sleep keys and the lid switch by taking a low-level inhibitor lock
- ("handle-power-key", "handle-suspend-key", "handle-hibernate-key",
- "handle-lid-switch"). This is most commonly used by graphical desktop environments
+ (<literal>handle-power-key</literal>, <literal>handle-suspend-key</literal>,
+ <literal>handle-hibernate-key</literal>, <literal>handle-lid-switch</literal>).
+ This is most commonly used by graphical desktop environments
to take over suspend and hibernation handling, and to use their own configuration
mechanisms. If a low-level inhibitor lock is taken, logind will not take any
action when that key or switch is triggered and the <varname>Handle*=</varname>
@@ -261,7 +262,9 @@
<listitem><para>Controls whether actions that <command>systemd-logind</command>
takes when the power and sleep keys and the lid switch are triggered are subject
to high-level inhibitor locks ("shutdown", "sleep", "idle"). Low level inhibitor
- locks ("handle-*-key"), are always honored, irrespective of this setting.</para>
+ locks (<literal>handle-power-key</literal>, <literal>handle-suspend-key</literal>,
+ <literal>handle-hibernate-key</literal>, <literal>handle-lid-switch</literal>),
+ are always honored, irrespective of this setting.</para>
<para>These settings take boolean arguments. If <literal>no</literal>, the
inhibitor locks taken by applications are respected. If <literal>yes</literal>,
diff --git a/man/machinectl.xml b/man/machinectl.xml
index 7a159aecdc..46dcb44ca6 100644
--- a/man/machinectl.xml
+++ b/man/machinectl.xml
@@ -713,19 +713,22 @@
is automatically derived from the last component of the URL,
with its suffix removed.</para>
- <para>The image is verified before it is made available,
- unless <option>--verify=no</option> is specified. Verification
- is done via SHA256SUMS and SHA256SUMS.gpg files that need to
- be made available on the same web server, under the same URL
- as the <filename>.tar</filename> file, but with the last
- component (the filename) of the URL replaced. With
- <option>--verify=checksum</option>, only the SHA256 checksum
- for the file is verified, based on the
- <filename>SHA256SUMS</filename> file. With
- <option>--verify=signature</option>, the SHA256SUMS file is
- first verified with detached GPG signature file
- <filename>SHA256SUMS.gpg</filename>. The public key for this
- verification step needs to be available in
+ <para>The image is verified before it is made available, unless
+ <option>--verify=no</option> is specified.
+ Verification is done either via an inline signed file with the name
+ of the image and the suffix <filename>.sha256</filename> or via
+ separate <filename>SHA256SUMS</filename> and
+ <filename>SHA256SUMS.gpg</filename> files.
+ The signature files need to be made available on the same web
+ server, under the same URL as the <filename>.tar</filename> file.
+ With <option>--verify=checksum</option>, only the SHA256 checksum
+ for the file is verified, based on the <filename>.sha256</filename>
+ suffixed file or the<filename>SHA256SUMS</filename> file.
+ With <option>--verify=signature</option>, the sha checksum file is
+ first verified with the inline signature in the
+ <filename>.sha256</filename> file or the detached GPG signature file
+ <filename>SHA256SUMS.gpg</filename>.
+ The public key for this verification step needs to be available in
<filename>/usr/lib/systemd/import-pubring.gpg</filename> or
<filename>/etc/systemd/import-pubring.gpg</filename>.</para>
diff --git a/man/meson.build b/man/meson.build
new file mode 100644
index 0000000000..4f2ddad31a
--- /dev/null
+++ b/man/meson.build
@@ -0,0 +1,204 @@
+# This is lame, I know, but meson has no other include mechanism
+subdir('rules')
+
+want_man = get_option('man')
+want_html = get_option('html')
+xsltproc = find_program('xsltproc',
+ required : want_man == 'true' or want_html == 'true')
+want_man = want_man != 'false' and xsltproc.found()
+want_html = want_html != 'false' and xsltproc.found()
+
+xsltproc_flags = [
+ '--nonet',
+ '--xinclude',
+ '--stringparam', 'man.output.quietly', '1',
+ '--stringparam', 'funcsynopsis.style', 'ansi',
+ '--stringparam', 'man.authors.section.enabled', '0',
+ '--stringparam', 'man.copyright.section.enabled', '0',
+ '--stringparam', 'systemd.version', '@0@'.format(meson.project_version()),
+ '--path',
+ '@0@:@1@'.format(meson.current_build_dir(), meson.current_source_dir())]
+
+custom_man_xsl = files('custom-man.xsl')
+custom_html_xsl = files('custom-html.xsl')
+xslt_cmd = [xsltproc, '-o', '@OUTPUT0@'] + xsltproc_flags
+
+custom_entities_ent = configure_file(
+ input : 'custom-entities.ent.in',
+ output : 'custom-entities.ent',
+ configuration : conf)
+
+man_pages = []
+html_pages = []
+source_xml_files = []
+foreach tuple : manpages
+ stem = tuple[0]
+ section = tuple[1]
+ aliases = tuple[2]
+ condition = tuple[3]
+
+ xml = stem + '.xml'
+ html = stem + '.html'
+ man = stem + '.' + section
+
+ manaliases = []
+ htmlaliases = []
+ foreach alias : aliases
+ manaliases += [alias + '.' + section]
+ htmlaliases += [alias + '.html']
+ endforeach
+
+ mandirn = join_paths(get_option('mandir'), 'man' + section)
+
+ if condition == '' or conf.get(condition, false)
+ p1 = custom_target(
+ man,
+ input : xml,
+ output : [man] + manaliases,
+ command : xslt_cmd + [custom_man_xsl, '@INPUT@'],
+ depend_files : custom_entities_ent,
+ install : want_man,
+ install_dir : mandirn)
+ man_pages += [p1]
+
+ p2 = []
+ foreach htmlalias : htmlaliases
+ link = custom_target(
+ htmlalias,
+ input : p2,
+ output : htmlalias,
+ command : ['ln', '-fs', html, '@OUTPUT@'])
+ if want_html
+ dst = join_paths(docdir, 'html', htmlalias)
+ cmd = 'ln -fs @0@ $DESTDIR@1@'.format(html, dst)
+ meson.add_install_script('sh', '-c', cmd)
+ p2 += [link]
+ endif
+ html_pages += [link]
+ endforeach
+
+ p3 = custom_target(
+ html,
+ input : xml,
+ output : html,
+ command : xslt_cmd + [custom_html_xsl, '@INPUT@'],
+ depend_files : custom_entities_ent,
+ depends : p2,
+ install : want_html,
+ install_dir : join_paths(docdir, 'html'))
+ html_pages += [p3]
+
+ source_xml_files += files(tuple[0] + '.xml')
+ else
+ message('Skipping @0@.@1@ because @2@ is false'.format(stem, section, condition))
+ endif
+endforeach
+
+############################################################
+
+have_lxml = run_command(xml_helper_py).returncode() == 0
+if not have_lxml
+ message('python-lxml not available, not making man page indices')
+endif
+
+systemd_directives_xml = custom_target(
+ 'systemd.directives.xml',
+ input : source_xml_files,
+ output : 'systemd.directives.xml',
+ command : [make_directive_index_py, '@OUTPUT@'] + source_xml_files)
+
+nonindex_xml_files = source_xml_files + [systemd_directives_xml]
+systemd_index_xml = custom_target(
+ 'systemd.index.xml',
+ input : nonindex_xml_files,
+ 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]]
+ stem = tuple[0]
+ section = tuple[1]
+ xml = tuple[2]
+
+ html = stem + '.html'
+ man = stem + '.' + section
+
+ mandirn = join_paths(get_option('mandir'), 'man' + section)
+
+ p1 = custom_target(
+ man,
+ input : xml,
+ output : man,
+ command : xslt_cmd + [custom_man_xsl, '@INPUT@'],
+ install : want_man and have_lxml,
+ install_dir : mandirn)
+ man_pages += [p1]
+
+ p2 = []
+ if html == 'systemd.index.html'
+ htmlalias = 'index.html'
+ link = custom_target(
+ htmlalias,
+ input : p2,
+ output : htmlalias,
+ command : ['ln', '-fs', html, '@OUTPUT@'])
+ if want_html
+ dst = join_paths(docdir, 'html', htmlalias)
+ cmd = 'ln -fs @0@ $DESTDIR@1@'.format(html, dst)
+ meson.add_install_script('sh', '-c', cmd)
+ p2 += [link]
+ endif
+ html_pages += [link]
+ endif
+
+ p3 = custom_target(
+ html,
+ input : xml,
+ output : html,
+ command : xslt_cmd + [custom_html_xsl, '@INPUT@'],
+ depend_files : custom_entities_ent,
+ depends : p2,
+ install : want_html and have_lxml,
+ install_dir : join_paths(docdir, 'html'))
+ html_pages += [p3]
+endforeach
+
+# cannot use run_target until https://github.com/mesonbuild/meson/issues/1644 is resolved
+man = custom_target(
+ 'man',
+ output : 'man',
+ depends : man_pages,
+ command : ['echo'])
+
+html = run_target(
+ 'html',
+ depends : html_pages,
+ output : 'html',
+ command : ['echo'])
+
+run_target(
+ 'doc-sync',
+ depends : man_pages + html_pages,
+ command : ['rsync', '-rlv',
+ '--delete-excluded',
+ '--include=man',
+ '--include=*.html',
+ '--exclude=*',
+ '--omit-dir-times',
+ meson.current_build_dir(),
+ get_option('www-target')])
+
+############################################################
+
+if git.found()
+ run_target(
+ 'update-man-rules',
+ # slightly strange syntax because of
+ # https://github.com/mesonbuild/meson/issues/1643
+ # and https://github.com/mesonbuild/meson/issues/1512
+ command : ['sh', '-c',
+ 'cd @0@ && '.format(meson.build_root()) +
+ 'python3 @0@/tools/make-man-rules.py --meson `git ls-files ":/man/*.xml"` >t && '.format(meson.source_root()) +
+ 'mv t @0@/rules/meson.build'.format(meson.current_source_dir())],
+ depend_files : custom_entities_ent)
+endif
diff --git a/man/networkctl.xml b/man/networkctl.xml
index 809eb7ec6a..d4fa5e9029 100644
--- a/man/networkctl.xml
+++ b/man/networkctl.xml
@@ -172,14 +172,40 @@ s - Service VLAN, m - Two-port MAC Relay (TPMR)
1 neighbors listed.</programlisting></para>
</listitem>
</varlistentry>
+
+ <varlistentry>
+ <term>
+ <command>label</command>
+ </term>
+
+ <listitem><para>Show numerical address labels that can be used for address selection.
+ This is the same information that
+ <citerefentry><refentrytitle>ip-addrlabel</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ shows. See <ulink url="https://tools.ietf.org/html/rfc3484">RFC 3484</ulink>
+ for a discussion of address labels.</para>
+
+ <para>Produces output similar to:
+ <programlisting>Prefix/Prefixlen Label
+ ::/0 1
+ fc00::/7 5
+ fec0::/10 11
+ 2002::/16 2
+ 3ffe::/16 12
+ 2001:10::/28 7
+ 2001::/32 6
+::ffff:0.0.0.0/96 4
+ ::/96 3
+ ::1/128 0</programlisting></para>
+ </listitem>
+ </varlistentry>
+
</variablelist>
</refsect1>
<refsect1>
<title>Exit status</title>
- <para>On success, 0 is returned, a non-zero failure
- code otherwise.</para>
+ <para>On success, 0 is returned, a non-zero failure code otherwise.</para>
</refsect1>
<refsect1>
@@ -187,7 +213,8 @@ s - Service VLAN, m - Two-port MAC Relay (TPMR)
<para>
<citerefentry><refentrytitle>systemd-networkd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd.network</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>systemd.netdev</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ <citerefentry><refentrytitle>systemd.netdev</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+ <citerefentry project='die-net'><refentrytitle>ip</refentrytitle><manvolnum>8</manvolnum></citerefentry>
</para>
</refsect1>
</refentry>
diff --git a/man/nss-resolve.xml b/man/nss-resolve.xml
index 4e102cec26..3a4e98e88f 100644
--- a/man/nss-resolve.xml
+++ b/man/nss-resolve.xml
@@ -63,13 +63,24 @@
hostnames via DNS.</para>
<para>To activate the NSS module, add <literal>resolve</literal> to the line starting with
- <literal>hosts:</literal> in <filename>/etc/nsswitch.conf</filename>. Specifcally, it is recommended to place
- <literal>resolve</literal> early in <filename>/etc/nsswitch.conf</filename>' <literal>hosts:</literal> line (but
+ <literal>hosts:</literal> in <filename>/etc/nsswitch.conf</filename>. Specifically, it is recommended to place
+ <literal>resolve</literal> early in <filename>/etc/nsswitch.conf</filename>'s <literal>hosts:</literal> line (but
after the <literal>files</literal> or <literal>mymachines</literal> entries), right before the
<literal>dns</literal> entry if it exists, followed by <literal>[!UNAVAIL=return]</literal>, to ensure DNS queries
are always routed via
<citerefentry><refentrytitle>systemd-resolved</refentrytitle><manvolnum>8</manvolnum></citerefentry> if it is
running, but are routed to <command>nss-dns</command> if this service is not available.</para>
+
+ <para>Note that <command>systemd-resolved</command> will synthesize DNS resource
+ records in a few cases, for example for <literal>localhost</literal> and the
+ current hostname, see
+ <citerefentry><refentrytitle>systemd-resolved</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ for the full list. This duplicates the functionality of
+ <citerefentry><refentrytitle>nss-myhostname</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+ but it is still recommended (see examples below) to keep
+ <command>nss-myhostname</command> configured in
+ <filename>/etc/nsswitch.conf</filename>, to keep those names resolveable if
+ <command>systemd-resolved</command> is not running.</para>
</refsect1>
<refsect1>
diff --git a/man/nss-systemd.xml b/man/nss-systemd.xml
index 71aed4df83..34811f0a2e 100644
--- a/man/nss-systemd.xml
+++ b/man/nss-systemd.xml
@@ -21,7 +21,7 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
-->
-<refentry id="nss-systemd">
+<refentry id="nss-systemd" conditional='ENABLE_NSS_SYSTEMD'>
<refentryinfo>
<title>nss-systemd</title>
diff --git a/man/rules/meson.build b/man/rules/meson.build
new file mode 100644
index 0000000000..9f7201a909
--- /dev/null
+++ b/man/rules/meson.build
@@ -0,0 +1,766 @@
+# Do not edit. Generated by make-man-rules.py.
+manpages = [
+['binfmt.d', '5', [], 'ENABLE_BINFMT'],
+ ['bootctl', '1', [], 'ENABLE_EFI'],
+ ['bootup', '7', [], ''],
+ ['busctl', '1', [], ''],
+ ['coredump.conf', '5', ['coredump.conf.d'], 'ENABLE_COREDUMP'],
+ ['coredumpctl', '1', [], 'ENABLE_COREDUMP'],
+ ['crypttab', '5', [], 'HAVE_LIBCRYPTSETUP'],
+ ['daemon', '7', [], ''],
+ ['dnssec-trust-anchors.d',
+ '5',
+ ['systemd.negative', 'systemd.positive'],
+ 'ENABLE_RESOLVED'],
+ ['environment.d', '5', [], 'ENABLE_ENVIRONMENT_D'],
+ ['file-hierarchy', '7', [], ''],
+ ['halt', '8', ['poweroff', 'reboot'], ''],
+ ['hostname', '5', [], ''],
+ ['hostnamectl', '1', [], 'ENABLE_HOSTNAMED'],
+ ['hwdb', '7', [], 'ENABLE_HWDB'],
+ ['journal-remote.conf', '5', ['journal-remote.conf.d'], 'HAVE_MICROHTTPD'],
+ ['journal-upload.conf', '5', ['journal-upload.conf.d'], 'HAVE_MICROHTTPD'],
+ ['journalctl', '1', [], ''],
+ ['journald.conf', '5', ['journald.conf.d'], ''],
+ ['kernel-command-line', '7', [], ''],
+ ['kernel-install', '8', [], ''],
+ ['libudev', '3', [], ''],
+ ['locale.conf', '5', [], ''],
+ ['localectl', '1', [], 'ENABLE_LOCALED'],
+ ['localtime', '5', [], ''],
+ ['loginctl', '1', [], 'ENABLE_LOGIND'],
+ ['logind.conf', '5', ['logind.conf.d'], 'ENABLE_LOGIND'],
+ ['machine-id', '5', [], ''],
+ ['machine-info', '5', [], ''],
+ ['machinectl', '1', [], 'ENABLE_MACHINED'],
+ ['modules-load.d', '5', [], 'HAVE_KMOD'],
+ ['networkctl', '1', [], 'ENABLE_NETWORKD'],
+ ['networkd.conf', '5', ['networkd.conf.d'], 'ENABLE_NETWORKD'],
+ ['nss-myhostname', '8', ['libnss_myhostname.so.2'], 'HAVE_MYHOSTNAME'],
+ ['nss-mymachines', '8', ['libnss_mymachines.so.2'], 'ENABLE_MACHINED'],
+ ['nss-resolve', '8', ['libnss_resolve.so.2'], 'ENABLE_RESOLVED'],
+ ['nss-systemd', '8', ['libnss_systemd.so.2'], 'ENABLE_NSS_SYSTEMD'],
+ ['os-release', '5', [], ''],
+ ['pam_systemd', '8', [], 'HAVE_PAM'],
+ ['resolved.conf', '5', ['resolved.conf.d'], 'ENABLE_RESOLVED'],
+ ['runlevel', '8', [], 'HAVE_UTMP'],
+ ['sd-bus-errors',
+ '3',
+ ['SD_BUS_ERROR_ACCESS_DENIED',
+ 'SD_BUS_ERROR_ADDRESS_IN_USE',
+ 'SD_BUS_ERROR_AUTH_FAILED',
+ 'SD_BUS_ERROR_BAD_ADDRESS',
+ 'SD_BUS_ERROR_DISCONNECTED',
+ 'SD_BUS_ERROR_FAILED',
+ 'SD_BUS_ERROR_FILE_EXISTS',
+ 'SD_BUS_ERROR_FILE_NOT_FOUND',
+ 'SD_BUS_ERROR_INCONSISTENT_MESSAGE',
+ 'SD_BUS_ERROR_INTERACTIVE_AUTHORIZATION_REQUIRED',
+ 'SD_BUS_ERROR_INVALID_ARGS',
+ 'SD_BUS_ERROR_INVALID_SIGNATURE',
+ 'SD_BUS_ERROR_IO_ERROR',
+ 'SD_BUS_ERROR_LIMITS_EXCEEDED',
+ 'SD_BUS_ERROR_MATCH_RULE_INVALID',
+ 'SD_BUS_ERROR_MATCH_RULE_NOT_FOUND',
+ 'SD_BUS_ERROR_NAME_HAS_NO_OWNER',
+ 'SD_BUS_ERROR_NOT_SUPPORTED',
+ 'SD_BUS_ERROR_NO_MEMORY',
+ 'SD_BUS_ERROR_NO_NETWORK',
+ 'SD_BUS_ERROR_NO_REPLY',
+ 'SD_BUS_ERROR_NO_SERVER',
+ 'SD_BUS_ERROR_PROPERTY_READ_ONLY',
+ 'SD_BUS_ERROR_SERVICE_UNKNOWN',
+ 'SD_BUS_ERROR_TIMEOUT',
+ 'SD_BUS_ERROR_UNIX_PROCESS_ID_UNKNOWN',
+ 'SD_BUS_ERROR_UNKNOWN_INTERFACE',
+ 'SD_BUS_ERROR_UNKNOWN_METHOD',
+ 'SD_BUS_ERROR_UNKNOWN_OBJECT',
+ 'SD_BUS_ERROR_UNKNOWN_PROPERTY'],
+ ''],
+ ['sd-bus', '3', [], ''],
+ ['sd-daemon',
+ '3',
+ ['SD_ALERT',
+ 'SD_CRIT',
+ 'SD_DEBUG',
+ 'SD_EMERG',
+ 'SD_ERR',
+ 'SD_INFO',
+ 'SD_NOTICE',
+ 'SD_WARNING'],
+ ''],
+ ['sd-event', '3', [], ''],
+ ['sd-id128',
+ '3',
+ ['SD_ID128_CONST_STR',
+ 'SD_ID128_FORMAT_STR',
+ 'SD_ID128_FORMAT_VAL',
+ 'SD_ID128_MAKE',
+ 'SD_ID128_MAKE_STR',
+ 'SD_ID128_NULL',
+ 'sd_id128_equal',
+ 'sd_id128_is_null',
+ 'sd_id128_t'],
+ ''],
+ ['sd-journal', '3', [], ''],
+ ['sd-login', '3', [], 'HAVE_PAM'],
+ ['sd_booted', '3', [], ''],
+ ['sd_bus_add_match', '3', [], ''],
+ ['sd_bus_creds_get_pid',
+ '3',
+ ['sd_bus_creds_get_audit_login_uid',
+ 'sd_bus_creds_get_audit_session_id',
+ 'sd_bus_creds_get_cgroup',
+ 'sd_bus_creds_get_cmdline',
+ 'sd_bus_creds_get_comm',
+ 'sd_bus_creds_get_description',
+ 'sd_bus_creds_get_egid',
+ 'sd_bus_creds_get_euid',
+ 'sd_bus_creds_get_exe',
+ 'sd_bus_creds_get_fsgid',
+ 'sd_bus_creds_get_fsuid',
+ 'sd_bus_creds_get_gid',
+ 'sd_bus_creds_get_owner_uid',
+ 'sd_bus_creds_get_ppid',
+ 'sd_bus_creds_get_selinux_context',
+ 'sd_bus_creds_get_session',
+ 'sd_bus_creds_get_sgid',
+ 'sd_bus_creds_get_slice',
+ 'sd_bus_creds_get_suid',
+ 'sd_bus_creds_get_supplementary_gids',
+ 'sd_bus_creds_get_tid',
+ 'sd_bus_creds_get_tid_comm',
+ 'sd_bus_creds_get_tty',
+ 'sd_bus_creds_get_uid',
+ 'sd_bus_creds_get_unique_name',
+ 'sd_bus_creds_get_unit',
+ 'sd_bus_creds_get_user_slice',
+ 'sd_bus_creds_get_user_unit',
+ 'sd_bus_creds_get_well_known_names',
+ 'sd_bus_creds_has_bounding_cap',
+ 'sd_bus_creds_has_effective_cap',
+ 'sd_bus_creds_has_inheritable_cap',
+ 'sd_bus_creds_has_permitted_cap'],
+ ''],
+ ['sd_bus_creds_new_from_pid',
+ '3',
+ ['sd_bus_creds_get_augmented_mask',
+ 'sd_bus_creds_get_mask',
+ 'sd_bus_creds_ref',
+ 'sd_bus_creds_unref',
+ 'sd_bus_creds_unrefp'],
+ ''],
+ ['sd_bus_default',
+ '3',
+ ['sd_bus_default_system',
+ 'sd_bus_default_user',
+ 'sd_bus_open',
+ 'sd_bus_open_system',
+ 'sd_bus_open_system_machine',
+ 'sd_bus_open_system_remote',
+ 'sd_bus_open_user'],
+ ''],
+ ['sd_bus_error',
+ '3',
+ ['SD_BUS_ERROR_MAKE_CONST',
+ 'SD_BUS_ERROR_NULL',
+ 'sd_bus_error_copy',
+ 'sd_bus_error_free',
+ 'sd_bus_error_get_errno',
+ 'sd_bus_error_has_name',
+ 'sd_bus_error_is_set',
+ 'sd_bus_error_set',
+ 'sd_bus_error_set_const',
+ 'sd_bus_error_set_errno',
+ 'sd_bus_error_set_errnof',
+ 'sd_bus_error_set_errnofv',
+ 'sd_bus_error_setf'],
+ ''],
+ ['sd_bus_error_add_map',
+ '3',
+ ['SD_BUS_ERROR_END', 'SD_BUS_ERROR_MAP', 'sd_bus_error_map'],
+ ''],
+ ['sd_bus_get_fd', '3', [], ''],
+ ['sd_bus_message_append', '3', ['sd_bus_message_appendv'], ''],
+ ['sd_bus_message_append_array',
+ '3',
+ ['sd_bus_message_append_array_iovec',
+ 'sd_bus_message_append_array_memfd',
+ 'sd_bus_message_append_array_space'],
+ ''],
+ ['sd_bus_message_append_basic', '3', [], ''],
+ ['sd_bus_message_append_string_memfd',
+ '3',
+ ['sd_bus_message_append_string_iovec', 'sd_bus_message_append_string_space'],
+ ''],
+ ['sd_bus_message_append_strv', '3', [], ''],
+ ['sd_bus_message_get_cookie', '3', ['sd_bus_message_get_reply_cookie'], ''],
+ ['sd_bus_message_get_monotonic_usec',
+ '3',
+ ['sd_bus_message_get_realtime_usec', 'sd_bus_message_get_seqnum'],
+ ''],
+ ['sd_bus_message_read_basic', '3', [], ''],
+ ['sd_bus_negotiate_fds',
+ '3',
+ ['sd_bus_negotiate_creds', 'sd_bus_negotiate_timestamp'],
+ ''],
+ ['sd_bus_new', '3', ['sd_bus_ref', 'sd_bus_unref', 'sd_bus_unrefp'], ''],
+ ['sd_bus_path_encode',
+ '3',
+ ['sd_bus_path_decode', 'sd_bus_path_decode_many', 'sd_bus_path_encode_many'],
+ ''],
+ ['sd_bus_process', '3', [], ''],
+ ['sd_bus_request_name', '3', ['sd_bus_release_name'], ''],
+ ['sd_bus_track_add_name',
+ '3',
+ ['sd_bus_track_add_sender',
+ 'sd_bus_track_contains',
+ 'sd_bus_track_count',
+ 'sd_bus_track_count_name',
+ 'sd_bus_track_count_sender',
+ 'sd_bus_track_first',
+ 'sd_bus_track_next',
+ 'sd_bus_track_remove_name',
+ 'sd_bus_track_remove_sender'],
+ ''],
+ ['sd_bus_track_new',
+ '3',
+ ['sd_bus_track_get_bus',
+ 'sd_bus_track_get_recursive',
+ 'sd_bus_track_get_userdata',
+ 'sd_bus_track_ref',
+ 'sd_bus_track_set_recursive',
+ 'sd_bus_track_set_userdata',
+ 'sd_bus_track_unref',
+ 'sd_bus_track_unrefp'],
+ ''],
+ ['sd_event_add_child',
+ '3',
+ ['sd_event_child_handler_t', 'sd_event_source_get_child_pid'],
+ ''],
+ ['sd_event_add_defer',
+ '3',
+ ['sd_event_add_exit', 'sd_event_add_post', 'sd_event_handler_t'],
+ ''],
+ ['sd_event_add_io',
+ '3',
+ ['sd_event_io_handler_t',
+ 'sd_event_source',
+ 'sd_event_source_get_io_events',
+ 'sd_event_source_get_io_fd',
+ 'sd_event_source_get_io_revents',
+ 'sd_event_source_set_io_events',
+ 'sd_event_source_set_io_fd'],
+ ''],
+ ['sd_event_add_signal',
+ '3',
+ ['sd_event_signal_handler_t', 'sd_event_source_get_signal'],
+ ''],
+ ['sd_event_add_time',
+ '3',
+ ['sd_event_source_get_time',
+ 'sd_event_source_get_time_accuracy',
+ 'sd_event_source_get_time_clock',
+ 'sd_event_source_set_time',
+ 'sd_event_source_set_time_accuracy',
+ 'sd_event_time_handler_t'],
+ ''],
+ ['sd_event_exit', '3', ['sd_event_get_exit_code'], ''],
+ ['sd_event_get_fd', '3', [], ''],
+ ['sd_event_new',
+ '3',
+ ['sd_event',
+ 'sd_event_default',
+ 'sd_event_get_tid',
+ 'sd_event_ref',
+ 'sd_event_unref',
+ 'sd_event_unrefp'],
+ ''],
+ ['sd_event_now', '3', [], ''],
+ ['sd_event_run', '3', ['sd_event_loop'], ''],
+ ['sd_event_set_watchdog', '3', ['sd_event_get_watchdog'], ''],
+ ['sd_event_source_get_event', '3', [], ''],
+ ['sd_event_source_get_pending', '3', [], ''],
+ ['sd_event_source_set_description',
+ '3',
+ ['sd_event_source_get_description'],
+ ''],
+ ['sd_event_source_set_enabled',
+ '3',
+ ['SD_EVENT_OFF',
+ 'SD_EVENT_ON',
+ 'SD_EVENT_ONESHOT',
+ 'sd_event_source_get_enabled'],
+ ''],
+ ['sd_event_source_set_prepare', '3', [], ''],
+ ['sd_event_source_set_priority',
+ '3',
+ ['SD_EVENT_PRIORITY_IDLE',
+ 'SD_EVENT_PRIORITY_IMPORTANT',
+ 'SD_EVENT_PRIORITY_NORMAL',
+ 'sd_event_source_get_priority'],
+ ''],
+ ['sd_event_source_set_userdata', '3', ['sd_event_source_get_userdata'], ''],
+ ['sd_event_source_unref',
+ '3',
+ ['sd_event_source_ref', 'sd_event_source_unrefp'],
+ ''],
+ ['sd_event_wait',
+ '3',
+ ['SD_EVENT_ARMED',
+ 'SD_EVENT_EXITING',
+ 'SD_EVENT_FINISHED',
+ 'SD_EVENT_INITIAL',
+ 'SD_EVENT_PENDING',
+ 'SD_EVENT_PREPARING',
+ 'SD_EVENT_RUNNING',
+ 'sd_event_dispatch',
+ 'sd_event_get_iteration',
+ 'sd_event_get_state',
+ 'sd_event_prepare'],
+ ''],
+ ['sd_get_seats',
+ '3',
+ ['sd_get_machine_names', 'sd_get_sessions', 'sd_get_uids'],
+ 'HAVE_PAM'],
+ ['sd_id128_get_machine',
+ '3',
+ ['sd_id128_get_boot',
+ 'sd_id128_get_invocation',
+ 'sd_id128_get_machine_app_specific'],
+ ''],
+ ['sd_id128_randomize', '3', [], ''],
+ ['sd_id128_to_string', '3', ['sd_id128_from_string'], ''],
+ ['sd_is_fifo',
+ '3',
+ ['sd_is_mq',
+ 'sd_is_socket',
+ 'sd_is_socket_inet',
+ 'sd_is_socket_sockaddr',
+ 'sd_is_socket_unix',
+ 'sd_is_special'],
+ ''],
+ ['sd_journal_add_match',
+ '3',
+ ['sd_journal_add_conjunction',
+ 'sd_journal_add_disjunction',
+ 'sd_journal_flush_matches'],
+ ''],
+ ['sd_journal_enumerate_fields',
+ '3',
+ ['SD_JOURNAL_FOREACH_FIELD', 'sd_journal_restart_fields'],
+ ''],
+ ['sd_journal_get_catalog', '3', ['sd_journal_get_catalog_for_message_id'], ''],
+ ['sd_journal_get_cursor', '3', ['sd_journal_test_cursor'], ''],
+ ['sd_journal_get_cutoff_realtime_usec',
+ '3',
+ ['sd_journal_get_cutoff_monotonic_usec'],
+ ''],
+ ['sd_journal_get_data',
+ '3',
+ ['SD_JOURNAL_FOREACH_DATA',
+ 'sd_journal_enumerate_data',
+ 'sd_journal_get_data_threshold',
+ 'sd_journal_restart_data',
+ 'sd_journal_set_data_threshold'],
+ ''],
+ ['sd_journal_get_fd',
+ '3',
+ ['SD_JOURNAL_APPEND',
+ 'SD_JOURNAL_INVALIDATE',
+ 'SD_JOURNAL_NOP',
+ 'sd_journal_get_events',
+ 'sd_journal_get_timeout',
+ 'sd_journal_process',
+ 'sd_journal_reliable_fd',
+ 'sd_journal_wait'],
+ ''],
+ ['sd_journal_get_realtime_usec', '3', ['sd_journal_get_monotonic_usec'], ''],
+ ['sd_journal_get_usage', '3', [], ''],
+ ['sd_journal_has_runtime_files', '3', ['sd_journal_has_persistent_files'], ''],
+ ['sd_journal_next',
+ '3',
+ ['SD_JOURNAL_FOREACH',
+ 'SD_JOURNAL_FOREACH_BACKWARDS',
+ 'sd_journal_next_skip',
+ 'sd_journal_previous',
+ 'sd_journal_previous_skip'],
+ ''],
+ ['sd_journal_open',
+ '3',
+ ['SD_JOURNAL_CURRENT_USER',
+ 'SD_JOURNAL_LOCAL_ONLY',
+ 'SD_JOURNAL_OS_ROOT',
+ 'SD_JOURNAL_RUNTIME_ONLY',
+ 'SD_JOURNAL_SYSTEM',
+ 'sd_journal',
+ 'sd_journal_close',
+ 'sd_journal_open_directory',
+ 'sd_journal_open_directory_fd',
+ 'sd_journal_open_files',
+ 'sd_journal_open_files_fd'],
+ ''],
+ ['sd_journal_print',
+ '3',
+ ['SD_JOURNAL_SUPPRESS_LOCATION',
+ 'sd_journal_perror',
+ 'sd_journal_printv',
+ 'sd_journal_send',
+ 'sd_journal_sendv'],
+ ''],
+ ['sd_journal_query_unique',
+ '3',
+ ['SD_JOURNAL_FOREACH_UNIQUE',
+ 'sd_journal_enumerate_unique',
+ 'sd_journal_restart_unique'],
+ ''],
+ ['sd_journal_seek_head',
+ '3',
+ ['sd_journal_seek_cursor',
+ 'sd_journal_seek_monotonic_usec',
+ 'sd_journal_seek_realtime_usec',
+ 'sd_journal_seek_tail'],
+ ''],
+ ['sd_journal_stream_fd', '3', [], ''],
+ ['sd_listen_fds',
+ '3',
+ ['SD_LISTEN_FDS_START', 'sd_listen_fds_with_names'],
+ ''],
+ ['sd_login_monitor_new',
+ '3',
+ ['sd_login_monitor',
+ 'sd_login_monitor_flush',
+ 'sd_login_monitor_get_events',
+ 'sd_login_monitor_get_fd',
+ 'sd_login_monitor_get_timeout',
+ 'sd_login_monitor_unref',
+ 'sd_login_monitor_unrefp'],
+ 'HAVE_PAM'],
+ ['sd_machine_get_class', '3', ['sd_machine_get_ifindices'], ''],
+ ['sd_notify',
+ '3',
+ ['sd_notifyf', 'sd_pid_notify', 'sd_pid_notify_with_fds', 'sd_pid_notifyf'],
+ ''],
+ ['sd_pid_get_session',
+ '3',
+ ['sd_peer_get_cgroup',
+ 'sd_peer_get_machine_name',
+ 'sd_peer_get_owner_uid',
+ 'sd_peer_get_session',
+ 'sd_peer_get_slice',
+ 'sd_peer_get_unit',
+ 'sd_peer_get_user_slice',
+ 'sd_peer_get_user_unit',
+ 'sd_pid_get_cgroup',
+ 'sd_pid_get_machine_name',
+ 'sd_pid_get_owner_uid',
+ 'sd_pid_get_slice',
+ 'sd_pid_get_unit',
+ 'sd_pid_get_user_slice',
+ 'sd_pid_get_user_unit'],
+ 'HAVE_PAM'],
+ ['sd_seat_get_active',
+ '3',
+ ['sd_seat_can_graphical',
+ 'sd_seat_can_multi_session',
+ 'sd_seat_can_tty',
+ 'sd_seat_get_sessions'],
+ 'HAVE_PAM'],
+ ['sd_session_is_active',
+ '3',
+ ['sd_session_get_class',
+ 'sd_session_get_desktop',
+ 'sd_session_get_display',
+ 'sd_session_get_remote_host',
+ 'sd_session_get_remote_user',
+ 'sd_session_get_seat',
+ 'sd_session_get_service',
+ 'sd_session_get_state',
+ 'sd_session_get_tty',
+ 'sd_session_get_type',
+ 'sd_session_get_uid',
+ 'sd_session_get_vt',
+ 'sd_session_is_remote'],
+ 'HAVE_PAM'],
+ ['sd_uid_get_state',
+ '3',
+ ['sd_uid_get_display',
+ 'sd_uid_get_seats',
+ 'sd_uid_get_sessions',
+ 'sd_uid_is_on_seat'],
+ 'HAVE_PAM'],
+ ['sd_watchdog_enabled', '3', [], ''],
+ ['shutdown', '8', [], ''],
+ ['sysctl.d', '5', [], ''],
+ ['systemctl', '1', [], ''],
+ ['systemd-analyze', '1', [], ''],
+ ['systemd-ask-password-console.service',
+ '8',
+ ['systemd-ask-password-console.path',
+ 'systemd-ask-password-wall.path',
+ 'systemd-ask-password-wall.service'],
+ ''],
+ ['systemd-ask-password', '1', [], ''],
+ ['systemd-backlight@.service', '8', ['systemd-backlight'], 'ENABLE_BACKLIGHT'],
+ ['systemd-binfmt.service', '8', ['systemd-binfmt'], 'ENABLE_BINFMT'],
+ ['systemd-cat', '1', [], ''],
+ ['systemd-cgls', '1', [], ''],
+ ['systemd-cgtop', '1', [], ''],
+ ['systemd-coredump',
+ '8',
+ ['systemd-coredump.socket', 'systemd-coredump@.service'],
+ 'ENABLE_COREDUMP'],
+ ['systemd-cryptsetup-generator', '8', [], 'HAVE_LIBCRYPTSETUP'],
+ ['systemd-cryptsetup@.service',
+ '8',
+ ['systemd-cryptsetup'],
+ 'HAVE_LIBCRYPTSETUP'],
+ ['systemd-debug-generator', '8', [], ''],
+ ['systemd-delta', '1', [], ''],
+ ['systemd-detect-virt', '1', [], ''],
+ ['systemd-environment-d-generator',
+ '8',
+ ['30-systemd-environment-d-generator'],
+ 'ENABLE_ENVIRONMENT_D'],
+ ['systemd-escape', '1', [], ''],
+ ['systemd-firstboot', '1', ['systemd-firstboot.service'], 'ENABLE_FIRSTBOOT'],
+ ['systemd-fsck@.service',
+ '8',
+ ['systemd-fsck', 'systemd-fsck-root.service'],
+ ''],
+ ['systemd-fstab-generator', '8', [], ''],
+ ['systemd-getty-generator', '8', [], ''],
+ ['systemd-gpt-auto-generator', '8', [], ''],
+ ['systemd-halt.service',
+ '8',
+ ['systemd-kexec.service',
+ 'systemd-poweroff.service',
+ 'systemd-reboot.service',
+ 'systemd-shutdown'],
+ ''],
+ ['systemd-hibernate-resume-generator', '8', [], 'ENABLE_HIBERNATE'],
+ ['systemd-hibernate-resume@.service',
+ '8',
+ ['systemd-hibernate-resume'],
+ 'ENABLE_HIBERNATE'],
+ ['systemd-hostnamed.service', '8', ['systemd-hostnamed'], 'ENABLE_HOSTNAMED'],
+ ['systemd-hwdb', '8', [], 'ENABLE_HWDB'],
+ ['systemd-importd.service', '8', ['systemd-importd'], 'ENABLE_IMPORTD'],
+ ['systemd-inhibit', '1', [], ''],
+ ['systemd-initctl.service',
+ '8',
+ ['systemd-initctl', 'systemd-initctl.socket'],
+ ''],
+ ['systemd-journal-gatewayd.service',
+ '8',
+ ['systemd-journal-gatewayd', 'systemd-journal-gatewayd.socket'],
+ 'HAVE_MICROHTTPD'],
+ ['systemd-journal-remote', '8', [], 'HAVE_MICROHTTPD'],
+ ['systemd-journal-upload', '8', [], 'HAVE_MICROHTTPD'],
+ ['systemd-journald.service',
+ '8',
+ ['systemd-journald',
+ 'systemd-journald-audit.socket',
+ 'systemd-journald-dev-log.socket',
+ 'systemd-journald.socket'],
+ ''],
+ ['systemd-localed.service', '8', ['systemd-localed'], 'ENABLE_LOCALED'],
+ ['systemd-logind.service', '8', ['systemd-logind'], 'ENABLE_LOGIND'],
+ ['systemd-machine-id-commit.service', '8', [], ''],
+ ['systemd-machine-id-setup', '1', [], ''],
+ ['systemd-machined.service', '8', ['systemd-machined'], 'ENABLE_MACHINED'],
+ ['systemd-modules-load.service', '8', ['systemd-modules-load'], 'HAVE_KMOD'],
+ ['systemd-mount', '1', ['systemd-umount'], ''],
+ ['systemd-networkd-wait-online.service',
+ '8',
+ ['systemd-networkd-wait-online'],
+ 'ENABLE_NETWORKD'],
+ ['systemd-networkd.service', '8', ['systemd-networkd'], 'ENABLE_NETWORKD'],
+ ['systemd-notify', '1', [], ''],
+ ['systemd-nspawn', '1', [], ''],
+ ['systemd-path', '1', [], ''],
+ ['systemd-quotacheck.service',
+ '8',
+ ['systemd-quotacheck'],
+ 'ENABLE_QUOTACHECK'],
+ ['systemd-random-seed.service',
+ '8',
+ ['systemd-random-seed'],
+ 'ENABLE_RANDOMSEED'],
+ ['systemd-remount-fs.service', '8', ['systemd-remount-fs'], ''],
+ ['systemd-resolve', '1', [], 'ENABLE_RESOLVED'],
+ ['systemd-resolved.service', '8', ['systemd-resolved'], 'ENABLE_RESOLVED'],
+ ['systemd-rfkill.service',
+ '8',
+ ['systemd-rfkill', 'systemd-rfkill.socket'],
+ 'ENABLE_RFKILL'],
+ ['systemd-run', '1', [], ''],
+ ['systemd-sleep.conf', '5', ['sleep.conf.d'], ''],
+ ['systemd-socket-activate', '1', [], ''],
+ ['systemd-socket-proxyd', '8', [], ''],
+ ['systemd-suspend.service',
+ '8',
+ ['systemd-hibernate.service',
+ 'systemd-hybrid-sleep.service',
+ 'systemd-sleep'],
+ ''],
+ ['systemd-sysctl.service', '8', ['systemd-sysctl'], ''],
+ ['systemd-system-update-generator', '8', [], ''],
+ ['systemd-system.conf',
+ '5',
+ ['system.conf.d', 'systemd-user.conf', 'user.conf.d'],
+ ''],
+ ['systemd-sysusers', '8', ['systemd-sysusers.service'], ''],
+ ['systemd-sysv-generator', '8', [], 'HAVE_SYSV_COMPAT'],
+ ['systemd-timedated.service', '8', ['systemd-timedated'], 'ENABLE_TIMEDATED'],
+ ['systemd-timesyncd.service', '8', ['systemd-timesyncd'], 'ENABLE_TIMESYNCD'],
+ ['systemd-tmpfiles',
+ '8',
+ ['systemd-tmpfiles-clean.service',
+ 'systemd-tmpfiles-clean.timer',
+ 'systemd-tmpfiles-setup-dev.service',
+ 'systemd-tmpfiles-setup.service'],
+ ''],
+ ['systemd-tty-ask-password-agent', '1', [], ''],
+ ['systemd-udevd.service',
+ '8',
+ ['systemd-udevd',
+ 'systemd-udevd-control.socket',
+ 'systemd-udevd-kernel.socket'],
+ ''],
+ ['systemd-update-done.service', '8', ['systemd-update-done'], ''],
+ ['systemd-update-utmp.service',
+ '8',
+ ['systemd-update-utmp', 'systemd-update-utmp-runlevel.service'],
+ 'HAVE_UTMP'],
+ ['systemd-user-sessions.service', '8', ['systemd-user-sessions'], 'HAVE_PAM'],
+ ['systemd-vconsole-setup.service',
+ '8',
+ ['systemd-vconsole-setup'],
+ 'ENABLE_VCONSOLE'],
+ ['systemd-veritysetup-generator', '8', [], 'HAVE_LIBCRYPTSETUP'],
+ ['systemd-veritysetup@.service',
+ '8',
+ ['systemd-veritysetup'],
+ 'HAVE_LIBCRYPTSETUP'],
+ ['systemd-volatile-root.service', '8', ['systemd-volatile-root'], ''],
+ ['systemd', '1', ['init'], ''],
+ ['systemd.automount', '5', [], ''],
+ ['systemd.device', '5', [], ''],
+ ['systemd.environment-generator', '7', [], 'ENABLE_ENVIRONMENT_D'],
+ ['systemd.exec', '5', [], ''],
+ ['systemd.generator', '7', [], ''],
+ ['systemd.journal-fields', '7', [], ''],
+ ['systemd.kill', '5', [], ''],
+ ['systemd.link', '5', [], ''],
+ ['systemd.mount', '5', [], ''],
+ ['systemd.netdev', '5', [], 'ENABLE_NETWORKD'],
+ ['systemd.network', '5', [], 'ENABLE_NETWORKD'],
+ ['systemd.nspawn', '5', [], ''],
+ ['systemd.offline-updates', '7', [], ''],
+ ['systemd.path', '5', [], ''],
+ ['systemd.preset', '5', [], ''],
+ ['systemd.resource-control', '5', [], ''],
+ ['systemd.scope', '5', [], ''],
+ ['systemd.service', '5', [], ''],
+ ['systemd.slice', '5', [], ''],
+ ['systemd.socket', '5', [], ''],
+ ['systemd.special', '7', [], ''],
+ ['systemd.swap', '5', [], ''],
+ ['systemd.target', '5', [], ''],
+ ['systemd.time', '7', [], ''],
+ ['systemd.timer', '5', [], ''],
+ ['systemd.unit', '5', [], ''],
+ ['sysusers.d', '5', [], 'ENABLE_SYSUSERS'],
+ ['telinit', '8', [], ''],
+ ['timedatectl', '1', [], 'ENABLE_TIMEDATED'],
+ ['timesyncd.conf', '5', ['timesyncd.conf.d'], 'ENABLE_TIMESYNCD'],
+ ['tmpfiles.d', '5', [], ''],
+ ['udev', '7', [], ''],
+ ['udev.conf', '5', [], ''],
+ ['udev_device_get_syspath',
+ '3',
+ ['udev_device_get_action',
+ 'udev_device_get_devnode',
+ 'udev_device_get_devnum',
+ 'udev_device_get_devpath',
+ 'udev_device_get_devtype',
+ 'udev_device_get_driver',
+ 'udev_device_get_is_initialized',
+ 'udev_device_get_parent',
+ 'udev_device_get_parent_with_subsystem_devtype',
+ 'udev_device_get_subsystem',
+ 'udev_device_get_sysname',
+ 'udev_device_get_sysnum',
+ 'udev_device_get_udev'],
+ ''],
+ ['udev_device_has_tag',
+ '3',
+ ['udev_device_get_devlinks_list_entry',
+ 'udev_device_get_properties_list_entry',
+ 'udev_device_get_property_value',
+ 'udev_device_get_sysattr_list_entry',
+ 'udev_device_get_sysattr_value',
+ 'udev_device_get_tags_list_entry',
+ 'udev_device_set_sysattr_value'],
+ ''],
+ ['udev_device_new_from_syspath',
+ '3',
+ ['udev_device_new_from_device_id',
+ 'udev_device_new_from_devnum',
+ 'udev_device_new_from_environment',
+ 'udev_device_new_from_subsystem_sysname',
+ 'udev_device_ref',
+ 'udev_device_unref'],
+ ''],
+ ['udev_enumerate_add_match_subsystem',
+ '3',
+ ['udev_enumerate_add_match_is_initialized',
+ 'udev_enumerate_add_match_parent',
+ 'udev_enumerate_add_match_property',
+ 'udev_enumerate_add_match_sysattr',
+ 'udev_enumerate_add_match_sysname',
+ 'udev_enumerate_add_match_tag',
+ 'udev_enumerate_add_nomatch_subsystem',
+ 'udev_enumerate_add_nomatch_sysattr'],
+ ''],
+ ['udev_enumerate_new',
+ '3',
+ ['udev_enumerate_ref', 'udev_enumerate_unref'],
+ ''],
+ ['udev_enumerate_scan_devices',
+ '3',
+ ['udev_enumerate_add_syspath',
+ 'udev_enumerate_get_list_entry',
+ 'udev_enumerate_get_udev',
+ 'udev_enumerate_scan_subsystems'],
+ ''],
+ ['udev_list_entry',
+ '3',
+ ['udev_list_entry_get_by_name',
+ 'udev_list_entry_get_name',
+ 'udev_list_entry_get_next',
+ 'udev_list_entry_get_value'],
+ ''],
+ ['udev_monitor_filter_update',
+ '3',
+ ['udev_monitor_filter_add_match_subsystem_devtype',
+ 'udev_monitor_filter_add_match_tag',
+ 'udev_monitor_filter_remove'],
+ ''],
+ ['udev_monitor_new_from_netlink',
+ '3',
+ ['udev_monitor_ref', 'udev_monitor_unref'],
+ ''],
+ ['udev_monitor_receive_device',
+ '3',
+ ['udev_monitor_enable_receiving',
+ 'udev_monitor_get_fd',
+ 'udev_monitor_get_udev',
+ 'udev_monitor_set_receive_buffer_size'],
+ ''],
+ ['udev_new', '3', ['udev_ref', 'udev_unref'], ''],
+ ['udevadm', '8', [], ''],
+ ['vconsole.conf', '5', [], 'ENABLE_VCONSOLE']
+]
+# Really, do not edit.
diff --git a/man/sd_bus_add_match.xml b/man/sd_bus_add_match.xml
index 8bcf7164a0..2014141ae3 100644
--- a/man/sd_bus_add_match.xml
+++ b/man/sd_bus_add_match.xml
@@ -73,26 +73,34 @@
<title>Description</title>
<para>
- <function>sd_bus_add_match()</function> adds a match rule used to dispatch
- incoming messages. The syntax of the rule passed in
- <parameter>match</parameter> is described in the
- <ulink url="https://dbus.freedesktop.org/doc/dbus-specification.html">D-Bus Specification</ulink>.
+ <function>sd_bus_add_match()</function> installs a match rule for incoming messages received on the specified bus
+ connection object <parameter>bus</parameter>. The syntax of the match rule expression passed in
+ <parameter>match</parameter> is described in the <ulink
+ url="https://dbus.freedesktop.org/doc/dbus-specification.html">D-Bus Specification</ulink>. The specified handler
+ function <parameter>callback</parameter> is called for eaching incoming message matching the specified
+ expression, the <parameter>userdata</parameter> parameter is passed as-is to the callback function.
</para>
<para>
- The message <parameter>m</parameter> passed to the callback is only
- borrowed, that is, the callback should not call
- <citerefentry><refentrytitle>sd_bus_message_unref</refentrytitle><manvolnum>3</manvolnum></citerefentry>
- on it. If the callback wants to hold on to the message beyond the lifetime
- of the callback, it needs to call
- <citerefentry><refentrytitle>sd_bus_message_ref</refentrytitle><manvolnum>3</manvolnum></citerefentry>
- to create a new reference.
+ On success, and if non-<constant>NULL</constant>, the <parameter>slot</parameter> return parameter will be set to
+ a slot object that may be used as a reference to the installed match, and may be utilized to remove it again at a
+ later time with
+ <citerefentry><refentrytitle>sd_bus_slot_unref</refentrytitle><manvolnum>3</manvolnum></citerefentry>. If
+ specified as <constant>NULL</constant> the lifetime of the match is bound to the lifetime of the bus object itself, and the match
+ cannot be removed independently.
</para>
<para>
- If an error occurs during the callback invocation, the callback should
- return a negative error number. If it wants other callbacks that match the
- same rule to be called, it should return 0. Otherwise it should return a
+ The message <parameter>m</parameter> passed to the callback is only borrowed, that is, the callback should not
+ call <citerefentry><refentrytitle>sd_bus_message_unref</refentrytitle><manvolnum>3</manvolnum></citerefentry> on
+ it. If the callback wants to hold on to the message beyond the lifetime of the callback, it needs to call
+ <citerefentry><refentrytitle>sd_bus_message_ref</refentrytitle><manvolnum>3</manvolnum></citerefentry> to create
+ a new reference.
+ </para>
+
+ <para>
+ If an error occurs during the callback invocation, the callback should return a negative error number. If it
+ wants other callbacks that match the same rule to be called, it should return 0. Otherwise it should return a
positive integer.
</para>
</refsect1>
@@ -101,9 +109,8 @@
<title>Return Value</title>
<para>
- On success, <function>sd_bus_add_match()</function> returns 0 or a
- positive integer. On failure, it returns a negative errno-style error
- code.
+ On success, <function>sd_bus_add_match()</function> returns 0 or a positive integer. On failure, it returns a
+ negative errno-style error code.
</para>
</refsect1>
@@ -112,7 +119,7 @@
<para>
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>sd-bus</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>sd-bus</refentrytitle><manvolnum>3</manvolnum></citerefentry>
</para>
</refsect1>
diff --git a/man/sd_bus_error.xml b/man/sd_bus_error.xml
index 3091e1f019..4970ce3c08 100644
--- a/man/sd_bus_error.xml
+++ b/man/sd_bus_error.xml
@@ -265,7 +265,7 @@
<parameter>dst</parameter> using the values in
<parameter>e</parameter>. If the strings in
<parameter>e</parameter> were set using
- <function>sd_bus_set_error_const()</function>, they will be shared.
+ <function>sd_bus_error_set_const()</function>, they will be shared.
Otherwise, they will be copied. Returns a converted
<varname>errno</varname>-like, negative error code.</para>
diff --git a/man/sd_bus_message_append.xml b/man/sd_bus_message_append.xml
index 132ce66434..2c28ee7154 100644
--- a/man/sd_bus_message_append.xml
+++ b/man/sd_bus_message_append.xml
@@ -45,6 +45,7 @@
<refnamediv>
<refname>sd_bus_message_append</refname>
+ <refname>sd_bus_message_appendv</refname>
<refpurpose>Attach fields to a D-Bus message based on a type
string</refpurpose>
@@ -60,6 +61,14 @@
<paramdef>const char *<parameter>types</parameter></paramdef>
<paramdef>…</paramdef>
</funcprototype>
+
+ <funcprototype>
+ <funcdef>int sd_bus_message_appendv</funcdef>
+ <paramdef>sd_bus_message *<parameter>m</parameter></paramdef>
+ <paramdef>const char *<parameter>types</parameter></paramdef>
+ <paramdef>va_list <parameter>ap</parameter></paramdef>
+ </funcprototype>
+
</funcsynopsis>
</refsynopsisdiv>
@@ -109,6 +118,14 @@
values for each entry matching the element type of
the dictionary entries.</para>
+ <para>The <function>sd_bus_message_appendv()</function> is equivalent to
+ the function <function>sd_bus_message_append()</function>,
+ except that it is called with a <literal>va_list</literal> instead of
+ a variable number of arguments. This function does not call the
+ <function>va_end()</function> macro. Because it invokes the
+ <function>va_arg()</function> macro, the value of ap
+ is undefined after the call.</para>
+
<para>For further details on the D-Bus type system, please consult
the <ulink
url="http://dbus.freedesktop.org/doc/dbus-specification.html#type-system">D-Bus
@@ -238,8 +255,8 @@ sd_bus_message_append(m, "ynqiuxtd", y, n, q, i, u, x, t, d);</programlisting>
<refsect1>
<title>Return Value</title>
- <para>On success, this call returns 0 or a positive
- integer. On failure, this call returns a negative
+ <para>On success, these functions return 0 or a positive
+ integer. On failure, these functions return a negative
errno-style error code.</para>
</refsect1>
diff --git a/man/sd_get_seats.xml b/man/sd_get_seats.xml
index 37eb3fc894..c053144483 100644
--- a/man/sd_get_seats.xml
+++ b/man/sd_get_seats.xml
@@ -81,8 +81,10 @@
<title>Description</title>
<para><function>sd_get_seats()</function> may be used to determine
- all currently available local seats. Returns a
- <constant>NULL</constant> terminated array of seat identifiers.
+ all currently available local seats. Returns the number of seat
+ identifiers and if the input pointer is non-NULL, a
+ <constant>NULL</constant>-terminated array of seat identifiers
+ is stored at the address.
The returned array and all strings it references need to be freed
with the libc
<citerefentry project='man-pages'><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
@@ -124,13 +126,6 @@
<variablelist>
<varlistentry>
- <term><constant>-EINVAL</constant></term>
-
- <listitem><para>An input parameter was invalid (out of range,
- or NULL, where that is not accepted).</para></listitem>
- </varlistentry>
-
- <varlistentry>
<term><constant>-ENOMEM</constant></term>
<listitem><para>Memory allocation failed.</para></listitem>
diff --git a/man/sd_id128_randomize.xml b/man/sd_id128_randomize.xml
index ab449d2937..852a9fd7eb 100644
--- a/man/sd_id128_randomize.xml
+++ b/man/sd_id128_randomize.xml
@@ -77,7 +77,7 @@
<citerefentry><refentrytitle>sd-id128</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para>
<para><citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s
- <option>--new-id</option> option may be used as a command line
+ <option>--new-id128</option> option may be used as a command line
front-end for <function>sd_id128_randomize()</function>.</para>
</refsect1>
diff --git a/man/sd_journal_get_catalog.xml b/man/sd_journal_get_catalog.xml
index 604deb4e8c..92ed0dea06 100644
--- a/man/sd_journal_get_catalog.xml
+++ b/man/sd_journal_get_catalog.xml
@@ -114,7 +114,7 @@
<para>Function <function>sd_journal_get_catalog()</function> is thread-agnostic and only a
single thread may operate on a given <structname>sd_journal</structname> object. Function
- <function>sd_journal_get_catalog_for_message_id() is thread-safe.</function></para>
+ <function>sd_journal_get_catalog_for_message_id()</function> is thread-safe.</para>
<para>The <function>sd_journal_get_catalog()</function> and
<function>sd_journal_get_catalog_for_message_id()</function>
diff --git a/man/sd_notify.xml b/man/sd_notify.xml
index 4dcefc4baf..e8ddea2f5f 100644
--- a/man/sd_notify.xml
+++ b/man/sd_notify.xml
@@ -205,25 +205,24 @@
<varlistentry>
<term>FDSTORE=1</term>
- <listitem><para>Stores additional file descriptors in the service manager. File
- descriptors sent this way will be maintained per-service by the service manager
- and will be passed again using the usual file descriptor passing logic on the next
- invocation of the service, see
- <citerefentry><refentrytitle>sd_listen_fds</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
- This is useful for implementing service restart schemes where services serialize
- their state to <filename>/run</filename>, push their file descriptors to the
- system manager, and are then restarted, retrieving their state again via socket
- passing and <filename>/run</filename>. Note that the service manager will accept
- messages for a service only if <varname>FileDescriptorStoreMax=</varname> is set
- to non-zero for it (defaults to zero, see
- <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>).
- File descriptors must be pollable, see
- <citerefentry><refentrytitle>epoll_ctl</refentrytitle><manvolnum>2</manvolnum></citerefentry>.
- Multiple arrays of file descriptors may be sent in separate messages, in which
- case the arrays are combined. Note that the service manager removes duplicate
- file descriptors before passing them to the service. Use
- <function>sd_pid_notify_with_fds()</function> to send messages with
- <literal>FDSTORE=1</literal>, see below.</para></listitem>
+ <listitem><para>Stores additional file descriptors in the service manager. File descriptors sent this way will
+ be maintained per-service by the service manager and will later be handed back using the usual file descriptor
+ passing logic at the next invocation of the service, see
+ <citerefentry><refentrytitle>sd_listen_fds</refentrytitle><manvolnum>3</manvolnum></citerefentry>. This is
+ useful for implementing services that can restart after an explicit request or a crash without losing
+ state. Any open sockets and other file descriptors which should not be closed during the restart may be stored
+ this way. Application state can either be serialized to a file in <filename>/run</filename>, or better, stored
+ in a <citerefentry><refentrytitle>memfd_create</refentrytitle><manvolnum>2</manvolnum></citerefentry> memory
+ file descriptor. Note that the service manager will accept messages for a service only if its
+ <varname>FileDescriptorStoreMax=</varname> setting is non-zero (defaults to zero, see
+ <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>). If file
+ descriptors sent are pollable (see
+ <citerefentry><refentrytitle>epoll_ctl</refentrytitle><manvolnum>2</manvolnum></citerefentry>), then any
+ <constant>EPOLLHUP</constant> or <constant>EPOLLERR</constant> event seen on them will result in their
+ automatic removal from the store. Multiple arrays of file descriptors may be sent in separate messages, in
+ which case the arrays are combined. Note that the service manager removes duplicate (pointing to the same
+ object) file descriptors before passing them to the service. Use <function>sd_pid_notify_with_fds()</function>
+ to send messages with <literal>FDSTORE=1</literal>, see below.</para></listitem>
</varlistentry>
<varlistentry>
@@ -312,13 +311,14 @@
<refsect1>
<title>Return Value</title>
- <para>On failure, these calls return a negative errno-style error
- code. If <varname>$NOTIFY_SOCKET</varname> was not set and hence
- no status data could be sent, 0 is returned. If the status was
- sent, these functions return with a positive return value. In
- order to support both, init systems that implement this scheme and
- those which do not, it is generally recommended to ignore the
- return value of this call.</para>
+ <para>On failure, these calls return a negative errno-style error code. If <varname>$NOTIFY_SOCKET</varname> was
+ not set and hence no status message could be sent, 0 is returned. If the status was sent, these functions return a
+ positive value. In order to support both service managers that implement this scheme and those which do not, it is
+ generally recommended to ignore the return value of this call. Note that the return value simply indicates whether
+ the notification message was enqueued properly, it does not reflect whether the message could be processed
+ successfully. Specifically, no error is returned when a file descriptor is attempted to be stored using
+ <varname>FDSTORE=1</varname> but the service is not actually configured to permit storing of file descriptors (see
+ above).</para>
</refsect1>
<refsect1>
diff --git a/man/sd_pid_get_session.xml b/man/sd_pid_get_session.xml
index 806cff34e4..14ebd53e36 100644
--- a/man/sd_pid_get_session.xml
+++ b/man/sd_pid_get_session.xml
@@ -177,7 +177,7 @@
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
- -ENODATA. The returned string needs to be freed with the libc
+ <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>
@@ -189,7 +189,7 @@
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 -ENODATA. (More specifically, this call will not
+ 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>
@@ -208,7 +208,7 @@
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 -ENODATA.</para>
+ 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
@@ -217,7 +217,7 @@
<citerefentry
project='man-pages'><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
call after use. For processes not part of a VM or containers, this
- function fails with -ENODATA.</para>
+ function fails with <constant>-ENODATA</constant>.</para>
<para><function>sd_pid_get_slice()</function> may be used to
determine the slice unit the process is a member of. See
@@ -285,7 +285,7 @@
</varlistentry>
<varlistentry>
- <term><constant>-BADF</constant></term>
+ <term><constant>-EBADF</constant></term>
<listitem><para>The specified socket file descriptor was
invalid.</para></listitem>
diff --git a/man/sd_seat_get_active.xml b/man/sd_seat_get_active.xml
index c5e6ddab02..3dd461f83f 100644
--- a/man/sd_seat_get_active.xml
+++ b/man/sd_seat_get_active.xml
@@ -105,8 +105,9 @@
one (<constant>NULL</constant> terminated) with the session
identifiers of the sessions and one with the user identifiers of
the Unix users the sessions belong to. An additional parameter may
- be used to return the number of entries in the latter array. The
- two arrays and the latter parameter may be passed as
+ be used to return the number of entries in the latter array. This
+ value is the same the return value, if the latter is nonnegative.
+ The two arrays and the last parameter may be passed as
<constant>NULL</constant> in case these values need not to be
determined. The arrays and the strings referenced by them need to
be freed with the libc
diff --git a/man/sd_session_is_active.xml b/man/sd_session_is_active.xml
index a6076b177a..f95e74ead6 100644
--- a/man/sd_session_is_active.xml
+++ b/man/sd_session_is_active.xml
@@ -184,8 +184,9 @@
<para><function>sd_session_get_seat()</function> may be used to
determine the seat identifier of the seat the session identified
by the specified session identifier belongs to. Note that not all
- sessions are attached to a seat, this call will fail for them. The
- returned string needs to be freed with the libc
+ sessions are attached to a seat, this call will fail (returning
+ <constant>-ENODATA</constant>) for them. 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>
diff --git a/man/systemctl.xml b/man/systemctl.xml
index 7e1864c4f1..14405141cf 100644
--- a/man/systemctl.xml
+++ b/man/systemctl.xml
@@ -907,7 +907,7 @@ Sun 2017-02-26 20:57:49 EST 2h 3min left Sun 2017-02-26 11:56:36 EST 6h ago
<programlisting>$ systemctl status bluetooth
● bluetooth.service - Bluetooth service
- Loaded: loaded (/lib/systemd/system/bluetooth.service; enabled; vendor preset: enabled)
+ Loaded: loaded (/usr/lib/systemd/system/bluetooth.service; enabled; vendor preset: enabled)
Active: active (running) since Wed 2017-01-04 13:54:04 EST; 1 weeks 0 days ago
Docs: man:bluetoothd(8)
Main PID: 930 (bluetoothd)
@@ -1495,11 +1495,26 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
<term><command>show-environment</command></term>
<listitem>
- <para>Dump the systemd manager environment block. The
- environment block will be dumped in straight-forward form
- suitable for sourcing into a shell script. This environment
- block will be passed to all processes the manager
- spawns.</para>
+ <para>Dump the systemd manager environment block. This is the environment
+ block that is passed to all processes the manager spawns. The environment
+ block will be dumped in straight-forward form suitable for sourcing into
+ most shells. If no special characters or whitespace is present in the variable
+ values, no escaping is performed, and the assignments have the form
+ <literal>VARIABLE=value</literal>. If whitespace or characters which have
+ special meaning to the shell are present, dollar-single-quote escaping is
+ used, and assignments have the form <literal>VARIABLE=$'value'</literal>.
+ This syntax is known to be supported by
+ <citerefentry project='die-net'><refentrytitle>bash</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+ <citerefentry project='die-net'><refentrytitle>zsh</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+ <citerefentry project='die-net'><refentrytitle>ksh</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+ and
+ <citerefentry project='die-net'><refentrytitle>busybox</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s
+ <citerefentry project='die-net'><refentrytitle>ash</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+ but not
+ <citerefentry project='die-net'><refentrytitle>dash</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+ or
+ <citerefentry project='die-net'><refentrytitle>fish</refentrytitle><manvolnum>1</manvolnum></citerefentry>.
+ </para>
</listitem>
</varlistentry>
<varlistentry>
diff --git a/man/systemd-ask-password.xml b/man/systemd-ask-password.xml
index 51d8ef5d82..16ec257014 100644
--- a/man/systemd-ask-password.xml
+++ b/man/systemd-ask-password.xml
@@ -230,7 +230,7 @@
<para>
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd-ask-password-console.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>systemd-tty-ask-password</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>systemd-tty-ask-password-agent</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry project='die-net'><refentrytitle>keyctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry project='die-net'><refentrytitle>plymouth</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry project='man-pages'><refentrytitle>wall</refentrytitle><manvolnum>1</manvolnum></citerefentry>
diff --git a/man/systemd-coredump.xml b/man/systemd-coredump.xml
index 2c285bcb22..d71fdc644f 100644
--- a/man/systemd-coredump.xml
+++ b/man/systemd-coredump.xml
@@ -123,7 +123,7 @@
<para>In order to by used in the <option>--backtrace</option> mode, an appropriate backtrace
handler must be installed on the sender side. For example, in case of
- <citerefentry><refentrytitle>python</refentrytitle><manvolnum>1</manvolnum></citerefentry>, this
+ <citerefentry project='die-net'><refentrytitle>python</refentrytitle><manvolnum>1</manvolnum></citerefentry>, this
means a <varname>sys.excepthook</varname> must installed, see
<ulink url="https://github.com/keszybz/systemd-coredump-python">systemd-coredump-python</ulink>.
</para>
diff --git a/man/systemd-delta.xml b/man/systemd-delta.xml
index 6628213209..be241f6950 100644
--- a/man/systemd-delta.xml
+++ b/man/systemd-delta.xml
@@ -63,7 +63,7 @@
compare configuration files that override other configuration
files. Files in <filename>/etc</filename> have highest priority,
files in <filename>/run</filename> have the second highest
- priority, …, files in <filename>/lib</filename> have lowest
+ priority, …, files in <filename>/usr/lib</filename> have lowest
priority. Files in a directory with higher priority override files
with the same name in directories of lower priority. In addition,
certain configuration files can have <literal>.d</literal>
diff --git a/man/systemd-environment-d-generator.xml b/man/systemd-environment-d-generator.xml
index cc00a5256d..7950aa98a5 100644
--- a/man/systemd-environment-d-generator.xml
+++ b/man/systemd-environment-d-generator.xml
@@ -23,7 +23,7 @@
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-environment-d-generator">
+<refentry id="systemd-environment-d-generator" conditional='ENABLE_ENVIRONMENT_D'>
<refentryinfo>
<title>systemd-environment-d-generator</title>
diff --git a/man/systemd-fstab-generator.xml b/man/systemd-fstab-generator.xml
index 50d24d67f0..b898d719f2 100644
--- a/man/systemd-fstab-generator.xml
+++ b/man/systemd-fstab-generator.xml
@@ -71,6 +71,14 @@
for more information about special <filename>/etc/fstab</filename>
mount options this generator understands.</para>
+ <para>One special topic is handling of symbolic links. Historical init
+ implementations supported symlinks in <filename>/etc/fstab</filename>.
+ Because mount units will refuse mounts where the target is a symbolic link,
+ this generator will resolve any symlinks as far as possible when processing
+ <filename>/etc/fstab</filename> in order to enhance backwards compatibility.
+ If a symlink target does not exist at the time that this generator runs, it
+ is assumed that the symlink target is the final target of the mount.</para>
+
<para><filename>systemd-fstab-generator</filename> implements
<citerefentry><refentrytitle>systemd.generator</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
</refsect1>
diff --git a/man/systemd-hibernate-resume-generator.xml b/man/systemd-hibernate-resume-generator.xml
index d811b9b551..3bbb6ab989 100644
--- a/man/systemd-hibernate-resume-generator.xml
+++ b/man/systemd-hibernate-resume-generator.xml
@@ -19,7 +19,7 @@
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-hibernate-resume-generator">
+<refentry id="systemd-hibernate-resume-generator" conditional='ENABLE_HIBERNATE'>
<refentryinfo>
<title>systemd-hibernate-resume-generator</title>
diff --git a/man/systemd-hibernate-resume@.service.xml b/man/systemd-hibernate-resume@.service.xml
index 7d00827447..a968adf0a9 100644
--- a/man/systemd-hibernate-resume@.service.xml
+++ b/man/systemd-hibernate-resume@.service.xml
@@ -19,7 +19,7 @@
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-hibernate-resume@.service">
+<refentry id="systemd-hibernate-resume@.service" conditional='ENABLE_HIBERNATE'>
<refentryinfo>
<title>systemd-hibernate-resume@.service</title>
diff --git a/man/systemd-mount.xml b/man/systemd-mount.xml
index 8bba286787..63e4fc40f1 100644
--- a/man/systemd-mount.xml
+++ b/man/systemd-mount.xml
@@ -62,9 +62,10 @@
<arg choice="plain"><option>--list</option></arg>
</cmdsynopsis>
<cmdsynopsis>
- <command>systemd-umount</command>
+ <command>systemd-mount</command>
<arg choice="opt" rep="repeat"><replaceable>OPTIONS</replaceable></arg>
- <arg choice="plain" rep="repeat"><replaceable>WHERE</replaceable></arg>
+ <arg choice="plain"><option>--umount</option></arg>
+ <arg choice="plain" rep="repeat"><replaceable>WHAT|WHERE</replaceable></arg>
</cmdsynopsis>
</refsynopsisdiv>
@@ -76,13 +77,14 @@
<replaceable>WHERE</replaceable>.</para>
<para>In many ways, <command>systemd-mount</command> is similar to the lower-level
- <citerefentry><refentrytitle>mount</refentrytitle><manvolnum>8</manvolnum></citerefentry> command, however instead
+ <citerefentry project='man-pages'><refentrytitle>mount</refentrytitle><manvolnum>8</manvolnum></citerefentry> command, however instead
of executing the mount operation directly and immediately, <command>systemd-mount</command> schedules it through
the service manager job queue, so that it may pull in further dependencies (such as parent mounts, or a file system
checker to execute a priori), and may make use of the auto-mounting logic.</para>
<para>The command takes either one or two arguments. If only one argument is specified it should refer to a block
- device containing a file system (e.g. <literal>/dev/sdb1</literal>), which is then probed for a label and other
+ device or regular file containing a file system (e.g. <literal>/dev/sdb1</literal> or
+ <literal>/path/to/disk.img</literal>). If it is a block device, which is then probed for a label and other
metadata, and is mounted to a directory whose name is generated from the label. In this mode the block device must
exist at the time of invocation of the command, so that it may be probed. If the device is found to be a removable
block device (e.g. a USB stick) an automount point instead of a regular mount point is created (i.e. the
@@ -253,8 +255,13 @@
<term><option>--umount</option></term>
<listitem><para>Stop the mount and automount units corresponding to the specified mount points
- <replaceable>WHERE</replaceable>.</para>
- </listitem>
+ <replaceable>WHERE</replaceable> or the devices <replaceable>WHAT</replaceable>.
+ <command>systemd-mount</command> with this option or <command>systemd-umount</command> can take multiple arguments
+ which can be mount points, devices, <filename>/etc/fstab</filename> style node names, or backing files
+ corresponding to loop devices, like
+ <command>systemd-mount --umount /path/to/umount /dev/sda1 UUID=xxxxxx-xxxx LABEL=xxxxx /path/to/disk.img</command>.
+ Note that when <option>-H</option> or <option>-M</option> is specified, only absolute paths to mount points are
+ supported.</para></listitem>
</varlistentry>
<xi:include href="user-system-options.xml" xpointer="user" />
@@ -301,7 +308,7 @@
<title>See Also</title>
<para>
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>mount</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+ <citerefentry project='man-pages'><refentrytitle>mount</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd.mount</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
diff --git a/man/systemd-nspawn.xml b/man/systemd-nspawn.xml
index ef80d90ba4..973e2148d6 100644
--- a/man/systemd-nspawn.xml
+++ b/man/systemd-nspawn.xml
@@ -398,24 +398,19 @@
<varlistentry>
<term><option>--slice=</option></term>
- <listitem><para>Make the container part of the specified
- slice, instead of the default
- <filename>machine.slice</filename>. This is only applies if
- the machine is run in its own scope unit, i.e. if
- <option>--keep-unit</option> is not used.</para>
+ <listitem><para>Make the container part of the specified slice, instead of the default
+ <filename>machine.slice</filename>. This applies only if the machine is run in its own scope unit, i.e. if
+ <option>--keep-unit</option> isn't used.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--property=</option></term>
- <listitem><para>Set a unit property on the scope unit to
- register for the machine. This only applies if the machine is
- run in its own scope unit, i.e. if
- <option>--keep-unit</option> is not used. Takes unit property
- assignments in the same format as <command>systemctl
- set-property</command>. This is useful to set memory limits
- and similar for machines.</para>
+ <listitem><para>Set a unit property on the scope unit to register for the machine. This applies only if the
+ machine is run in its own scope unit, i.e. if <option>--keep-unit</option> isn't used. Takes unit property
+ assignments in the same format as <command>systemctl set-property</command>. This is useful to set memory
+ limits and similar for container.</para>
</listitem>
</varlistentry>
@@ -888,18 +883,16 @@
<varlistentry>
<term><option>--register=</option></term>
- <listitem><para>Controls whether the container is registered
- with
- <citerefentry><refentrytitle>systemd-machined</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
- Takes a boolean argument, which defaults to <literal>yes</literal>.
- This option should be enabled when the container runs a full
- Operating System (more specifically: an init system), and is
- useful to ensure that the container is accessible via
- <citerefentry><refentrytitle>machinectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
- and shown by tools such as
- <citerefentry project='man-pages'><refentrytitle>ps</refentrytitle><manvolnum>1</manvolnum></citerefentry>.
- If the container does not run an init system, it is
- recommended to set this option to <literal>no</literal>.</para></listitem>
+ <listitem><para>Controls whether the container is registered with
+ <citerefentry><refentrytitle>systemd-machined</refentrytitle><manvolnum>8</manvolnum></citerefentry>. Takes a
+ boolean argument, which defaults to <literal>yes</literal>. This option should be enabled when the container
+ runs a full Operating System (more specifically: a system and service manager as PID 1), and is useful to
+ ensure that the container is accessible via
+ <citerefentry><refentrytitle>machinectl</refentrytitle><manvolnum>1</manvolnum></citerefentry> and shown by
+ tools such as <citerefentry
+ project='man-pages'><refentrytitle>ps</refentrytitle><manvolnum>1</manvolnum></citerefentry>. If the container
+ does not run a service manager, it is recommended to set this option to
+ <literal>no</literal>.</para></listitem>
</varlistentry>
<varlistentry>
@@ -916,7 +909,9 @@
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>
+ session.</para>
+ <para>Note that passing <option>--keep-unit</option> disables the effect of <option>--slice=</option> and
+ <option>--property=</option>.</para></listitem>
</varlistentry>
<varlistentry>
@@ -1098,6 +1093,18 @@
</example>
<example>
+ <title>Install the OpenSUSE Tumbleweed rolling distribution</title>
+
+ <programlisting># zypper --root=/var/lib/machines/tumbleweed ar -c \
+ https://download.opensuse.org/tumbleweed/repo/oss tumbleweed
+# zypper --root=/var/lib/machines/tumbleweed refresh
+# zypper --root=/var/lib/machines/tumbleweed install --no-recommends \
+ systemd shadow zypper openSUSE-release vim
+# systemd-nspawn -M tumbleweed passwd root
+# systemd-nspawn -M tumbleweed -b</programlisting>
+ </example>
+
+ <example>
<title>Boot into an ephemeral snapshot of the host system</title>
<programlisting># systemd-nspawn -D / -xb</programlisting>
@@ -1139,6 +1146,7 @@
<citerefentry project='mankier'><refentrytitle>dnf</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry project='die-net'><refentrytitle>debootstrap</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry project='archlinux'><refentrytitle>pacman</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+ <citerefentry project='mankier'><refentrytitle>zypper</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd.slice</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry><refentrytitle>machinectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry project='man-pages'><refentrytitle>btrfs</refentrytitle><manvolnum>8</manvolnum></citerefentry>
diff --git a/man/systemd-resolve.xml b/man/systemd-resolve.xml
index 50da971b07..e3ef26bb81 100644
--- a/man/systemd-resolve.xml
+++ b/man/systemd-resolve.xml
@@ -21,7 +21,7 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
-->
-<refentry id="systemd-resolve"
+<refentry id="systemd-resolve" conditional='ENABLE_RESOLVED'
xmlns:xi="http://www.w3.org/2001/XInclude">
<refentryinfo>
diff --git a/man/systemd-vconsole-setup.service.xml b/man/systemd-vconsole-setup.service.xml
index f2da2a7b77..6df82aed32 100644
--- a/man/systemd-vconsole-setup.service.xml
+++ b/man/systemd-vconsole-setup.service.xml
@@ -59,7 +59,7 @@
<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><command>udev</command></citerefentry> during vtconsole subsystem initialization.
+ 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
diff --git a/man/systemd.environment-generator.xml b/man/systemd.environment-generator.xml
index fedbd60175..ff8be92833 100644
--- a/man/systemd.environment-generator.xml
+++ b/man/systemd.environment-generator.xml
@@ -24,7 +24,8 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
-->
-<refentry id="systemd.environment-generator" xmlns:xi="http://www.w3.org/2001/XInclude">
+<refentry id="systemd.environment-generator" conditional='ENABLE_ENVIRONMENT_D'
+ xmlns:xi="http://www.w3.org/2001/XInclude">
<refentryinfo>
<title>systemd.environment-generator</title>
<productname>systemd</productname>
diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml
index 9a9387b798..d28de2d0f2 100644
--- a/man/systemd.exec.xml
+++ b/man/systemd.exec.xml
@@ -165,13 +165,28 @@
<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 numeric ID as argument. For system services (services run by the system service manager,
+ 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
is set, the default group of the user is used. This setting does not affect commands whose command line is
- prefixed with <literal>+</literal>.</para></listitem>
+ prefixed with <literal>+</literal>.</para>
+
+ <para>Note that restrictions on the user/group name syntax are enforced: the specified name must consist only
+ of the characters a-z, A-Z, 0-9, <literal>_</literal> and <literal>-</literal>, except for the first character
+ which must be one of a-z, A-Z or <literal>_</literal> (i.e. numbers and <literal>-</literal> are not permitted
+ as first character). The user/group name must have at least one character, and at most 31. These restrictions
+ are enforced in order to avoid ambiguities and to ensure user/group names and unit files remain portable among
+ Linux systems.</para>
+
+ <para>When used in conjunction with <varname>DynamicUser=</varname> the user/group name specified is
+ dynamically allocated at the time the service is started, and released at the time the service is stopped —
+ unless it is already allocated statically (see below). If <varname>DynamicUser=</varname> is not used the
+ specified user and group must have been created statically in the user database no later than the moment the
+ service is started, for example using the
+ <citerefentry><refentrytitle>sysusers.d</refentrytitle><manvolnum>5</manvolnum></citerefentry> facility, which
+ is applied at boot or package install time.</para></listitem>
</varlistentry>
<varlistentry>
@@ -352,7 +367,7 @@
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 to a variable, use double
+ to assign a value containing spaces or the equals sign to a variable, use double
quotes (") for the assignment.</para>
<para>Example:
@@ -1038,14 +1053,19 @@
<varname>After=</varname> dependencies on all mount units necessary to access <filename>/tmp</filename> and
<filename>/var/tmp</filename>. Moreover an implicitly <varname>After=</varname> ordering on
<citerefentry><refentrytitle>systemd-tmpfiles-setup.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
- is added.</para></listitem>
+ 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
+ security.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>PrivateDevices=</varname></term>
- <listitem><para>Takes a boolean argument. If true, sets up a new /dev namespace for the executed processes and
- only adds API pseudo devices such as <filename>/dev/null</filename>, <filename>/dev/zero</filename> or
+ <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
@@ -1056,8 +1076,8 @@
<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 /dev namespace will be
- mounted read-only and 'noexec'. The latter may break old programs which try to set up executable memory by
+ 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>. This setting is implied if
<varname>DynamicUser=</varname> is set. For this setting the same restrictions regarding mount propagation and
@@ -1065,7 +1085,11 @@
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>
+ </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
+ security.</para></listitem>
</varlistentry>
<varlistentry>
@@ -1076,7 +1100,7 @@
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
- securely turn off network access by the executed process.
+ 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
@@ -1086,7 +1110,11 @@
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></listitem>
+ 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>
<varlistentry>
@@ -1108,7 +1136,11 @@
<para>This setting is particularly useful in conjunction with
<varname>RootDirectory=</varname>/<varname>RootImage=</varname>, as the need to synchronize the user and group
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></listitem>
+ 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
+ security.</para></listitem>
</varlistentry>
<varlistentry>
@@ -1580,7 +1612,7 @@
<listitem><para>Restricts access to Linux namespace functionality for the processes of this unit. For details
about Linux namespaces, see
- <citerefentry><refentrytitle>namespaces</refentrytitle><manvolnum>7</manvolnum></citerefentry>. Either takes a
+ <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
@@ -1597,7 +1629,8 @@
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, s390 and s390x, and enforces no restrictions on other architectures. If running in user
+ 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>
@@ -1620,7 +1653,6 @@
<varlistentry>
<term><varname>RuntimeDirectory=</varname></term>
- <term><varname>RuntimeDirectoryMode=</varname></term>
<listitem><para>Takes a list of directory names. If set, one
or more directories by the specified names will be created
@@ -1645,6 +1677,16 @@
</varlistentry>
<varlistentry>
+ <term><varname>RuntimeDirectoryMode=</varname></term>
+
+ <listitem><para>Specifies the access mode of the directories specified in
+ <varname>RuntimeDirectory=</varname> 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>MemoryDenyWriteExecute=</varname></term>
<listitem><para>Takes a boolean argument. If set, attempts to create memory mappings that are writable and
diff --git a/man/systemd.journal-fields.xml b/man/systemd.journal-fields.xml
index 747d985aa1..b82c1300ca 100644
--- a/man/systemd.journal-fields.xml
+++ b/man/systemd.journal-fields.xml
@@ -87,7 +87,7 @@
recommended to be a UUID-compatible ID, but this is not
enforced, and formatted differently. Developers can generate
a new ID for this purpose with <command>journalctl
- <option>--new-id</option></command>.
+ <option>--new-id128</option></command>.
</para>
</listitem>
</varlistentry>
@@ -156,7 +156,9 @@
<listitem>
<para>The process, user, and group ID of the process the
journal entry originates from formatted as a decimal
- string.</para>
+ string. Note that entries obtained via <literal>stdout</literal> or
+ <literal>stderr</literal> of forked processes will contain credentials valid for a parent
+ process (that initiated the connection to <command>systemd-journald</command>).</para>
</listitem>
</varlistentry>
diff --git a/man/systemd.link.xml b/man/systemd.link.xml
index 023e24eeb3..1e4a1528db 100644
--- a/man/systemd.link.xml
+++ b/man/systemd.link.xml
@@ -402,6 +402,47 @@
</listitem>
</varlistentry>
<varlistentry>
+ <term><varname>Port=</varname></term>
+ <listitem>
+ <para>The port option is used to select the device port. The
+ supported values are:</para>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>tp</literal></term>
+ <listitem>
+ <para>An Ethernet interface using Twisted-Pair cable as the medium.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>aui</literal></term>
+ <listitem>
+ <para>Attachment Unit Interface (AUI). Normally used with hubs.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>bnc</literal></term>
+ <listitem>
+ <para>An Ethernet interface using BNC connectors and co-axial cable.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>mii</literal></term>
+ <listitem>
+ <para>An Ethernet interface using a Media Independent Interface (MII).</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>fibre</literal></term>
+ <listitem>
+ <para>An Ethernet interface using Optical Fibre as the medium.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
<term><varname>TCPSegmentationOffload=</varname></term>
<listitem>
<para>The TCP Segmentation Offload (TSO) when true enables
diff --git a/man/systemd.mount.xml b/man/systemd.mount.xml
index 4a404fb424..1bed7d17f1 100644
--- a/man/systemd.mount.xml
+++ b/man/systemd.mount.xml
@@ -161,8 +161,15 @@
<para>The NFS mount option <option>bg</option> for NFS background mounts
as documented in <citerefentry project='man-pages'><refentrytitle>nfs</refentrytitle><manvolnum>5</manvolnum></citerefentry>
- is not supported in <filename>/etc/fstab</filename> entries. The systemd mount option <option>nofail</option>
- provides similar functionality and should be used instead.</para>
+ is detected by <command>systemd-fstab-generator</command> and the options
+ are transformed so that systemd fulfills the job-control implications of
+ that option. Specifically <command>systemd-fstab-generator</command> acts
+ as though <literal>x-systemd.mount-timout=infinity,retry=10000</literal> was
+ prepended to the option list, and <literal>fg,nofail</literal> was appended.
+ Depending on specific requirements, it may be appropriate to provide some of
+ these options explicitly, or to make use of the
+ <literal>x-systemd.automount</literal> option described below instead
+ of using <literal>bg</literal>.</para>
<para>When reading <filename>/etc/fstab</filename> a few special
mount options are understood by systemd which influence how
@@ -230,7 +237,7 @@
<listitem><para>The block device backed file system will be upgraded
to <varname>BindsTo=</varname> dependency. This option is only useful
when mounting file systems manually with
- <citerefentry><refentrytitle>mount</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ <citerefentry project='man-pages'><refentrytitle>mount</refentrytitle><manvolnum>8</manvolnum></citerefentry>
as the default dependency in this case is <varname>Requires=</varname>.
This option is already implied by entries in <filename>/etc/fstab</filename>
or by mount units.
@@ -366,8 +373,9 @@
<varlistentry>
<term><varname>Where=</varname></term>
- <listitem><para>Takes an absolute path of a directory of the
- mount point. If the mount point does not exist at the time of
+ <listitem><para>Takes an absolute path of a directory for the
+ mount point; in particular, the destination cannot be a symbolic
+ link. If the mount point does not exist at the time of
mounting, it is created. This string must be reflected in the
unit filename. (See above.) This option is
mandatory.</para></listitem>
diff --git a/man/systemd.netdev.xml b/man/systemd.netdev.xml
index 39e69480ec..e925b302bf 100644
--- a/man/systemd.netdev.xml
+++ b/man/systemd.netdev.xml
@@ -169,6 +169,9 @@
<row><entry><varname>vxlan</varname></entry>
<entry>A virtual extensible LAN (vxlan), for connecting Cloud computing deployments.</entry></row>
+ <row><entry><varname>geneve</varname></entry>
+ <entry>A GEneric NEtwork Virtualization Encapsulation (GENEVE) netdev driver.</entry></row>
+
<row><entry><varname>vrf</varname></entry>
<entry>A Virtual Routing and Forwarding (<ulink url="https://www.kernel.org/doc/Documentation/networking/vrf.txt">VRF</ulink>) interface to create separate routing and forwarding domains.</entry></row>
@@ -341,7 +344,8 @@
<varlistentry>
<term><varname>DefaultPVID=</varname></term>
<listitem>
- <para>This specifies the default port VLAN ID of a newly attached bridge port.</para>
+ <para>This specifies the default port VLAN ID of a newly attached bridge port.
+ Set this to an integer in the range 1–4094 or <literal>none</literal> to disable the PVID.</para>
</listitem>
</varlistentry>
<varlistentry>
@@ -399,8 +403,40 @@
This option is compulsory.</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><varname>GVRP=</varname></term>
+ <listitem>
+ <para>The Generic VLAN Registration Protocol (GVRP) is a protocol that
+ allows automatic learning of VLANs on a network. A boolean. When unset,
+ the kernel's default setting applies.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><varname>MVRP=</varname></term>
+ <listitem>
+ <para>Multiple VLAN Registration Protocol (MVRP) formerly known as GARP VLAN
+ Registration Protocol (GVRP) is a standards-based Layer 2 network protocol,
+ for automatic configuration of VLAN information on switches. It was defined
+ in the 802.1ak amendment to 802.1Q-2005. A boolean. When unset, the kernel's
+ default setting applies.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><varname>LooseBinding=</varname></term>
+ <listitem>
+ <para>The VLAN loose binding mode, in which only the operational state is passed
+ from the parent to the associated VLANs, but the VLAN device state is not changed.
+ A boolean. When unset, the kernel's default setting applies.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><varname>ReorderHeader=</varname></term>
+ <listitem>
+ <para>The VLAN reorder header is set VLAN interfaces behave like physical interfaces.
+ A boolean. When unset, the kernel's default setting applies.</para>
+ </listitem>
+ </varlistentry>
</variablelist>
-
</refsect1>
<refsect1>
@@ -590,8 +626,8 @@
<listitem>
<para>Configures the default destination UDP port on a per-device basis.
If destination port is not specified then Linux kernel default will be used.
- Set destination port 4789 to get the IANA assigned value,
- and destination port 0 to get default values.</para>
+ Set destination port 4789 to get the IANA assigned value. If not set or if the
+ destination port is assigned the empty string the default port of 4789 is used.</para>
</listitem>
</varlistentry>
<varlistentry>
@@ -604,6 +640,78 @@
ports, and allows overriding via configuration.</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><varname>FlowLabel=</varname></term>
+ <listitem>
+ <para>Specifies the flow label to use in outgoing packets.
+ The valid range is 0-1048575.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+ <refsect1>
+ <title>[GENEVE] Section Options</title>
+ <para>The <literal>[GENEVE]</literal> section only applies for
+ netdevs of kind <literal>geneve</literal>, and accepts the
+ following keys:</para>
+
+ <variablelist class='network-directives'>
+ <varlistentry>
+ <term><varname>Id=</varname></term>
+ <listitem>
+ <para>Specifies the Virtual Network Identifer (VNI) to use. Ranges [0-16777215].</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><varname>Remote=</varname></term>
+ <listitem>
+ <para>Specifies the unicast destination IP address to use in outgoing packets.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><varname>TOS=</varname></term>
+ <listitem>
+ <para>Specifies the TOS value to use in outgoing packets. Ranges [1-255].</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><varname>TTL=</varname></term>
+ <listitem>
+ <para>Specifies the TTL value to use in outgoing packets. Ranges [1-255].</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><varname>UDPChecksum=</varname></term>
+ <listitem>
+ <para>A boolean. When true, specifies if UDP checksum is calculated for transmitted packets over IPv4.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><varname>UDP6ZeroChecksumTx=</varname></term>
+ <listitem>
+ <para>A boolean. When true, skip UDP checksum calculation for transmitted packets over IPv6.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><varname>UDP6ZeroChecksumRx=</varname></term>
+ <listitem>
+ <para>A boolean. When true, allows incoming UDP packets over IPv6 with zero checksum field.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><varname>DestinationPort=</varname></term>
+ <listitem>
+ <para>Specifies destination port. Defaults to 6081. If not set or assigned the empty string, the default
+ port of 6081 is used.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><varname>FlowLabel=</varname></term>
+ <listitem>
+ <para>Specifies the flow label to use in outgoing packets.</para>
+ </listitem>
+ </varlistentry>
</variablelist>
</refsect1>
<refsect1>
diff --git a/man/systemd.network.xml b/man/systemd.network.xml
index aaa7b0968d..6b83a5b851 100644
--- a/man/systemd.network.xml
+++ b/man/systemd.network.xml
@@ -507,7 +507,7 @@
<para>This setting is read by
<citerefentry><refentrytitle>systemd-resolved.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
"Search domains" correspond to the <varname>domain</varname> and <varname>search</varname> entries in
- <citerefentry><refentrytitle>resolv.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
+ <citerefentry project='man-pages'><refentrytitle>resolv.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
Domain name routing has no equivalent in the traditional glibc API, which has no concept of domain
name servers limited to a specific link.</para>
</listitem>
@@ -612,22 +612,27 @@
</para></listitem>
</varlistentry>
<varlistentry>
- <term><varname>IPv6ProxyNDPAddress=</varname></term>
- <listitem><para>An IPv6 address, for which Neighbour Advertisement
- messages will be proxied.
- Proxy NDP (Neighbor Discovery Protocol) is a technique for IPv6 to
- allow routing of addresses to a different destination when peers expect them
- to be present on a certain physical link.
+ <term><varname>IPv6ProxyNDP=</varname></term>
+ <listitem><para>A boolean. Configures proxy NDP for IPv6. Proxy NDP (Neighbor Discovery
+ Protocol) is a technique for IPv6 to allow routing of addresses to a different
+ destination when peers expect them to be present on a certain physical link.
In this case a router answers Neighbour Advertisement messages intended for
another machine by offering its own MAC address as destination.
- Unlike proxy ARP for IPv4, is not enabled globally, but will only send Neighbour
+ Unlike proxy ARP for IPv4, it is not enabled globally, but will only send Neighbour
Advertisement messages for addresses in the IPv6 neighbor proxy table,
- which can also be shown by <command>ip -6 neighbour show proxy</command>
- This option may be specified more than once. systemd-networkd will control the
- per-interface `proxy_ndp` switch for each configured interface, depending on whether
- there are <option>IPv6ProxyNDPAddress=</option> entries configured and add these to
- the kernels IPv6 neighbor proxy table.
- Defaults to unset.
+ which can also be shown by <command>ip -6 neighbour show proxy</command>.
+ systemd-networkd will control the per-interface `proxy_ndp` switch for each configured
+ interface depending on this option.
+ Defautls to unset.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><varname>IPv6ProxyNDPAddress=</varname></term>
+ <listitem><para>An IPv6 address, for which Neighbour Advertisement messages will be
+ proxied. This option may be specified more than once. systemd-networkd will add the
+ <option>IPv6ProxyNDPAddress=</option> entries to the kernel's IPv6 neighbor proxy table.
+ This option implies <option>IPv6ProxyNDP=true</option> but has no effect if
+ <option>IPv6ProxyNDP</option> has been set to false. Defaults to unset.
</para></listitem>
</varlistentry>
<varlistentry>
@@ -796,6 +801,33 @@
</variablelist>
</refsect1>
+ <refsect1>
+ <title>[IPv6AddressLabel] Section Options</title>
+
+ <para>An <literal>[IPv6AddressLabel]</literal> section accepts the
+ following keys. Specify several <literal>[IPv6AddressLabel]</literal>
+ sections to configure several addresse labels. IPv6 address labels are
+ used for address selection. See <ulink url="https://tools.ietf.org/html/rfc3484">RFC 3484</ulink>.
+ Precedence is managed by userspace, and only the label itself is stored in the kernel</para>
+
+ <variablelist class='network-directives'>
+ <varlistentry>
+ <term><varname>Label=</varname></term>
+ <listitem>
+ <para> The label for the prefix (an unsigned integer) ranges 0 to 4294967294.
+ 0xffffffff is reserved. This key is mandatory.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><varname>Prefix=</varname></term>
+ <listitem>
+ <para>IPv6 prefix is an address with a prefix length, separated by a slash <literal>/</literal> character.
+ This key is mandatory. </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
<refsect1>
<title>[Route] Section Options</title>
<para>The <literal>[Route]</literal> section accepts the
@@ -809,6 +841,16 @@
<para>As in the <literal>[Network]</literal> section.</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><varname>GatewayOnlink=</varname></term>
+ <listitem>
+ <para>The <literal>GatewayOnlink</literal> option tells the kernel that it does not have
+ to check if the gateway is reachable directly by the current machine (i.e., the kernel does
+ not need to check if the gateway is attached to the local network), so that we can insert the
+ route in the kernel table without it being complained about. A boolean, defaults to <literal>no</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
<varlistentry>
<term><varname>Destination=</varname></term>
<listitem>
@@ -832,6 +874,16 @@
</listitem>
</varlistentry>
<varlistentry>
+ <term><varname>IPv6Preference=</varname></term>
+ <listitem>
+ <para>Specifies the route preference as defined in <ulink
+ url="https://tools.ietf.org/html/rfc4191">RFC4191</ulink> for Router Discovery messages.
+ Which can be one of <literal>low</literal> the route has a lowest priority,
+ <literal>medium</literal> the route has a default priority or
+ <literal>high</literal> the route has a highest priority.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
<term><varname>Scope=</varname></term>
<listitem>
<para>The scope of the route, which can be <literal>global</literal>,
@@ -855,6 +907,15 @@
</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><varname>Protocol=</varname></term>
+ <listitem>
+ <para>The Protocol identifier for the route. Takes a number between 0 and 255 or the special values
+ <literal>kernel</literal>, <literal>boot</literal> and <literal>static</literal>. Defaults to
+ <literal>static</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
</variablelist>
</refsect1>
@@ -1259,7 +1320,18 @@
<para>Sets the "cost" of sending packets of this interface.
Each port in a bridge may have a different speed and the cost
is used to decide which link to use. Faster interfaces
- should have lower costs.</para>
+ should have lower costs. It is an interger value between 1 and
+ 65535.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><varname>Priority=</varname></term>
+ <listitem>
+ <para>Sets the "priority" of sending packets on this interface.
+ Each port in a bridge may have a different priority which is used
+ to decide which link to use. Lower value means higher priority.
+ It is an interger value between 0 to 63. Networkd does not set any
+ default, meaning the kernel default value of 32 is used.</para>
</listitem>
</varlistentry>
</variablelist>
@@ -1515,7 +1587,7 @@ VRF=vrf1
<title>MacVTap</title>
<para>This brings up a network interface <literal>macvtap-test</literal>
and attaches it to <literal>enp0s25</literal>.</para>
- <programlisting># /lib/systemd/network/25-macvtap.network
+ <programlisting># /usr/lib/systemd/network/25-macvtap.network
[Match]
Name=enp0s25
diff --git a/man/systemd.service.xml b/man/systemd.service.xml
index 555719186e..da35a5205d 100644
--- a/man/systemd.service.xml
+++ b/man/systemd.service.xml
@@ -328,14 +328,13 @@
all <varname>ExecStartPre=</varname> commands that were not prefixed
with a <literal>-</literal> exit successfully.</para>
- <para><varname>ExecStartPost=</varname> commands are only run after
- the service has started successfully, as determined by <varname>Type=</varname>
- (i.e. the process has been started for <varname>Type=simple</varname>
- or <varname>Type=idle</varname>, the process exits successfully for
- <varname>Type=oneshot</varname>, the initial process exits successfully
- for <varname>Type=forking</varname>, <literal>READY=1</literal> is sent
- for <varname>Type=notify</varname>, or the <varname>BusName=</varname>
- has been taken for <varname>Type=dbus</varname>).</para>
+ <para><varname>ExecStartPost=</varname> commands are only run after the commands specified in
+ <varname>ExecStart=</varname> have been invoked successfully, as determined by <varname>Type=</varname>
+ (i.e. the process has been started for <varname>Type=simple</varname> or <varname>Type=idle</varname>, the last
+ <varname>ExecStart=</varname> process exited successfully for <varname>Type=oneshot</varname>, the initial
+ process exited successfully for <varname>Type=forking</varname>, <literal>READY=1</literal> is sent for
+ <varname>Type=notify</varname>, or the <varname>BusName=</varname> has been taken for
+ <varname>Type=dbus</varname>).</para>
<para>Note that <varname>ExecStartPre=</varname> may not be
used to start long-running processes. All processes forked
@@ -384,7 +383,8 @@
multiple command lines, following the same scheme as described
for <varname>ExecStart=</varname> above. Use of this setting
is optional. After the commands configured in this option are
- run, all processes remaining for a service are terminated
+ run, it is implied that the service is stopped, and any processes
+ remaining for it are terminated
according to the <varname>KillMode=</varname> setting (see
<citerefentry><refentrytitle>systemd.kill</refentrytitle><manvolnum>5</manvolnum></citerefentry>).
If this option is not specified, the process is terminated by
@@ -657,9 +657,10 @@
<para>As exceptions to the setting above, the service will not
be restarted if the exit code or signal is specified in
- <varname>RestartPreventExitStatus=</varname> (see below).
- Also, the services will always be restarted if the exit code
- or signal is specified in
+ <varname>RestartPreventExitStatus=</varname> (see below) or
+ the service is stopped with <command>systemctl stop</command>
+ or an equivalent operation. Also, the services will always be
+ restarted if the exit code or signal is specified in
<varname>RestartForceExitStatus=</varname> (see below).</para>
<para>Note that service restart is subject to unit start rate
@@ -780,15 +781,14 @@
<varlistentry>
<term><varname>NonBlocking=</varname></term>
- <listitem><para>Set the <constant>O_NONBLOCK</constant> flag
- for all file descriptors passed via socket-based activation.
- If true, all file descriptors >= 3 (i.e. all except stdin,
- stdout, and stderr) will have the
- <constant>O_NONBLOCK</constant> flag set and hence are in
- non-blocking mode. This option is only useful in conjunction
- with a socket unit, as described in
- <citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
- Defaults to false.</para></listitem>
+ <listitem><para>Set the <constant>O_NONBLOCK</constant> flag for all file descriptors passed via socket-based
+ activation. If true, all file descriptors >= 3 (i.e. all except stdin, stdout, stderr), excluding those passed
+ in via the file descriptor storage logic (see <varname>FileDescriptorStoreMax=</varname> for details), will
+ have the <constant>O_NONBLOCK</constant> flag set and hence are in non-blocking mode. This option is only
+ useful in conjunction with a socket unit, as described in
+ <citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry> and has no
+ effect on file descriptors which were previously saved in the file-descriptor store for example. Defaults to
+ false.</para></listitem>
</varlistentry>
<varlistentry>
@@ -852,21 +852,18 @@
<varlistentry>
<term><varname>FileDescriptorStoreMax=</varname></term>
- <listitem><para>Configure how many file descriptors may be
- stored in the service manager for the service using
+ <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
- <literal>FDSTORE=1</literal> messages. This is useful for
- implementing service restart schemes where the state is
- serialized to <filename>/run</filename> and the file
- descriptors passed to the service manager, to allow restarts
- without losing state. Defaults to 0, i.e. no file descriptors
- may be stored in the service manager. All file
- descriptors passed to the service manager from a specific
- service are passed back to the service's main process on the
- next service restart. Any file descriptors passed to the
- service manager are automatically closed when POLLHUP or
- POLLERR is seen on them, or when the service is fully stopped
- and no job is queued or being executed for it.</para></listitem>
+ <literal>FDSTORE=1</literal> messages. This is useful for implementing services that can restart after an
+ explicit request or a crash without losing state. Any open sockets and other file descriptors which should not
+ be closed during the restart may be stored this way. Application state can either be serialized to a file in
+ <filename>/run</filename>, or better, stored in a
+ <citerefentry><refentrytitle>memfd_create</refentrytitle><manvolnum>2</manvolnum></citerefentry> memory file
+ descriptor. Defaults to 0, i.e. no file descriptors may be stored in the service manager. All file descriptors
+ passed to the service manager from a specific service are passed back to the service's main process on the next
+ service restart. Any file descriptors passed to the service manager are automatically closed when
+ <constant>POLLHUP</constant> or <constant>POLLERR</constant> is seen on them, or when the service is fully
+ stopped and no job is queued or being executed for it.</para></listitem>
</varlistentry>
<varlistentry>
@@ -919,12 +916,14 @@
<para>Each command line is split on whitespace, with the first item being the command to
execute, and the subsequent items being the arguments. Double quotes ("…") and single quotes
- ('…') may be used, in which case everything until the next matching quote becomes part of the
- same argument. Quotes themselves are removed. C-style escapes are also supported. The table
- below contains the list of known escape patterns. Only escape patterns which match the syntax in
- the table are allowed; other patterns may be added in the future and unknown patterns will
- result in a warning. In particular, any backslashes should be doubled. Finally, a trailing
- backslash (<literal>\</literal>) may be used to merge lines.</para>
+ ('…') may be used to wrap a whole item (the opening quote may appear only at the beginning or
+ after whitespace that is not quoted, and the closing quote must be followed by whitespace or the
+ end of line), in which case everything until the next matching quote becomes part of the same
+ argument. Quotes themselves are removed. C-style escapes are also supported. The table below
+ contains the list of known escape patterns. Only escape patterns which match the syntax in the
+ table are allowed; other patterns may be added in the future and unknown patterns will result in
+ a warning. In particular, any backslashes should be doubled. Finally, a trailing backslash
+ (<literal>\</literal>) may be used to merge lines.</para>
<para>This syntax is inspired by shell syntax, but only the meta-characters and expansions
described in the following paragraphs are understood, and the expansion of variables is
diff --git a/man/systemd.special.xml b/man/systemd.special.xml
index fa3dc1c5d4..66c45e39a3 100644
--- a/man/systemd.special.xml
+++ b/man/systemd.special.xml
@@ -901,64 +901,58 @@
<refsect1>
<title>Special Passive User Units</title>
- <refsect2>
- <title>graphical-session.target</title>
-
- <para>This target is active whenever any graphical session is running. It
- is used to stop user services which only apply to a graphical (X,
- Wayland, etc.) session when the session is terminated. Such services
- should have <literal>PartOf=graphical-session.target</literal> in their
- <literal>[Unit]</literal> section. A target for a particular session
- (e. g. <filename>gnome-session.target</filename>) starts and stops
- <literal>graphical-session.target</literal> with
- <literal>BindsTo=graphical-session.target</literal>.</para>
-
- <para>Which services are started by a session target is determined by the
- <literal>Wants=</literal> and <literal>Requires=</literal> dependencies.
- For services that can be enabled independently, symlinks in
- <literal>.wants/</literal> and <literal>.requires/</literal> should be
- used, see
- <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
- Those symlinks should either be shipped in packages, or should be added
- dynamically after installation, for example using <literal>systemctl add-wants</literal>, see
- <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>.
- </para>
+ <variablelist>
+ <varlistentry>
+ <term><filename>graphical-session.target</filename></term>
+ <listitem>
+ <para>This target is active whenever any graphical session is running. It is used to stop user services which
+ only apply to a graphical (X, Wayland, etc.) session when the session is terminated. Such services should
+ have <literal>PartOf=graphical-session.target</literal> in their <literal>[Unit]</literal> section. A target
+ for a particular session (e. g. <filename>gnome-session.target</filename>) starts and stops
+ <literal>graphical-session.target</literal> with <literal>BindsTo=graphical-session.target</literal>.</para>
+
+ <para>Which services are started by a session target is determined by the <literal>Wants=</literal> and
+ <literal>Requires=</literal> dependencies. For services that can be enabled independently, symlinks in
+ <literal>.wants/</literal> and <literal>.requires/</literal> should be used, see
+ <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>. Those
+ symlinks should either be shipped in packages, or should be added dynamically after installation, for example
+ using <literal>systemctl add-wants</literal>, see
+ <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>.
+ </para>
- <example>
- <title>Nautilus as part of a GNOME session</title>
+ <example>
+ <title>Nautilus as part of a GNOME session</title>
- <para><literal>gnome-session.target</literal> pulls in Nautilus as
- top-level service:</para>
+ <para><literal>gnome-session.target</literal> pulls in Nautilus as top-level service:</para>
- <programlisting>[Unit]
+ <programlisting>[Unit]
Description=User systemd services for GNOME graphical session
Wants=nautilus.service
-BindsTo=graphical-session.target
- </programlisting>
+BindsTo=graphical-session.target</programlisting>
- <para><literal>nautilus.service</literal> gets stopped when the session stops:</para>
+ <para><literal>nautilus.service</literal> gets stopped when the session stops:</para>
- <programlisting>[Unit]
+ <programlisting>[Unit]
Description=Render the desktop icons with Nautilus
PartOf=graphical-session.target
[Service]
-…
- </programlisting>
- </example>
- </refsect2>
-
- <refsect2>
- <title>graphical-session-pre.target</title>
-
- <para>This target contains services which set up the environment or
- global configuration of a graphical session, such as SSH/GPG agents
- (which need to export an environment variable into all desktop processes)
- or migration of obsolete d-conf keys after an OS upgrade (which needs to
- happen before starting any process that might use them). This target must
- be started before starting a graphical session
- like <filename>gnome-session.target</filename>.</para>
- </refsect2>
+…</programlisting>
+ </example>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><filename>graphical-session-pre.target</filename></term>
+ <listitem>
+ <para>This target contains services which set up the environment or global configuration of a graphical
+ session, such as SSH/GPG agents (which need to export an environment variable into all desktop processes) or
+ migration of obsolete d-conf keys after an OS upgrade (which needs to happen before starting any process that
+ might use them). This target must be started before starting a graphical session like
+ <filename>gnome-session.target</filename>.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
</refsect1>
diff --git a/man/systemd.target.xml b/man/systemd.target.xml
index b3cccd4e52..dbe7ff014b 100644
--- a/man/systemd.target.xml
+++ b/man/systemd.target.xml
@@ -99,6 +99,43 @@
</refsect1>
<refsect1>
+ <title>Example</title>
+
+ <example>
+ <title>Simple standalone target</title>
+
+ <programlisting># emergency-net.target
+
+[Unit]
+Description=Emergency Mode with Networking
+Requires=emergency.target systemd-networkd.service
+After=emergency.target systemd-networkd.service
+AllowIsolate=yes</programlisting>
+
+ <para>When adding dependencies to other units, it's important to check if they set
+ <varname>DefaultDependencies=</varname>. Service units, unless they set
+ <varname>DefaultDependencies=no</varname>, automatically get a dependency on
+ <filename>sysinit.target</filename>. In this case, both
+ <filename>emergency.target</filename> and <filename>systemd-networkd.service</filename>
+ have <varname>DefaultDependencies=no</varname>, so they are suitable for use
+ in this target, and do not pull in <filename>sysinit.target</filename>.</para>
+
+ <para>You can now switch into this emergency mode by running <varname>systemctl
+ isolate emergency-net.target</varname> or by passing the option
+ <varname>systemd.unit=emergency-net.target</varname> on the kernel command
+ line.</para>
+
+ <para>Other units can have <varname>WantedBy=emergency-net.target</varname> in the
+ <varname>[Install]</varname> section. After they are enabled using
+ <command>systemctl enable</command>, they will be started before
+ <varname>emergency-net.target</varname> is started. It is also possible to add
+ arbitrary units as dependencies of <filename>emergency.target</filename> without
+ modifying them by using <command>systemctl add-wants</command>.
+ </para>
+ </example>
+ </refsect1>
+
+ <refsect1>
<title>See Also</title>
<para>
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
diff --git a/man/systemd.time.xml b/man/systemd.time.xml
index d30c6cffc9..659f14328e 100644
--- a/man/systemd.time.xml
+++ b/man/systemd.time.xml
@@ -242,23 +242,17 @@
the local timezone, similar to the supported syntax of timestamps (see above). Non-local timezones except for UTC
are not supported.</para>
- <para>The special expressions
- <literal>minutely</literal>,
- <literal>hourly</literal>, <literal>daily</literal>,
- <literal>monthly</literal>, <literal>weekly</literal>,
- <literal>yearly</literal>,
- <literal>quarterly</literal>,
- <literal>semiannually</literal> may be used as
- calendar events which refer to
- <literal>*-*-* *:*:00</literal>,
- <literal>*-*-* *:00:00</literal>,
- <literal>*-*-* 00:00:00</literal>,
- <literal>*-*-01 00:00:00</literal>,
- <literal>Mon *-*-* 00:00:00</literal>,
- <literal>*-01-01 00:00:00</literal>,
- <literal>*-01,04,07,10-01 00:00:00</literal> and
- <literal>*-01,07-01 00:00:00</literal>, respectively.
- </para>
+ <para>The following special expressions may be used as shorthands for longer normalized forms:</para>
+
+ <programlisting> minutely → *-*-* *:*:00
+ hourly → *-*-* *:00:00
+ daily → *-*-* 00:00:00
+ monthly → *-*-01 00:00:00
+ weekly → Mon *-*-* 00:00:00
+ yearly → *-01-01 00:00:00
+ quarterly → *-01,04,07,10-01 00:00:00
+semiannually → *-01,07-01 00:00:00
+ </programlisting>
<para>Examples for valid timestamps and their
normalized form:</para>
diff --git a/man/systemd.timer.xml b/man/systemd.timer.xml
index 7102d626e1..26a47a1e5a 100644
--- a/man/systemd.timer.xml
+++ b/man/systemd.timer.xml
@@ -173,7 +173,9 @@
<para>Note that timers do not necessarily expire at the
precise time configured with this setting, as it is subject to
the <varname>AccuracySec=</varname> setting
- below.</para></listitem>
+ below.</para>
+
+ <para>May be specified more than once.</para></listitem>
</varlistentry>
<varlistentry>
diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml
index c963a93531..dedeb6c6d0 100644
--- a/man/systemd.unit.xml
+++ b/man/systemd.unit.xml
@@ -546,26 +546,29 @@
<term><varname>Before=</varname></term>
<term><varname>After=</varname></term>
- <listitem><para>A space-separated list of unit names. Configures ordering dependencies between units. If a
- unit <filename>foo.service</filename> contains a setting <option>Before=bar.service</option> and both units are
- being started, <filename>bar.service</filename>'s start-up is delayed until <filename>foo.service</filename> is
- started up. Note that this setting is independent of and orthogonal to the requirement dependencies as
- configured by <varname>Requires=</varname>, <varname>Wants=</varname> or <varname>BindsTo=</varname>. It is a
- common pattern to include a unit name in both the <varname>After=</varname> and <varname>Requires=</varname>
- option, in which case the unit listed will be started before the unit that is configured with these
- options. This option may be specified more than once, in which case ordering dependencies for all listed names
- are created. <varname>After=</varname> is the inverse of <varname>Before=</varname>, i.e. while
- <varname>After=</varname> ensures that the configured unit is started after the listed unit finished starting
- up, <varname>Before=</varname> ensures the opposite, i.e. that the configured unit is fully started up before
- the listed unit is started. Note that when two units with an ordering dependency between them are shut down,
- the inverse of the start-up order is applied. i.e. if a unit is configured with <varname>After=</varname> on
- another unit, the former is stopped before the latter if both are shut down. Given two units with any ordering
- dependency between them, if one unit is shut down and the other is started up, the shutdown is ordered before
- the start-up. It doesn't matter if the ordering dependency is <varname>After=</varname> or
- <varname>Before=</varname>, in this case. It also doesn't matter which of the two is shut down, as long as one
- is shut down and the other is started up. The shutdown is ordered before the start-up in all cases. If two
- units have no ordering dependencies between them, they are shut down or started up simultaneously, and no
- ordering takes place. </para></listitem>
+ <listitem><para>These two settings expect a space-separated list of unit names. They configure ordering
+ dependencies between units. If a unit <filename>foo.service</filename> contains a setting
+ <option>Before=bar.service</option> and both units are being started, <filename>bar.service</filename>'s
+ start-up is delayed until <filename>foo.service</filename> has finished starting up. Note that this setting is
+ independent of and orthogonal to the requirement dependencies as configured by <varname>Requires=</varname>,
+ <varname>Wants=</varname> or <varname>BindsTo=</varname>. It is a common pattern to include a unit name in both
+ the <varname>After=</varname> and <varname>Requires=</varname> options, in which case the unit listed will be
+ started before the unit that is configured with these options. This option may be specified more than once, in
+ which case ordering dependencies for all listed names are created. <varname>After=</varname> is the inverse of
+ <varname>Before=</varname>, i.e. while <varname>After=</varname> ensures that the configured unit is started
+ after the listed unit finished starting up, <varname>Before=</varname> ensures the opposite, that the
+ configured unit is fully started up before the listed unit is started. Note that when two units with an
+ ordering dependency between them are shut down, the inverse of the start-up order is applied. i.e. if a unit is
+ configured with <varname>After=</varname> on another unit, the former is stopped before the latter if both are
+ shut down. Given two units with any ordering dependency between them, if one unit is shut down and the other is
+ started up, the shutdown is ordered before the start-up. It doesn't matter if the ordering dependency is
+ <varname>After=</varname> or <varname>Before=</varname>, in this case. It also doesn't matter which of the two
+ is shut down, as long as one is shut down and the other is started up. The shutdown is ordered before the
+ start-up in all cases. If two units have no ordering dependencies between them, they are shut down or started
+ up simultaneously, and no ordering takes place. It depends on the unit type when precisely a unit has finished
+ starting up. Most importantly, for service units start-up is considered completed for the purpose of
+ <varname>Before=</varname>/<varname>After=</varname> when all its configured start-up commands have been
+ invoked and they either failed or reported start-up success.</para></listitem>
</varlistentry>
<varlistentry>
@@ -718,17 +721,20 @@
<varlistentry>
<term><varname>JobTimeoutSec=</varname></term>
+ <term><varname>JobRunningTimeoutSec=</varname></term>
<term><varname>JobTimeoutAction=</varname></term>
<term><varname>JobTimeoutRebootArgument=</varname></term>
- <listitem><para>When a job for this unit is queued, a time-out may be configured. If this time limit is
- reached, the job will be cancelled, the unit however will not change state or even enter the
- <literal>failed</literal> mode. This value defaults to <literal>infinity</literal> (job timeouts disabled),
- except for device units. NB: this timeout is independent from any unit-specific timeout (for example, the
- timeout set with <varname>TimeoutStartSec=</varname> in service units) as the job timeout has no effect on the
- unit itself, only on the job that might be pending for it. Or in other words: unit-specific timeouts are useful
- to abort unit state changes, and revert them. The job timeout set with this option however is useful to abort
- only the job waiting for the unit state to change.</para>
+ <listitem><para>When a job for this unit is queued, a time-out <varname>JobTimeoutSec=</varname> may be
+ configured. Similarly, <varname>JobRunningTimeoutSec=</varname> starts counting when the queued job is actually
+ started. If either time limit is reached, the job will be cancelled, the unit however will not change state or
+ even enter the <literal>failed</literal> mode. This value defaults to <literal>infinity</literal> (job timeouts
+ disabled), except for device units (<varname>JobRunningTimeoutSec=</varname> defaults to
+ <varname>DefaultTimeoutStartSec=</varname>). NB: this timeout is independent from any unit-specific timeout
+ (for example, the timeout set with <varname>TimeoutStartSec=</varname> in service units) as the job timeout has
+ no effect on the unit itself, only on the job that might be pending for it. Or in other words: unit-specific
+ timeouts are useful to abort unit state changes, and revert them. The job timeout set with this option however
+ is useful to abort only the job waiting for the unit state to change.</para>
<para><varname>JobTimeoutAction=</varname>
optionally configures an additional
@@ -817,6 +823,8 @@
<term><varname>ConditionDirectoryNotEmpty=</varname></term>
<term><varname>ConditionFileNotEmpty=</varname></term>
<term><varname>ConditionFileIsExecutable=</varname></term>
+ <term><varname>ConditionUser=</varname></term>
+ <term><varname>ConditionGroup=</varname></term>
<!-- We do not document ConditionNull=
here, as it is not particularly
@@ -861,7 +869,9 @@
<varname>sh64</varname>,
<varname>m68k</varname>,
<varname>tilegx</varname>,
- <varname>cris</varname> to test
+ <varname>cris</varname>,
+ <varname>arc</varname>,
+ <varname>arc-be</varname> to test
against a specific architecture. The architecture is
determined from the information returned by
<citerefentry project='man-pages'><refentrytitle>uname</refentrytitle><manvolnum>2</manvolnum></citerefentry>
@@ -973,13 +983,11 @@
to make sure they run before the stamp file's modification
time gets reset indicating a completed update.</para>
- <para><varname>ConditionFirstBoot=</varname> takes a boolean
- argument. This condition may be used to conditionalize units
- on whether the system is booting up with an unpopulated
- <filename>/etc</filename> directory. This may be used to
- populate <filename>/etc</filename> on the first boot after
- factory reset, or when a new system instances boots up for the
- first time.</para>
+ <para><varname>ConditionFirstBoot=</varname> takes a boolean argument. This condition may be used to
+ conditionalize units on whether the system is booting up with an unpopulated <filename>/etc</filename>
+ directory (specifically: an <filename>/etc</filename> with no <filename>/etc/machine-id</filename>). This may
+ be used to populate <filename>/etc</filename> on the first boot after factory reset, or when a new system
+ instance boots up for the first time.</para>
<para>With <varname>ConditionPathExists=</varname> a file
existence condition is checked before a unit is started. If
@@ -1028,6 +1036,21 @@
whether a certain path exists, is a regular file and marked
executable.</para>
+ <para><varname>ConditionUser=</varname> takes a numeric
+ <literal>UID</literal>, a UNIX user name, or the special value
+ <literal>@system</literal>. This condition may be used to check
+ whether the service manager is running as the given user. The
+ special value <literal>@system</literal> can be used to check
+ if the user id is within the system user range. This option is not
+ useful for system services, as the system manager exclusively
+ runs as the root user, and thus the test result is constant.</para>
+
+ <para><varname>ConditionGroup=</varname> is similar
+ to <varname>ConditionUser=</varname> but verifies that the
+ service manager's real or effective group, or any of its
+ auxiliary groups match the specified group or GID. This setting
+ does not have a special value <literal>@system</literal>.</para>
+
<para>If multiple conditions are specified, the unit will be
executed if all of them apply (i.e. a logical AND is applied).
Condition checks can be prefixed with a pipe symbol (|) in
@@ -1064,6 +1087,8 @@
<term><varname>AssertDirectoryNotEmpty=</varname></term>
<term><varname>AssertFileNotEmpty=</varname></term>
<term><varname>AssertFileIsExecutable=</varname></term>
+ <term><varname>AssertUser=</varname></term>
+ <term><varname>AssertGroup=</varname></term>
<listitem><para>Similar to the <varname>ConditionArchitecture=</varname>,
<varname>ConditionVirtualization=</varname>, …, condition settings described above, these settings add
@@ -1384,7 +1409,7 @@ WantedBy=multi-user.target</programlisting>
ordered appropriately (<varname>After=</varname>). Thirdly, in
order to harden the service a bit more, the administrator would
like to set the <varname>PrivateTmp=</varname> setting (see
- <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for details). And lastly, the administrator would like to reset
the niceness of the service to its default value of 0.</para>
diff --git a/man/sysusers.d.xml b/man/sysusers.d.xml
index 18ee3800d6..f232d9906d 100644
--- a/man/sysusers.d.xml
+++ b/man/sysusers.d.xml
@@ -53,15 +53,11 @@
<refsect1>
<title>Description</title>
- <para><command>systemd-sysusers</command> uses the files from
- <filename>sysusers.d</filename> directory to create system users
- and groups at package installation or boot time. This tool may be
- used to allocate system users and groups only, it is not useful
- for creating non-system users and groups, as it accesses
- <filename>/etc/passwd</filename> and
- <filename>/etc/group</filename> directly, bypassing any more
- complex user databases, for example any database involving NIS or
- LDAP.</para>
+ <para><command>systemd-sysusers</command> uses the files from <filename>sysusers.d</filename> directory to create
+ system users and groups at package installation or boot time. This tool may be used to allocate system users and
+ groups only, it is not useful for creating non-system (i.e. regular, "human") users and groups, as it accesses
+ <filename>/etc/passwd</filename> and <filename>/etc/group</filename> directly, bypassing any more complex user
+ databases, for example any database involving NIS or LDAP.</para>
</refsect1>
<refsect1>
@@ -83,6 +79,9 @@ g input - -
m authd input
u root 0 "Superuser" /root</programlisting>
+ <para>Empty lines and lines beginning with the <literal>#</literal> character are ignored, and may be used for
+ commenting.</para>
+
<refsect2>
<title>Type</title>
@@ -134,14 +133,14 @@ u root 0 "Superuser" /root</programlisting>
<refsect2>
<title>Name</title>
- <para>The name field specifies the user or group name. It should
- be shorter than 31 characters and avoid any non-ASCII
- characters, and not begin with a numeric character. It is
- strongly recommended to pick user and group names that are
- unlikely to clash with normal users created by the
- administrator. A good scheme to guarantee this is by prefixing
- all system and group names with the underscore, and avoiding too
- generic names.</para>
+ <para>The name field specifies the user or group name. The specified name must consist only of the characters a-z,
+ A-Z, 0-9, <literal>_</literal> and <literal>-</literal>, except for the first character which must be one of a-z,
+ A-Z or <literal>_</literal> (i.e. numbers and <literal>-</literal> are not permitted as first character). The
+ user/group name must have at least one character, and at most 31.</para>
+
+ <para>It is strongly recommended to pick user and group names that are unlikely to clash with normal users
+ created by the administrator. A good scheme to guarantee this is by prefixing all system and group names with the
+ underscore, and avoiding too generic names.</para>
<para>For <varname>m</varname> lines, this field should contain
the user name to add to a group.</para>
diff --git a/man/udevadm.xml b/man/udevadm.xml
index 1c7921f5bd..8d4fe31ec1 100644
--- a/man/udevadm.xml
+++ b/man/udevadm.xml
@@ -488,14 +488,14 @@
<term><option>-s</option></term>
<term><option>--subsystem-match=<replaceable>string[/string]</replaceable></option></term>
<listitem>
- <para>Filter events by subsystem[/devtype]. Only udev events with a matching subsystem value will pass.</para>
+ <para>Filter kernel uevents and udev events by subsystem[/devtype]. Only events with a matching subsystem value will pass.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-t</option></term>
<term><option>--tag-match=<replaceable>string</replaceable></option></term>
<listitem>
- <para>Filter events by property. Only udev events with a given tag attached will pass.</para>
+ <para>Filter udev events by tag. Only udev events with a given tag attached will pass.</para>
</listitem>
</varlistentry>
<varlistentry>
diff --git a/man/vconsole.conf.xml b/man/vconsole.conf.xml
index fa30ca6569..4a6672cbae 100644
--- a/man/vconsole.conf.xml
+++ b/man/vconsole.conf.xml
@@ -78,6 +78,13 @@
<para>Depending on the operating system other configuration files
might be checked for configuration of the virtual console as well,
however only as fallback.</para>
+
+ <para><filename>/etc/vconsole.conf</filename> is usually created and updated
+ using
+ <citerefentry><refentrytitle>systemd-localed.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
+ <citerefentry><refentrytitle>localectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+ may be used to instruct <command>systemd-localed.service</command> to
+ query or update configuration.</para>
</refsect1>
<refsect1>
diff --git a/meson.build b/meson.build
new file mode 100644
index 0000000000..098c1e9ada
--- /dev/null
+++ b/meson.build
@@ -0,0 +1,2529 @@
+project('systemd', 'c',
+ version : '234',
+ license : 'LGPLv2+',
+ default_options: [
+ 'c_std=gnu99',
+ 'prefix=/usr',
+ 'sysconfdir=/etc',
+ 'localstatedir=/var',
+ ],
+ meson_version : '>= 0.40',
+ )
+
+# We need the same data in three different formats, ugh!
+# Also, for hysterical reasons, we use different variable
+# names, sometimes. Not all variables are included in every
+# set. Ugh, ugh, ugh!
+conf = configuration_data()
+conf.set_quoted('PACKAGE_STRING', meson.project_name() + ' ' + meson.project_version())
+conf.set_quoted('PACKAGE_VERSION', meson.project_version())
+
+substs = configuration_data()
+substs.set('PACKAGE_URL', 'https://www.freedesktop.org/wiki/Software/systemd')
+substs.set('PACKAGE_VERSION', meson.project_version())
+
+m4_defines = []
+
+#####################################################################
+
+rootprefixdir = get_option('rootprefix')
+if get_option('split-usr')
+ conf.set('HAVE_SPLIT_USR', true)
+ rootprefixdir = rootprefixdir != '' ? rootprefixdir : '/'
+else
+ rootprefixdir = rootprefixdir != '' ? rootprefixdir : '/usr'
+endif
+
+sysvinit_path = get_option('sysvinit-path')
+sysvrcnd_path = get_option('sysvrcnd-path')
+if sysvinit_path != '' or sysvrcnd_path != ''
+ conf.set('HAVE_SYSV_COMPAT', true,
+ description : 'SysV init scripts and rcN.d links are supported')
+ m4_defines += ['-DHAVE_SYSV_COMPAT']
+endif
+
+# join_paths ignore the preceding arguments if an absolute component is
+# encountered, so this should canonicalize various paths when they are
+# absolute or relative.
+prefixdir = get_option('prefix')
+if not prefixdir.startswith('/')
+ error('Prefix is not absolute: "@0@"'.format(prefixdir))
+endif
+bindir = join_paths(prefixdir, get_option('bindir'))
+libdir = join_paths(prefixdir, get_option('libdir'))
+sysconfdir = join_paths(prefixdir, get_option('sysconfdir'))
+includedir = join_paths(prefixdir, get_option('includedir'))
+datadir = join_paths(prefixdir, get_option('datadir'))
+localstatedir = join_paths('/', get_option('localstatedir'))
+
+rootbindir = join_paths(rootprefixdir, 'bin')
+rootlibexecdir = join_paths(rootprefixdir, 'lib/systemd')
+
+rootlibdir = get_option('rootlibdir')
+if rootlibdir == ''
+ rootlibdir = join_paths(rootprefixdir, libdir.split('/')[-1])
+endif
+
+# Dirs of external packages
+pkgconfigdatadir = join_paths(datadir, 'pkgconfig')
+pkgconfiglibdir = join_paths(libdir, 'pkgconfig')
+polkitpolicydir = join_paths(datadir, 'polkit-1/actions')
+polkitrulesdir = join_paths(datadir, 'polkit-1/rules.d')
+polkitpkladir = join_paths(localstatedir, 'lib/polkit-1/localauthority/10-vendor.d')
+varlogdir = join_paths(localstatedir, 'log')
+xinitrcdir = join_paths(sysconfdir, 'X11/xinit/xinitrc.d')
+rpmmacrosdir = get_option('rpmmacrosdir')
+
+# Our own paths
+pkgdatadir = join_paths(datadir, 'systemd')
+environmentdir = join_paths(prefixdir, 'lib/environment.d')
+pkgsysconfdir = join_paths(sysconfdir, 'systemd')
+userunitdir = join_paths(prefixdir, 'lib/systemd/user')
+userpresetdir = join_paths(prefixdir, 'lib/systemd/user-preset')
+tmpfilesdir = join_paths(prefixdir, 'lib/tmpfiles.d')
+sysusersdir = join_paths(prefixdir, 'lib/sysusers.d')
+sysctldir = join_paths(prefixdir, 'lib/sysctl.d')
+binfmtdir = join_paths(prefixdir, 'lib/binfmt.d')
+modulesloaddir = join_paths(prefixdir, 'lib/modules-load.d')
+networkdir = join_paths(rootprefixdir, 'lib/systemd/network')
+pkgincludedir = join_paths(includedir, 'systemd')
+systemgeneratordir = join_paths(rootlibexecdir, 'system-generators')
+usergeneratordir = join_paths(prefixdir, 'lib/systemd/user-generators')
+systemenvgeneratordir = join_paths(prefixdir, 'lib/systemd/system-environment-generators')
+userenvgeneratordir = join_paths(prefixdir, 'lib/systemd/user-environment-generators')
+systemshutdowndir = join_paths(rootlibexecdir, 'system-shutdown')
+systemsleepdir = join_paths(rootlibexecdir, 'system-sleep')
+systemunitdir = join_paths(rootprefixdir, 'lib/systemd/system')
+systempresetdir = join_paths(rootprefixdir, 'lib/systemd/system-preset')
+udevlibexecdir = join_paths(rootprefixdir, 'lib/udev')
+udevhomedir = udevlibexecdir
+udevrulesdir = join_paths(udevlibexecdir, 'rules.d')
+udevhwdbdir = join_paths(udevlibexecdir, 'hwdb.d')
+catalogdir = join_paths(prefixdir, 'lib/systemd/catalog')
+kernelinstalldir = join_paths(prefixdir, 'lib/kernel/install.d')
+factorydir = join_paths(datadir, 'factory')
+docdir = join_paths(datadir, 'doc/systemd')
+bootlibdir = join_paths(prefixdir, 'lib/systemd/boot/efi')
+testsdir = join_paths(prefixdir, 'lib/systemd/tests')
+systemdstatedir = join_paths(localstatedir, 'lib/systemd')
+catalogstatedir = join_paths(systemdstatedir, 'catalog')
+randomseeddir = join_paths(localstatedir, 'lib/systemd')
+
+dbuspolicydir = get_option('dbuspolicydir')
+if dbuspolicydir == ''
+ dbuspolicydir = join_paths(datadir, 'dbus-1/system.d')
+endif
+
+dbussessionservicedir = get_option('dbussessionservicedir')
+if dbussessionservicedir == ''
+ dbussessionservicedir = join_paths(datadir, 'dbus-1/services')
+endif
+
+dbussystemservicedir = get_option('dbussystemservicedir')
+if dbussystemservicedir == ''
+ dbussystemservicedir = join_paths(datadir, 'dbus-1/system-services')
+endif
+
+pamlibdir = get_option('pamlibdir')
+if pamlibdir == ''
+ pamlibdir = join_paths(rootlibdir, 'security')
+endif
+
+pamconfdir = get_option('pamconfdir')
+if pamconfdir == ''
+ pamconfdir = join_paths(sysconfdir, 'pam.d')
+endif
+
+conf.set_quoted('PKGSYSCONFDIR', pkgsysconfdir)
+conf.set_quoted('SYSTEM_CONFIG_UNIT_PATH', join_paths(pkgsysconfdir, 'system'))
+conf.set_quoted('SYSTEM_DATA_UNIT_PATH', systemunitdir)
+conf.set_quoted('SYSTEM_SYSVINIT_PATH', sysvinit_path)
+conf.set_quoted('SYSTEM_SYSVRCND_PATH', sysvrcnd_path)
+conf.set_quoted('RC_LOCAL_SCRIPT_PATH_START', get_option('rc-local'))
+conf.set_quoted('RC_LOCAL_SCRIPT_PATH_STOP', get_option('halt-local'))
+conf.set_quoted('USER_CONFIG_UNIT_PATH', join_paths(pkgsysconfdir, 'user'))
+conf.set_quoted('USER_DATA_UNIT_PATH', userunitdir)
+conf.set_quoted('CERTIFICATE_ROOT', get_option('certificate-root'))
+conf.set_quoted('CATALOG_DATABASE', join_paths(catalogstatedir, 'database'))
+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_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'))
+conf.set_quoted('SYSTEMD_TTY_ASK_PASSWORD_AGENT_BINARY_PATH', join_paths(rootbindir, 'systemd-tty-ask-password-agent'))
+conf.set_quoted('SYSTEMD_STDIO_BRIDGE_BINARY_PATH', join_paths(bindir, 'systemd-stdio-bridge'))
+conf.set_quoted('ROOTPREFIX', rootprefixdir)
+conf.set_quoted('RANDOM_SEED_DIR', randomseeddir)
+conf.set_quoted('RANDOM_SEED', join_paths(randomseeddir, 'random-seed'))
+conf.set_quoted('SYSTEMD_CRYPTSETUP_PATH', join_paths(rootlibexecdir, 'systemd-cryptsetup'))
+conf.set_quoted('SYSTEM_GENERATOR_PATH', systemgeneratordir)
+conf.set_quoted('USER_GENERATOR_PATH', usergeneratordir)
+conf.set_quoted('SYSTEM_ENV_GENERATOR_PATH', systemenvgeneratordir)
+conf.set_quoted('USER_ENV_GENERATOR_PATH', userenvgeneratordir)
+conf.set_quoted('SYSTEM_SHUTDOWN_PATH', systemshutdowndir)
+conf.set_quoted('SYSTEM_SLEEP_PATH', systemsleepdir)
+conf.set_quoted('SYSTEMD_KBD_MODEL_MAP', join_paths(pkgdatadir, 'kbd-model-map'))
+conf.set_quoted('SYSTEMD_LANGUAGE_FALLBACK_MAP', join_paths(pkgdatadir, 'language-fallback-map'))
+conf.set_quoted('UDEVLIBEXECDIR', udevlibexecdir)
+conf.set_quoted('POLKIT_AGENT_BINARY_PATH', join_paths(bindir, 'pkttyagent'))
+conf.set_quoted('LIBDIR', libdir)
+conf.set_quoted('ROOTLIBDIR', rootlibdir)
+conf.set_quoted('ROOTLIBEXECDIR', rootlibexecdir)
+conf.set_quoted('BOOTLIBDIR', bootlibdir)
+conf.set_quoted('SYSTEMD_PULL_PATH', join_paths(rootlibexecdir, 'systemd-pull'))
+conf.set_quoted('SYSTEMD_IMPORT_PATH', join_paths(rootlibexecdir, 'systemd-import'))
+conf.set_quoted('SYSTEMD_EXPORT_PATH', join_paths(rootlibexecdir, 'systemd-export'))
+conf.set_quoted('VENDOR_KEYRING_PATH', join_paths(rootlibexecdir, 'import-pubring.gpg'))
+conf.set_quoted('USER_KEYRING_PATH', join_paths(pkgsysconfdir, 'import-pubring.gpg'))
+conf.set_quoted('DOCUMENT_ROOT', join_paths(pkgdatadir, 'gatewayd'))
+
+conf.set_quoted('ABS_BUILD_DIR', meson.build_root())
+conf.set_quoted('ABS_SRC_DIR', meson.source_root())
+
+substs.set('prefix', prefixdir)
+substs.set('exec_prefix', prefixdir)
+substs.set('libdir', libdir)
+substs.set('rootlibdir', rootlibdir)
+substs.set('includedir', includedir)
+substs.set('pkgsysconfdir', pkgsysconfdir)
+substs.set('bindir', bindir)
+substs.set('rootbindir', rootbindir)
+substs.set('rootlibexecdir', rootlibexecdir)
+substs.set('systemunitdir', systemunitdir)
+substs.set('userunitdir', userunitdir)
+substs.set('systempresetdir', systempresetdir)
+substs.set('userpresetdir', userpresetdir)
+substs.set('udevhwdbdir', udevhwdbdir)
+substs.set('udevrulesdir', udevrulesdir)
+substs.set('udevlibexecdir', udevlibexecdir)
+substs.set('catalogdir', catalogdir)
+substs.set('tmpfilesdir', tmpfilesdir)
+substs.set('sysusersdir', sysusersdir)
+substs.set('sysctldir', sysctldir)
+substs.set('binfmtdir', binfmtdir)
+substs.set('modulesloaddir', modulesloaddir)
+substs.set('systemgeneratordir', systemgeneratordir)
+substs.set('usergeneratordir', usergeneratordir)
+substs.set('systemenvgeneratordir', systemenvgeneratordir)
+substs.set('userenvgeneratordir', userenvgeneratordir)
+substs.set('systemshutdowndir', systemshutdowndir)
+substs.set('systemsleepdir', systemsleepdir)
+substs.set('VARLOGDIR', varlogdir)
+substs.set('CERTIFICATEROOT', get_option('certificate-root'))
+substs.set('SYSTEMCTL', join_paths(rootbindir, 'systemctl'))
+substs.set('RANDOM_SEED', join_paths(randomseeddir, 'random-seed'))
+substs.set('SYSTEM_SYSVINIT_PATH', sysvinit_path)
+substs.set('SYSTEM_SYSVRCND_PATH', sysvrcnd_path)
+substs.set('RC_LOCAL_SCRIPT_PATH_START', get_option('rc-local'))
+substs.set('RC_LOCAL_SCRIPT_PATH_STOP', get_option('halt-local'))
+
+#####################################################################
+
+cc = meson.get_compiler('c')
+pkgconfig = import('pkgconfig')
+check_compilation_sh = find_program('tools/meson-check-compilation.sh')
+
+cxx = find_program('c++', required : false)
+if cxx.found()
+ # Used only for tests
+ add_languages('cpp')
+endif
+
+foreach arg : ['-Wextra',
+ '-Wundef',
+ '-Wlogical-op',
+ '-Wmissing-include-dirs',
+ '-Wold-style-definition',
+ '-Wpointer-arith',
+ '-Winit-self',
+ '-Wdeclaration-after-statement',
+ '-Wfloat-equal',
+ '-Wsuggest-attribute=noreturn',
+ '-Werror=missing-prototypes',
+ '-Werror=implicit-function-declaration',
+ '-Werror=missing-declarations',
+ '-Werror=return-type',
+ '-Werror=incompatible-pointer-types',
+ '-Werror=format=2',
+ '-Wstrict-prototypes',
+ '-Wredundant-decls',
+ '-Wmissing-noreturn',
+ '-Wshadow',
+ '-Wendif-labels',
+ '-Wstrict-aliasing=2',
+ '-Wwrite-strings',
+ '-Werror=overflow',
+ '-Wdate-time',
+ '-Wnested-externs',
+ '-ffast-math',
+ '-fno-common',
+ '-fdiagnostics-show-option',
+ '-fno-strict-aliasing',
+ '-fvisibility=hidden',
+ '-fstack-protector',
+ '-fstack-protector-strong',
+ '-fPIE',
+ '--param=ssp-buffer-size=4',
+ ]
+ if cc.has_argument(arg)
+ add_project_arguments(arg, language : 'c')
+ endif
+endforeach
+
+# "negative" arguments: gcc on purpose does not return an error for "-Wno-"
+# arguments, just emits a warnings. So test for the "positive" version instead.
+foreach arg : ['unused-parameter',
+ 'missing-field-initializers',
+ 'unused-result',
+ 'format-signedness']
+ if cc.has_argument('-W' + arg)
+ add_project_arguments('-Wno-' + arg, language : 'c')
+ endif
+endforeach
+
+if cc.compiles('
+ #include <time.h>
+ #include <inttypes.h>
+ typedef uint64_t usec_t;
+ usec_t now(clockid_t clock);
+ int main(void) {
+ struct timespec now;
+ return 0;
+ }
+', name : '-Werror=shadow with local shadowing')
+ add_project_arguments('-Werror=shadow', language : 'c')
+endif
+
+if cc.get_id() == 'clang'
+ foreach arg : ['-Wno-typedef-redefinition',
+ '-Wno-gnu-variable-sized-type-not-at-end',
+ ]
+ if cc.has_argument(arg,
+ name : '@0@ is supported'.format(arg))
+ add_project_arguments(arg, language : 'c')
+ endif
+ endforeach
+endif
+
+link_test_c = files('tools/meson-link-test.c')
+
+# --as-needed and --no-undefined are provided by meson by default,
+# run mesonconf to see what is enabled
+foreach arg : ['-Wl,-z,relro',
+ '-Wl,-z,now',
+ '-pie',
+ ]
+
+ have = run_command(check_compilation_sh,
+ cc.cmd_array(), '-x', 'c', arg,
+ '-include', link_test_c).returncode() == 0
+ message('Linking with @0@ supported: @1@'.format(arg, have ? 'yes' : 'no'))
+ if have
+ add_project_link_arguments(arg, language : 'c')
+ endif
+endforeach
+
+if get_option('buildtype') != 'debug'
+ foreach arg : ['-ffunction-sections',
+ '-fdata-sections']
+ if cc.has_argument(arg,
+ name : '@0@ is supported'.format(arg))
+ add_project_arguments(arg, language : 'c')
+ endif
+ endforeach
+
+ foreach arg : ['-Wl,--gc-sections']
+ have = run_command(check_compilation_sh,
+ cc.cmd_array(), '-x', 'c', arg,
+ '-include', link_test_c).returncode() == 0
+ message('Linking with @0@ supported: @1@'.format(arg, have ? 'yes' : 'no'))
+ if have
+ add_project_link_arguments(arg, language : 'c')
+ endif
+ endforeach
+endif
+
+cpp = ' '.join(cc.cmd_array()) + ' -E'
+
+#####################################################################
+# compilation result tests
+
+conf.set('_GNU_SOURCE', true)
+conf.set('__SANE_USERSPACE_TYPES__', true)
+
+conf.set('SIZEOF_PID_T', cc.sizeof('pid_t', prefix : '#include <sys/types.h>'))
+conf.set('SIZEOF_UID_T', cc.sizeof('uid_t', prefix : '#include <sys/types.h>'))
+conf.set('SIZEOF_GID_T', cc.sizeof('gid_t', prefix : '#include <sys/types.h>'))
+conf.set('SIZEOF_DEV_T', cc.sizeof('dev_t', prefix : '#include <sys/types.h>'))
+conf.set('SIZEOF_INO_T', cc.sizeof('ino_t', prefix : '#include <sys/types.h>'))
+conf.set('SIZEOF_TIME_T', cc.sizeof('time_t', prefix : '#include <sys/time.h>'))
+conf.set('SIZEOF_RLIM_T', cc.sizeof('rlim_t', prefix : '#include <sys/resource.h>'))
+
+decl_headers = '''
+#include <uchar.h>
+#include <linux/ethtool.h>
+'''
+# FIXME: key_serial_t is only defined in keyutils.h, this is bound to fail
+
+foreach decl : ['char16_t',
+ 'char32_t',
+ 'key_serial_t',
+ 'struct ethtool_link_settings',
+ ]
+
+ # We get -1 if the size cannot be determined
+ have = cc.sizeof(decl, prefix : decl_headers) > 0
+ conf.set('HAVE_' + decl.underscorify().to_upper(), have)
+endforeach
+
+foreach decl : [['IFLA_INET6_ADDR_GEN_MODE', 'linux/if_link.h'],
+ ['IN6_ADDR_GEN_MODE_STABLE_PRIVACY', 'linux/if_link.h'],
+ ['IFLA_VRF_TABLE', 'linux/if_link.h'],
+ ['IFLA_MACVLAN_FLAGS', 'linux/if_link.h'],
+ ['IFLA_IPVLAN_MODE', 'linux/if_link.h'],
+ ['IFLA_PHYS_PORT_ID', 'linux/if_link.h'],
+ ['IFLA_BOND_AD_INFO', 'linux/if_link.h'],
+ ['IFLA_VLAN_PROTOCOL', 'linux/if_link.h'],
+ ['IFLA_VXLAN_REMCSUM_NOPARTIAL', 'linux/if_link.h'],
+ ['IFLA_VXLAN_GPE', 'linux/if_link.h'],
+ ['IFLA_GENEVE_LABEL', 'linux/if_link.h'],
+ # if_tunnel.h is buggy and cannot be included on its own
+ ['IFLA_VTI_REMOTE', 'linux/if_tunnel.h', '#include <net/if.h>'],
+ ['IFLA_IPTUN_ENCAP_DPORT', 'linux/if_tunnel.h', '#include <net/if.h>'],
+ ['IFLA_GRE_ENCAP_DPORT', 'linux/if_tunnel.h', '#include <net/if.h>'],
+ ['IFLA_BRIDGE_VLAN_INFO', 'linux/if_bridge.h'],
+ ['IFLA_BRPORT_PROXYARP', 'linux/if_link.h'],
+ ['IFLA_BRPORT_LEARNING_SYNC', 'linux/if_link.h'],
+ ['IFLA_BR_VLAN_DEFAULT_PVID', 'linux/if_link.h'],
+ ['NDA_IFINDEX', 'linux/neighbour.h'],
+ ['IFA_FLAGS', 'linux/if_addr.h'],
+ ['LO_FLAGS_PARTSCAN', 'linux/loop.h'],
+ ]
+ prefix = decl.length() > 2 ? decl[2] : ''
+ have = cc.has_header_symbol(decl[1], decl[0], prefix : prefix)
+ conf.set10('HAVE_DECL_' + decl[0], have)
+endforeach
+
+skip = false
+foreach ident : ['secure_getenv', '__secure_getenv']
+ if not skip and cc.has_function(ident)
+ conf.set('HAVE_' + ident.to_upper(), true)
+ skip = true
+ endif
+endforeach
+
+foreach ident : [
+ ['memfd_create', '''#include <sys/memfd.h>'''],
+ ['gettid', '''#include <sys/types.h>'''],
+ ['pivot_root', '''#include <stdlib.h>'''], # no known header declares pivot_root
+ ['name_to_handle_at', '''#define _GNU_SOURCE
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <fcntl.h>'''],
+ ['setns', '''#define _GNU_SOURCE
+ #include <sched.h>'''],
+ ['renameat2', '''#include <stdio.h>'''],
+ ['kcmp', '''#include <linux/kcmp.h>'''],
+ ['keyctl', '''#include <sys/types.h>
+ #include <keyutils.h>'''],
+ ['copy_file_range', '''#include <sys/syscall.h>
+ #include <unistd.h>'''],
+ ['explicit_bzero' , '''#include <string.h>'''],
+]
+
+ have = cc.has_function(ident[0], prefix : ident[1])
+ conf.set10('HAVE_DECL_' + ident[0].to_upper(), have)
+endforeach
+
+if cc.has_function('getrandom', prefix : '''#include <sys/random.h>''')
+ conf.set('USE_SYS_RANDOM_H', true)
+ conf.set10('HAVE_DECL_GETRANDOM', true)
+else
+ have = cc.has_function('getrandom', prefix : '''#include <linux/random.h>''')
+ conf.set10('HAVE_DECL_GETRANDOM', have)
+endif
+
+#####################################################################
+
+sed = find_program('sed')
+grep = find_program('grep')
+awk = find_program('awk')
+m4 = find_program('m4')
+stat = find_program('stat')
+git = find_program('git', required : false)
+
+meson_make_symlink = meson.source_root() + '/tools/meson-make-symlink.sh'
+mkdir_p = 'mkdir -p $DESTDIR/@0@'
+test_efi_create_disk_sh = find_program('test/test-efi-create-disk.sh')
+splash_bmp = files('test/splash.bmp')
+
+# if -Dxxx-path option is found, use that. Otherwise, check in $PATH,
+# /usr/sbin, /sbin, and fall back to the default from middle column.
+progs = [['telinit', '/lib/sysvinit/telinit'],
+ ['quotaon', '/usr/sbin/quotaon' ],
+ ['quotacheck', '/usr/sbin/quotacheck' ],
+ ['kill', '/usr/bin/kill' ],
+ ['kmod', '/usr/bin/kmod' ],
+ ['kexec', '/usr/sbin/kexec' ],
+ ['sulogin', '/usr/sbin/sulogin' ],
+ ['mount', '/usr/bin/mount', 'MOUNT_PATH'],
+ ['umount', '/usr/bin/umount', 'UMOUNT_PATH'],
+ ['loadkeys', '/usr/bin/loadkeys', 'KBD_LOADKEYS'],
+ ['setfont', '/usr/bin/setfont', 'KBD_SETFONT'],
+ ]
+foreach prog : progs
+ path = get_option(prog[0] + '-path')
+ if path != ''
+ message('Using @1@ for @0@'.format(prog[0], path))
+ else
+ exe = find_program(prog[0],
+ '/usr/sbin/' + prog[0],
+ '/sbin/' + prog[0],
+ required: false)
+ path = exe.found() ? exe.path() : prog[1]
+ endif
+ name = prog.length() > 2 ? prog[2] : prog[0].to_upper()
+ conf.set_quoted(name, path)
+ substs.set(name, path)
+endforeach
+
+if run_command('ln', '--relative', '--help').returncode() != 0
+ error('ln does not support --relative')
+endif
+
+############################################################
+
+gperf = find_program('gperf')
+
+gperf_test_format = '''
+#include <string.h>
+const char * in_word_set(const char *, @0@);
+@1@
+'''
+gperf_snippet_format = 'echo foo,bar | @0@ -L ANSI-C'
+gperf_snippet = run_command('sh', '-c', gperf_snippet_format.format(gperf.path()))
+gperf_test = gperf_test_format.format('size_t', gperf_snippet.stdout())
+if cc.compiles(gperf_test)
+ gperf_len_type = 'size_t'
+else
+ gperf_test = gperf_test_format.format('unsigned', gperf_snippet.stdout())
+ if cc.compiles(gperf_test)
+ gperf_len_type = 'unsigned'
+ else
+ error('unable to determine gperf len type')
+ endif
+endif
+message('gperf len type is @0@'.format(gperf_len_type))
+conf.set('GPERF_LEN_TYPE', gperf_len_type,
+ description : 'The type of gperf "len" parameter')
+
+############################################################
+
+if not cc.has_header('sys/capability.h')
+ error('POSIX caps headers not found')
+endif
+foreach header : ['linux/btrfs.h',
+ 'linux/memfd.h',
+ 'linux/vm_sockets.h',
+ 'valgrind/memcheck.h',
+ 'valgrind/valgrind.h',
+ ]
+
+ conf.set('HAVE_' + header.underscorify().to_upper(),
+ cc.has_header(header))
+endforeach
+
+############################################################
+
+conf.set_quoted('FALLBACK_HOSTNAME', get_option('fallback-hostname'))
+
+default_hierarchy = get_option('default-hierarchy')
+conf.set_quoted('DEFAULT_HIERARCHY_NAME', default_hierarchy,
+ description : 'default cgroup hierarchy as string')
+if default_hierarchy == 'legacy'
+ conf.set('DEFAULT_HIERARCHY', 'CGROUP_UNIFIED_NONE')
+elif default_hierarchy == 'hybrid'
+ conf.set('DEFAULT_HIERARCHY', 'CGROUP_UNIFIED_SYSTEMD233')
+else
+ conf.set('DEFAULT_HIERARCHY', 'CGROUP_UNIFIED_ALL')
+endif
+
+time_epoch = get_option('time-epoch')
+if time_epoch == ''
+ NEWS = files('NEWS')
+ time_epoch = run_command(stat, '-c', '%Y', NEWS).stdout()
+endif
+time_epoch = time_epoch.to_int()
+conf.set('TIME_EPOCH', time_epoch)
+
+system_uid_max = get_option('system-uid-max')
+if system_uid_max == ''
+ system_uid_max = run_command(
+ awk,
+ 'BEGIN { uid=999 } /^\s*SYS_UID_MAX\s+/ { uid=$2 } END { print uid }',
+ '/etc/login.defs').stdout()
+endif
+system_uid_max = system_uid_max.to_int()
+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(
+ awk,
+ 'BEGIN { gid=999 } /^\s*SYS_GID_MAX\s+/ { gid=$2 } END { print gid }',
+ '/etc/login.defs').stdout()
+endif
+system_gid_max = system_gid_max.to_int()
+conf.set('SYSTEM_GID_MAX', system_gid_max)
+substs.set('systemgidmax', system_gid_max)
+message('maximum system GID is @0@'.format(system_gid_max))
+
+tty_gid = get_option('tty-gid')
+conf.set('TTY_GID', tty_gid)
+substs.set('TTY_GID', tty_gid)
+
+if get_option('adm-group')
+ m4_defines += ['-DENABLE_ADM_GROUP']
+endif
+
+if get_option('wheel-group')
+ m4_defines += ['-DENABLE_WHEEL_GROUP']
+endif
+
+substs.set('DEV_KVM_MODE', get_option('dev-kvm-mode'))
+
+kill_user_processes = get_option('default-kill-user-processes')
+conf.set10('KILL_USER_PROCESSES', kill_user_processes)
+substs.set('KILL_USER_PROCESSES', kill_user_processes ? 'yes' : 'no')
+
+dns_servers = get_option('dns-servers')
+conf.set_quoted('DNS_SERVERS', dns_servers)
+substs.set('DNS_SERVERS', dns_servers)
+
+ntp_servers = get_option('ntp-servers')
+conf.set_quoted('NTP_SERVERS', ntp_servers)
+substs.set('NTP_SERVERS', ntp_servers)
+
+conf.set_quoted('GETTEXT_PACKAGE', meson.project_name())
+
+substs.set('SUSHELL', get_option('debug-shell'))
+substs.set('DEBUGTTY', get_option('debug-tty'))
+
+debug = get_option('debug')
+if debug != ''
+ foreach name : debug.split(',')
+ if name == 'hashmap'
+ conf.set('ENABLE_DEBUG_HASHMAP', true)
+ elif name == 'mmap-cache'
+ conf.set('ENABLE_DEBUG_MMAP_CACHE', true)
+ else
+ message('unknown debug option "@0@", ignoring'.format(name))
+ endif
+ endforeach
+endif
+
+#####################################################################
+
+threads = dependency('threads')
+librt = cc.find_library('rt')
+libm = cc.find_library('m')
+libdl = cc.find_library('dl')
+libcrypt = cc.find_library('crypt')
+
+libcap = dependency('libcap', required : false)
+if not libcap.found()
+ # Compat with Ubuntu 14.04 which ships libcap w/o .pc file
+ libcap = cc.find_library('cap')
+endif
+
+libmount = dependency('mount',
+ version : '>= 2.27')
+
+want_seccomp = get_option('seccomp')
+if want_seccomp != 'false'
+ libseccomp = dependency('libseccomp',
+ version : '>= 2.3.1',
+ required : want_seccomp == 'true')
+ if libseccomp.found()
+ conf.set('HAVE_SECCOMP', true)
+ m4_defines += ['-DHAVE_SECCOMP']
+ endif
+else
+ libseccomp = []
+endif
+
+want_selinux = get_option('selinux')
+if want_selinux != 'false'
+ libselinux = dependency('libselinux',
+ version : '>= 2.1.9',
+ required : want_selinux == 'true')
+ if libselinux.found()
+ conf.set('HAVE_SELINUX', true)
+ m4_defines += ['-DHAVE_SELINUX']
+ endif
+else
+ libselinux = []
+endif
+
+want_apparmor = get_option('apparmor')
+if want_apparmor != 'false'
+ libapparmor = dependency('libapparmor',
+ required : want_apparmor == 'true')
+ if libapparmor.found()
+ conf.set('HAVE_APPARMOR', true)
+ m4_defines += ['-DHAVE_APPARMOR']
+ endif
+else
+ libapparmor = []
+endif
+
+smack_run_label = get_option('smack-run-label')
+if smack_run_label != ''
+ conf.set_quoted('SMACK_RUN_LABEL', smack_run_label)
+ m4_defines += ['-DHAVE_SMACK_RUN_LABEL']
+endif
+
+want_polkit = get_option('polkit')
+install_polkit = false
+install_polkit_pkla = false
+if want_polkit != 'false'
+ conf.set('ENABLE_POLKIT', true)
+ install_polkit = true
+
+ libpolkit = dependency('polkit-gobject-1',
+ required : false)
+ if libpolkit.found() and libpolkit.version().version_compare('< 0.106')
+ message('Old polkit detected, will install pkla files')
+ install_polkit_pkla = true
+ endif
+endif
+
+want_acl = get_option('acl')
+if want_acl != 'false'
+ libacl = cc.find_library('acl', required : want_acl == 'true')
+ if libacl.found()
+ conf.set('HAVE_ACL', true)
+ m4_defines += ['-DHAVE_ACL']
+ endif
+else
+ libacl = []
+endif
+
+want_audit = get_option('audit')
+if want_audit != 'false'
+ libaudit = dependency('audit', required : want_audit == 'true')
+ conf.set('HAVE_AUDIT', libaudit.found())
+else
+ libaudit = []
+endif
+
+want_blkid = get_option('blkid')
+if want_blkid != 'false'
+ libblkid = dependency('blkid', required : want_blkid == 'true')
+ conf.set('HAVE_BLKID', libblkid.found())
+else
+ libblkid = []
+endif
+
+want_kmod = get_option('kmod')
+if want_kmod != 'false'
+ libkmod = dependency('libkmod',
+ version : '>= 15',
+ required : want_kmod == 'true')
+ conf.set('HAVE_KMOD', libkmod.found())
+else
+ libkmod = []
+endif
+
+want_pam = get_option('pam')
+if want_pam != 'false'
+ libpam = cc.find_library('pam', required : want_pam == 'true')
+ libpam_misc = cc.find_library('pam_misc', required : want_pam == 'true')
+ if libpam.found() and libpam_misc.found()
+ conf.set('HAVE_PAM', true)
+ m4_defines += ['-DHAVE_PAM']
+ endif
+else
+ libpam = []
+ libpam_misc = []
+endif
+
+want_microhttpd = get_option('microhttpd')
+if want_microhttpd != 'false'
+ libmicrohttpd = dependency('libmicrohttpd',
+ version : '>= 0.9.33',
+ required : want_microhttpd == 'true')
+ if libmicrohttpd.found()
+ conf.set('HAVE_MICROHTTPD', true)
+ m4_defines += ['-DHAVE_MICROHTTPD']
+ endif
+else
+ libmicrohttpd = []
+endif
+
+want_libcryptsetup = get_option('libcryptsetup')
+if want_libcryptsetup != 'false'
+ libcryptsetup = dependency('libcryptsetup',
+ version : '>= 1.6.0',
+ required : want_libcryptsetup == 'true')
+ conf.set('HAVE_LIBCRYPTSETUP', libcryptsetup.found())
+else
+ libcryptsetup = []
+endif
+
+want_libcurl = get_option('libcurl')
+if want_libcurl != 'false'
+ libcurl = dependency('libcurl',
+ version : '>= 7.32.0',
+ required : want_libcurl == 'true')
+ if libcurl.found()
+ conf.set('HAVE_LIBCURL', true)
+ m4_defines += ['-DHAVE_LIBCURL']
+ endif
+else
+ libcurl = []
+endif
+
+want_libidn = get_option('libidn')
+want_libidn2 = get_option('libidn2')
+if want_libidn == 'true' and want_libidn2 == 'true'
+ error('libidn and libidn2 cannot be requested simultaneously')
+endif
+
+if want_libidn != 'false' and want_libidn2 != 'true'
+ libidn = dependency('libidn',
+ required : want_libidn == 'true')
+ if libidn.found()
+ conf.set('HAVE_LIBIDN', true)
+ m4_defines += ['-DHAVE_LIBIDN']
+ endif
+else
+ libidn = []
+endif
+if not conf.get('HAVE_LIBIDN', false) and want_libidn2 != 'false'
+ # libidn is used for both libidn and libidn2 objects
+ libidn = dependency('libidn2',
+ required : want_libidn2 == 'true')
+ if libidn.found()
+ conf.set('HAVE_LIBIDN2', true)
+ m4_defines += ['-DHAVE_LIBIDN2']
+ endif
+endif
+
+want_libiptc = get_option('libiptc')
+if want_libiptc != 'false'
+ libiptc = dependency('libiptc',
+ required : want_libiptc == 'true')
+ if libiptc.found()
+ conf.set('HAVE_LIBIPTC', true)
+ m4_defines += ['-DHAVE_LIBIPTC']
+ endif
+else
+ libiptc = []
+endif
+
+want_qrencode = get_option('qrencode')
+if want_qrencode != 'false'
+ libqrencode = dependency('libqrencode',
+ required : want_qrencode == 'true')
+ conf.set('HAVE_QRENCODE', libqrencode.found())
+else
+ libqrencode = []
+endif
+
+want_gnutls = get_option('gnutls')
+if want_gnutls != 'false'
+ libgnutls = dependency('gnutls',
+ version : '>= 3.1.4',
+ required : want_gnutls == 'true')
+ conf.set('HAVE_GNUTLS', libgnutls.found())
+else
+ libgnutls = []
+endif
+
+want_elfutils = get_option('elfutils')
+if want_elfutils != 'false'
+ libdw = dependency('libdw',
+ required : want_elfutils == 'true')
+ conf.set('HAVE_ELFUTILS', libdw.found())
+else
+ libdw = []
+endif
+
+want_zlib = get_option('zlib')
+if want_zlib != 'false'
+ libz = dependency('zlib',
+ required : want_zlib == 'true')
+ conf.set('HAVE_ZLIB', libz.found())
+else
+ libz = []
+endif
+
+want_bzip2 = get_option('bzip2')
+if want_bzip2 != 'false'
+ libbzip2 = cc.find_library('bz2',
+ required : want_bzip2 == 'true')
+ conf.set('HAVE_BZIP2', libbzip2.found())
+else
+ libbzip2 = []
+endif
+
+want_xz = get_option('xz')
+if want_xz != 'false'
+ libxz = dependency('liblzma',
+ required : want_xz == 'true')
+ conf.set('HAVE_XZ', libxz.found())
+else
+ libxz = []
+endif
+
+want_lz4 = get_option('lz4')
+if want_lz4 != 'false'
+ liblz4 = dependency('liblz4',
+ required : want_lz4 == 'true')
+ conf.set('HAVE_LZ4', liblz4.found())
+else
+ liblz4 = []
+endif
+
+want_glib = get_option('glib')
+if want_glib != 'false'
+ libglib = dependency('glib-2.0',
+ version : '>= 2.22.0',
+ required : want_glib == 'true')
+ libgobject = dependency('gobject-2.0',
+ version : '>= 2.22.0',
+ required : want_glib == 'true')
+ libgio = dependency('gio-2.0',
+ required : want_glib == 'true')
+ have = libglib.found() and libgobject.found() and libgio.found()
+ conf.set('HAVE_GLIB', have)
+else
+ libglib = []
+ libgobject = []
+ libgio = []
+endif
+
+want_xkbcommon = get_option('xkbcommon')
+if want_xkbcommon != 'false'
+ libxkbcommon = dependency('xkbcommon',
+ version : '>= 0.3.0',
+ required : want_xkbcommon == 'true')
+ conf.set('HAVE_XKBCOMMON', libxkbcommon.found())
+else
+ libxkbcommon = []
+endif
+
+want_dbus = get_option('dbus')
+if want_dbus != 'false'
+ libdbus = dependency('dbus-1',
+ version : '>= 1.3.2',
+ required : want_dbus == 'true')
+ conf.set('HAVE_DBUS', libdbus.found())
+else
+ libdbus = []
+endif
+
+want_gcrypt = get_option('gcrypt')
+if want_gcrypt != 'false'
+ libgcrypt = cc.find_library('gcrypt', required : want_gcrypt == 'true')
+ libgpg_error = cc.find_library('gpg-error', required : want_gcrypt == 'true')
+
+ have_deps = libgcrypt.found() and libgpg_error.found()
+ conf.set('HAVE_GCRYPT', have_deps)
+ if not have_deps
+ # link to neither of the libs if one is not found
+ libgcrypt = []
+ libgpg_error = []
+ endif
+else
+ libgcrypt = []
+ libgpg_error = []
+endif
+
+default_dnssec = get_option('default-dnssec')
+if default_dnssec != 'no' and not conf.get('HAVE_GCRYPT', false)
+ message('default-dnssec cannot be set to yes or allow-downgrade when gcrypt is disabled. Setting default-dnssec to no.')
+ default_dnssec = 'no'
+endif
+conf.set('DEFAULT_DNSSEC_MODE',
+ 'DNSSEC_' + default_dnssec.underscorify().to_upper())
+substs.set('DEFAULT_DNSSEC_MODE', default_dnssec)
+
+want_importd = get_option('importd')
+if want_importd != 'false'
+ have_deps = (conf.get('HAVE_LIBCURL', false) and
+ conf.get('HAVE_ZLIB', false) and
+ conf.get('HAVE_BZIP2', false) and
+ conf.get('HAVE_XZ', false) and
+ conf.get('HAVE_GCRYPT', false))
+ conf.set('ENABLE_IMPORTD', have_deps)
+ if want_importd == 'true' and not have_deps
+ error('importd support was requested, but dependencies are not available')
+ endif
+endif
+
+want_remote = get_option('remote')
+if want_remote != 'false'
+ have_deps = [conf.get('HAVE_MICROHTTPD', false),
+ conf.get('HAVE_LIBCURL', false)]
+ # sd-j-remote requires µhttpd, and sd-j-upload requires libcurl, so
+ # it's possible to build one without the other. Complain only if
+ # support was explictly requested. The auxiliary files like sysusers
+ # config should be installed when any of the programs are built.
+ if want_remote == 'true' and not (have_deps[0] and have_deps[1])
+ error('remote support was requested, but dependencies are not available')
+ endif
+ conf.set('ENABLE_REMOTE', have_deps[0] or have_deps[1])
+endif
+
+foreach pair : [['utmp', 'HAVE_UTMP'],
+ ['hibernate', 'ENABLE_HIBERNATE'],
+ ['environment-d', 'ENABLE_ENVIRONMENT_D'],
+ ['binfmt', 'ENABLE_BINFMT'],
+ ['coredump', 'ENABLE_COREDUMP'],
+ ['resolve', 'ENABLE_RESOLVED'],
+ ['logind', 'ENABLE_LOGIND'],
+ ['hostnamed', 'ENABLE_HOSTNAMED'],
+ ['localed', 'ENABLE_LOCALED'],
+ ['machined', 'ENABLE_MACHINED'],
+ ['networkd', 'ENABLE_NETWORKD'],
+ ['timedated', 'ENABLE_TIMEDATED'],
+ ['timesyncd', 'ENABLE_TIMESYNCD'],
+ ['myhostname', 'HAVE_MYHOSTNAME'],
+ ['firstboot', 'ENABLE_FIRSTBOOT'],
+ ['randomseed', 'ENABLE_RANDOMSEED'],
+ ['backlight', 'ENABLE_BACKLIGHT'],
+ ['vconsole', 'ENABLE_VCONSOLE'],
+ ['quotacheck', 'ENABLE_QUOTACHECK'],
+ ['sysusers', 'ENABLE_SYSUSERS'],
+ ['tmpfiles', 'ENABLE_TMPFILES'],
+ ['hwdb', 'ENABLE_HWDB'],
+ ['rfkill', 'ENABLE_RFKILL'],
+ ['ldconfig', 'ENABLE_LDCONFIG'],
+ ['efi', 'ENABLE_EFI'],
+ ['tpm', 'SD_BOOT_LOG_TPM'],
+ ['ima', 'HAVE_IMA'],
+ ['smack', 'HAVE_SMACK'],
+ ['gshadow', 'ENABLE_GSHADOW'],
+ ['idn', 'ENABLE_IDN'],
+ ['nss-systemd', 'ENABLE_NSS_SYSTEMD'],
+ ]
+
+ if get_option(pair[0])
+ conf.set(pair[1], true)
+ m4_defines += ['-D' + pair[1]]
+ endif
+endforeach
+
+want_tests = get_option('tests')
+install_tests = get_option('install-tests')
+tests = []
+
+#####################################################################
+
+if get_option('efi')
+ efi_arch = host_machine.cpu_family()
+
+ if efi_arch == 'x86'
+ EFI_MACHINE_TYPE_NAME = 'ia32'
+ gnu_efi_arch = 'ia32'
+ elif efi_arch == 'x86_64'
+ EFI_MACHINE_TYPE_NAME = 'x64'
+ gnu_efi_arch = 'x86_64'
+ elif efi_arch == 'arm'
+ EFI_MACHINE_TYPE_NAME = 'arm'
+ gnu_efi_arch = 'arm'
+ elif efi_arch == 'aarch64'
+ EFI_MACHINE_TYPE_NAME = 'aa64'
+ gnu_efi_arch = 'aarch64'
+ else
+ EFI_MACHINE_TYPE_NAME = ''
+ gnu_efi_arch = ''
+ endif
+
+ conf.set('ENABLE_EFI', true)
+ conf.set_quoted('EFI_MACHINE_TYPE_NAME', EFI_MACHINE_TYPE_NAME)
+
+ conf.set('SD_TPM_PCR', get_option('tpm-pcrindex').to_int())
+endif
+
+#####################################################################
+
+config_h = configure_file(
+ output : 'config.h',
+ configuration : conf)
+
+includes = include_directories('src/basic',
+ 'src/shared',
+ 'src/systemd',
+ 'src/journal',
+ 'src/resolve',
+ 'src/timesync',
+ 'src/login',
+ 'src/udev',
+ 'src/libudev',
+ 'src/core',
+ 'src/libsystemd/sd-bus',
+ 'src/libsystemd/sd-device',
+ 'src/libsystemd/sd-hwdb',
+ 'src/libsystemd/sd-id128',
+ 'src/libsystemd/sd-netlink',
+ 'src/libsystemd/sd-network',
+ 'src/libsystemd-network',
+ )
+
+add_project_arguments('-include', 'config.h', language : 'c')
+
+gcrypt_util_sources = files('src/shared/gcrypt-util.h',
+ 'src/shared/gcrypt-util.c')
+
+subdir('po')
+subdir('catalog')
+subdir('src/systemd')
+subdir('src/basic')
+subdir('src/libsystemd')
+subdir('src/libsystemd-network')
+subdir('src/journal')
+subdir('src/login')
+
+libjournal_core = static_library(
+ 'journal-core',
+ libjournal_core_sources,
+ journald_gperf_c,
+ include_directories : includes,
+ install : false)
+
+libsystemd_sym_path = '@0@/@1@'.format(meson.current_source_dir(), libsystemd_sym)
+libsystemd = shared_library(
+ 'systemd',
+ libsystemd_internal_sources,
+ journal_internal_sources,
+ version : '0.19.0',
+ include_directories : includes,
+ link_args : ['-shared',
+ '-Wl,--version-script=' + libsystemd_sym_path],
+ link_with : [libbasic],
+ dependencies : [threads,
+ libgcrypt,
+ librt,
+ libxz,
+ liblz4],
+ link_depends : libsystemd_sym,
+ install : true,
+ install_dir : rootlibdir)
+
+############################################################
+
+# binaries that have --help and are intended for use by humans,
+# usually, but not always, installed in /bin.
+public_programs = []
+
+subdir('src/libudev')
+subdir('src/shared')
+subdir('src/core')
+subdir('src/udev')
+subdir('src/network')
+
+subdir('src/analyze')
+subdir('src/journal-remote')
+subdir('src/coredump')
+subdir('src/hostname')
+subdir('src/import')
+subdir('src/kernel-install')
+subdir('src/locale')
+subdir('src/machine')
+subdir('src/nspawn')
+subdir('src/resolve')
+subdir('src/timedate')
+subdir('src/timesync')
+subdir('src/vconsole')
+subdir('src/sulogin-shell')
+subdir('src/boot/efi')
+
+subdir('src/test')
+subdir('test')
+
+############################################################
+
+# only static linking apart from libdl, to make sure that the
+# module is linked to all libraries that it uses.
+test_dlopen = executable(
+ 'test-dlopen',
+ test_dlopen_c,
+ include_directories : includes,
+ link_with : [libbasic],
+ dependencies : [libdl])
+
+foreach tuple : [['myhostname', 'HAVE_MYHOSTNAME'],
+ ['systemd', 'ENABLE_NSS_SYSTEMD'],
+ ['mymachines', 'ENABLE_MACHINED'],
+ ['resolve', 'ENABLE_RESOLVED']]
+
+ condition = tuple[1] == '' or conf.get(tuple[1], false)
+ if condition
+ module = tuple[0]
+
+ sym = 'src/nss-@0@/nss-@0@.sym'.format(module)
+ version_script_arg = join_paths(meson.current_source_dir(), sym)
+
+ nss = shared_library(
+ 'nss_' + module,
+ 'src/nss-@0@/nss-@0@.c'.format(module),
+ version : '2',
+ include_directories : includes,
+ link_args : ['-shared',
+ '-Wl,--version-script=' + version_script_arg,
+ '-Wl,--undefined'],
+ link_with : [libsystemd_internal,
+ libbasic],
+ dependencies : [threads,
+ librt],
+ link_depends : sym,
+ install : true,
+ install_dir : rootlibdir)
+
+ # We cannot use shared_module because it does not support version suffix.
+ # Unfortunately shared_library insists on creating the symlink…
+ meson.add_install_script('sh', '-c',
+ 'rm $DESTDIR@0@/libnss_@1@.so'
+ .format(rootlibdir, module))
+
+ test('dlopen-nss_' + module,
+ test_dlopen,
+ args : [nss.full_path()]) # path to dlopen must include a slash
+ endif
+endforeach
+
+############################################################
+
+executable('systemd',
+ systemd_sources,
+ include_directories : includes,
+ link_with : [libcore,
+ libshared],
+ dependencies : [threads,
+ librt,
+ libseccomp,
+ libselinux,
+ libmount,
+ libblkid],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+
+exe = executable('systemd-analyze',
+ systemd_analyze_sources,
+ include_directories : includes,
+ link_with : [libcore,
+ libshared],
+ dependencies : [threads,
+ librt,
+ libseccomp,
+ libselinux,
+ libmount,
+ libblkid],
+ install_rpath : rootlibexecdir,
+ install : true)
+public_programs += [exe]
+
+executable('systemd-journald',
+ systemd_journald_sources,
+ include_directories : includes,
+ link_with : [libjournal_core,
+ libshared],
+ dependencies : [threads,
+ libxz,
+ liblz4,
+ libselinux],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+
+exe = executable('systemd-cat',
+ systemd_cat_sources,
+ include_directories : includes,
+ link_with : [libjournal_core,
+ libshared],
+ dependencies : [threads],
+ install_rpath : rootlibexecdir,
+ install : true)
+public_programs += [exe]
+
+exe = executable('journalctl',
+ journalctl_sources,
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : [threads,
+ libqrencode,
+ libxz,
+ liblz4],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootbindir)
+public_programs += [exe]
+
+executable('systemd-getty-generator',
+ 'src/getty-generator/getty-generator.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : systemgeneratordir)
+
+executable('systemd-debug-generator',
+ 'src/debug-generator/debug-generator.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : systemgeneratordir)
+
+executable('systemd-fstab-generator',
+ 'src/fstab-generator/fstab-generator.c',
+ 'src/core/mount-setup.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : systemgeneratordir)
+
+if conf.get('ENABLE_ENVIRONMENT_D', false)
+ executable('30-systemd-environment-d-generator',
+ 'src/environment-d-generator/environment-d-generator.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : userenvgeneratordir)
+
+ meson.add_install_script(meson_make_symlink,
+ join_paths(sysconfdir, 'environment'),
+ join_paths(environmentdir, '99-environment.conf'))
+endif
+
+if conf.get('ENABLE_HIBERNATE', false)
+ executable('systemd-hibernate-resume-generator',
+ 'src/hibernate-resume/hibernate-resume-generator.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : systemgeneratordir)
+
+ executable('systemd-hibernate-resume',
+ 'src/hibernate-resume/hibernate-resume.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+endif
+
+if conf.get('HAVE_BLKID', false)
+ executable('systemd-gpt-auto-generator',
+ 'src/gpt-auto-generator/gpt-auto-generator.c',
+ 'src/basic/blkid-util.h',
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : libblkid,
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : systemgeneratordir)
+
+ exe = executable('systemd-dissect',
+ 'src/dissect/dissect.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+ public_programs += [exe]
+endif
+
+if conf.get('ENABLE_RESOLVED', false)
+ executable('systemd-resolved',
+ systemd_resolved_sources,
+ gcrypt_util_sources,
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : [threads,
+ libgcrypt,
+ libgpg_error,
+ libm,
+ libidn],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+
+ exe = executable('systemd-resolve',
+ systemd_resolve_sources,
+ gcrypt_util_sources,
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : [threads,
+ libgcrypt,
+ libgpg_error,
+ libm,
+ libidn],
+ install_rpath : rootlibexecdir,
+ install : true)
+ public_programs += [exe]
+endif
+
+if conf.get('ENABLE_LOGIND', false)
+ executable('systemd-logind',
+ systemd_logind_sources,
+ include_directories : includes,
+ link_with : [liblogind_core,
+ libshared],
+ dependencies : [threads,
+ libacl],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+
+ exe = executable('loginctl',
+ loginctl_sources,
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : [threads,
+ liblz4,
+ libxz],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootbindir)
+ public_programs += [exe]
+
+ exe = executable('systemd-inhibit',
+ 'src/login/inhibit.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootbindir)
+ public_programs += [exe]
+
+ if conf.get('HAVE_PAM', false)
+ version_script_arg = join_paths(meson.current_source_dir(), pam_systemd_sym)
+ pam_systemd = shared_library(
+ 'pam_systemd',
+ pam_systemd_c,
+ name_prefix : '',
+ include_directories : includes,
+ link_args : ['-shared',
+ '-Wl,--version-script=' + version_script_arg],
+ link_with : [libsystemd_internal,
+ libshared_static],
+ dependencies : [threads,
+ libpam,
+ libpam_misc],
+ link_depends : pam_systemd_sym,
+ install : true,
+ install_dir : pamlibdir)
+
+ test('dlopen-pam_systemd',
+ test_dlopen,
+ args : [pam_systemd.full_path()]) # path to dlopen must include a slash
+ endif
+endif
+
+if conf.get('HAVE_PAM', false)
+ executable('systemd-user-sessions',
+ 'src/user-sessions/user-sessions.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+endif
+
+if conf.get('ENABLE_EFI', false) and conf.get('HAVE_BLKID', false)
+ exe = executable('bootctl',
+ 'src/boot/bootctl.c',
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : [libblkid],
+ install_rpath : rootlibexecdir,
+ install : true)
+ public_programs += [exe]
+endif
+
+exe = executable('systemd-socket-activate', 'src/activate/activate.c',
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : [threads],
+ install_rpath : rootlibexecdir,
+ install : true)
+public_programs += [exe]
+
+exe = executable('systemctl', 'src/systemctl/systemctl.c',
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : [threads,
+ libcap,
+ libselinux,
+ libxz,
+ liblz4],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootbindir)
+public_programs += [exe]
+
+if conf.get('ENABLE_BACKLIGHT', false)
+ executable('systemd-backlight',
+ 'src/backlight/backlight.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+endif
+
+if conf.get('ENABLE_RFKILL', false)
+ executable('systemd-rfkill',
+ 'src/rfkill/rfkill.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+endif
+
+executable('systemd-system-update-generator',
+ 'src/system-update-generator/system-update-generator.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : systemgeneratordir)
+
+if conf.get('HAVE_LIBCRYPTSETUP', false)
+ executable('systemd-cryptsetup',
+ 'src/cryptsetup/cryptsetup.c',
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : [libcryptsetup],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+
+ executable('systemd-cryptsetup-generator',
+ 'src/cryptsetup/cryptsetup-generator.c',
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : [libcryptsetup],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : systemgeneratordir)
+
+ executable('systemd-veritysetup',
+ 'src/veritysetup/veritysetup.c',
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : [libcryptsetup],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+
+ executable('systemd-veritysetup-generator',
+ 'src/veritysetup/veritysetup-generator.c',
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : [libcryptsetup],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : systemgeneratordir)
+endif
+
+if conf.get('HAVE_SYSV_COMPAT', false)
+ executable('systemd-sysv-generator',
+ 'src/sysv-generator/sysv-generator.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : systemgeneratordir)
+
+ executable('systemd-rc-local-generator',
+ 'src/rc-local-generator/rc-local-generator.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : systemgeneratordir)
+endif
+
+if conf.get('ENABLE_HOSTNAMED', false)
+ executable('systemd-hostnamed',
+ 'src/hostname/hostnamed.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+
+ exe = executable('hostnamectl',
+ 'src/hostname/hostnamectl.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true)
+ public_programs += [exe]
+endif
+
+if conf.get('ENABLE_LOCALED', false)
+ if conf.get('HAVE_XKBCOMMON', false)
+ # logind will load libxkbcommon.so dynamically on its own
+ deps = [libdl]
+ else
+ deps = []
+ endif
+
+ executable('systemd-localed',
+ systemd_localed_sources,
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : deps,
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+
+ exe = executable('localectl',
+ localectl_sources,
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true)
+ public_programs += [exe]
+endif
+
+if conf.get('ENABLE_TIMEDATED', false)
+ executable('systemd-timedated',
+ 'src/timedate/timedated.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+
+ exe = executable('timedatectl',
+ 'src/timedate/timedatectl.c',
+ include_directories : includes,
+ install_rpath : rootlibexecdir,
+ link_with : [libshared],
+ install : true)
+ public_programs += [exe]
+endif
+
+if conf.get('ENABLE_TIMESYNCD', false)
+ executable('systemd-timesyncd',
+ systemd_timesyncd_sources,
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : [threads,
+ libm],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+endif
+
+if conf.get('ENABLE_MACHINED', false)
+ executable('systemd-machined',
+ systemd_machined_sources,
+ include_directories : includes,
+ link_with : [libmachine_core,
+ libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+
+ exe = executable('machinectl',
+ 'src/machine/machinectl.c',
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : [threads,
+ libxz,
+ liblz4],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootbindir)
+ public_programs += [exe]
+endif
+
+if conf.get('ENABLE_IMPORTD', false)
+ executable('systemd-importd',
+ systemd_importd_sources,
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : [threads],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+
+ systemd_pull = executable('systemd-pull',
+ systemd_pull_sources,
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : [libcurl,
+ libz,
+ libbzip2,
+ libxz,
+ libgcrypt],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+
+ systemd_import = executable('systemd-import',
+ systemd_import_sources,
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : [libcurl,
+ libz,
+ libbzip2,
+ libxz],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+
+ systemd_export = executable('systemd-export',
+ systemd_export_sources,
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : [libcurl,
+ libz,
+ libbzip2,
+ libxz],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+ public_programs += [systemd_pull, systemd_import, systemd_export]
+endif
+
+if conf.get('ENABLE_REMOTE', false) and conf.get('HAVE_LIBCURL', false)
+ exe = executable('systemd-journal-upload',
+ systemd_journal_upload_sources,
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : [threads,
+ libcurl,
+ libgnutls,
+ libxz,
+ liblz4],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+ public_programs += [exe]
+endif
+
+if conf.get('ENABLE_REMOTE', false) and conf.get('HAVE_MICROHTTPD', false)
+ s_j_remote = executable('systemd-journal-remote',
+ systemd_journal_remote_sources,
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : [threads,
+ libmicrohttpd,
+ libgnutls,
+ libxz,
+ liblz4],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+
+ s_j_gatewayd = executable('systemd-journal-gatewayd',
+ systemd_journal_gatewayd_sources,
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : [threads,
+ libmicrohttpd,
+ libgnutls,
+ libxz,
+ liblz4],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+ public_programs += [s_j_remote, s_j_gatewayd]
+endif
+
+if conf.get('ENABLE_COREDUMP', false)
+ executable('systemd-coredump',
+ systemd_coredump_sources,
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : [threads,
+ libacl,
+ libdw,
+ libxz,
+ liblz4],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+
+ exe = executable('coredumpctl',
+ coredumpctl_sources,
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : [threads,
+ libxz,
+ liblz4],
+ install_rpath : rootlibexecdir,
+ install : true)
+ public_programs += [exe]
+endif
+
+if conf.get('ENABLE_BINFMT', false)
+ exe = executable('systemd-binfmt',
+ 'src/binfmt/binfmt.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+ public_programs += [exe]
+
+ meson.add_install_script('sh', '-c',
+ mkdir_p.format(binfmtdir))
+ meson.add_install_script('sh', '-c',
+ mkdir_p.format(join_paths(sysconfdir, 'binfmt.d')))
+endif
+
+if conf.get('ENABLE_VCONSOLE', false)
+ executable('systemd-vconsole-setup',
+ 'src/vconsole/vconsole-setup.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+endif
+
+if conf.get('ENABLE_RANDOMSEED', false)
+ executable('systemd-random-seed',
+ 'src/random-seed/random-seed.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+endif
+
+if conf.get('ENABLE_FIRSTBOOT', false)
+ executable('systemd-firstboot',
+ 'src/firstboot/firstboot.c',
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : [libcrypt],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootbindir)
+endif
+
+executable('systemd-remount-fs',
+ 'src/remount-fs/remount-fs.c',
+ 'src/core/mount-setup.c',
+ 'src/core/mount-setup.h',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+
+executable('systemd-machine-id-setup',
+ 'src/machine-id-setup/machine-id-setup-main.c',
+ 'src/core/machine-id-setup.c',
+ 'src/core/machine-id-setup.h',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootbindir)
+
+executable('systemd-fsck',
+ 'src/fsck/fsck.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,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+
+exe = executable('systemd-sysctl',
+ 'src/sysctl/sysctl.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+public_programs += [exe]
+
+executable('systemd-ac-power',
+ 'src/ac-power/ac-power.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+
+exe = executable('systemd-detect-virt',
+ 'src/detect-virt/detect-virt.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true)
+public_programs += [exe]
+
+exe = executable('systemd-delta',
+ 'src/delta/delta.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true)
+public_programs += [exe]
+
+exe = executable('systemd-escape',
+ 'src/escape/escape.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootbindir)
+public_programs += [exe]
+
+exe = executable('systemd-notify',
+ 'src/notify/notify.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootbindir)
+public_programs += [exe]
+
+executable('systemd-volatile-root',
+ 'src/volatile-root/volatile-root.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+
+executable('systemd-cgroups-agent',
+ 'src/cgroups-agent/cgroups-agent.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+
+exe = executable('systemd-path',
+ 'src/path/path.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true)
+public_programs += [exe]
+
+exe = executable('systemd-ask-password',
+ 'src/ask-password/ask-password.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootbindir)
+public_programs += [exe]
+
+executable('systemd-reply-password',
+ 'src/reply-password/reply-password.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+
+exe = executable('systemd-tty-ask-password-agent',
+ 'src/tty-ask-password-agent/tty-ask-password-agent.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootbindir)
+public_programs += [exe]
+
+exe = executable('systemd-cgls',
+ 'src/cgls/cgls.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true)
+public_programs += [exe]
+
+exe = executable('systemd-cgtop',
+ 'src/cgtop/cgtop.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true)
+public_programs += [exe]
+
+executable('systemd-initctl',
+ 'src/initctl/initctl.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+
+exe = executable('systemd-mount',
+ 'src/mount/mount-tool.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true)
+public_programs += [exe]
+
+meson.add_install_script(meson_make_symlink,
+ 'systemd-mount', join_paths(bindir, 'systemd-umount'))
+
+exe = executable('systemd-run',
+ 'src/run/run.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true)
+public_programs += [exe]
+
+exe = executable('systemd-stdio-bridge',
+ 'src/stdio-bridge/stdio-bridge.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true)
+public_programs += [exe]
+
+exe = executable('busctl',
+ 'src/busctl/busctl.c',
+ 'src/busctl/busctl-introspect.c',
+ 'src/busctl/busctl-introspect.h',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true)
+public_programs += [exe]
+
+if conf.get('ENABLE_SYSUSERS', false)
+ exe = executable('systemd-sysusers',
+ 'src/sysusers/sysusers.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootbindir)
+ public_programs += [exe]
+endif
+
+if conf.get('ENABLE_TMPFILES', false)
+ exe = executable('systemd-tmpfiles',
+ 'src/tmpfiles/tmpfiles.c',
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : [libacl],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootbindir)
+ public_programs += [exe]
+endif
+
+if conf.get('ENABLE_HWDB', false)
+ exe = executable('systemd-hwdb',
+ 'src/hwdb/hwdb.c',
+ 'src/libsystemd/sd-hwdb/hwdb-internal.h',
+ include_directories : includes,
+ link_with : [libudev_internal],
+ install_rpath : udev_rpath,
+ install : true,
+ install_dir : rootbindir)
+ public_programs += [exe]
+endif
+
+if conf.get('ENABLE_QUOTACHECK', false)
+ executable('systemd-quotacheck',
+ 'src/quotacheck/quotacheck.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+endif
+
+exe = executable('systemd-socket-proxyd',
+ 'src/socket-proxy/socket-proxyd.c',
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : [threads],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+public_programs += [exe]
+
+exe = executable('systemd-udevd',
+ systemd_udevd_sources,
+ include_directories : includes,
+ c_args : ['-DLOG_REALM=LOG_REALM_UDEV'],
+ link_with : [libudev_core,
+ libsystemd_network,
+ libudev_internal],
+ dependencies : [threads,
+ libkmod,
+ libidn,
+ libacl,
+ libblkid],
+ install_rpath : udev_rpath,
+ install : true,
+ install_dir : rootlibexecdir)
+public_programs += [exe]
+
+exe = executable('udevadm',
+ udevadm_sources,
+ include_directories : includes,
+ link_with : [libudev_core,
+ libsystemd_network,
+ libudev_internal],
+ dependencies : [threads,
+ libkmod,
+ libidn,
+ libacl,
+ libblkid],
+ install_rpath : udev_rpath,
+ install : true,
+ install_dir : rootbindir)
+public_programs += [exe]
+
+executable('systemd-shutdown',
+ systemd_shutdown_sources,
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+
+executable('systemd-update-done',
+ 'src/update-done/update-done.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+
+executable('systemd-update-utmp',
+ 'src/update-utmp/update-utmp.c',
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : [libaudit],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+
+if conf.get('HAVE_KMOD', false)
+ executable('systemd-modules-load',
+ 'src/modules-load/modules-load.c',
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : [libkmod],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+
+ meson.add_install_script('sh', '-c',
+ mkdir_p.format(modulesloaddir))
+ meson.add_install_script('sh', '-c',
+ mkdir_p.format(join_paths(sysconfdir, 'modules-load.d')))
+endif
+
+exe = executable('systemd-nspawn',
+ systemd_nspawn_sources,
+ 'src/core/mount-setup.c', # FIXME: use a variable?
+ 'src/core/mount-setup.h',
+ 'src/core/loopback-setup.c',
+ 'src/core/loopback-setup.h',
+ include_directories : [includes, include_directories('src/nspawn')],
+ link_with : [libshared],
+ dependencies : [libacl,
+ libblkid,
+ libmount,
+ libseccomp,
+ libselinux],
+ install_rpath : rootlibexecdir,
+ install : true)
+public_programs += [exe]
+
+if conf.get('ENABLE_NETWORKD', false)
+ executable('systemd-networkd',
+ systemd_networkd_sources,
+ include_directories : includes,
+ link_with : [libnetworkd_core,
+ libsystemd_network,
+ libudev_internal,
+ libshared],
+ dependencies : [threads],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+
+ executable('systemd-networkd-wait-online',
+ systemd_networkd_wait_online_sources,
+ include_directories : includes,
+ link_with : [libnetworkd_core,
+ libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+endif
+
+exe = executable('networkctl',
+ networkctl_sources,
+ include_directories : includes,
+ link_with : [libsystemd_network,
+ libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootbindir)
+public_programs += [exe]
+
+############################################################
+
+foreach tuple : tests
+ sources = tuple[0]
+ link_with = tuple[1].length() > 0 ? tuple[1] : [libshared]
+ dependencies = tuple[2]
+ condition = tuple.length() >= 4 ? tuple[3] : ''
+ type = tuple.length() >= 5 ? tuple[4] : ''
+ defs = tuple.length() >= 6 ? tuple[5] : []
+ incs = tuple.length() >= 7 ? tuple[6] : includes
+ timeout = 30
+
+ name = sources[0].split('/')[-1].split('.')[0]
+ if type.startswith('timeout=')
+ timeout = type.split('=')[1].to_int()
+ type = ''
+ endif
+
+ if condition == '' or conf.get(condition, false)
+ exe = executable(
+ name,
+ sources,
+ include_directories : incs,
+ link_with : link_with,
+ dependencies : dependencies,
+ c_args : defs,
+ install_rpath : rootlibexecdir,
+ install : install_tests,
+ install_dir : join_paths(testsdir, type))
+
+ if type == 'manual'
+ message('@0@ is a manual test'.format(name))
+ elif type == 'unsafe' and want_tests != 'unsafe'
+ message('@0@ is an unsafe test'.format(name))
+ else
+ test(name, exe,
+ env : test_env,
+ timeout : timeout)
+ endif
+ else
+ message('Not compiling @0@ because @1@ is not true'.format(name, condition))
+ endif
+endforeach
+
+test_libsystemd_sym = executable(
+ 'test-libsystemd-sym',
+ test_libsystemd_sym_c,
+ include_directories : includes,
+ link_with : [libsystemd],
+ install : install_tests,
+ install_dir : testsdir)
+test('test-libsystemd-sym',
+ test_libsystemd_sym)
+
+test_libudev_sym = executable(
+ 'test-libudev-sym',
+ test_libudev_sym_c,
+ include_directories : includes,
+ c_args : ['-Wno-deprecated-declarations'],
+ link_with : [libudev],
+ install : install_tests,
+ install_dir : testsdir)
+test('test-libudev-sym',
+ test_libudev_sym)
+
+############################################################
+
+make_directive_index_py = find_program('tools/make-directive-index.py')
+make_man_index_py = find_program('tools/make-man-index.py')
+xml_helper_py = find_program('tools/xml_helper.py')
+hwdb_update_sh = find_program('tools/meson-hwdb-update.sh')
+
+subdir('units')
+subdir('sysctl.d')
+subdir('sysusers.d')
+subdir('tmpfiles.d')
+subdir('rules')
+subdir('hwdb')
+subdir('network')
+subdir('man')
+subdir('shell-completion/bash')
+subdir('shell-completion/zsh')
+subdir('docs/sysvinit')
+subdir('docs/var-log')
+
+# FIXME: figure out if the warning is true:
+# https://github.com/mesonbuild/meson/wiki/Reference-manual#install_subdir
+install_subdir('factory/etc',
+ install_dir : factorydir)
+
+
+install_data('xorg/50-systemd-user.sh',
+ install_dir : xinitrcdir)
+install_data('system-preset/90-systemd.preset',
+ install_dir : systempresetdir)
+install_data('README',
+ 'NEWS',
+ 'CODING_STYLE',
+ 'DISTRO_PORTING',
+ 'ENVIRONMENT.md',
+ 'LICENSE.GPL2',
+ 'LICENSE.LGPL2.1',
+ 'src/libsystemd/sd-bus/GVARIANT-SERIALIZATION',
+ install_dir : docdir)
+
+meson.add_install_script('sh', '-c', mkdir_p.format(systemdstatedir))
+meson.add_install_script('sh', '-c', 'touch $DESTDIR@0@'.format(prefixdir))
+
+############################################################
+
+meson_check_help = find_program('tools/meson-check-help.sh')
+
+foreach exec : public_programs
+ name = exec.full_path().split('/')[-1]
+ test('check-help-' + name,
+ meson_check_help,
+ args : [exec.full_path()])
+endforeach
+
+############################################################
+
+if git.found()
+ all_files = run_command(
+ git,
+ ['--git-dir=@0@/.git'.format(meson.source_root()),
+ 'ls-files',
+ ':/*.[ch]'])
+ all_files = files(all_files.stdout().split())
+
+ run_target(
+ 'tags',
+ input : all_files,
+ command : ['env', 'etags', '-o', '@0@/TAGS'.format(meson.source_root())] + all_files)
+ run_target(
+ 'ctags',
+ input : all_files,
+ command : ['env', 'ctags', '-o', '@0@/tags'.format(meson.source_root())] + all_files)
+endif
+
+if git.found()
+ meson_git_contrib_sh = find_program('tools/meson-git-contrib.sh')
+ run_target(
+ 'git-contrib',
+ command : [meson_git_contrib_sh])
+endif
+
+if git.found()
+ git_head = run_command(
+ git,
+ ['--git-dir=@0@/.git'.format(meson.source_root()),
+ 'rev-parse', 'HEAD']).stdout().strip()
+ git_head_short = run_command(
+ git,
+ ['--git-dir=@0@/.git'.format(meson.source_root()),
+ 'rev-parse', '--short=7', 'HEAD']).stdout().strip()
+
+ run_target(
+ 'git-snapshot',
+ command : ['git', 'archive',
+ '-o', '@0@/systemd-@1@.tar.gz'.format(meson.source_root(),
+ git_head_short),
+ '--prefix', 'systemd-@0@/'.format(git_head),
+ 'HEAD'])
+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),
+ '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),
+ '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),
+ '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),
+ 'maximum system UID: @0@'.format(system_uid_max),
+ 'maximum system GID: @0@'.format(system_gid_max),
+ '/dev/kvm access mode: @0@'.format(get_option('dev-kvm-mode')),
+ 'certificate root: @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')),
+ 'fallback hostname: @0@'.format(get_option('fallback-hostname')),
+
+ 'default DNSSEC mode: @0@'.format(default_dnssec),
+ 'default cgroup hierarchy: @0@'.format(default_hierarchy),
+ 'default KillUserProcesses setting: @0@'.format(kill_user_processes)]
+
+alt_dns_servers = '\n '.join(dns_servers.split(' '))
+alt_ntp_servers = '\n '.join(ntp_servers.split(' '))
+status += [
+ 'default DNS servers: @0@'.format(alt_dns_servers),
+ 'default NTP servers: @0@'.format(alt_ntp_servers)]
+
+alt_time_epoch = run_command('date', '-Is', '-u', '-d',
+ '@@0@'.format(time_epoch)).stdout().strip()
+status += [
+ 'time epoch: @0@ (@1@)'.format(time_epoch, alt_time_epoch)]
+
+# TODO:
+# CFLAGS: ${OUR_CFLAGS} ${CFLAGS}
+# CPPFLAGS: ${OUR_CPPFLAGS} ${CPPFLAGS}
+# LDFLAGS: ${OUR_LDFLAGS} ${LDFLAGS}
+
+if conf.get('ENABLE_EFI', false)
+ status += [
+ 'efi arch: @0@'.format(efi_arch)]
+
+ if have_gnu_efi
+ 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)]
+ endif
+endif
+
+found = []
+missing = []
+
+foreach tuple : [
+ ['libcryptsetup'],
+ ['PAM'],
+ ['AUDIT'],
+ ['IMA'],
+ ['AppArmor'],
+ ['SELinux'],
+ ['SECCOMP'],
+ ['SMACK'],
+ ['zlib'],
+ ['xz'],
+ ['lz4'],
+ ['bzip2'],
+ ['ACL'],
+ ['gcrypt'],
+ ['qrencode'],
+ ['microhttpd'],
+ ['gnutls'],
+ ['libcurl'],
+ ['idn'],
+ ['libidn2'],
+ ['libidn'],
+ ['nss-systemd'],
+ ['libiptc'],
+ ['elfutils'],
+ ['binfmt'],
+ ['vconsole'],
+ ['quotacheck'],
+ ['tmpfiles'],
+ ['environment.d'],
+ ['sysusers'],
+ ['firstboot'],
+ ['randomseed'],
+ ['backlight'],
+ ['rfkill'],
+ ['logind'],
+ ['machined'],
+ ['importd'],
+ ['hostnamed'],
+ ['timedated'],
+ ['timesyncd'],
+ ['localed'],
+ ['networkd'],
+ ['resolved'],
+ ['coredump'],
+ ['polkit'],
+ ['legacy pkla', install_polkit_pkla],
+ ['efi'],
+ ['gnu-efi', have_gnu_efi],
+ ['kmod'],
+ ['xkbcommon'],
+ ['blkid'],
+ ['dbus'],
+ ['glib'],
+ ['nss-myhostname', conf.get('HAVE_MYHOSTNAME', false)],
+ ['hwdb'],
+ ['tpm'],
+ ['man pages', want_man],
+ ['html pages', want_html],
+ ['man page indices', want_man and have_lxml],
+ ['split /usr', conf.get('HAVE_SPLIT_USR', false)],
+ ['SysV compat'],
+ ['utmp'],
+ ['ldconfig'],
+ ['hibernate'],
+ ['adm group', get_option('adm-group')],
+ ['wheel group', get_option('wheel-group')],
+ ['gshadow'],
+ ['debug hashmap'],
+ ['debug mmap cache'],
+]
+
+ cond = tuple.get(1, '')
+ if cond == ''
+ ident1 = 'HAVE_' + tuple[0].underscorify().to_upper()
+ ident2 = 'ENABLE_' + tuple[0].underscorify().to_upper()
+ cond = conf.get(ident1, false) or conf.get(ident2, false)
+ endif
+ if cond
+ found += [tuple[0]]
+ else
+ missing += [tuple[0]]
+ endif
+endforeach
+
+status += [
+ 'enabled features: @0@'.format(', '.join(found)),
+ 'disabled features: @0@'.format(', '.join(missing))]
+message('\n '.join(status))
diff --git a/meson_options.txt b/meson_options.txt
new file mode 100644
index 0000000000..1594fec41f
--- /dev/null
+++ b/meson_options.txt
@@ -0,0 +1,256 @@
+# -*- mode: meson -*-
+
+option('split-usr', type : 'boolean', value : false,
+ description : '''assume that /bin, /sbin aren't symlinks into /usr''')
+option('rootlibdir', type : 'string',
+ description : '''[/usr]/lib/x86_64-linux-gnu or such''')
+option('rootprefix', type : 'string',
+ description : '''override the root prefix''')
+option('link-udev-shared', type : 'boolean',
+ description : 'link systemd-udev and its helpers to libsystemd-shared.so')
+
+option('sysvinit-path', type : 'string', value : '/etc/init.d',
+ description : 'the directory where the SysV init scripts are located')
+option('sysvrcnd-path', type : 'string', value : '/etc/rc.d',
+ description : 'the base directory for SysV rcN.d directories')
+option('telinit-path', type : 'string', description : 'path to telinit')
+option('rc-local', type : 'string',
+ value : '/etc/rc.local')
+option('halt-local', type : 'string',
+ value : '/usr/sbin/halt.local')
+
+option('quotaon-path', type : 'string', description : 'path to quotaon')
+option('quotacheck-path', type : 'string', description : 'path to quotacheck')
+option('kill-path', type : 'string', description : 'path to kill')
+option('kmod-path', type : 'string', description : 'path to kmod')
+option('kexec-path', type : 'string', description : 'path to kexec')
+option('sulogin-path', type : 'string', description : 'path to sulogin')
+option('mount-path', type : 'string', description : 'path to mount')
+option('umount-path', type : 'string', description : 'path to umount')
+option('loadkeys-path', type : 'string', description : 'path to loadkeys')
+option('setfont-path', type : 'string', description : 'path to setfont')
+
+option('debug-shell', type : 'string', value : '/bin/sh',
+ description : 'path to debug shell binary')
+option('debug-tty', type : 'string', value : '/dev/tty9',
+ description : 'specify the tty device for debug shell')
+option('debug', type : 'string',
+ description : 'enable extra debugging (hashmap,mmap-cache)')
+
+option('utmp', type : 'boolean',
+ description : 'support for utmp/wtmp log handling')
+option('hibernate', type : 'boolean',
+ description : 'support for hibernation')
+option('ldconfig', type : 'boolean',
+ description : 'support for dynamic linker cache creation')
+option('resolve', type : 'boolean',
+ description : 'systemd-resolved stack')
+option('efi', type : 'boolean',
+ description : 'enable systemd-boot and bootctl')
+option('tpm', type : 'boolean', value : false,
+ description : 'TPM should be used to log events and extend the registers')
+option('environment-d', type : 'boolean',
+ description : 'support for environment.d')
+option('binfmt', type : 'boolean',
+ description : 'support for custom binary formats')
+option('coredump', type : 'boolean',
+ description : 'install the coredump handler')
+option('logind', type : 'boolean',
+ description : 'install the systemd-logind stack')
+option('hostnamed', type : 'boolean',
+ description : 'install the systemd-hostnamed stack')
+option('localed', type : 'boolean',
+ description : 'install the systemd-localed stack')
+option('machined', type : 'boolean',
+ description : 'install the systemd-machined stack')
+option('networkd', type : 'boolean',
+ description : 'install the systemd-networkd stack')
+option('timedated', type : 'boolean',
+ description : 'install the systemd-timedated daemon')
+option('timesyncd', type : 'boolean',
+ description : 'install the systemd-timesyncd daemon')
+option('remote', type : 'boolean',
+ description : 'support for "journal over the network"')
+option('myhostname', type : 'boolean',
+ description : 'nss-myhostname support')
+option('firstboot', type : 'boolean',
+ description : 'support for firstboot mechanism')
+option('randomseed', type : 'boolean',
+ description : 'support for restoring random seed')
+option('backlight', type : 'boolean',
+ description : 'support for restoring backlight state')
+option('vconsole', type : 'boolean',
+ description : 'support for vconsole configuration')
+option('quotacheck', type : 'boolean',
+ description : 'support for the quotacheck tools')
+option('sysusers', type : 'boolean',
+ description : 'support for the sysusers configuration')
+option('tmpfiles', type : 'boolean',
+ description : 'support for tmpfiles.d')
+option('importd', type : 'boolean',
+ description : 'install the systemd-importd daemon')
+option('hwdb', type : 'boolean',
+ description : 'support for the hardware database')
+option('rfkill', type : 'boolean',
+ description : 'support for the rfkill tools')
+option('man', type : 'combo', choices : ['auto', 'true', 'false'],
+ description : 'build and install man pages')
+option('html', type : 'combo', choices : ['auto', 'true', 'false'],
+ value : 'false',
+ description : 'build and install html pages')
+
+option('certificate-root', type : 'string', value : '/etc/ssl',
+ description : 'the prefix for TLS certificates')
+option('dbuspolicydir', type : 'string',
+ description : 'D-Bus policy directory')
+option('dbussessionservicedir', type : 'string',
+ description : 'D-Bus session service directory')
+option('dbussystemservicedir', type : 'string',
+ description : 'D-Bus system service directory')
+option('pkgconfigdatadir', type : 'string', value : 'share/pkgconfig',
+ description : 'directory for ')
+option('pkgconfiglibdir', type : 'string', value : '',
+ description : 'directory for ')
+option('rpmmacrosdir', type : 'string', value : 'lib/rpm/macros.d',
+ description : 'directory for rpm macros ["no" disables]')
+option('pamlibdir', type : 'string',
+ description : 'directory for PAM modules')
+option('pamconfdir', type : 'string',
+ description : 'directory for PAM configuration ["no" disables]')
+
+option('fallback-hostname', type : 'string', value : 'localhost',
+ description : 'the hostname used if none configured')
+option('default-hierarchy', type : 'combo',
+ choices : ['legacy', 'hybrid', 'unified'], value : 'hybrid',
+ description : 'default cgroup hierarchy')
+option('time-epoch', type : 'string',
+ description : 'time epoch for time clients')
+option('system-uid-max', type : 'string',
+ description : 'maximum system UID')
+option('system-gid-max', type : 'string',
+ description : 'maximum system GID')
+option('tty-gid', type : 'string',
+ description : 'the numeric GID of the "tty" group',
+ value : '5')
+option('adm-group', type : 'boolean',
+ description : 'the ACL for adm group should be added')
+option('wheel-group', type : 'boolean',
+ description : 'the ACL for wheel group should be added')
+option('nobody-user', type : 'string',
+ description : 'The name of the nobody user (the one with UID 65534)',
+ value : 'nobody')
+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',
+ description : '/dev/kvm access mode')
+option('default-kill-user-processes', type : 'boolean',
+ description : 'the default value for KillUserProcesses= setting')
+option('gshadow', type : 'boolean',
+ description : 'support for shadow group')
+
+option('default-dnssec', type : 'combo',
+ description : 'default DNSSEC mode',
+ choices : ['yes', 'allow-downgrade', 'no'],
+ value : 'allow-downgrade')
+option('dns-servers', type : 'string',
+ description : 'space-separated list of default DNS servers',
+ value : '8.8.8.8 8.8.4.4 2001:4860:4860::8888 2001:4860:4860::8844')
+option('ntp-servers', type : 'string',
+ description : 'space-separated list of default NTP servers',
+ value : 'time1.google.com time2.google.com time3.google.com time4.google.com')
+option('support-url', type : 'string',
+ description : 'the support URL to show in catalog entries included in systemd',
+ value : 'https://lists.freedesktop.org/mailman/listinfo/systemd-devel')
+option('www-target', type : 'string',
+ description : 'the address and dir to upload docs too',
+ value : 'www.freedesktop.org:/srv/www.freedesktop.org/www/software/systemd')
+
+option('seccomp', type : 'combo', choices : ['auto', 'true', 'false'],
+ description : 'SECCOMP support')
+option('selinux', type : 'combo', choices : ['auto', 'true', 'false'],
+ description : 'SELinux support')
+option('apparmor', type : 'combo', choices : ['auto', 'true', 'false'],
+ description : 'AppArmor support')
+option('smack', type : 'boolean',
+ description : 'SMACK support')
+option('smack-run-label', type : 'string',
+ description : 'run systemd --system itself with a specific SMACK label')
+option('polkit', type : 'combo', choices : ['auto', 'true', 'false'],
+ description : 'PolicyKit support')
+option('ima', type : 'boolean',
+ description : 'IMA support')
+
+option('acl', type : 'combo', choices : ['auto', 'true', 'false'],
+ description : 'libacl support')
+option('audit', type : 'combo', choices : ['auto', 'true', 'false'],
+ description : 'libaudit support')
+option('blkid', type : 'combo', choices : ['auto', 'true', 'false'],
+ description : 'libblkid support')
+option('kmod', type : 'combo', choices : ['auto', 'true', 'false'],
+ description : 'support for loadable modules')
+option('pam', type : 'combo', choices : ['auto', 'true', 'false'],
+ description : 'PAM support')
+option('microhttpd', type : 'combo', choices : ['auto', 'true', 'false'],
+ description : 'libµhttpd support')
+option('libcryptsetup', type : 'combo', choices : ['auto', 'true', 'false'],
+ description : 'libcryptsetup support')
+option('libcurl', type : 'combo', choices : ['auto', 'true', 'false'],
+ description : 'libcurl support')
+option('idn', type : 'boolean',
+ description : 'use IDN when printing host names')
+option('libidn2', type : 'combo', choices : ['auto', 'true', 'false'],
+ description : 'libidn2 support')
+option('libidn', type : 'combo', choices : ['auto', 'true', 'false'],
+ description : 'libidn support')
+option('nss-systemd', type : 'boolean',
+ description : 'enable nss-systemd')
+option('libiptc', type : 'combo', choices : ['auto', 'true', 'false'],
+ description : 'libiptc support')
+option('qrencode', type : 'combo', choices : ['auto', 'true', 'false'],
+ description : 'libqrencode support')
+option('gcrypt', type : 'combo', choices : ['auto', 'true', 'false'],
+ description : 'gcrypt support')
+option('gnutls', type : 'combo', choices : ['auto', 'true', 'false'],
+ description : 'gnutls support')
+option('elfutils', type : 'combo', choices : ['auto', 'true', 'false'],
+ description : 'elfutils support')
+option('zlib', type : 'combo', choices : ['auto', 'true', 'false'],
+ description : 'zlib compression support')
+option('bzip2', type : 'combo', choices : ['auto', 'true', 'false'],
+ description : 'bzip2 compression support')
+option('xz', type : 'combo', choices : ['auto', 'true', 'false'],
+ description : 'xz compression support')
+option('lz4', type : 'combo', choices : ['auto', 'true', 'false'],
+ description : 'lz4 compression support')
+option('xkbcommon', type : 'combo', choices : ['auto', 'true', 'false'],
+ description : 'xkbcommon keymap support')
+option('glib', type : 'combo', choices : ['auto', 'true', 'false'],
+ description : 'libglib support (for tests only)')
+option('dbus', type : 'combo', choices : ['auto', 'true', 'false'],
+ description : 'libdbus support (for tests only)')
+
+option('gnu-efi', type : 'combo', choices : ['auto', 'true', 'false'],
+ description : 'gnu-efi support for sd-boot')
+option('efi-cc', type : 'string', value : 'gcc',
+ description : 'the compiler to use for EFI modules')
+option('efi-ld', type : 'string', value : 'ld',
+ description : 'the linker to use for EFI modules')
+option('efi-libdir', type : 'string',
+ description : 'path to the EFI lib directory')
+option('efi-ldsdir', type : 'string',
+ description : 'path to the EFI lds directory')
+option('efi-includedir', type : 'string', value : '/usr/include/efi',
+ description : 'path to the EFI header directory')
+option('tpm-pcrindex', type : 'string', value : '8',
+ description : 'TPM PCR register number to use')
+
+option('bashcompletiondir', type : 'string',
+ description : 'directory for bash completion scripts ["no" disables]')
+option('zshcompletiondir', type : 'string',
+ description : 'directory for zsh completion scripts ["no" disables]')
+
+option('tests', type : 'combo', choices : ['true', 'unsafe'],
+ description : 'enable extra tests with =unsafe')
+option('install-tests', type : 'boolean', value : 'false',
+ description : 'install test executables')
diff --git a/mkosi.build b/mkosi.build
index 872841eb63..2231118da5 100755
--- a/mkosi.build
+++ b/mkosi.build
@@ -20,11 +20,11 @@
# This is a build script for OS image generation using mkosi (https://github.com/systemd/mkosi).
# Simply invoke "mkosi" in the project directory to build an OS image.
-./autogen.sh c
-make -j `nproc`
-
-make check
-make install
+export LC_CTYPE=C.UTF-8
+meson build
+ninja -C build all
+ninja -C build test
+ninja -C build install
mkdir -p $DESTDIR/etc
diff --git a/network/meson.build b/network/meson.build
new file mode 100644
index 0000000000..e9f9bbae42
--- /dev/null
+++ b/network/meson.build
@@ -0,0 +1,12 @@
+if conf.get('ENABLE_NETWORKD', false)
+ install_data('80-container-host0.network',
+ '80-container-ve.network',
+ '80-container-vz.network',
+ install_dir : networkdir)
+
+ meson.add_install_script('sh', '-c',
+ mkdir_p.format(join_paths(sysconfdir, 'systemd/network')))
+endif
+
+install_data('99-default.link',
+ install_dir : networkdir)
diff --git a/po/LINGUAS b/po/LINGUAS
index bd283b6130..cc64eab997 100644
--- a/po/LINGUAS
+++ b/po/LINGUAS
@@ -17,6 +17,7 @@ ko
pl
pt_BR
ru
+sk
sr
sv
tr
diff --git a/po/cs.po b/po/cs.po
index 014ed4266c..9622c71054 100644
--- a/po/cs.po
+++ b/po/cs.po
@@ -1,15 +1,15 @@
# Czech translation for systemd.
-# Copyright (C) 2016 systemd's author and translators.
+# Copyright (C) 2016-2017 systemd's author and translators.
# This file is distributed under the same license as the systemd package.
-# Daniel Maixner <xskipy@gmail.com>, 2016
-# Daniel Rusek <mail@asciiwolf.com>, 2016
+# Daniel Maixner <xskipy@gmail.com>, 2016.
+# Daniel Rusek <mail@asciiwolf.com>, 2016, 2017.
#
msgid ""
msgstr ""
"Project-Id-Version: systemd master\n"
-"Report-Msgid-Bugs-To: \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-02-07 18:38+0100\n"
+"PO-Revision-Date: 2017-04-20 23:00+0200\n"
"Last-Translator: Daniel Rusek <mail@asciiwolf.com>\n"
"Language: cs\n"
"MIME-Version: 1.0\n"
@@ -26,36 +26,35 @@ msgstr "Odeslat heslo zpět do systému"
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:2
msgid "Authentication is required to send the entered passphrase back to the system."
-msgstr "Autentizace je vyžadována pro odeslání zadaného hesla do systému."
+msgstr "Pro odeslání zadaného hesla do systému je vyžadováno ověření."
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:3
msgid "Manage system services or other units"
-msgstr "Správa systémových služeb nebo dalších jednotek"
+msgstr "Spravovat systémové služby nebo další jednotky"
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:4
msgid "Authentication is required to manage system services or other units."
-msgstr ""
-"Autentizace je vyžadována pro správu systémových služeb nebo dalších jednotek."
+msgstr "Pro správu systémových služeb nebo dalších jednotek je vyžadováno ověření."
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:5
msgid "Manage system service or unit files"
-msgstr "Správa systémové služby nebo souborů jednotky"
+msgstr "Spravovat systémové služby nebo soubory jednotek"
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:6
msgid "Authentication is required to manage system service or unit files."
-msgstr "Autentizace je vyžadována pro správu systémové služby nebo souborů jednotky."
+msgstr "Pro správu systémových služeb nebo souborů jednotek je vyžadováno ověření."
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:7
msgid "Set or unset system and service manager environment variables"
-msgstr "Nastavení nebo rušení proměnných správce systému a služeb"
+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 ""
-"Autentizace je vyžadována pro nastavení nebo rušení proměnných správce systému a "
-"služeb."
+"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"
@@ -63,53 +62,51 @@ msgstr "Znovu načíst stav systemd"
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:10
msgid "Authentication is required to reload the systemd state."
-msgstr "Autentizace je vyžadována pro znovu načtení stavu systemd."
+msgstr "Pro znovu načtení stavu systemd je vyžadováno ověření."
#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:1
msgid "Set host name"
-msgstr "Nastavení názvu stroje"
+msgstr "Nastavit název stroje"
#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:2
msgid "Authentication is required to set the local host name."
-msgstr "Autentizace je vyžadována pro nastavení lokálního názvu stroje."
+msgstr "Pro nastavení lokálního názvu stroje je vyžadováno ověření."
#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:3
msgid "Set static host name"
-msgstr "Nastavení statického názvu stoje"
+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."
msgstr ""
-"Autentizace je vyžadována pro nastavení staticky konfigurovaného názvu lokálního "
-"stroje, stejně tak pro změnu uživatelsky přívětivého jména."
+"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"
-msgstr "Nastavení informací o stroji"
+msgstr "Nastavit informace o stroji"
#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:6
msgid "Authentication is required to set local machine information."
-msgstr "Autentizace je vyžadována pro nastavení informací o stroji."
+msgstr "Pro nastavení informací o stroji je vyžadováno ověření."
#: ../src/import/org.freedesktop.import1.policy.in.h:1
msgid "Import a VM or container image"
-msgstr "Import obrazu virtuální stroje nebo kontejneru"
+msgstr "Importovat obraz virtuální stroje nebo kontejneru"
#: ../src/import/org.freedesktop.import1.policy.in.h:2
msgid "Authentication is required to import a VM or container image"
-msgstr ""
-"Autentizace je vyžadována pro import obrazu virtuálního stroje nebo kontejneru"
+msgstr "Pro import obrazu virtuálního stroje nebo kontejneru je vyžadováno ověření"
#: ../src/import/org.freedesktop.import1.policy.in.h:3
msgid "Export a VM or container image"
-msgstr "Export obrazu virtuálního stroje nebo kontejneru"
+msgstr "Exportovat obraz virtuálního stroje nebo kontejneru"
#: ../src/import/org.freedesktop.import1.policy.in.h:4
msgid "Authentication is required to export a VM or container image"
-msgstr ""
-"Autentizace je vyžadována pro export obrazu virtuálního stroje nebo kontejneru"
+msgstr "Pro export obrazu virtuálního stroje nebo kontejneru je vyžadováno ověření"
#: ../src/import/org.freedesktop.import1.policy.in.h:5
msgid "Download a VM or container image"
@@ -117,24 +114,23 @@ msgstr "Stáhnout obraz virtuálního stroje nebo kontejneru"
#: ../src/import/org.freedesktop.import1.policy.in.h:6
msgid "Authentication is required to download a VM or container image"
-msgstr ""
-"Autentizace je vyžadována pro stažení obrazu virtuálního stroje nebo kontejneru"
+msgstr "Pro stažení obrazu virtuálního stroje nebo kontejneru je vyžadováno ověření"
#: ../src/locale/org.freedesktop.locale1.policy.in.h:1
msgid "Set system locale"
-msgstr "Nastavení lokalizace systému"
+msgstr "Nastavit lokalizaci systému"
#: ../src/locale/org.freedesktop.locale1.policy.in.h:2
msgid "Authentication is required to set the system locale."
-msgstr "Autentizace je vyžadována pro nastavení lokalizace systému."
+msgstr "Pro nastavení lokalizace systému je vyžadováno ověření."
#: ../src/locale/org.freedesktop.locale1.policy.in.h:3
msgid "Set system keyboard settings"
-msgstr "Nastavení systémové konfigurace klávesnice"
+msgstr "Nastavit systémovou konfiguraci klávesnice"
#: ../src/locale/org.freedesktop.locale1.policy.in.h:4
msgid "Authentication is required to set the system keyboard settings."
-msgstr "Autentizace je vyžadována pro nastavení systémové konfigurace klávesnice."
+msgstr "Pro nastavení systémové konfigurace klávesnice je vyžadováno ověření."
#: ../src/login/org.freedesktop.login1.policy.in.h:1
msgid "Allow applications to inhibit system shutdown"
@@ -142,7 +138,7 @@ msgstr "Povolit aplikacím zakázat vypnutí systému"
#: ../src/login/org.freedesktop.login1.policy.in.h:2
msgid "Authentication is required for an application to inhibit system shutdown."
-msgstr "Autentizace je vyžadována pro povolení aplikacím zakázat vypnutí systému."
+msgstr "Pro povolení aplikacím zakázat vypnutí systému je vyžadováno ověření."
#: ../src/login/org.freedesktop.login1.policy.in.h:3
msgid "Allow applications to delay system shutdown"
@@ -150,7 +146,7 @@ msgstr "Povolit aplikacím odložit vypnutí systému"
#: ../src/login/org.freedesktop.login1.policy.in.h:4
msgid "Authentication is required for an application to delay system shutdown."
-msgstr "Autentizace je vyžadována pro povolení aplikacím odložit vypnutí systému."
+msgstr "Pro povolení aplikacím odložit vypnutí systému je vyžadováno ověření."
#: ../src/login/org.freedesktop.login1.policy.in.h:5
msgid "Allow applications to inhibit system sleep"
@@ -158,7 +154,7 @@ msgstr "Povolit aplikacím zakázat uspání systému"
#: ../src/login/org.freedesktop.login1.policy.in.h:6
msgid "Authentication is required for an application to inhibit system sleep."
-msgstr "Autentizace je vyžadována pro povolení aplikacím zakázat uspání systému."
+msgstr "Pro povolení aplikacím zakázat uspání systému je vyžadováno ověření."
#: ../src/login/org.freedesktop.login1.policy.in.h:7
msgid "Allow applications to delay system sleep"
@@ -166,7 +162,7 @@ msgstr "Povolit aplikacím odložit uspání systému"
#: ../src/login/org.freedesktop.login1.policy.in.h:8
msgid "Authentication is required for an application to delay system sleep."
-msgstr "Autentizace je vyžadována pro povolení aplikacím odložit uspání systému."
+msgstr "Pro povolení aplikacím odložit uspání systému je vyžadováno ověření."
#: ../src/login/org.freedesktop.login1.policy.in.h:9
msgid "Allow applications to inhibit automatic system suspend"
@@ -176,8 +172,7 @@ msgstr "Povolit aplikacím zakázat automatické vypnutí systému"
msgid ""
"Authentication is required for an application to inhibit automatic system suspend."
msgstr ""
-"Autentizace je vyžadována pro povolení aplikacím zakázat automatické vypnutí "
-"systému."
+"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"
@@ -188,8 +183,8 @@ msgid ""
"Authentication is required for an application to inhibit system handling of the "
"power key."
msgstr ""
-"Autentizace je vyžadována pro povolení aplikacím zakázat chovaní systému na "
-"stisknutí vypínacího tlačítka."
+"Pro povolení aplikacím zakázat chovaní systému na stisknutí vypínacího tlačítka je "
+"vyžadováno ověření."
#: ../src/login/org.freedesktop.login1.policy.in.h:13
msgid "Allow applications to inhibit system handling of the suspend key"
@@ -200,8 +195,8 @@ msgid ""
"Authentication is required for an application to inhibit system handling of the "
"suspend key."
msgstr ""
-"Autentizace je vyžadována pro povolení aplikacím zakázat chovaní systému na "
-"stisknutí uspávacího tlačítka."
+"Pro povolení aplikacím zakázat chovaní systému na stisknutí uspávacího tlačítka je "
+"vyžadováno ověření."
#: ../src/login/org.freedesktop.login1.policy.in.h:15
msgid "Allow applications to inhibit system handling of the hibernate key"
@@ -212,8 +207,8 @@ msgid ""
"Authentication is required for an application to inhibit system handling of the "
"hibernate key."
msgstr ""
-"Autentizace je vyžadována pro povolení aplikacím zakázat chovaní systému na "
-"stisknutí tlačítka hibernace."
+"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"
@@ -224,8 +219,8 @@ msgid ""
"Authentication is required for an application to inhibit system handling of the "
"lid switch."
msgstr ""
-"Autentizace je vyžadována pro povolení aplikacím zakázat chovaní systému na "
-"zavření víka."
+"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"
@@ -234,7 +229,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 ""
-"Speciální požadavek je třeba ke spuštění programů jako nepřihlášený uživatel."
+"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"
@@ -242,33 +237,33 @@ msgstr "Povolit nepřihlášeným uživatelům spouštět programy"
#: ../src/login/org.freedesktop.login1.policy.in.h:22
msgid "Authentication is required to run programs as a non-logged-in user."
-msgstr "Autentizace je vyžadována ke spuštění programů jako nepřihlášený uživatel."
+msgstr "Ke spuštění programů jako nepřihlášený uživatel je vyžadováno ověření."
#: ../src/login/org.freedesktop.login1.policy.in.h:23
msgid "Allow attaching devices to seats"
-msgstr "Povolit připojování zařízení ke stanovišti"
+msgstr "Povolit připojování zařízení ke stanovištím"
#: ../src/login/org.freedesktop.login1.policy.in.h:24
msgid "Authentication is required for attaching a device to a seat."
-msgstr "Autentizace je vyžadována pro připojování zařízení ke stanovišti."
+msgstr "Pro připojování zařízení ke stanovišti je vyžadováno ověření."
#: ../src/login/org.freedesktop.login1.policy.in.h:25
msgid "Flush device to seat attachments"
-msgstr "Odstranění přiřazení zařízení ke stanovištím"
+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 ""
-"Autentizace je vyžadována pro reset způsobu jak jsou zařízení přiřazována ke "
-"stanovištím."
+"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"
-msgstr "Vypnutí systému"
+msgstr "Vypnout systém"
#: ../src/login/org.freedesktop.login1.policy.in.h:28
msgid "Authentication is required for powering off the system."
-msgstr "Autentizace je vyžadována pro vypnutí systému."
+msgstr "Pro vypnutí systému je vyžadováno ověření."
#: ../src/login/org.freedesktop.login1.policy.in.h:29
msgid "Power off the system while other users are logged in"
@@ -279,8 +274,7 @@ msgid ""
"Authentication is required for powering off the system while other users are "
"logged in."
msgstr ""
-"Autentizace je vyžadována pro vypnutí systému, když jsou přihlášeni další "
-"uživatelé."
+"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"
@@ -291,8 +285,7 @@ msgid ""
"Authentication is required for powering off the system while an application asked "
"to inhibit it."
msgstr ""
-"Autentizace je vyžadována pro vypnutí systému, když aplikace požádala o zákaz "
-"vypnutí."
+"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,7 +293,7 @@ msgstr "Restartovat systém"
#: ../src/login/org.freedesktop.login1.policy.in.h:34
msgid "Authentication is required for rebooting the system."
-msgstr "Autentizace je vyžadována pro restartovaní systému."
+msgstr "Pro restartování systému je vyžadováno ověření."
#: ../src/login/org.freedesktop.login1.policy.in.h:35
msgid "Reboot the system while other users are logged in"
@@ -311,8 +304,8 @@ msgid ""
"Authentication is required for rebooting the system while other users are logged "
"in."
msgstr ""
-"Autentizace je vyžadována pro restart systému, když jsou přihlášeni další "
-"uživatelé."
+"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"
@@ -323,16 +316,16 @@ msgid ""
"Authentication is required for rebooting the system while an application asked to "
"inhibit it."
msgstr ""
-"Autentizace je vyžadována pro restart systému, když aplikace požádala o zákaz "
-"restartu."
+"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 "Suspend the system"
-msgstr "Uspání systému"
+msgstr "Uspat systém"
#: ../src/login/org.freedesktop.login1.policy.in.h:40
msgid "Authentication is required for suspending the system."
-msgstr "Autentizace je vyžadována pro uspání systému."
+msgstr "Pro uspání systému je vyžadováno ověření."
#: ../src/login/org.freedesktop.login1.policy.in.h:41
msgid "Suspend the system while other users are logged in"
@@ -343,7 +336,7 @@ msgid ""
"Authentication is required for suspending the system while other users are logged "
"in."
msgstr ""
-"Autentizace je vyžadována pro uspání systému, když jsou přihlášeni další uživatelé."
+"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
msgid "Suspend the system while an application asked to inhibit it"
@@ -354,16 +347,15 @@ msgid ""
"Authentication is required for suspending the system while an application asked to "
"inhibit it."
msgstr ""
-"Autentizace je vyžadována pro uspání systému, když aplikace požádala o zákaz "
-"uspání."
+"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
msgid "Hibernate the system"
-msgstr "Hibernace systému"
+msgstr "Hibernovat systém"
#: ../src/login/org.freedesktop.login1.policy.in.h:46
msgid "Authentication is required for hibernating the system."
-msgstr "Autentizace je vyžadována k hibernaci systému."
+msgstr "Pro hibernaci systému je vyžadováno ověření."
#: ../src/login/org.freedesktop.login1.policy.in.h:47
msgid "Hibernate the system while other users are logged in"
@@ -374,37 +366,35 @@ msgid ""
"Authentication is required for hibernating the system while other users are logged "
"in."
msgstr ""
-"Autentizace je vyžadována pro hibernaci systému, když jsou přihlášeni další "
-"uživatelé."
+"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
msgid "Hibernate the system while an application asked to inhibit it"
-msgstr "Hibernace systému, i když aplikace požádala o zákaz hibernace"
+msgstr "Hibernovat systém, i když aplikace požádala o zákaz hibernace"
#: ../src/login/org.freedesktop.login1.policy.in.h:50
msgid ""
"Authentication is required for hibernating the system while an application asked "
"to inhibit it."
msgstr ""
-"Autentizace je vyžadována pro hibernaci systému, když aplikace požádala o zákaz "
-"hibernace."
+"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
msgid "Manage active sessions, users and seats"
-msgstr "Správa aktivních sezení, uživatelů a stanovišť"
+msgstr "Spravovat aktivní sezení, uživatele a stanoviště"
#: ../src/login/org.freedesktop.login1.policy.in.h:52
msgid "Authentication is required for managing active sessions, users and seats."
-msgstr ""
-"Autentizace je vyžadována pro správu aktivních sezení, uživatelů a stanovišť."
+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
msgid "Lock or unlock active sessions"
-msgstr "Zamčení nebo odemčení aktivních sezení"
+msgstr "Zamknout nebo odemknout aktivní sezení"
#: ../src/login/org.freedesktop.login1.policy.in.h:54
msgid "Authentication is required to lock or unlock active sessions."
-msgstr "Autentizace je vyžadována pro zamčení nebo odemčení aktivních sezení."
+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
msgid "Allow indication to the firmware to boot to setup interface"
@@ -414,8 +404,7 @@ msgstr "Povolit indikaci firmwaru bootovat instalační prostředí"
msgid ""
"Authentication is required to indicate to the firmware to boot to setup interface."
msgstr ""
-"Autentizace je vyžadována k povolení indikace firmwaru bootovat instalační "
-"prostředí."
+"K povolení indikace firmwaru bootovat instalační prostředí je vyžadováno ověření."
#: ../src/login/org.freedesktop.login1.policy.in.h:57
msgid "Set a wall message"
@@ -423,7 +412,7 @@ msgstr "Nastavit zprávu všem uživatelům"
#: ../src/login/org.freedesktop.login1.policy.in.h:58
msgid "Authentication is required to set a wall message"
-msgstr "Autentizace je vyžadována k nastavení zprávy všem uživatelům"
+msgstr "K nastavení zprávy všem uživatelům je vyžadováno ověření"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:1
msgid "Log into a local container"
@@ -431,7 +420,7 @@ msgstr "Přihlásit se do lokálního kontejneru"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:2
msgid "Authentication is required to log into a local container."
-msgstr "Autentizace je vyžadována pro přihlášení do lokálního kontejneru."
+msgstr "Pro přihlášení do lokálního kontejneru je vyžadováno ověření."
#: ../src/machine/org.freedesktop.machine1.policy.in.h:3
msgid "Log into the local host"
@@ -439,39 +428,39 @@ msgstr "Přihlásit se na lokální stroj"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:4
msgid "Authentication is required to log into the local host."
-msgstr "Autentizace je vyžadována pro přihlášení k lokálnímu stroji."
+msgstr "Pro přihlášení k lokálnímu stroji je vyžadováno ověření."
#: ../src/machine/org.freedesktop.machine1.policy.in.h:5
msgid "Acquire a shell in a local container"
-msgstr "Získání shellu v lokálním kontejneru"
+msgstr "Získat shell v lokálním kontejneru"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:6
msgid "Authentication is required to acquire a shell in a local container."
-msgstr "Autentizace je vyžadována pro získání shellu v lokálním kontejneru."
+msgstr "Pro získání shellu v lokálním kontejneru je vyžadováno ověření."
#: ../src/machine/org.freedesktop.machine1.policy.in.h:7
msgid "Acquire a shell on the local host"
-msgstr "Získání shellu na lokálním stroji"
+msgstr "Získat shell na lokálním stroji"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:8
msgid "Authentication is required to acquire a shell on the local host."
-msgstr "Autentizace je vyžadována pro získání shellu na lokálním stroji."
+msgstr "Pro získání shellu na lokálním stroji je vyžadováno ověření."
#: ../src/machine/org.freedesktop.machine1.policy.in.h:9
msgid "Acquire a pseudo TTY in a local container"
-msgstr "Získání Pseudo TTY v lokálním kontejneru"
+msgstr "Získat pseudo TTY v lokálním kontejneru"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:10
msgid "Authentication is required to acquire a pseudo TTY in a local container."
-msgstr "Autentizace je vyžadována pro získání pseudo TTY v lokálním kontejneru."
+msgstr "Pro získání pseudo TTY v lokálním kontejneru je vyžadováno ověření."
#: ../src/machine/org.freedesktop.machine1.policy.in.h:11
msgid "Acquire a pseudo TTY on the local host"
-msgstr "Získání pseudo TTY na lokálním stroji"
+msgstr "Získat pseudo TTY na lokálním stroji"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:12
msgid "Authentication is required to acquire a pseudo TTY on the local host."
-msgstr "Autentizace je vyžadována pro získání pseudo TTY na lokálním stroji."
+msgstr "Pro získání pseudo TTY na lokálním stroji je vyžadováno ověření."
#: ../src/machine/org.freedesktop.machine1.policy.in.h:13
msgid "Manage local virtual machines and containers"
@@ -479,8 +468,7 @@ msgstr "Spravovat lokální virtuální stroje a kontejnery"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:14
msgid "Authentication is required to manage local virtual machines and containers."
-msgstr ""
-"Autentizace je vyžadována pro správu lokálních virtuálních strojů a kontejnerů."
+msgstr "Pro správu lokálních virtuálních strojů a kontejnerů je vyžadováno ověření."
#: ../src/machine/org.freedesktop.machine1.policy.in.h:15
msgid "Manage local virtual machine and container images"
@@ -489,7 +477,8 @@ 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 "Autentizace je vyžadována ke správě obrazů virtuálních strojů a kontejnerů."
+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"
@@ -497,7 +486,7 @@ msgstr "Nastavit systémový čas"
#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:2
msgid "Authentication is required to set the system time."
-msgstr "Autentizace je vyžadována pro nastavení systémového času."
+msgstr "Pro nastavení systémového času je vyžadováno ověření."
#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:3
msgid "Set system timezone"
@@ -505,7 +494,7 @@ msgstr "Nastavit systémovou časovou zónu"
#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:4
msgid "Authentication is required to set the system timezone."
-msgstr "Autentizace je vyžadována pro nastavení systémové časové zóny."
+msgstr "Pro nastavení systémové časové zóny je vyžadováno ověření."
#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:5
msgid "Set RTC to local timezone or UTC"
@@ -515,8 +504,8 @@ msgstr "Nastavit RTC na lokální časovou zónu nebo UTC"
msgid ""
"Authentication is required to control whether the RTC stores the local or UTC time."
msgstr ""
-"Autentizace je vyžadována pro kontrolu jestli RTC ukládá lokální časovou zónu nebo "
-"UTC čas."
+"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"
@@ -526,32 +515,32 @@ msgstr "Zapnout nebo vypnout synchronizaci s časem ze sítě"
msgid ""
"Authentication is required to control whether network time synchronization shall "
"be enabled."
-msgstr "Autentizace je vyžadována pro kontrolu synchronizace času ze sítě."
+msgstr "Pro kontrolu synchronizace času ze sítě je vyžadováno ověření."
#: ../src/core/dbus-unit.c:459
msgid "Authentication is required to start '$(unit)'."
-msgstr "Autentizace je vyžadována pro spuštění „$(unit)”."
+msgstr "Pro spuštění „$(unit)” je vyžadováno ověření."
#: ../src/core/dbus-unit.c:460
msgid "Authentication is required to stop '$(unit)'."
-msgstr "Autentizace je vyžadována pro vypnutí „$(unit)”."
+msgstr "Pro vypnutí „$(unit)” je vyžadováno ověření."
#: ../src/core/dbus-unit.c:461
msgid "Authentication is required to reload '$(unit)'."
-msgstr "Autentizace je vyžadována pro znovu načtení „$(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
msgid "Authentication is required to restart '$(unit)'."
-msgstr "Autentizace je vyžadována pro restart „$(unit)”."
+msgstr "Pro restart „$(unit)” je vyžadováno ověření."
#: ../src/core/dbus-unit.c:570
msgid "Authentication is required to kill '$(unit)'."
-msgstr "Autentizace je vyžadována pro ukončení „$(unit)”."
+msgstr "Pro ukončení „$(unit)” je vyžadováno ověření."
#: ../src/core/dbus-unit.c:601
msgid "Authentication is required to reset the \"failed\" state of '$(unit)'."
-msgstr "Autentizace je vyžadována pro resetování chybného stavu „$(unit)”."
+msgstr "Pro resetování chybného stavu „$(unit)” je vyžadováno ověření."
#: ../src/core/dbus-unit.c:634
msgid "Authentication is required to set properties on '$(unit)'."
-msgstr "Autentizace je vyžadována pro nastavení vlastností na „$(unit)”."
+msgstr "Pro nastavení vlastností na „$(unit)” je vyžadováno ověření."
diff --git a/po/meson.build b/po/meson.build
new file mode 100644
index 0000000000..f89291bfc4
--- /dev/null
+++ b/po/meson.build
@@ -0,0 +1,12 @@
+i18n = import('i18n')
+i18n.gettext(meson.project_name())
+
+#####################################################################
+
+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/pt_BR.po b/po/pt_BR.po
index 2a11371f97..a087a4786b 100644
--- a/po/pt_BR.po
+++ b/po/pt_BR.po
@@ -1,23 +1,22 @@
# Brazilian Portuguese translation for systemd.
-# Copyright (C) 2015 systemd's COPYRIGHT HOLDER
+# Copyright (C) 2017 systemd's COPYRIGHT HOLDER
# This file is distributed under the same license as the systemd package.
-# Rafael Ferreira <rafael.f.f1@gmail.com>, 2014.
# Enrico Nicoletto <liverig@gmail.com>, 2014.
-#
+# Rafael Fontenelle <rafaelff@gnome.org>, 2015, 2017.
msgid ""
msgstr ""
"Project-Id-Version: systemd master\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-11-22 16:37+0100\n"
-"PO-Revision-Date: 2015-01-10 12:23-0300\n"
-"Last-Translator: Rafael Ferreira <rafael.f.f1@gmail.com>\n"
+"Report-Msgid-Bugs-To: https://github.com/systemd/systemd/issues\n"
+"POT-Creation-Date: 2016-11-17 03:29+0000\n"
+"PO-Revision-Date: 2017-04-03 14:25-0200\n"
+"Last-Translator: Rafael Fontenelle <rafaelff@gnome.org>\n"
"Language-Team: Brazilian Portuguese <gnome-pt_br-list@gnome.org>\n"
"Language: pt_BR\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
-"X-Generator: Poedit 1.7.1\n"
+"X-Generator: Virtaal 1.0.0-beta1\n"
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:1
msgid "Send passphrase back to system"
@@ -31,15 +30,14 @@ msgstr ""
"sistema."
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:3
-#, fuzzy
msgid "Manage system services or other units"
-msgstr "Gerenciar unidades e serviços do sistema"
+msgstr "Gerenciar serviços do sistema e outras unidades"
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:4
-#, fuzzy
msgid "Authentication is required to manage system services or other units."
msgstr ""
-"É necessária autenticação para gerenciar unidades e serviços do sistema."
+"É necessária autenticação para gerenciar serviços do sistema ou outras "
+"unidades."
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:5
msgid "Manage system service or unit files"
@@ -52,18 +50,18 @@ msgstr ""
"sistema."
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:7
-#, fuzzy
msgid "Set or unset system and service manager environment variables"
-msgstr "Acesso privilegiado ao gerenciador de serviço e de sistema"
+msgstr ""
+"Definir ou retirar definição de variáveis de ambiente de gerenciador de "
+"serviço e sistema"
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:8
-#, fuzzy
msgid ""
"Authentication is required to set or unset system and service manager "
"environment variables."
msgstr ""
-"É necessária autenticação para gerenciar arquivos \"unit\" e \"service\" do "
-"sistema."
+"É necessária autenticação para definir ou retirar definição de variáveis de "
+"ambiente de gerenciador de serviço e sistema."
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:9
msgid "Reload the systemd state"
@@ -103,30 +101,27 @@ msgstr "É necessária autenticação para definir informações de máquina loc
#: ../src/import/org.freedesktop.import1.policy.in.h:1
msgid "Import a VM or container image"
-msgstr ""
+msgstr "Importar uma VM ou imagem contêiner"
#: ../src/import/org.freedesktop.import1.policy.in.h:2
-#, fuzzy
msgid "Authentication is required to import a VM or container image"
-msgstr "É necessária autenticação para se conectar a um contêiner local."
+msgstr "É necessária autenticação para importar uma VM ou imagem contêiner"
#: ../src/import/org.freedesktop.import1.policy.in.h:3
msgid "Export a VM or container image"
-msgstr ""
+msgstr "Exportar uma VM ou imagem contêiner"
#: ../src/import/org.freedesktop.import1.policy.in.h:4
-#, fuzzy
msgid "Authentication is required to export a VM or container image"
-msgstr "É necessária autenticação para se conectar a um contêiner local."
+msgstr "É necessária autenticação para exportar uma VM ou imagem contêiner"
#: ../src/import/org.freedesktop.import1.policy.in.h:5
msgid "Download a VM or container image"
-msgstr ""
+msgstr "Baixar uma VM ou imagem contêiner"
#: ../src/import/org.freedesktop.import1.policy.in.h:6
-#, fuzzy
msgid "Authentication is required to download a VM or container image"
-msgstr "É necessária autenticação para se conectar a um contêiner local."
+msgstr "É necessária autenticação para baixar uma VM ou imagem contêiner"
#: ../src/locale/org.freedesktop.locale1.policy.in.h:1
msgid "Set system locale"
@@ -254,48 +249,61 @@ msgstr ""
"sistema sobre o interruptor da tela."
#: ../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 ""
+"Permitir que programas sejam executados por usuário que não possui sessão"
+
+#: ../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 ""
+"É necessária requisição explícita para executar programas como usuário sem "
+"sessão aberta."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:21
msgid "Allow non-logged-in users to run programs"
msgstr ""
"Permitir que programas sejam executados por usuários que não possuem sessão"
-#: ../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 ""
"É necessária autenticação para executar programas como usuário sem sessão "
"aberta."
-#: ../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 "Permitir conectar dispositivos em estações"
-#: ../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 "É necessária autenticação para conectar um dispositivo em uma estação."
-#: ../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 "Liberar dispositivo para conexões da estação"
-#: ../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 ""
"É necessária autenticação para redefinir a quantidade de dispositivos "
"conectados na estação."
-#: ../src/login/org.freedesktop.login1.policy.in.h:25
+#: ../src/login/org.freedesktop.login1.policy.in.h:27
msgid "Power off the system"
msgstr "Desligar o sistema"
-#: ../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 "É necessária autenticação para desligar o sistema."
-#: ../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 "Desligar o sistema enquanto outros usuários estão conectados"
-#: ../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."
@@ -303,11 +311,11 @@ msgstr ""
"É necessária autenticação para desligar o sistema enquanto outros usuários "
"estão conectados."
-#: ../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 "Desligar o sistema enquanto um aplicativo solicitou inibição"
-#: ../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."
@@ -315,19 +323,19 @@ msgstr ""
"É necessária autenticação para desligar o sistema enquanto um aplicativo "
"solicitou inibição."
-#: ../src/login/org.freedesktop.login1.policy.in.h:31
+#: ../src/login/org.freedesktop.login1.policy.in.h:33
msgid "Reboot the system"
msgstr "Reiniciar o sistema"
-#: ../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 "É necessária autenticação para reiniciar o sistema."
-#: ../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 "Reiniciar o sistema enquanto outros usuários estiverem conectados"
-#: ../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."
@@ -335,11 +343,11 @@ msgstr ""
"É necessária autenticação para reiniciar o sistema enquanto outros usuários "
"estiverem conectados."
-#: ../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 "Reiniciar o sistema enquanto um aplicativo solicitou inibição"
-#: ../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."
@@ -347,19 +355,19 @@ msgstr ""
"É necessária autenticação para reiniciar o sistema enquanto um aplicativo "
"solicitou inibição."
-#: ../src/login/org.freedesktop.login1.policy.in.h:37
+#: ../src/login/org.freedesktop.login1.policy.in.h:39
msgid "Suspend the system"
msgstr "Suspender o sistema"
-#: ../src/login/org.freedesktop.login1.policy.in.h:38
+#: ../src/login/org.freedesktop.login1.policy.in.h:40
msgid "Authentication is required for suspending the system."
msgstr "É necessária autenticação para suspender o sistema."
-#: ../src/login/org.freedesktop.login1.policy.in.h:39
+#: ../src/login/org.freedesktop.login1.policy.in.h:41
msgid "Suspend the system while other users are logged in"
msgstr "Suspender o sistema enquanto outros usuários estiverem conectados"
-#: ../src/login/org.freedesktop.login1.policy.in.h:40
+#: ../src/login/org.freedesktop.login1.policy.in.h:42
msgid ""
"Authentication is required for suspending the system while other users are "
"logged in."
@@ -367,11 +375,11 @@ msgstr ""
"É necessária autenticação para suspender o sistema enquanto outros usuários "
"estiverem conectados."
-#: ../src/login/org.freedesktop.login1.policy.in.h:41
+#: ../src/login/org.freedesktop.login1.policy.in.h:43
msgid "Suspend the system while an application asked to inhibit it"
msgstr "Suspender o sistema enquanto um aplicativo solicitou inibição"
-#: ../src/login/org.freedesktop.login1.policy.in.h:42
+#: ../src/login/org.freedesktop.login1.policy.in.h:44
msgid ""
"Authentication is required for suspending the system while an application "
"asked to inhibit it."
@@ -379,19 +387,19 @@ msgstr ""
"É necessária autenticação para suspender o sistema enquanto um aplicativo "
"solicitou inibição."
-#: ../src/login/org.freedesktop.login1.policy.in.h:43
+#: ../src/login/org.freedesktop.login1.policy.in.h:45
msgid "Hibernate the system"
msgstr "Hibernar o sistema"
-#: ../src/login/org.freedesktop.login1.policy.in.h:44
+#: ../src/login/org.freedesktop.login1.policy.in.h:46
msgid "Authentication is required for hibernating the system."
msgstr "É necessária autenticação para hibernar o sistema."
-#: ../src/login/org.freedesktop.login1.policy.in.h:45
+#: ../src/login/org.freedesktop.login1.policy.in.h:47
msgid "Hibernate the system while other users are logged in"
msgstr "Hibernar o sistema enquanto outros usuários estiverem conectados"
-#: ../src/login/org.freedesktop.login1.policy.in.h:46
+#: ../src/login/org.freedesktop.login1.policy.in.h:48
msgid ""
"Authentication is required for hibernating the system while other users are "
"logged in."
@@ -399,11 +407,11 @@ msgstr ""
"É necessária autenticação para hibernar o sistema enquanto outros usuários "
"estiverem conectados."
-#: ../src/login/org.freedesktop.login1.policy.in.h:47
+#: ../src/login/org.freedesktop.login1.policy.in.h:49
msgid "Hibernate the system while an application asked to inhibit it"
msgstr "Hibernar o sistema enquanto um aplicativo solicitou inibição"
-#: ../src/login/org.freedesktop.login1.policy.in.h:48
+#: ../src/login/org.freedesktop.login1.policy.in.h:50
msgid ""
"Authentication is required for hibernating the system while an application "
"asked to inhibit it."
@@ -411,123 +419,121 @@ msgstr ""
"É necessária autenticação para hibernar o sistema enquanto um aplicativo "
"solicitou inibição."
-#: ../src/login/org.freedesktop.login1.policy.in.h:49
+#: ../src/login/org.freedesktop.login1.policy.in.h:51
msgid "Manage active sessions, users and seats"
-msgstr ""
+msgstr "Gerenciar estações, usuários e sessões ativas"
-#: ../src/login/org.freedesktop.login1.policy.in.h:50
-#, fuzzy
+#: ../src/login/org.freedesktop.login1.policy.in.h:52
msgid ""
"Authentication is required for managing active sessions, users and seats."
-msgstr "É necessária autenticação para conectar um dispositivo em uma estação."
+msgstr ""
+"É necessária autenticação para gerenciar estações, usuários e sessões ativas."
-#: ../src/login/org.freedesktop.login1.policy.in.h:51
+#: ../src/login/org.freedesktop.login1.policy.in.h:53
msgid "Lock or unlock active sessions"
-msgstr ""
+msgstr "Travar ou destravar sessões ativas"
-#: ../src/login/org.freedesktop.login1.policy.in.h:52
-#, fuzzy
+#: ../src/login/org.freedesktop.login1.policy.in.h:54
msgid "Authentication is required to lock or unlock active sessions."
-msgstr "É necessária autenticação para se conectar a um contêiner local."
+msgstr "É necessária autenticação para travar ou destravar sessões ativas."
-#: ../src/login/org.freedesktop.login1.policy.in.h:53
+#: ../src/login/org.freedesktop.login1.policy.in.h:55
msgid "Allow indication to the firmware to boot to setup interface"
msgstr ""
+"Permitir indicação para o firmware inicializar para a interface de "
+"configuração"
-#: ../src/login/org.freedesktop.login1.policy.in.h:54
-#, fuzzy
+#: ../src/login/org.freedesktop.login1.policy.in.h:56
msgid ""
"Authentication is required to indicate to the firmware to boot to setup "
"interface."
-msgstr "É necessária autenticação para definir nome de máquina local."
+msgstr ""
+"É necessária autenticação para indicar para o firmware inicializar para a "
+"interface de configuração."
-#: ../src/login/org.freedesktop.login1.policy.in.h:55
+#: ../src/login/org.freedesktop.login1.policy.in.h:57
msgid "Set a wall message"
-msgstr ""
+msgstr "Definir uma mensagem de parede"
-#: ../src/login/org.freedesktop.login1.policy.in.h:56
-#, fuzzy
+#: ../src/login/org.freedesktop.login1.policy.in.h:58
msgid "Authentication is required to set a wall message"
-msgstr "É necessária autenticação para definir nome de máquina local."
+msgstr "É necessária autenticação para definir uma mensagem de parede"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:1
msgid "Log into a local container"
msgstr "Conectar a um contêiner local"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:2
-#, fuzzy
msgid "Authentication is required to log into a local container."
msgstr "É necessária autenticação para se conectar a um contêiner local."
#: ../src/machine/org.freedesktop.machine1.policy.in.h:3
-#, fuzzy
msgid "Log into the local host"
-msgstr "Conectar a um contêiner local"
+msgstr "Conectar a uma máquina local"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:4
-#, fuzzy
msgid "Authentication is required to log into the local host."
-msgstr "É necessária autenticação para se conectar a um contêiner local."
+msgstr "É necessária autenticação para se conectar a uma máquina local."
#: ../src/machine/org.freedesktop.machine1.policy.in.h:5
-#, fuzzy
msgid "Acquire a shell in a local container"
-msgstr "Conectar a um contêiner local"
+msgstr "Adquirir uma shell em um contêiner local"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:6
-#, fuzzy
msgid "Authentication is required to acquire a shell in a local container."
-msgstr "É necessária autenticação para se conectar a um contêiner local."
+msgstr ""
+"É necessária autenticação para adquirir uma shell em um contêiner local."
#: ../src/machine/org.freedesktop.machine1.policy.in.h:7
msgid "Acquire a shell on the local host"
-msgstr ""
+msgstr "Adquirir uma shell na máquina local"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:8
-#, fuzzy
msgid "Authentication is required to acquire a shell on the local host."
-msgstr "É necessária autenticação para definir nome de máquina local."
+msgstr ""
+"É necessária autenticação para adquirir uma shell em uma máquina local."
#: ../src/machine/org.freedesktop.machine1.policy.in.h:9
-#, fuzzy
msgid "Acquire a pseudo TTY in a local container"
-msgstr "Conectar a um contêiner local"
+msgstr "Adquirir um pseudo TTY em um contêiner local"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:10
-#, fuzzy
msgid ""
"Authentication is required to acquire a pseudo TTY in a local container."
-msgstr "É necessária autenticação para se conectar a um contêiner local."
+msgstr ""
+"É necessária autenticação para adquirir um pseudo TTY em um contêiner local."
#: ../src/machine/org.freedesktop.machine1.policy.in.h:11
msgid "Acquire a pseudo TTY on the local host"
-msgstr ""
+msgstr "Adquiri um pseudo TTY na máquina local"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:12
-#, fuzzy
msgid "Authentication is required to acquire a pseudo TTY on the local host."
-msgstr "É necessária autenticação para definir nome de máquina local."
+msgstr ""
+"É necessária autenticação para adquirir um pseudo TTY em um máquina local."
#: ../src/machine/org.freedesktop.machine1.policy.in.h:13
msgid "Manage local virtual machines and containers"
-msgstr ""
+msgstr "Gerenciar máquinas virtuais locais e contêineres"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:14
-#, fuzzy
msgid ""
"Authentication is required to manage local virtual machines and containers."
-msgstr "É necessária autenticação para definir informações de máquina local."
+msgstr ""
+"É necessária autenticação para gerenciar máquinas virtuais locais e "
+"contêineres."
#: ../src/machine/org.freedesktop.machine1.policy.in.h:15
msgid "Manage local virtual machine and container images"
-msgstr ""
+msgstr "Gerenciar máquinas virtuais locais e imagens contêineres"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:16
-#, fuzzy
msgid ""
"Authentication is required to manage local virtual machine and container "
"images."
-msgstr "É necessária autenticação para definir informações de máquina local."
+msgstr ""
+"É necessária autenticação para gerenciar máquinas virtuais locais e imagens "
+"contêineres."
#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:1
msgid "Set system time"
@@ -569,37 +575,31 @@ msgstr ""
"É necessária autenticação para controlar se deve ser habilitada, ou não, a "
"sincronização de horário através de rede."
-#: ../src/core/dbus-unit.c:428
-#, fuzzy
+#: ../src/core/dbus-unit.c:457
msgid "Authentication is required to start '$(unit)'."
-msgstr "É necessária autenticação para definir o horário do sistema."
+msgstr "É necessária autenticação para iniciar '$(unit)'."
-#: ../src/core/dbus-unit.c:429
-#, fuzzy
+#: ../src/core/dbus-unit.c:458
msgid "Authentication is required to stop '$(unit)'."
-msgstr "É necessária autenticação para definir o horário do sistema."
+msgstr "É necessária autenticação para parar '$(unit)'."
-#: ../src/core/dbus-unit.c:430
-#, fuzzy
+#: ../src/core/dbus-unit.c:459
msgid "Authentication is required to reload '$(unit)'."
-msgstr "É necessária autenticação para recarregar o estado do sistema."
+msgstr "É necessária autenticação para recarregar '$(unit)'."
-#: ../src/core/dbus-unit.c:431 ../src/core/dbus-unit.c:432
-#, fuzzy
+#: ../src/core/dbus-unit.c:460 ../src/core/dbus-unit.c:461
msgid "Authentication is required to restart '$(unit)'."
-msgstr "É necessária autenticação para definir o horário do sistema."
+msgstr "É necessária autenticação para reiniciar '$(unit)'."
-#: ../src/core/dbus-unit.c:535
-#, fuzzy
+#: ../src/core/dbus-unit.c:568
msgid "Authentication is required to kill '$(unit)'."
-msgstr "É necessária autenticação para se conectar a um contêiner local."
+msgstr "É necessária autenticação para matar '$(unit)'."
-#: ../src/core/dbus-unit.c:565
-#, fuzzy
+#: ../src/core/dbus-unit.c:599
msgid "Authentication is required to reset the \"failed\" state of '$(unit)'."
-msgstr "É necessária autenticação para definir nome de máquina local."
+msgstr ""
+"É necessária autenticação para reiniciar o estado \"failed\" de '$(unit)'."
-#: ../src/core/dbus-unit.c:597
-#, fuzzy
+#: ../src/core/dbus-unit.c:632
msgid "Authentication is required to set properties on '$(unit)'."
-msgstr "É necessária autenticação para definir o horário do sistema."
+msgstr "É necessária autenticação para definir propriedades em '$(unit)'."
diff --git a/po/sk.po b/po/sk.po
new file mode 100644
index 0000000000..84dd7326fe
--- /dev/null
+++ b/po/sk.po
@@ -0,0 +1,556 @@
+# Slovak translation for systemd.
+# Copyright (C) 2017 systemd's COPYRIGHT HOLDER
+# This file is distributed under the same license as the systemd package.
+# Dušan Kazik <prescott66@gmail.com>, 2017.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: systemd master\n"
+"Report-Msgid-Bugs-To: https://github.com/systemd/systemd/issues\n"
+"POT-Creation-Date: 2017-06-24 03:26+0000\n"
+"PO-Revision-Date: 2017-06-25 11:03+0200\n"
+"Language-Team: Slovak <gnome-sk-list@gnome.org>\n"
+"Language: sk\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) ? 1 : (n>=2 && n<=4) ? 2 : 0;\n"
+"Last-Translator: Dušan Kazik <prescott66@gmail.com>\n"
+"X-Generator: Poedit 2.0.2\n"
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:1
+msgid "Send passphrase back to system"
+msgstr "Odoslanie hesla späť do systému"
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:2
+msgid ""
+"Authentication is required to send the entered passphrase back to the system."
+msgstr ""
+"Vyžaduje sa overenie totožnosti na odoslanie zadaného hesla späť do systému."
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:3
+msgid "Manage system services or other units"
+msgstr "Správa systémových služieb alebo iných jednotiek"
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:4
+msgid "Authentication is required to manage system services or other units."
+msgstr ""
+"Vyžaduje sa overenie totožnosti na správu systémových služieb alebo iných "
+"jednotiek."
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:5
+msgid "Manage system service or unit files"
+msgstr "Správa systémovej služby alebo súborov jednotky"
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:6
+msgid "Authentication is required to manage system service or unit files."
+msgstr ""
+"Vyžaduje sa overenie totožnosti na správu systémovej služby alebo súborov "
+"jednotky."
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:7
+msgid "Set or unset system and service manager environment variables"
+msgstr ""
+"Nastavenie alebo zrušenie nastavenia premenných prostredia systému a správcu "
+"služieb"
+
+#: ../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 ""
+"Vyžaduje sa overenie totožnosti na nastavenie alebo zrušenie nastavenia "
+"premenných prostredia systému a správcu služieb."
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:9
+msgid "Reload the systemd state"
+msgstr "Znovu načítanie stavu systému systemd"
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:10
+msgid "Authentication is required to reload the systemd state."
+msgstr ""
+"Vyžaduje sa overenie totožnosti na znovu načítanie stavu systému systemd."
+
+#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:1
+msgid "Set host name"
+msgstr "Nastavenie názvu hostiteľa"
+
+#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:2
+msgid "Authentication is required to set the local host name."
+msgstr "Vyžaduje sa overenie totožnosti na nastavenie názvu hostiteľa."
+
+#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:3
+msgid "Set static host name"
+msgstr "Nastavenie nemenného názvu hostiteľa"
+
+#: ../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."
+msgstr ""
+"Vyžaduje sa overenie totožnosti na nastavenie pevne určeného názvu miestneho "
+"hostiteľa, známeho ako zrozumiteľný názov hostiteľa."
+
+#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:5
+msgid "Set machine information"
+msgstr "Nastavenie informácií o počítači"
+
+#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:6
+msgid "Authentication is required to set local machine information."
+msgstr ""
+"Vyžaduje sa overenie totožnosti na nastavenie informácií o miestnom počítači."
+
+#: ../src/import/org.freedesktop.import1.policy.in.h:1
+msgid "Import a VM or container image"
+msgstr ""
+
+#: ../src/import/org.freedesktop.import1.policy.in.h:2
+msgid "Authentication is required to import a VM or container image"
+msgstr ""
+
+#: ../src/import/org.freedesktop.import1.policy.in.h:3
+msgid "Export a VM or container image"
+msgstr ""
+
+#: ../src/import/org.freedesktop.import1.policy.in.h:4
+msgid "Authentication is required to export a VM or container image"
+msgstr ""
+
+#: ../src/import/org.freedesktop.import1.policy.in.h:5
+msgid "Download a VM or container image"
+msgstr ""
+
+#: ../src/import/org.freedesktop.import1.policy.in.h:6
+msgid "Authentication is required to download a VM or container image"
+msgstr ""
+
+#: ../src/locale/org.freedesktop.locale1.policy.in.h:1
+msgid "Set system locale"
+msgstr "Nastavenie miestnych nastavení"
+
+#: ../src/locale/org.freedesktop.locale1.policy.in.h:2
+msgid "Authentication is required to set the system locale."
+msgstr "Vyžaduje sa overenie totožnosti na nastavenie miestnych nastavení."
+
+#: ../src/locale/org.freedesktop.locale1.policy.in.h:3
+msgid "Set system keyboard settings"
+msgstr "Nastavenie nastavení systémovej klávesnice"
+
+#: ../src/locale/org.freedesktop.locale1.policy.in.h:4
+msgid "Authentication is required to set the system keyboard settings."
+msgstr ""
+"Vyžaduje sa overenie totožnosti na nastavenie nastavení systémovej "
+"klávesnice."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:1
+msgid "Allow applications to inhibit system shutdown"
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:2
+msgid ""
+"Authentication is required for an application to inhibit system shutdown."
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:3
+msgid "Allow applications to delay system shutdown"
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:4
+msgid "Authentication is required for an application to delay system shutdown."
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:5
+msgid "Allow applications to inhibit system sleep"
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:6
+msgid "Authentication is required for an application to inhibit system sleep."
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:7
+msgid "Allow applications to delay system sleep"
+msgstr "Umožnenie aplikáciám odložiť spánok systému"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:8
+msgid "Authentication is required for an application to delay system sleep."
+msgstr ""
+"Vyžaduje sa overenie totožnosti na odloženie spánku systému aplikáciou."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:9
+msgid "Allow applications to inhibit automatic system suspend"
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:10
+msgid ""
+"Authentication is required for an application to inhibit automatic system "
+"suspend."
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:11
+msgid "Allow applications to inhibit system handling of the power key"
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:12
+msgid ""
+"Authentication is required for an application to inhibit system handling of "
+"the power key."
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:13
+msgid "Allow applications to inhibit system handling of the suspend key"
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:14
+msgid ""
+"Authentication is required for an application to inhibit system handling of "
+"the suspend key."
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:15
+msgid "Allow applications to inhibit system handling of the hibernate key"
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:16
+msgid ""
+"Authentication is required for an application to inhibit system handling of "
+"the hibernate key."
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:17
+msgid "Allow applications to inhibit system handling of the lid switch"
+msgstr ""
+
+#: ../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 ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:19
+msgid "Allow non-logged-in user to run programs"
+msgstr "Umožnenie neprihlásenému používateľovi spúšťanie programov"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:20
+msgid "Explicit request is required to run programs as a non-logged-in user."
+msgstr ""
+"Vyžaduje sa explicitná požiadavka na spúšťanie programov ako neprihlásený "
+"používateľ."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:21
+msgid "Allow non-logged-in users to run programs"
+msgstr "Umožnenie neprihláseným používateľom spúšťanie programov"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:22
+msgid "Authentication is required to run programs as a non-logged-in user."
+msgstr ""
+"Vyžaduje sa overenie totožnosti na spúšťanie programov ako neprihlásený "
+"používateľ."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:23
+msgid "Allow attaching devices to seats"
+msgstr ""
+
+#: ../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:25
+msgid "Flush device to seat attachments"
+msgstr ""
+
+#: ../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:27
+msgid "Power off the system"
+msgstr "Vypnutie systému"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:28
+msgid "Authentication is required for powering off the system."
+msgstr "Vyžaduje sa overenie totožnosti na vypnutie systému."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:29
+msgid "Power off the system while other users are logged in"
+msgstr "Vypnutie systému, pokiaľ sú prihlásení iní používatelia"
+
+#: ../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 ""
+"Vyžaduje sa overenie totožnosti na vypnutie systému, pokiaľ sú prihlásení "
+"iní používatelia."
+
+#: ../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:32
+msgid ""
+"Authentication is required for powering off the system while an application "
+"asked to inhibit it."
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:33
+msgid "Reboot the system"
+msgstr "Reštart systému"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:34
+msgid "Authentication is required for rebooting the system."
+msgstr "Vyžaduje sa overenie totožnosti na reštartovanie systému."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:35
+msgid "Reboot the system while other users are logged in"
+msgstr "Reštart systému, pokiaľ sú prihlásení iní používatelia"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:36
+msgid ""
+"Authentication is required for rebooting the system while other users are "
+"logged in."
+msgstr ""
+"Vyžaduje sa overenie totožnosti na reštartovanie systému, pokiaľ sú "
+"prihlásení iní používatelia."
+
+#: ../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:38
+msgid ""
+"Authentication is required for rebooting the system while an application "
+"asked to inhibit it."
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:39
+msgid "Suspend the system"
+msgstr "Uspanie systému"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:40
+msgid "Authentication is required for suspending the system."
+msgstr "Vyžaduje sa overenie totožnosti na uspanie systému."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:41
+msgid "Suspend the system while other users are logged in"
+msgstr "Uspanie systému, pokiaľ sú prihlásení iní používatelia"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:42
+msgid ""
+"Authentication is required for suspending the system while other users are "
+"logged in."
+msgstr ""
+"Vyžaduje sa overenie totožnosti na uspanie systému, pokiaľ sú prihlásení iní "
+"používatelia."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:43
+msgid "Suspend the system while an application asked to inhibit it"
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:44
+msgid ""
+"Authentication is required for suspending the system while an application "
+"asked to inhibit it."
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:45
+msgid "Hibernate the system"
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:46
+msgid "Authentication is required for hibernating the system."
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:47
+msgid "Hibernate the system while other users are logged in"
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:48
+msgid ""
+"Authentication is required for hibernating the system while other users are "
+"logged in."
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:49
+msgid "Hibernate the system while an application asked to inhibit it"
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:50
+msgid ""
+"Authentication is required for hibernating the system while an application "
+"asked to inhibit it."
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:51
+msgid "Manage active sessions, users and seats"
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:52
+msgid ""
+"Authentication is required for managing active sessions, users and seats."
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:53
+msgid "Lock or unlock active sessions"
+msgstr "Zamknutie alebo odomknutie aktívnych relácií"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:54
+msgid "Authentication is required to lock or unlock active sessions."
+msgstr ""
+"Vyžaduje sa overenie totožnosti na uzamknutie alebo odomknutie aktívnych "
+"relácií."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:55
+msgid "Allow indication to the firmware to boot to setup interface"
+msgstr "Umožnenie indikácie spustenia inštalačného rozhrania pre firmvér"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:56
+msgid ""
+"Authentication is required to indicate to the firmware to boot to setup "
+"interface."
+msgstr ""
+"Vyžaduje sa overenie totožnosti na indikáciu spustenia inštalačného "
+"rozhrania pre firmvér."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:57
+msgid "Set a wall message"
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:58
+msgid "Authentication is required to set a wall message"
+msgstr ""
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:1
+msgid "Log into a local container"
+msgstr "Prihlásenie do miestneho kontajneru"
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:2
+msgid "Authentication is required to log into a local container."
+msgstr ""
+"Vyžaduje sa overenie totožnosti na prihlásenie do miestneho kontajneru."
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:3
+msgid "Log into the local host"
+msgstr ""
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:4
+msgid "Authentication is required to log into the local host."
+msgstr ""
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:5
+msgid "Acquire a shell in a local container"
+msgstr ""
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:6
+msgid "Authentication is required to acquire a shell in a local container."
+msgstr ""
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:7
+msgid "Acquire a shell on the local host"
+msgstr ""
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:8
+msgid "Authentication is required to acquire a shell on the local host."
+msgstr ""
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:9
+msgid "Acquire a pseudo TTY in a local container"
+msgstr ""
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:10
+msgid ""
+"Authentication is required to acquire a pseudo TTY in a local container."
+msgstr ""
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:11
+msgid "Acquire a pseudo TTY on the local host"
+msgstr ""
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:12
+msgid "Authentication is required to acquire a pseudo TTY on the local host."
+msgstr ""
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:13
+msgid "Manage local virtual machines and containers"
+msgstr ""
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:14
+msgid ""
+"Authentication is required to manage local virtual machines and containers."
+msgstr ""
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:15
+msgid "Manage local virtual machine and container images"
+msgstr ""
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:16
+msgid ""
+"Authentication is required to manage local virtual machine and container "
+"images."
+msgstr ""
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:1
+msgid "Set system time"
+msgstr ""
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:2
+msgid "Authentication is required to set the system time."
+msgstr ""
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:3
+msgid "Set system timezone"
+msgstr ""
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:4
+msgid "Authentication is required to set the system timezone."
+msgstr ""
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:5
+msgid "Set RTC to local timezone or UTC"
+msgstr ""
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:6
+msgid ""
+"Authentication is required to control whether the RTC stores the local or "
+"UTC time."
+msgstr ""
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:7
+msgid "Turn network time synchronization on or off"
+msgstr "Zapnutie alebo vypnutie sieťovej synchronizácie času"
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:8
+msgid ""
+"Authentication is required to control whether network time synchronization "
+"shall be enabled."
+msgstr ""
+"Vyžaduje sa overenie totožnosti na ovládanie, či má byť povolená "
+"synchronizácia času cez sieť."
+
+#: ../src/core/dbus-unit.c:457
+msgid "Authentication is required to start '$(unit)'."
+msgstr ""
+
+#: ../src/core/dbus-unit.c:458
+msgid "Authentication is required to stop '$(unit)'."
+msgstr ""
+
+#: ../src/core/dbus-unit.c:459
+msgid "Authentication is required to reload '$(unit)'."
+msgstr ""
+
+#: ../src/core/dbus-unit.c:460 ../src/core/dbus-unit.c:461
+msgid "Authentication is required to restart '$(unit)'."
+msgstr ""
+
+#: ../src/core/dbus-unit.c:568
+msgid "Authentication is required to kill '$(unit)'."
+msgstr ""
+
+#: ../src/core/dbus-unit.c:599
+msgid "Authentication is required to reset the \"failed\" state of '$(unit)'."
+msgstr ""
+
+#: ../src/core/dbus-unit.c:632
+msgid "Authentication is required to set properties on '$(unit)'."
+msgstr ""
diff --git a/po/sv.po b/po/sv.po
index 6ecf5479a4..1de9b4650d 100644
--- a/po/sv.po
+++ b/po/sv.po
@@ -1,24 +1,23 @@
# Swedish translation for systemd.
# Copyright © 2015 systemd's COPYRIGHT HOLDER
# This file is distributed under the same license as the systemd package.
-# Josef Andersson <josef.andersson@fripost.org>, 2015.
# Sebastian Rasmussen <sebras@gmail.com>, 2015.
# Andreas Henriksson <andreas@fatal.se>, 2016.
-#
+# Josef Andersson <l10nl18nsweja@gmail.com>, 2015, 2017.
msgid ""
msgstr ""
"Project-Id-Version: systemd master\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-11-22 16:37+0100\n"
-"PO-Revision-Date: 2016-09-29 11:58+0200\n"
-"Last-Translator: Andreas Henriksson <andreas@fatal.se>\n"
+"Report-Msgid-Bugs-To: https://github.com/systemd/systemd/issues\n"
+"POT-Creation-Date: 2017-03-01 15:50+0000\n"
+"PO-Revision-Date: 2017-03-19 21:18+0100\n"
+"Last-Translator: Josef Andersson <l10nl18nsweja@gmail.com>\n"
"Language-Team: Swedish\n"
"Language: sv\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Gtranslator 2.91.7\n"
+"X-Generator: Poedit 1.8.9\n"
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:1
msgid "Send passphrase back to system"
@@ -134,7 +133,8 @@ msgstr "Ange systeminställningar för tangentbord"
#: ../src/locale/org.freedesktop.locale1.policy.in.h:4
msgid "Authentication is required to set the system keyboard settings."
-msgstr "Autentisering krävs för att ställa in systeminställningar för tangentbord."
+msgstr ""
+"Autentisering krävs för att ställa in systeminställningar för tangentbord."
#: ../src/login/org.freedesktop.login1.policy.in.h:1
msgid "Allow applications to inhibit system shutdown"
@@ -237,45 +237,54 @@ msgstr ""
"av brytaren för datorhöljet."
#: ../src/login/org.freedesktop.login1.policy.in.h:19
+msgid "Allow non-logged-in user to run programs"
+msgstr "Tillåt ej inloggad användare att köra program"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:20
+msgid "Explicit request is required to run programs as a non-logged-in user."
+msgstr ""
+"Uttrycklig begäran krävs för att köra program som en icke inloggad användare."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:21
msgid "Allow non-logged-in users to run programs"
msgstr "Tillåt ej inloggade användare att köra program"
-#: ../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 ""
"Autentisering krävs för att köra program som en icke inloggad användare."
-#: ../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 "Tillåt att binda enheter till platser"
-#: ../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 "Autentisering krävs för att binda en enhet till en plats."
-#: ../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 "Töm bindningar för enhet-till-plats"
-#: ../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 ""
"Autentisering krävs för att återställa hur enheter är bundna till platser."
-#: ../src/login/org.freedesktop.login1.policy.in.h:25
+#: ../src/login/org.freedesktop.login1.policy.in.h:27
msgid "Power off the system"
msgstr "Stäng av systemet"
-#: ../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 "Autentisering krävs för att stänga av systemet."
-#: ../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 "Stäng av systemet medan andra användare är inloggade"
-#: ../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."
@@ -283,11 +292,11 @@ msgstr ""
"Autentisering krävs för att stänga av systemet medan andra användare är "
"inloggade."
-#: ../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 "Stäng av systemet även då ett program hindrar det"
-#: ../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."
@@ -295,19 +304,19 @@ msgstr ""
"Autentisering krävs för att stänga av systemet även då ett program hindrar "
"det."
-#: ../src/login/org.freedesktop.login1.policy.in.h:31
+#: ../src/login/org.freedesktop.login1.policy.in.h:33
msgid "Reboot the system"
msgstr "Starta om systemet"
-#: ../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 "Autentisering krävs för att starta om systemet."
-#: ../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 "Starta om systemet medan andra användare är inloggade"
-#: ../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."
@@ -315,11 +324,11 @@ msgstr ""
"Autentisering krävs för att starta om systemet medan andra användare är "
"inloggade."
-#: ../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 "Starta om systemet även då ett program hindrar det"
-#: ../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."
@@ -327,19 +336,19 @@ msgstr ""
"Autentisering krävs för att starta om systemet även då ett program hindrar "
"det."
-#: ../src/login/org.freedesktop.login1.policy.in.h:37
+#: ../src/login/org.freedesktop.login1.policy.in.h:39
msgid "Suspend the system"
msgstr "Försätt system i vänteläge"
-#: ../src/login/org.freedesktop.login1.policy.in.h:38
+#: ../src/login/org.freedesktop.login1.policy.in.h:40
msgid "Authentication is required for suspending the system."
msgstr "Autentisering krävs för att försätta system i vänteläge."
-#: ../src/login/org.freedesktop.login1.policy.in.h:39
+#: ../src/login/org.freedesktop.login1.policy.in.h:41
msgid "Suspend the system while other users are logged in"
msgstr "Försätt systemet i vänteläge medan andra användare är inloggade"
-#: ../src/login/org.freedesktop.login1.policy.in.h:40
+#: ../src/login/org.freedesktop.login1.policy.in.h:42
msgid ""
"Authentication is required for suspending the system while other users are "
"logged in."
@@ -347,11 +356,11 @@ msgstr ""
"Autentisering krävs för att försätta systemet i vänteläge medan andra "
"användare är inloggade."
-#: ../src/login/org.freedesktop.login1.policy.in.h:41
+#: ../src/login/org.freedesktop.login1.policy.in.h:43
msgid "Suspend the system while an application asked to inhibit it"
msgstr "Försätt systemet i vänteläge även då ett program hindrar det"
-#: ../src/login/org.freedesktop.login1.policy.in.h:42
+#: ../src/login/org.freedesktop.login1.policy.in.h:44
msgid ""
"Authentication is required for suspending the system while an application "
"asked to inhibit it."
@@ -359,19 +368,19 @@ msgstr ""
"Autentisering krävs för att försätta ett program i vänteläge även då ett "
"program hindrar det."
-#: ../src/login/org.freedesktop.login1.policy.in.h:43
+#: ../src/login/org.freedesktop.login1.policy.in.h:45
msgid "Hibernate the system"
msgstr "Försätt systemet i viloläge"
-#: ../src/login/org.freedesktop.login1.policy.in.h:44
+#: ../src/login/org.freedesktop.login1.policy.in.h:46
msgid "Authentication is required for hibernating the system."
msgstr "Autentisering krävs för att försätta systemet i viloläge."
-#: ../src/login/org.freedesktop.login1.policy.in.h:45
+#: ../src/login/org.freedesktop.login1.policy.in.h:47
msgid "Hibernate the system while other users are logged in"
msgstr "Försätt systemet i viloläge medan andra användare är inloggade"
-#: ../src/login/org.freedesktop.login1.policy.in.h:46
+#: ../src/login/org.freedesktop.login1.policy.in.h:48
msgid ""
"Authentication is required for hibernating the system while other users are "
"logged in."
@@ -379,11 +388,11 @@ msgstr ""
"Autentisering krävs för att försätta systemet i viloläge medan andra "
"användare är inloggade."
-#: ../src/login/org.freedesktop.login1.policy.in.h:47
+#: ../src/login/org.freedesktop.login1.policy.in.h:49
msgid "Hibernate the system while an application asked to inhibit it"
msgstr "Försätt systemet i viloläge även då ett program hindrar det"
-#: ../src/login/org.freedesktop.login1.policy.in.h:48
+#: ../src/login/org.freedesktop.login1.policy.in.h:50
msgid ""
"Authentication is required for hibernating the system while an application "
"asked to inhibit it."
@@ -391,30 +400,30 @@ msgstr ""
"Autentisering krävs för att försätta ett program i viloläge även då ett "
"program hindrar det."
-#: ../src/login/org.freedesktop.login1.policy.in.h:49
+#: ../src/login/org.freedesktop.login1.policy.in.h:51
msgid "Manage active sessions, users and seats"
msgstr "Hantera aktiva sessioner, användare och platser"
-#: ../src/login/org.freedesktop.login1.policy.in.h:50
+#: ../src/login/org.freedesktop.login1.policy.in.h:52
msgid ""
"Authentication is required for managing active sessions, users and seats."
msgstr ""
"Autentisering krävs för att hantera aktiva sessioner, användare och platser."
-#: ../src/login/org.freedesktop.login1.policy.in.h:51
+#: ../src/login/org.freedesktop.login1.policy.in.h:53
msgid "Lock or unlock active sessions"
msgstr "Lås eller lås upp aktiva sessioner"
-#: ../src/login/org.freedesktop.login1.policy.in.h:52
+#: ../src/login/org.freedesktop.login1.policy.in.h:54
msgid "Authentication is required to lock or unlock active sessions."
msgstr "Autentisering krävs för att låsa eller låsa upp aktiva sessioner."
-#: ../src/login/org.freedesktop.login1.policy.in.h:53
+#: ../src/login/org.freedesktop.login1.policy.in.h:55
msgid "Allow indication to the firmware to boot to setup interface"
msgstr ""
"Tillåt indikering till firmware att starta upp i inställningsgränssnitt"
-#: ../src/login/org.freedesktop.login1.policy.in.h:54
+#: ../src/login/org.freedesktop.login1.policy.in.h:56
msgid ""
"Authentication is required to indicate to the firmware to boot to setup "
"interface."
@@ -422,11 +431,11 @@ msgstr ""
"Autentisering krävs för att indikera till firmware att starta upp till "
"inställningsgränssnitt."
-#: ../src/login/org.freedesktop.login1.policy.in.h:55
+#: ../src/login/org.freedesktop.login1.policy.in.h:57
msgid "Set a wall message"
msgstr "Ange ett väggmeddelande"
-#: ../src/login/org.freedesktop.login1.policy.in.h:56
+#: ../src/login/org.freedesktop.login1.policy.in.h:58
msgid "Authentication is required to set a wall message"
msgstr "Autentisering krävs för att ställa in ett väggmeddelande"
@@ -547,33 +556,33 @@ msgstr ""
"Autentisering krävs för att kontrollera huruvida synkronisering av "
"nätverkstid ska vara aktiverat."
-#: ../src/core/dbus-unit.c:428
+#: ../src/core/dbus-unit.c:457
msgid "Authentication is required to start '$(unit)'."
msgstr "Autentisering krävs för att starta \"$(unit)\"."
-#: ../src/core/dbus-unit.c:429
+#: ../src/core/dbus-unit.c:458
msgid "Authentication is required to stop '$(unit)'."
msgstr "Autentisering krävs för att stoppa \"$(unit)\"."
-#: ../src/core/dbus-unit.c:430
+#: ../src/core/dbus-unit.c:459
msgid "Authentication is required to reload '$(unit)'."
msgstr "Autentisering krävs för att läsa om tillståndet för \"$(unit)\"."
-#: ../src/core/dbus-unit.c:431 ../src/core/dbus-unit.c:432
+#: ../src/core/dbus-unit.c:460 ../src/core/dbus-unit.c:461
msgid "Authentication is required to restart '$(unit)'."
msgstr "Autentisering krävs för att starta om \"$(unit)\"."
-#: ../src/core/dbus-unit.c:535
+#: ../src/core/dbus-unit.c:568
msgid "Authentication is required to kill '$(unit)'."
msgstr "Autentisering krävs för att döda \"$(unit)\"."
-#: ../src/core/dbus-unit.c:565
+#: ../src/core/dbus-unit.c:599
msgid "Authentication is required to reset the \"failed\" state of '$(unit)'."
msgstr ""
"Autentisering krävs för att återställa det \"fallerade\" tillståndet för "
"\"$(unit)\"."
-#: ../src/core/dbus-unit.c:597
+#: ../src/core/dbus-unit.c:632
msgid "Authentication is required to set properties on '$(unit)'."
msgstr "Autentisering krävs för att ställa in egenskaper på \"$(unit)\"."
diff --git a/rules/.gitignore b/rules/.gitignore
index 93a50ddd80..ea6e216bad 100644
--- a/rules/.gitignore
+++ b/rules/.gitignore
@@ -1 +1,2 @@
+/50-udev-default.rules
/99-systemd.rules
diff --git a/rules/50-udev-default.rules b/rules/50-udev-default.rules.in
index 3347c8cd89..898148c064 100644
--- a/rules/50-udev-default.rules
+++ b/rules/50-udev-default.rules.in
@@ -11,7 +11,6 @@ SUBSYSTEM=="rtc", ATTR{hctosys}=="1", SYMLINK+="rtc"
SUBSYSTEM=="rtc", KERNEL=="rtc0", SYMLINK+="rtc", OPTIONS+="link_priority=-100"
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", IMPORT{builtin}="usb_id", IMPORT{builtin}="hwdb --subsystem=usb"
-SUBSYSTEM=="input", ENV{ID_INPUT}=="", IMPORT{builtin}="input_id"
ENV{MODALIAS}!="", IMPORT{builtin}="hwdb --subsystem=$env{SUBSYSTEM}"
ACTION!="add", GOTO="default_end"
@@ -34,6 +33,8 @@ SUBSYSTEM=="video4linux", GROUP="video"
SUBSYSTEM=="graphics", GROUP="video"
SUBSYSTEM=="drm", GROUP="video"
SUBSYSTEM=="dvb", GROUP="video"
+SUBSYSTEM=="media", GROUP="video"
+SUBSYSTEM=="cec", GROUP="video"
SUBSYSTEM=="sound", GROUP="audio", \
OPTIONS+="static_node=snd/seq", OPTIONS+="static_node=snd/timer"
@@ -74,6 +75,8 @@ KERNEL=="tun", MODE="0666", OPTIONS+="static_node=net/tun"
KERNEL=="fuse", MODE="0666", OPTIONS+="static_node=fuse"
+KERNEL=="kvm", GROUP="kvm", MODE="@DEV_KVM_MODE@"
+
SUBSYSTEM=="ptp", ATTR{clock_name}=="KVM virtual PTP", SYMLINK += "ptp_kvm"
LABEL="default_end"
diff --git a/rules/60-cdrom_id.rules b/rules/60-cdrom_id.rules
index f91d8cb456..288f8ce2f9 100644
--- a/rules/60-cdrom_id.rules
+++ b/rules/60-cdrom_id.rules
@@ -2,7 +2,7 @@
ACTION=="remove", GOTO="cdrom_end"
SUBSYSTEM!="block", GOTO="cdrom_end"
-KERNEL!="sr[0-9]*|xvd*", GOTO="cdrom_end"
+KERNEL!="sr[0-9]*|vdisk*|xvd*", GOTO="cdrom_end"
ENV{DEVTYPE}!="disk", GOTO="cdrom_end"
# unconditionally tag device as CDROM
diff --git a/rules/60-evdev.rules b/rules/60-evdev.rules
index f5d5ba6a5f..e5e608acd3 100644
--- a/rules/60-evdev.rules
+++ b/rules/60-evdev.rules
@@ -8,7 +8,7 @@ IMPORT{builtin}="hwdb --subsystem=input --lookup-prefix=evdev:", \
RUN{builtin}+="keyboard", GOTO="evdev_end"
# AT keyboard matching by the machine's DMI data
-ENV{ID_INPUT_KEY}=="?*", DRIVERS=="atkbd", \
+DRIVERS=="atkbd", \
IMPORT{builtin}="hwdb 'evdev:atkbd:$attr{[dmi/id]modalias}'", \
RUN{builtin}+="keyboard", GOTO="evdev_end"
diff --git a/rules/60-input-id.rules b/rules/60-input-id.rules
new file mode 100644
index 0000000000..dee42199b6
--- /dev/null
+++ b/rules/60-input-id.rules
@@ -0,0 +1,7 @@
+# do not edit this file, it will be overwritten on update
+
+ACTION=="remove", GOTO="id_input_end"
+
+SUBSYSTEM=="input", ENV{ID_INPUT}=="", IMPORT{builtin}="input_id"
+
+LABEL="id_input_end"
diff --git a/rules/60-persistent-input.rules b/rules/60-persistent-input.rules
index 607144bf8a..91efbe7294 100644
--- a/rules/60-persistent-input.rules
+++ b/rules/60-persistent-input.rules
@@ -3,6 +3,8 @@
ACTION=="remove", GOTO="persistent_input_end"
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"
diff --git a/rules/60-sensor.rules b/rules/60-sensor.rules
index 82e44f8843..7ad2c36be3 100644
--- a/rules/60-sensor.rules
+++ b/rules/60-sensor.rules
@@ -7,4 +7,12 @@ SUBSYSTEM=="iio", KERNEL=="iio*", SUBSYSTEMS=="usb|i2c", \
IMPORT{builtin}="hwdb 'sensor:modalias:$attr{modalias}:$attr{[dmi/id]modalias}'", \
GOTO="sensor_end"
+SUBSYSTEM=="input", ENV{ID_INPUT_ACCELEROMETER}=="1", SUBSYSTEMS=="acpi", \
+ IMPORT{builtin}="hwdb 'sensor:modalias:acpi:$attr{hid}:$attr{[dmi/id]modalias}'", \
+ GOTO="sensor_end"
+
+SUBSYSTEM=="input", ENV{ID_INPUT_ACCELEROMETER}=="1", SUBSYSTEMS=="platform", \
+ IMPORT{builtin}="hwdb 'sensor:modalias:platform:$id:$attr{[dmi/id]modalias}'", \
+ GOTO="sensor_end"
+
LABEL="sensor_end"
diff --git a/rules/70-joystick.rules b/rules/70-joystick.rules
new file mode 100644
index 0000000000..b80d203670
--- /dev/null
+++ b/rules/70-joystick.rules
@@ -0,0 +1,12 @@
+# do not edit this file, it will be overwritten on update
+
+ACTION=="remove", GOTO="joystick_end"
+ENV{ID_INPUT_JOYSTICK}=="", GOTO="joystick_end"
+KERNEL!="event*", GOTO="joystick_end"
+
+# joystick:<bustype>:v<vid>p<pid>:name:<name>:*
+KERNELS=="input*", ENV{ID_BUS}!="", \
+ IMPORT{builtin}="hwdb 'joystick:$env{ID_BUS}:v$attr{id/vendor}p$attr{id/product}:name:$attr{name}:'", \
+ GOTO="joystick_end"
+
+LABEL="joystick_end"
diff --git a/rules/meson.build b/rules/meson.build
new file mode 100644
index 0000000000..7f4725ad65
--- /dev/null
+++ b/rules/meson.build
@@ -0,0 +1,40 @@
+rules = files('''
+ 60-block.rules
+ 60-cdrom_id.rules
+ 60-drm.rules
+ 60-evdev.rules
+ 60-input-id.rules
+ 60-persistent-alsa.rules
+ 60-persistent-input.rules
+ 60-persistent-storage.rules
+ 60-persistent-storage-tape.rules
+ 60-persistent-v4l.rules
+ 60-sensor.rules
+ 60-serial.rules
+ 64-btrfs.rules
+ 70-joystick.rules
+ 70-mouse.rules
+ 70-touchpad.rules
+ 75-net-description.rules
+ 75-probe_mtd.rules
+ 78-sound-card.rules
+ 80-drivers.rules
+ 80-net-setup-link.rules
+'''.split())
+
+install_data(rules,
+ install_dir : udevrulesdir)
+
+rules_in = '''
+ 50-udev-default.rules
+ 99-systemd.rules
+'''.split()
+
+foreach file : rules_in
+ gen = configure_file(
+ input : file + '.in',
+ output : file,
+ configuration : substs)
+ install_data(gen,
+ install_dir : udevrulesdir)
+endforeach
diff --git a/shell-completion/bash/meson.build b/shell-completion/bash/meson.build
new file mode 100644
index 0000000000..9399661845
--- /dev/null
+++ b/shell-completion/bash/meson.build
@@ -0,0 +1,50 @@
+bashcompletiondir = get_option('bashcompletiondir')
+if bashcompletiondir == ''
+ bash_completion = dependency('bash-completion', required : false)
+ if bash_completion.found()
+ bashcompletiondir = bash_completion.get_pkgconfig_variable('completionsdir')
+ else
+ bashcompletiondir = join_paths(datadir, 'bash-completion/completions')
+ endif
+
+ message('bash completions: @0@'.format(bashcompletiondir))
+endif
+
+if bashcompletiondir != 'no'
+ bash_systemctl = configure_file(
+ input : 'systemctl.in',
+ output : 'systemctl',
+ configuration : substs)
+
+ items = [['busctl', ''],
+ ['journalctl', ''],
+ ['systemd-analyze', ''],
+ ['systemd-cat', ''],
+ ['systemd-cgls', ''],
+ ['systemd-cgtop', ''],
+ ['systemd-delta', ''],
+ ['systemd-detect-virt', ''],
+ ['systemd-nspawn', ''],
+ ['systemd-path', ''],
+ ['systemd-run', ''],
+ ['udevadm', ''],
+ ['kernel-install', ''],
+ [bash_systemctl, ''],
+ ['bootctl', 'ENABLE_EFI'],
+ ['coredumpctl', 'ENABLE_COREDUMP'],
+ ['hostnamectl', 'ENABLE_HOSTNAMED'],
+ ['localectl', 'ENABLE_LOCALED'],
+ ['loginctl', 'ENABLE_LOGIND'],
+ ['machinectl', 'ENABLE_MACHINED'],
+ ['networkctl', 'ENABLE_NETWORKD'],
+ ['systemd-resolve', 'ENABLE_RESOLVED'],
+ ['timedatectl', 'ENABLE_TIMEDATED'],
+ ]
+
+ foreach item : items
+ if item[1] == '' or conf.get(item[1], false)
+ install_data(item[0],
+ install_dir : bashcompletiondir)
+ endif
+ endforeach
+endif
diff --git a/shell-completion/bash/networkctl b/shell-completion/bash/networkctl
index 942c7e1c00..68e3338471 100644
--- a/shell-completion/bash/networkctl
+++ b/shell-completion/bash/networkctl
@@ -36,7 +36,7 @@ _networkctl() {
)
local -A VERBS=(
- [STANDALONE]='list lldp'
+ [STANDALONE]='list lldp label'
[LINKS]='status'
)
diff --git a/shell-completion/bash/systemctl.in b/shell-completion/bash/systemctl.in
index 3e553c1e6c..0398d09d18 100644
--- a/shell-completion/bash/systemctl.in
+++ b/shell-completion/bash/systemctl.in
@@ -172,7 +172,7 @@ _systemctl () {
comps='full enable-only disable-only'
;;
--output|-o)
- comps='short short-full short-iso short-precise short-monotonic short-unix verbose export json
+ comps='short short-full short-iso short-iso-precise short-precise short-monotonic short-unix verbose export json
json-pretty json-sse cat'
;;
--machine|-M)
diff --git a/shell-completion/zsh/_networkctl b/shell-completion/zsh/_networkctl
index 61f173b78e..acf7463edb 100644
--- a/shell-completion/zsh/_networkctl
+++ b/shell-completion/zsh/_networkctl
@@ -6,6 +6,7 @@ _networkctl_command(){
'list:List existing links'
'status:Show information about the specified links'
'lldp:Show Link Layer Discovery Protocol status'
+ 'label:Show address labels'
)
if (( CURRENT == 1 )); then
_describe -t commands 'networkctl command' _networkctl_cmds
diff --git a/shell-completion/zsh/_sd_outputmodes b/shell-completion/zsh/_sd_outputmodes
index 52617c6b7a..2948f40130 100644
--- a/shell-completion/zsh/_sd_outputmodes
+++ b/shell-completion/zsh/_sd_outputmodes
@@ -1,5 +1,5 @@
#autoload
local -a _output_opts
-_output_opts=(short short-full short-iso short-precise short-monotonic short-unix verbose export json json-pretty json-sse cat)
+_output_opts=(short short-full short-iso short-iso-precise short-precise short-monotonic short-unix verbose export json json-pretty json-sse cat)
_describe -t output 'output mode' _output_opts || compadd "$@"
diff --git a/shell-completion/zsh/meson.build b/shell-completion/zsh/meson.build
new file mode 100644
index 0000000000..34408ce90d
--- /dev/null
+++ b/shell-completion/zsh/meson.build
@@ -0,0 +1,47 @@
+zshcompletiondir = get_option('zshcompletiondir')
+if zshcompletiondir == ''
+ zshcompletiondir = join_paths(datadir, 'zsh/site-functions')
+
+ message('zsh completions: @0@'.format(zshcompletiondir))
+endif
+
+if zshcompletiondir != 'no'
+ zsh_systemctl = configure_file(
+ input : '_systemctl.in',
+ output : '_systemctl',
+ configuration : substs)
+
+ items = [['_busctl', ''],
+ ['_journalctl', ''],
+ ['_systemd-analyze', ''],
+ ['_systemd-delta', ''],
+ ['_systemd-nspawn', ''],
+ ['_systemd', ''],
+ ['_systemd-run', ''],
+ ['_udevadm', ''],
+ ['_kernel-install', ''],
+ ['_sd_hosts_or_user_at_host', ''],
+ ['_sd_outputmodes', ''],
+ ['_sd_unit_files', ''],
+ ['_sd_machines', ''],
+ [zsh_systemctl, ''],
+ ['_bootctl', 'ENABLE_EFI'],
+ ['_coredumpctl', 'ENABLE_COREDUMP'],
+ ['_hostnamectl', 'ENABLE_HOSTNAMED'],
+ ['_localectl', 'ENABLE_LOCALED'],
+ ['_loginctl', 'ENABLE_LOGIND'],
+ ['_machinectl', 'ENABLE_MACHINED'],
+ ['_networkctl', 'ENABLE_NETWORKD'],
+ ['_systemd-inhibit', 'ENABLE_LOGIND'],
+ ['_systemd-resolve', 'ENABLE_RESOLVED'],
+ ['_systemd-tmpfiles', 'ENABLE_TMPFILES'],
+ ['_timedatectl', 'ENABLE_TIMEDATED'],
+ ]
+
+ foreach item : items
+ if item[1] == '' or conf.get(item[1], false)
+ install_data(item[0],
+ install_dir : zshcompletiondir)
+ endif
+ endforeach
+endif
diff --git a/src/activate/activate.c b/src/activate/activate.c
index 6ebd820410..4b82dca491 100644
--- a/src/activate/activate.c
+++ b/src/activate/activate.c
@@ -31,6 +31,7 @@
#include "fd-util.h"
#include "log.h"
#include "macro.h"
+#include "process-util.h"
#include "signal-util.h"
#include "socket-util.h"
#include "string-util.h"
@@ -221,7 +222,7 @@ static int exec_process(const char* name, char **argv, char **env, int start_fd,
if (asprintf((char**)(envp + n_env++), "LISTEN_FDS=%i", n_fds) < 0)
return log_oom();
- if (asprintf((char**)(envp + n_env++), "LISTEN_PID=" PID_FMT, getpid()) < 0)
+ if (asprintf((char**)(envp + n_env++), "LISTEN_PID=" PID_FMT, getpid_cached()) < 0)
return log_oom();
if (arg_fdnames) {
@@ -271,7 +272,7 @@ static int fork_and_exec_process(const char* child, char** argv, char **env, int
if (!joined)
return log_oom();
- parent_pid = getpid();
+ parent_pid = getpid_cached();
child_pid = fork();
if (child_pid < 0)
diff --git a/src/analyze/analyze.c b/src/analyze/analyze.c
index 36b01500ca..b7481a8ad4 100644
--- a/src/analyze/analyze.c
+++ b/src/analyze/analyze.c
@@ -627,7 +627,7 @@ static int analyze_plot(sd_bus *bus) {
"<!-- that render these files properly but much slower are ImageMagick, -->\n"
"<!-- gimp, inkscape, etc. To display the files on your system, just -->\n"
"<!-- point your browser to this file. -->\n\n"
- "<!-- This plot was generated by systemd-analyze version %-16.16s -->\n\n", VERSION);
+ "<!-- This plot was generated by systemd-analyze version %-16.16s -->\n\n", PACKAGE_VERSION);
/* style sheet */
svg("<defs>\n <style type=\"text/css\">\n <![CDATA[\n"
diff --git a/src/analyze/meson.build b/src/analyze/meson.build
new file mode 100644
index 0000000000..fcbd814233
--- /dev/null
+++ b/src/analyze/meson.build
@@ -0,0 +1,5 @@
+systemd_analyze_sources = files('''
+ analyze.c
+ analyze-verify.c
+ analyze-verify.h
+'''.split())
diff --git a/src/basic/af-to-name.awk b/src/basic/af-to-name.awk
new file mode 100644
index 0000000000..18d0a89728
--- /dev/null
+++ b/src/basic/af-to-name.awk
@@ -0,0 +1,9 @@
+BEGIN{
+ print "static const char* const af_names[] = { "
+}
+!/AF_FILE/ && !/AF_ROUTE/ && !/AF_LOCAL/ {
+ printf " [%s] = \"%s\",\n", $1, $1
+}
+END{
+ print "};"
+}
diff --git a/src/basic/architecture.c b/src/basic/architecture.c
index 5a3dc08a4a..2518dd8112 100644
--- a/src/basic/architecture.c
+++ b/src/basic/architecture.c
@@ -132,6 +132,9 @@ int uname_architecture(void) {
# elif __SIZEOF_POINTER__ == 8
{ "riscv", ARCHITECTURE_RISCV64 },
# endif
+#elif defined(__arc__)
+ { "arc", ARCHITECTURE_ARC },
+ { "arceb", ARCHITECTURE_ARC_BE },
#else
#error "Please register your architecture here!"
#endif
@@ -185,6 +188,8 @@ static const char *const architecture_table[_ARCHITECTURE_MAX] = {
[ARCHITECTURE_NIOS2] = "nios2",
[ARCHITECTURE_RISCV32] = "riscv32",
[ARCHITECTURE_RISCV64] = "riscv64",
+ [ARCHITECTURE_ARC] = "arc",
+ [ARCHITECTURE_ARC_BE] = "arc-be",
};
DEFINE_STRING_TABLE_LOOKUP(architecture, int);
diff --git a/src/basic/architecture.h b/src/basic/architecture.h
index 46883719d1..40a2ce6448 100644
--- a/src/basic/architecture.h
+++ b/src/basic/architecture.h
@@ -60,6 +60,8 @@ enum {
ARCHITECTURE_NIOS2,
ARCHITECTURE_RISCV32,
ARCHITECTURE_RISCV64,
+ ARCHITECTURE_ARC,
+ ARCHITECTURE_ARC_BE,
_ARCHITECTURE_MAX,
_ARCHITECTURE_INVALID = -1
};
@@ -79,7 +81,11 @@ int uname_architecture(void);
#if defined(__x86_64__)
# define native_architecture() ARCHITECTURE_X86_64
-# define LIB_ARCH_TUPLE "x86_64-linux-gnu"
+# if defined(__ILP32__)
+# define LIB_ARCH_TUPLE "x86_64-linux-gnux32"
+# else
+# define LIB_ARCH_TUPLE "x86_64-linux-gnu"
+# endif
# define SECONDARY_ARCHITECTURE ARCHITECTURE_X86
#elif defined(__i386__)
# define native_architecture() ARCHITECTURE_X86
@@ -97,7 +103,11 @@ int uname_architecture(void);
#elif defined(__powerpc__)
# if __BYTE_ORDER == __BIG_ENDIAN
# define native_architecture() ARCHITECTURE_PPC
-# define LIB_ARCH_TUPLE "powerpc-linux-gnu"
+# if defined(__NO_FPRS__)
+# define LIB_ARCH_TUPLE "powerpc-linux-gnuspe"
+# else
+# define LIB_ARCH_TUPLE "powerpc-linux-gnu"
+# endif
# else
# define native_architecture() ARCHITECTURE_PPC_LE
# error "Missing LIB_ARCH_TUPLE for PPCLE"
@@ -189,7 +199,23 @@ int uname_architecture(void);
# error "Missing LIB_ARCH_TUPLE for SH64"
#elif defined(__sh__)
# define native_architecture() ARCHITECTURE_SH
-# define LIB_ARCH_TUPLE "sh4-linux-gnu"
+# if defined(__SH1__)
+# define LIB_ARCH_TUPLE "sh1-linux-gnu"
+# elif defined(__SH2__)
+# define LIB_ARCH_TUPLE "sh2-linux-gnu"
+# elif defined(__SH2A__)
+# define LIB_ARCH_TUPLE "sh2a-linux-gnu"
+# elif defined(__SH2E__)
+# define LIB_ARCH_TUPLE "sh2e-linux-gnu"
+# elif defined(__SH3__)
+# define LIB_ARCH_TUPLE "sh3-linux-gnu"
+# elif defined(__SH3E__)
+# define LIB_ARCH_TUPLE "sh3e-linux-gnu"
+# elif defined(__SH4__) && !defined(__SH4A__)
+# define LIB_ARCH_TUPLE "sh4-linux-gnu"
+# elif defined(__SH4A__)
+# define LIB_ARCH_TUPLE "sh4a-linux-gnu"
+# endif
#elif defined(__m68k__)
# define native_architecture() ARCHITECTURE_M68K
# define LIB_ARCH_TUPLE "m68k-linux-gnu"
@@ -213,6 +239,14 @@ int uname_architecture(void);
# else
# error "Unrecognized riscv architecture variant"
# endif
+#elif defined(__arc__)
+# if __BYTE_ORDER == __BIG_ENDIAN
+# define native_architecture() ARCHITECTURE_ARC_BE
+# define LIB_ARCH_TUPLE "arceb-linux"
+# else
+# define native_architecture() ARCHITECTURE_ARC
+# define LIB_ARCH_TUPLE "arc-linux"
+# endif
#else
# error "Please register your architecture here!"
#endif
diff --git a/src/basic/arphrd-to-name.awk b/src/basic/arphrd-to-name.awk
new file mode 100644
index 0000000000..5a35673e2c
--- /dev/null
+++ b/src/basic/arphrd-to-name.awk
@@ -0,0 +1,9 @@
+BEGIN{
+ print "static const char* const arphrd_names[] = { "
+}
+!/CISCO/ {
+ printf " [ARPHRD_%s] = \"%s\",\n", $1, $1
+}
+END{
+ print "};"
+}
diff --git a/src/basic/blkid-util.h b/src/basic/blkid-util.h
index 7aa75eb091..1b9cace040 100644
--- a/src/basic/blkid-util.h
+++ b/src/basic/blkid-util.h
@@ -20,7 +20,7 @@
***/
#ifdef HAVE_BLKID
-#include <blkid/blkid.h>
+#include <blkid.h>
#endif
#include "util.h"
diff --git a/src/basic/build.h b/src/basic/build.h
index 91312bd2a3..3223915da6 100644
--- a/src/basic/build.h
+++ b/src/basic/build.h
@@ -127,6 +127,12 @@
#define _KMOD_FEATURE_ "-KMOD"
#endif
+#ifdef HAVE_LIBIDN2
+#define _IDN2_FEATURE_ "+IDN2"
+#else
+#define _IDN2_FEATURE_ "-IDN2"
+#endif
+
#ifdef HAVE_LIBIDN
#define _IDN_FEATURE_ "+IDN"
#else
@@ -154,5 +160,6 @@
_BLKID_FEATURE_ " " \
_ELFUTILS_FEATURE_ " " \
_KMOD_FEATURE_ " " \
+ _IDN2_FEATURE_ " " \
_IDN_FEATURE_ " " \
_CGROUP_HIEARCHY_
diff --git a/src/basic/calendarspec.c b/src/basic/calendarspec.c
index 2323eb8555..204120ee0e 100644
--- a/src/basic/calendarspec.c
+++ b/src/basic/calendarspec.c
@@ -487,22 +487,33 @@ static int parse_weekdays(const char **p, CalendarSpec *c) {
}
}
+static int parse_one_number(const char *p, const char **e, unsigned long *ret) {
+ char *ee = NULL;
+ unsigned long value;
+
+ errno = 0;
+ value = strtoul(p, &ee, 10);
+ if (errno > 0)
+ return -errno;
+ if (ee == p)
+ return -EINVAL;
+
+ *ret = value;
+ *e = ee;
+ return 0;
+}
+
static int parse_component_decimal(const char **p, bool usec, int *res) {
unsigned long value;
const char *e = NULL;
- char *ee = NULL;
int r;
if (!isdigit(**p))
return -EINVAL;
- errno = 0;
- value = strtoul(*p, &ee, 10);
- if (errno > 0)
- return -errno;
- if (ee == *p)
- return -EINVAL;
- e = ee;
+ r = parse_one_number(*p, &e, &value);
+ if (r < 0)
+ return r;
if (usec) {
if (value * USEC_PER_SEC / USEC_PER_SEC != value)
@@ -553,6 +564,47 @@ static int const_chain(int value, CalendarComponent **c) {
return 0;
}
+static int calendarspec_from_time_t(CalendarSpec *c, time_t time) {
+ struct tm tm;
+ CalendarComponent *year = NULL, *month = NULL, *day = NULL, *hour = NULL, *minute = NULL, *us = NULL;
+ int r;
+
+ assert_se(gmtime_r(&time, &tm));
+
+ r = const_chain(tm.tm_year + 1900, &year);
+ if (r < 0)
+ return r;
+
+ r = const_chain(tm.tm_mon + 1, &month);
+ if (r < 0)
+ return r;
+
+ r = const_chain(tm.tm_mday, &day);
+ if (r < 0)
+ return r;
+
+ r = const_chain(tm.tm_hour, &hour);
+ if (r < 0)
+ return r;
+
+ r = const_chain(tm.tm_min, &minute);
+ if (r < 0)
+ return r;
+
+ r = const_chain(tm.tm_sec * USEC_PER_SEC, &us);
+ if (r < 0)
+ return r;
+
+ c->utc = true;
+ c->year = year;
+ c->month = month;
+ c->day = day;
+ c->hour = hour;
+ c->minute = minute;
+ c->microsecond = us;
+ return 0;
+}
+
static int prepend_component(const char **p, bool usec, CalendarComponent **c) {
int r, start, stop = -1, repeat = 0;
CalendarComponent *cc;
@@ -657,6 +709,27 @@ static int parse_date(const char **p, CalendarSpec *c) {
if (*t == 0)
return 0;
+ /* @TIMESTAMP — UNIX time in seconds since the epoch */
+ if (*t == '@') {
+ unsigned long value;
+ time_t time;
+
+ r = parse_one_number(t + 1, &t, &value);
+ if (r < 0)
+ return r;
+
+ time = value;
+ if ((unsigned long) time != value)
+ return -ERANGE;
+
+ r = calendarspec_from_time_t(c, time);
+ if (r < 0)
+ return r;
+
+ *p = t;
+ return 1; /* finito, don't parse H:M:S after that */
+ }
+
r = parse_chain(&t, false, &first);
if (r < 0)
return r;
@@ -832,7 +905,7 @@ int calendar_spec_from_string(const char *p, CalendarSpec **spec) {
continue;
e = endswith_no_case(p, tzname[j]);
- if(!e)
+ if (!e)
continue;
if (e == p)
continue;
@@ -986,9 +1059,11 @@ int calendar_spec_from_string(const char *p, CalendarSpec **spec) {
if (r < 0)
goto fail;
- r = parse_calendar_time(&p, c);
- if (r < 0)
- goto fail;
+ if (r == 0) {
+ r = parse_calendar_time(&p, c);
+ if (r < 0)
+ goto fail;
+ }
if (*p != 0) {
r = -EINVAL;
diff --git a/src/basic/cap-to-name.awk b/src/basic/cap-to-name.awk
new file mode 100644
index 0000000000..402a782024
--- /dev/null
+++ b/src/basic/cap-to-name.awk
@@ -0,0 +1,9 @@
+BEGIN{
+ print "static const char* const capability_names[] = { "
+}
+{
+ printf " [%s] = \"%s\",\n", $1, tolower($1)
+}
+END{
+ print "};"
+}
diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c
index 540435c4fb..32639476fa 100644
--- a/src/basic/cgroup-util.c
+++ b/src/basic/cgroup-util.c
@@ -55,6 +55,7 @@
#include "stdio-util.h"
#include "string-table.h"
#include "string-util.h"
+#include "strv.h"
#include "unit-name.h"
#include "user-util.h"
@@ -254,7 +255,7 @@ int cg_kill(
return -ENOMEM;
}
- my_pid = getpid();
+ my_pid = getpid_cached();
do {
_cleanup_fclose_ FILE *f = NULL;
@@ -398,7 +399,7 @@ int cg_migrate(
if (!s)
return -ENOMEM;
- my_pid = getpid();
+ my_pid = getpid_cached();
do {
_cleanup_fclose_ FILE *f = NULL;
@@ -824,7 +825,7 @@ int cg_attach(const char *controller, const char *path, pid_t pid) {
return r;
if (pid == 0)
- pid = getpid();
+ pid = getpid_cached();
xsprintf(c, PID_FMT "\n", pid);
@@ -839,7 +840,7 @@ int cg_attach(const char *controller, const char *path, pid_t pid) {
if (r > 0 && streq(controller, SYSTEMD_CGROUP_CONTROLLER)) {
r = cg_attach(SYSTEMD_CGROUP_CONTROLLER_LEGACY, path, pid);
if (r < 0)
- log_warning_errno(r, "Failed to attach %d to compat systemd cgroup %s: %m", pid, path);
+ log_warning_errno(r, "Failed to attach "PID_FMT" to compat systemd cgroup %s: %m", pid, path);
}
return 0;
@@ -2237,6 +2238,60 @@ int cg_trim_everywhere(CGroupMask supported, const char *path, bool delete_root)
return 0;
}
+int cg_mask_to_string(CGroupMask mask, char **ret) {
+ const char *controllers[_CGROUP_CONTROLLER_MAX + 1];
+ CGroupController c;
+ int i = 0;
+ char *s;
+
+ assert(ret);
+
+ if (mask == 0) {
+ *ret = NULL;
+ return 0;
+ }
+
+ for (c = 0; c < _CGROUP_CONTROLLER_MAX; c++) {
+
+ if (!(mask & CGROUP_CONTROLLER_TO_MASK(c)))
+ continue;
+
+ controllers[i++] = cgroup_controller_to_string(c);
+ controllers[i] = NULL;
+ }
+
+ s = strv_join((char **)controllers, NULL);
+ if (!s)
+ return -ENOMEM;
+
+ *ret = s;
+ return 0;
+}
+
+int cg_mask_from_string(const char *value, CGroupMask *mask) {
+ assert(mask);
+ assert(value);
+
+ for (;;) {
+ _cleanup_free_ char *n = NULL;
+ CGroupController v;
+ int r;
+
+ r = extract_first_word(&value, &n, NULL, 0);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ break;
+
+ v = cgroup_controller_from_string(n);
+ if (v < 0)
+ continue;
+
+ *mask |= CGROUP_CONTROLLER_TO_MASK(v);
+ }
+ return 0;
+}
+
int cg_mask_supported(CGroupMask *ret) {
CGroupMask mask = 0;
int r;
@@ -2250,7 +2305,6 @@ int cg_mask_supported(CGroupMask *ret) {
return r;
if (r > 0) {
_cleanup_free_ char *root = NULL, *controllers = NULL, *path = NULL;
- const char *c;
/* In the unified hierarchy we can read the supported
* and accessible controllers from a the top-level
@@ -2268,23 +2322,9 @@ int cg_mask_supported(CGroupMask *ret) {
if (r < 0)
return r;
- c = controllers;
- for (;;) {
- _cleanup_free_ char *n = NULL;
- CGroupController v;
-
- r = extract_first_word(&c, &n, NULL, 0);
- if (r < 0)
- return r;
- if (r == 0)
- break;
-
- v = cgroup_controller_from_string(n);
- if (v < 0)
- continue;
-
- mask |= CGROUP_CONTROLLER_TO_MASK(v);
- }
+ r = cg_mask_from_string(controllers, &mask);
+ if (r < 0)
+ return r;
/* Currently, we support the cpu, memory, io and pids
* controller in the unified hierarchy, mask
diff --git a/src/basic/cgroup-util.h b/src/basic/cgroup-util.h
index 3cf11788e7..a8216c7b6a 100644
--- a/src/basic/cgroup-util.h
+++ b/src/basic/cgroup-util.h
@@ -238,6 +238,8 @@ int cg_trim_everywhere(CGroupMask supported, const char *path, bool delete_root)
int cg_enable_everywhere(CGroupMask supported, CGroupMask mask, const char *p);
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);
diff --git a/src/basic/def.h b/src/basic/def.h
index 200ea973c1..b1a3bc190b 100644
--- a/src/basic/def.h
+++ b/src/basic/def.h
@@ -67,10 +67,6 @@
.un.sun_path = "\0/org/freedesktop/plymouthd", \
}
-#ifndef TTY_GID
-#define TTY_GID 5
-#endif
-
#define NOTIFY_FD_MAX 768
#define NOTIFY_BUFFER_MAX PIPE_BUF
diff --git a/src/basic/dirent-util.c b/src/basic/dirent-util.c
index 6b9d26773e..5bf58bcdc3 100644
--- a/src/basic/dirent-util.c
+++ b/src/basic/dirent-util.c
@@ -75,3 +75,14 @@ bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) {
return endswith(de->d_name, suffix);
}
+
+struct dirent* readdir_no_dot(DIR *dirp) {
+ struct dirent* d;
+
+ for (;;) {
+ d = readdir(dirp);
+ if (d && dot_or_dot_dot(d->d_name))
+ continue;
+ return d;
+ }
+}
diff --git a/src/basic/dirent-util.h b/src/basic/dirent-util.h
index b91d04908f..18b9db9b28 100644
--- a/src/basic/dirent-util.h
+++ b/src/basic/dirent-util.h
@@ -31,6 +31,8 @@ int dirent_ensure_type(DIR *d, struct dirent *de);
bool dirent_is_file(const struct dirent *de) _pure_;
bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) _pure_;
+struct dirent* readdir_no_dot(DIR *dirp);
+
#define FOREACH_DIRENT(de, d, on_error) \
for (errno = 0, de = readdir(d);; errno = 0, de = readdir(d)) \
if (!de) { \
diff --git a/src/basic/env-util.c b/src/basic/env-util.c
index e79b441ab6..56e7b6fd8c 100644
--- a/src/basic/env-util.c
+++ b/src/basic/env-util.c
@@ -779,7 +779,7 @@ int serialize_environment(FILE *f, char **environment) {
if (!ce)
return -ENOMEM;
- fprintf(f, "env=%s\n", *e);
+ fprintf(f, "env=%s\n", ce);
}
/* caller should call ferror() */
@@ -788,7 +788,7 @@ int serialize_environment(FILE *f, char **environment) {
}
int deserialize_environment(char ***environment, const char *line) {
- char *uce = NULL;
+ char *uce;
int r;
assert(line);
diff --git a/src/basic/errno-to-name.awk b/src/basic/errno-to-name.awk
new file mode 100644
index 0000000000..0878abacbd
--- /dev/null
+++ b/src/basic/errno-to-name.awk
@@ -0,0 +1,9 @@
+BEGIN{
+ print "static const char* const errno_names[] = { "
+}
+!/EDEADLOCK/ && !/EWOULDBLOCK/ && !/ENOTSUP/ {
+ printf " [%s] = \"%s\",\n", $1, $1
+}
+END{
+ print "};"
+}
diff --git a/src/basic/escape.c b/src/basic/escape.c
index 4a1ec4505e..85e4b5282e 100644
--- a/src/basic/escape.c
+++ b/src/basic/escape.c
@@ -441,10 +441,16 @@ char *octescape(const char *s, size_t len) {
}
-static char *strcpy_backslash_escaped(char *t, const char *s, const char *bad) {
+static char *strcpy_backslash_escaped(char *t, const char *s, const char *bad, bool escape_tab_nl) {
assert(bad);
for (; *s; s++) {
+ if (escape_tab_nl && IN_SET(*s, '\n', '\t')) {
+ *(t++) = '\\';
+ *(t++) = *s == '\n' ? 'n' : 't';
+ continue;
+ }
+
if (*s == '\\' || strchr(bad, *s))
*(t++) = '\\';
@@ -461,20 +467,21 @@ char *shell_escape(const char *s, const char *bad) {
if (!r)
return NULL;
- t = strcpy_backslash_escaped(r, s, bad);
+ t = strcpy_backslash_escaped(r, s, bad, false);
*t = 0;
return r;
}
-char *shell_maybe_quote(const char *s) {
+char* shell_maybe_quote(const char *s, EscapeStyle style) {
const char *p;
char *r, *t;
assert(s);
- /* Encloses a string in double quotes if necessary to make it
- * OK as shell string. */
+ /* Encloses a string in quotes if necessary to make it OK as a shell
+ * string. Note that we treat benign UTF-8 characters as needing
+ * escaping too, but that should be OK. */
for (p = s; *p; p++)
if (*p <= ' ' ||
@@ -485,17 +492,30 @@ char *shell_maybe_quote(const char *s) {
if (!*p)
return strdup(s);
- r = new(char, 1+strlen(s)*2+1+1);
+ r = new(char, (style == ESCAPE_POSIX) + 1 + strlen(s)*2 + 1 + 1);
if (!r)
return NULL;
t = r;
- *(t++) = '"';
+ if (style == ESCAPE_BACKSLASH)
+ *(t++) = '"';
+ else if (style == ESCAPE_POSIX) {
+ *(t++) = '$';
+ *(t++) = '\'';
+ } else
+ assert_not_reached("Bad EscapeStyle");
+
t = mempcpy(t, s, p - s);
- t = strcpy_backslash_escaped(t, p, SHELL_NEED_ESCAPE);
+ if (style == ESCAPE_BACKSLASH)
+ t = strcpy_backslash_escaped(t, p, SHELL_NEED_ESCAPE, false);
+ else
+ t = strcpy_backslash_escaped(t, p, SHELL_NEED_ESCAPE_POSIX, true);
- *(t++)= '"';
+ if (style == ESCAPE_BACKSLASH)
+ *(t++) = '"';
+ else
+ *(t++) = '\'';
*t = 0;
return r;
diff --git a/src/basic/escape.h b/src/basic/escape.h
index deaa4def28..6f5cc60bc8 100644
--- a/src/basic/escape.h
+++ b/src/basic/escape.h
@@ -31,13 +31,30 @@
/* What characters are special in the shell? */
/* must be escaped outside and inside double-quotes */
#define SHELL_NEED_ESCAPE "\"\\`$"
-/* can be escaped or double-quoted */
-#define SHELL_NEED_QUOTES SHELL_NEED_ESCAPE GLOB_CHARS "'()<>|&;"
+
+/* Those that can be escaped or double-quoted.
+ *
+ * Stricly speaking, ! does not need to be escaped, except in interactive
+ * mode, but let's be extra nice to the user and quote ! in case this
+ * output is ever used in interactive mode. */
+#define SHELL_NEED_QUOTES SHELL_NEED_ESCAPE GLOB_CHARS "'()<>|&;!"
+
+/* Note that we assume control characters would need to be escaped too in
+ * addition to the "special" characters listed here, if they appear in the
+ * string. Current users disallow control characters. Also '"' shall not
+ * be escaped.
+ */
+#define SHELL_NEED_ESCAPE_POSIX "\\\'"
typedef enum UnescapeFlags {
UNESCAPE_RELAX = 1,
} UnescapeFlags;
+typedef enum EscapeStyle {
+ ESCAPE_BACKSLASH = 1,
+ ESCAPE_POSIX = 2,
+} EscapeStyle;
+
char *cescape(const char *s);
char *cescape_length(const char *s, size_t n);
size_t cescape_char(char c, char *buf);
@@ -51,4 +68,4 @@ char *xescape(const char *s, const char *bad);
char *octescape(const char *s, size_t len);
char *shell_escape(const char *s, const char *bad);
-char *shell_maybe_quote(const char *s);
+char* shell_maybe_quote(const char *s, EscapeStyle style);
diff --git a/src/basic/extract-word.c b/src/basic/extract-word.c
index f8cac3e911..804f14c44c 100644
--- a/src/basic/extract-word.c
+++ b/src/basic/extract-word.c
@@ -241,7 +241,12 @@ int extract_first_word_and_warn(
return log_syntax(unit, LOG_ERR, filename, line, r, "Unable to decode word \"%s\", ignoring: %m", rvalue);
}
-int extract_many_words(const char **p, const char *separators, ExtractFlags flags, ...) {
+/* We pass ExtractFlags as unsigned int (to avoid undefined behaviour when passing
+ * an object that undergoes default argument promotion as an argument to va_start).
+ * Let's make sure that ExtractFlags fits into an unsigned int. */
+assert_cc(sizeof(enum ExtractFlags) <= sizeof(unsigned));
+
+int extract_many_words(const char **p, const char *separators, unsigned flags, ...) {
va_list ap;
char **l;
int n = 0, i, c, r;
diff --git a/src/basic/extract-word.h b/src/basic/extract-word.h
index 21db5ef33f..04746c6d08 100644
--- a/src/basic/extract-word.h
+++ b/src/basic/extract-word.h
@@ -32,4 +32,4 @@ typedef enum ExtractFlags {
int extract_first_word(const char **p, char **ret, const char *separators, ExtractFlags flags);
int extract_first_word_and_warn(const char **p, char **ret, const char *separators, ExtractFlags flags, const char *unit, const char *filename, unsigned line, const char *rvalue);
-int extract_many_words(const char **p, const char *separators, ExtractFlags flags, ...) _sentinel_;
+int extract_many_words(const char **p, const char *separators, unsigned flags, ...) _sentinel_;
diff --git a/src/basic/fd-util.c b/src/basic/fd-util.c
index 19ad20789b..9d61044c89 100644
--- a/src/basic/fd-util.c
+++ b/src/basic/fd-util.c
@@ -31,6 +31,7 @@
#include "missing.h"
#include "parse-util.h"
#include "path-util.h"
+#include "process-util.h"
#include "socket-util.h"
#include "stdio-util.h"
#include "util.h"
@@ -282,7 +283,7 @@ int same_fd(int a, int b) {
return true;
/* Try to use kcmp() if we have it. */
- pid = getpid();
+ pid = getpid_cached();
r = kcmp(pid, pid, KCMP_FILE, a, b);
if (r == 0)
return true;
diff --git a/src/basic/fileio-label.c b/src/basic/fileio-label.c
index 66dbc0fe1e..ef51c49395 100644
--- a/src/basic/fileio-label.c
+++ b/src/basic/fileio-label.c
@@ -24,14 +24,14 @@
#include "fileio.h"
#include "selinux-util.h"
-int write_string_file_atomic_label(const char *fn, const char *line) {
+int write_string_file_atomic_label_ts(const char *fn, const char *line, struct timespec *ts) {
int r;
r = mac_selinux_create_file_prepare(fn, S_IFREG);
if (r < 0)
return r;
- r = write_string_file(fn, line, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC);
+ r = write_string_file_ts(fn, line, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC, ts);
mac_selinux_create_file_clear();
diff --git a/src/basic/fileio-label.h b/src/basic/fileio-label.h
index fe7543013d..9854ea50b9 100644
--- a/src/basic/fileio-label.h
+++ b/src/basic/fileio-label.h
@@ -24,7 +24,10 @@
#include "fileio.h"
-int write_string_file_atomic_label(const char *fn, const char *line);
+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);
+}
int write_env_file_label(const char *fname, char **l);
int fopen_temporary_label(const char *target,
const char *path, FILE **f, char **temp_path);
diff --git a/src/basic/fileio.c b/src/basic/fileio.c
index 7c2c2b38f5..0678db4a7b 100644
--- a/src/basic/fileio.c
+++ b/src/basic/fileio.c
@@ -41,6 +41,7 @@
#include "missing.h"
#include "parse-util.h"
#include "path-util.h"
+#include "process-util.h"
#include "random-util.h"
#include "stdio-util.h"
#include "string-util.h"
@@ -51,7 +52,7 @@
#define READ_FULL_BYTES_MAX (4U*1024U*1024U)
-int write_string_stream(FILE *f, const char *line, bool enforce_newline) {
+int write_string_stream_ts(FILE *f, const char *line, bool enforce_newline, struct timespec *ts) {
assert(f);
assert(line);
@@ -60,6 +61,13 @@ int write_string_stream(FILE *f, const char *line, bool enforce_newline) {
if (enforce_newline && !endswith(line, "\n"))
fputc('\n', f);
+ if (ts) {
+ struct timespec twice[2] = {*ts, *ts};
+
+ if (futimens(fileno(f), twice) < 0)
+ return -errno;
+ }
+
return fflush_and_check(f);
}
@@ -89,7 +97,7 @@ static int write_string_file_atomic(const char *fn, const char *line, bool enfor
return r;
}
-int write_string_file(const char *fn, const char *line, WriteStringFileFlags flags) {
+int write_string_file_ts(const char *fn, const char *line, WriteStringFileFlags flags, struct timespec *ts) {
_cleanup_fclose_ FILE *f = NULL;
int q, r;
@@ -104,7 +112,8 @@ int write_string_file(const char *fn, const char *line, WriteStringFileFlags fla
goto fail;
return r;
- }
+ } else
+ assert(ts == NULL);
if (flags & WRITE_STRING_FILE_CREATE) {
f = fopen(fn, "we");
@@ -131,7 +140,7 @@ int write_string_file(const char *fn, const char *line, WriteStringFileFlags fla
}
}
- r = write_string_stream(f, line, !(flags & WRITE_STRING_FILE_AVOID_NEWLINE));
+ r = write_string_stream_ts(f, line, !(flags & WRITE_STRING_FILE_AVOID_NEWLINE), ts);
if (r < 0)
goto fail;
@@ -1391,7 +1400,7 @@ int open_serialization_fd(const char *ident) {
if (fd < 0) {
const char *path;
- path = getpid() == 1 ? "/run/systemd" : "/tmp";
+ path = getpid_cached() == 1 ? "/run/systemd" : "/tmp";
fd = open_tmpfile_unlinkable(path, O_RDWR|O_CLOEXEC);
if (fd < 0)
return fd;
diff --git a/src/basic/fileio.h b/src/basic/fileio.h
index e547614cc4..6098562265 100644
--- a/src/basic/fileio.h
+++ b/src/basic/fileio.h
@@ -35,8 +35,14 @@ typedef enum {
WRITE_STRING_FILE_VERIFY_ON_FAILURE = 8,
} WriteStringFileFlags;
-int write_string_stream(FILE *f, const char *line, bool enforce_newline);
-int write_string_file(const char *fn, const char *line, WriteStringFileFlags flags);
+int write_string_stream_ts(FILE *f, const char *line, bool enforce_newline, struct timespec *ts);
+static inline int write_string_stream(FILE *f, const char *line, bool enforce_newline) {
+ return write_string_stream_ts(f, line, enforce_newline, NULL);
+}
+int write_string_file_ts(const char *fn, const char *line, WriteStringFileFlags flags, struct timespec *ts);
+static inline int write_string_file(const char *fn, const char *line, WriteStringFileFlags flags) {
+ return write_string_file_ts(fn, line, flags, NULL);
+}
int read_one_line_file(const char *fn, char **line);
int read_full_file(const char *fn, char **contents, size_t *size);
diff --git a/src/basic/fs-util.c b/src/basic/fs-util.c
index 8fe19ee4e4..5e1163c6a7 100644
--- a/src/basic/fs-util.c
+++ b/src/basic/fs-util.c
@@ -307,7 +307,7 @@ int fd_warn_permissions(const char *path, int fd) {
if (st.st_mode & 0002)
log_warning("Configuration file %s is marked world-writable. Please remove world writability permission bits. Proceeding anyway.", path);
- if (getpid() == 1 && (st.st_mode & 0044) != 0044)
+ if (getpid_cached() == 1 && (st.st_mode & 0044) != 0044)
log_warning("Configuration file %s is marked world-inaccessible. This has no effect as configuration data is accessible via APIs without restrictions. Proceeding anyway.", path);
return 0;
diff --git a/src/basic/generate-af-list.sh b/src/basic/generate-af-list.sh
new file mode 100755
index 0000000000..8d9cdd1836
--- /dev/null
+++ b/src/basic/generate-af-list.sh
@@ -0,0 +1,5 @@
+#!/bin/sh -eu
+
+$1 -E -dM -include sys/socket.h - </dev/null | \
+ grep -Ev 'AF_UNSPEC|AF_MAX' | \
+ awk '/^#define[ \t]+AF_[^ \t]+[ \t]+PF_[^ \t]/ { print $2; }'
diff --git a/src/basic/generate-arphrd-list.sh b/src/basic/generate-arphrd-list.sh
new file mode 100755
index 0000000000..ee207fb38e
--- /dev/null
+++ b/src/basic/generate-arphrd-list.sh
@@ -0,0 +1,5 @@
+#!/bin/sh -eu
+
+$1 -dM -include net/if_arp.h - </dev/null | \
+ awk '/^#define[ \t]+ARPHRD_[^ \t]+[ \t]+[^ \t]/ { print $2; }' | \
+ sed -e 's/ARPHRD_//'
diff --git a/src/basic/generate-cap-list.sh b/src/basic/generate-cap-list.sh
new file mode 100755
index 0000000000..1d4a562e7c
--- /dev/null
+++ b/src/basic/generate-cap-list.sh
@@ -0,0 +1,5 @@
+#!/bin/sh -eu
+
+$1 -dM -include linux/capability.h -include "$2" -include "$3" - </dev/null | \
+ awk '/^#define[ \t]+CAP_[A-Z_]+[ \t]+/ { print $2; }' | \
+ grep -v CAP_LAST_CAP
diff --git a/src/basic/generate-errno-list.sh b/src/basic/generate-errno-list.sh
new file mode 100755
index 0000000000..e2bab8b320
--- /dev/null
+++ b/src/basic/generate-errno-list.sh
@@ -0,0 +1,4 @@
+#!/bin/sh -eu
+
+$1 -dM -include errno.h - </dev/null | \
+ awk '/^#define[ \t]+E[^ _]+[ \t]+/ { print $2; }'
diff --git a/src/basic/generate-gperfs.py b/src/basic/generate-gperfs.py
new file mode 100755
index 0000000000..d4cc9aa45c
--- /dev/null
+++ b/src/basic/generate-gperfs.py
@@ -0,0 +1,16 @@
+#!/usr/bin/env python3
+
+"""Generate %-from-name.gperf from %-list.txt
+"""
+
+import sys
+
+name, prefix, input = sys.argv[1:]
+
+print("""\
+struct {}_name {{ const char* name; int id; }};
+%null-strings
+%%""".format(name))
+
+for line in open(input):
+ print("{0}, {1}{0}".format(line.rstrip(), prefix))
diff --git a/src/basic/glob-util.c b/src/basic/glob-util.c
index 007198c269..f611c42e4c 100644
--- a/src/basic/glob-util.c
+++ b/src/basic/glob-util.c
@@ -17,54 +17,70 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include <dirent.h>
#include <errno.h>
#include <glob.h>
+#include <sys/types.h>
+#include "dirent-util.h"
#include "glob-util.h"
#include "macro.h"
+#include "path-util.h"
#include "strv.h"
-int glob_exists(const char *path) {
- _cleanup_globfree_ glob_t g = {};
+int safe_glob(const char *path, int flags, glob_t *pglob) {
int k;
- assert(path);
+ /* We want to set GLOB_ALTDIRFUNC ourselves, don't allow it to be set. */
+ assert(!(flags & GLOB_ALTDIRFUNC));
+
+ if (!pglob->gl_closedir)
+ pglob->gl_closedir = (void (*)(void *)) closedir;
+ if (!pglob->gl_readdir)
+ pglob->gl_readdir = (struct dirent *(*)(void *)) readdir_no_dot;
+ if (!pglob->gl_opendir)
+ pglob->gl_opendir = (void *(*)(const char *)) opendir;
+ if (!pglob->gl_lstat)
+ pglob->gl_lstat = lstat;
+ if (!pglob->gl_stat)
+ pglob->gl_stat = stat;
errno = 0;
- k = glob(path, GLOB_NOSORT|GLOB_BRACE, NULL, &g);
+ k = glob(path, flags | GLOB_ALTDIRFUNC, NULL, pglob);
if (k == GLOB_NOMATCH)
- return 0;
+ return -ENOENT;
if (k == GLOB_NOSPACE)
return -ENOMEM;
if (k != 0)
return errno > 0 ? -errno : -EIO;
+ if (strv_isempty(pglob->gl_pathv))
+ return -ENOENT;
- return !strv_isempty(g.gl_pathv);
+ return 0;
}
-int glob_extend(char ***strv, const char *path) {
+int glob_exists(const char *path) {
_cleanup_globfree_ glob_t g = {};
int k;
- char **p;
- errno = 0;
- k = glob(path, GLOB_NOSORT|GLOB_BRACE, NULL, &g);
+ assert(path);
- if (k == GLOB_NOMATCH)
- return -ENOENT;
- if (k == GLOB_NOSPACE)
- return -ENOMEM;
- if (k != 0)
- return errno > 0 ? -errno : -EIO;
- if (strv_isempty(g.gl_pathv))
- return -ENOENT;
+ k = safe_glob(path, GLOB_NOSORT|GLOB_BRACE, &g);
+ if (k == -ENOENT)
+ return false;
+ if (k < 0)
+ return k;
+ return true;
+}
+
+int glob_extend(char ***strv, const char *path) {
+ _cleanup_globfree_ glob_t g = {};
+ int k;
- STRV_FOREACH(p, g.gl_pathv) {
- k = strv_extend(strv, *p);
- if (k < 0)
- return k;
- }
+ k = safe_glob(path, GLOB_NOSORT|GLOB_BRACE, &g);
+ if (k < 0)
+ return k;
- return 0;
+ return strv_extend_strv(strv, g.gl_pathv, false);
}
diff --git a/src/basic/glob-util.h b/src/basic/glob-util.h
index 5d8fb47a26..e1f6083afa 100644
--- a/src/basic/glob-util.h
+++ b/src/basic/glob-util.h
@@ -19,12 +19,16 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include <glob.h>
#include <stdbool.h>
#include <string.h>
#include "macro.h"
#include "string-util.h"
+/* Note: this function modifies pglob to set various functions. */
+int safe_glob(const char *path, int flags, glob_t *pglob);
+
int glob_exists(const char *path);
int glob_extend(char ***strv, const char *path);
diff --git a/src/basic/in-addr-util.c b/src/basic/in-addr-util.c
index 3927df2955..d52fdad3ac 100644
--- a/src/basic/in-addr-util.c
+++ b/src/basic/in-addr-util.c
@@ -464,3 +464,45 @@ int in_addr_mask(int family, union in_addr_union *addr, unsigned char prefixlen)
return -EAFNOSUPPORT;
}
+
+int in_addr_prefix_from_string(const char *p, int family, union in_addr_union *ret_prefix, uint8_t *ret_prefixlen) {
+ union in_addr_union buffer;
+ const char *e, *l;
+ uint8_t k;
+ int r;
+
+ assert(p);
+
+ if (!IN_SET(family, AF_INET, AF_INET6))
+ return -EAFNOSUPPORT;
+
+ e = strchr(p, '/');
+ if (e)
+ l = strndupa(p, e - p);
+ else
+ l = p;
+
+ r = in_addr_from_string(family, l, &buffer);
+ if (r < 0)
+ return r;
+
+ k = FAMILY_ADDRESS_SIZE(family) * 8;
+
+ if (e) {
+ uint8_t n;
+
+ r = safe_atou8(e + 1, &n);
+ if (r < 0)
+ return r;
+
+ if (n > k)
+ return -ERANGE;
+
+ k = n;
+ }
+
+ *ret_prefix = buffer;
+ *ret_prefixlen = k;
+
+ return 0;
+}
diff --git a/src/basic/in-addr-util.h b/src/basic/in-addr-util.h
index 51a5aa67e4..14e27246b5 100644
--- a/src/basic/in-addr-util.h
+++ b/src/basic/in-addr-util.h
@@ -60,6 +60,7 @@ struct in_addr* in_addr_prefixlen_to_netmask(struct in_addr *addr, unsigned char
int in_addr_default_prefixlen(const struct in_addr *addr, unsigned char *prefixlen);
int in_addr_default_subnet_mask(const struct in_addr *addr, struct in_addr *mask);
int in_addr_mask(int family, union in_addr_union *addr, unsigned char prefixlen);
+int in_addr_prefix_from_string(const char *p, int family, union in_addr_union *ret_prefix, uint8_t *ret_prefixlen);
static inline size_t FAMILY_ADDRESS_SIZE(int family) {
assert(family == AF_INET || family == AF_INET6);
diff --git a/src/basic/log.c b/src/basic/log.c
index 36efc9ac7d..d0caeb5ca3 100644
--- a/src/basic/log.c
+++ b/src/basic/log.c
@@ -58,7 +58,8 @@
#define SNDBUF_SIZE (8*1024*1024)
static LogTarget log_target = LOG_TARGET_CONSOLE;
-static int log_max_level = LOG_INFO;
+static int log_max_level[] = {LOG_INFO, LOG_INFO};
+assert_cc(ELEMENTSOF(log_max_level) == _LOG_REALM_MAX);
static int log_facility = LOG_DAEMON;
static int console_fd = STDERR_FILENO;
@@ -83,7 +84,7 @@ void log_close_console(void) {
if (console_fd < 0)
return;
- if (getpid() == 1) {
+ if (getpid_cached() == 1) {
if (console_fd >= 3)
safe_close(console_fd);
@@ -139,7 +140,7 @@ static int create_log_socket(int type) {
/* We need a blocking fd here since we'd otherwise lose
messages way too early. However, let's not hang forever in the
unlikely case of a deadlock. */
- if (getpid() == 1)
+ if (getpid_cached() == 1)
timeval_store(&tv, 10 * USEC_PER_MSEC);
else
timeval_store(&tv, 10 * USEC_PER_SEC);
@@ -231,6 +232,8 @@ fail:
int log_open(void) {
int r;
+ /* Do not call from library code. */
+
/* If we don't use the console we close it here, to not get
* killed by SAK. If we don't use syslog we close it here so
* that we are not confused by somebody deleting the socket in
@@ -245,7 +248,7 @@ int log_open(void) {
}
if (!IN_SET(log_target, LOG_TARGET_AUTO, LOG_TARGET_SAFE) ||
- getpid() == 1 ||
+ getpid_cached() == 1 ||
isatty(STDERR_FILENO) <= 0) {
if (IN_SET(log_target, LOG_TARGET_AUTO,
@@ -305,6 +308,8 @@ void log_set_target(LogTarget target) {
}
void log_close(void) {
+ /* Do not call from library code. */
+
log_close_journal();
log_close_syslog();
log_close_kmsg();
@@ -312,13 +317,16 @@ void log_close(void) {
}
void log_forget_fds(void) {
+ /* Do not call from library code. */
+
console_fd = kmsg_fd = syslog_fd = journal_fd = -1;
}
-void log_set_max_level(int level) {
+void log_set_max_level_realm(LogRealm realm, int level) {
assert((level & LOG_PRIMASK) == level);
+ assert(realm < ELEMENTSOF(log_max_level));
- log_max_level = level;
+ log_max_level[realm] = level;
}
void log_set_facility(int facility) {
@@ -362,7 +370,7 @@ static int write_to_console(
if (writev(console_fd, iovec, n) < 0) {
- if (errno == EIO && getpid() == 1) {
+ if (errno == EIO && getpid_cached() == 1) {
/* If somebody tried to kick us from our
* console tty (via vhangup() or suchlike),
@@ -415,7 +423,7 @@ static int write_to_syslog(
if (strftime(header_time, sizeof(header_time), "%h %e %T ", tm) <= 0)
return -EINVAL;
- xsprintf(header_pid, "["PID_FMT"]: ", getpid());
+ xsprintf(header_pid, "["PID_FMT"]: ", getpid_cached());
IOVEC_SET_STRING(iovec[0], header_priority);
IOVEC_SET_STRING(iovec[1], header_time);
@@ -460,7 +468,7 @@ static int write_to_kmsg(
return 0;
xsprintf(header_priority, "<%i>", level);
- xsprintf(header_pid, "["PID_FMT"]: ", getpid());
+ xsprintf(header_pid, "["PID_FMT"]: ", getpid_cached());
IOVEC_SET_STRING(iovec[0], header_priority);
IOVEC_SET_STRING(iovec[1], program_invocation_short_name);
@@ -553,7 +561,7 @@ static int write_to_journal(
return 1;
}
-static int log_dispatch(
+int log_dispatch_internal(
int level,
int error,
const char *file,
@@ -636,13 +644,14 @@ static int log_dispatch(
}
int log_dump_internal(
- int level,
- int error,
- const char *file,
- int line,
- const char *func,
- char *buffer) {
+ int level,
+ int error,
+ const char *file,
+ int line,
+ const char *func,
+ char *buffer) {
+ LogRealm realm = LOG_REALM_REMOVE_LEVEL(level);
PROTECT_ERRNO;
/* This modifies the buffer... */
@@ -650,13 +659,13 @@ int log_dump_internal(
if (error < 0)
error = -error;
- if (_likely_(LOG_PRI(level) > log_max_level))
+ if (_likely_(LOG_PRI(level) > log_max_level[realm]))
return -error;
- return log_dispatch(level, error, file, line, func, NULL, NULL, NULL, NULL, buffer);
+ return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, buffer);
}
-int log_internalv(
+int log_internalv_realm(
int level,
int error,
const char *file,
@@ -665,13 +674,14 @@ int log_internalv(
const char *format,
va_list ap) {
- PROTECT_ERRNO;
+ LogRealm realm = LOG_REALM_REMOVE_LEVEL(level);
char buffer[LINE_MAX];
+ PROTECT_ERRNO;
if (error < 0)
error = -error;
- if (_likely_(LOG_PRI(level) > log_max_level))
+ if (_likely_(LOG_PRI(level) > log_max_level[realm]))
return -error;
/* Make sure that %m maps to the specified error */
@@ -680,10 +690,10 @@ int log_internalv(
vsnprintf(buffer, sizeof(buffer), format, ap);
- return log_dispatch(level, error, file, line, func, NULL, NULL, NULL, NULL, buffer);
+ return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, buffer);
}
-int log_internal(
+int log_internal_realm(
int level,
int error,
const char *file,
@@ -695,7 +705,7 @@ int log_internal(
int r;
va_start(ap, format);
- r = log_internalv(level, error, file, line, func, format, ap);
+ r = log_internalv_realm(level, error, file, line, func, format, ap);
va_end(ap);
return r;
@@ -716,12 +726,11 @@ int log_object_internalv(
PROTECT_ERRNO;
char *buffer, *b;
- size_t l;
if (error < 0)
error = -error;
- if (_likely_(LOG_PRI(level) > log_max_level))
+ if (_likely_(LOG_PRI(level) > log_max_level[LOG_REALM_SYSTEMD]))
return -error;
/* Make sure that %m maps to the specified error */
@@ -733,18 +742,15 @@ int log_object_internalv(
size_t n;
n = strlen(object);
- l = n + 2 + LINE_MAX;
-
- buffer = newa(char, l);
+ buffer = newa(char, n + 2 + LINE_MAX);
b = stpcpy(stpcpy(buffer, object), ": ");
- } else {
- l = LINE_MAX;
- b = buffer = newa(char, l);
- }
+ } else
+ b = buffer = newa(char, LINE_MAX);
- vsnprintf(b, l, format, ap);
+ vsnprintf(b, LINE_MAX, format, ap);
- return log_dispatch(level, error, file, line, func, object_field, object, extra_field, extra, buffer);
+ return log_dispatch_internal(level, error, file, line, func,
+ object_field, object, extra_field, extra, buffer);
}
int log_object_internal(
@@ -778,8 +784,9 @@ static void log_assert(
const char *format) {
static char buffer[LINE_MAX];
+ LogRealm realm = LOG_REALM_REMOVE_LEVEL(level);
- if (_likely_(LOG_PRI(level) > log_max_level))
+ if (_likely_(LOG_PRI(level) > log_max_level[realm]))
return;
DISABLE_WARNING_FORMAT_NONLITERAL;
@@ -788,26 +795,45 @@ static void log_assert(
log_abort_msg = buffer;
- log_dispatch(level, 0, file, line, func, NULL, NULL, NULL, NULL, buffer);
+ log_dispatch_internal(level, 0, file, line, func, NULL, NULL, NULL, NULL, buffer);
}
-noreturn void log_assert_failed(const char *text, const char *file, int line, const char *func) {
- log_assert(LOG_CRIT, text, file, line, func, "Assertion '%s' failed at %s:%u, function %s(). Aborting.");
+noreturn void log_assert_failed_realm(
+ LogRealm realm,
+ const char *text,
+ const char *file,
+ int line,
+ const char *func) {
+ log_assert(LOG_REALM_PLUS_LEVEL(realm, LOG_CRIT), text, file, line, func,
+ "Assertion '%s' failed at %s:%u, function %s(). Aborting.");
abort();
}
-noreturn void log_assert_failed_unreachable(const char *text, const char *file, int line, const char *func) {
- log_assert(LOG_CRIT, text, file, line, func, "Code should not be reached '%s' at %s:%u, function %s(). Aborting.");
+noreturn void log_assert_failed_unreachable_realm(
+ LogRealm realm,
+ const char *text,
+ const char *file,
+ int line,
+ const char *func) {
+ log_assert(LOG_REALM_PLUS_LEVEL(realm, LOG_CRIT), text, file, line, func,
+ "Code should not be reached '%s' at %s:%u, function %s(). Aborting.");
abort();
}
-void log_assert_failed_return(const char *text, const char *file, int line, const char *func) {
+void log_assert_failed_return_realm(
+ LogRealm realm,
+ const char *text,
+ const char *file,
+ int line,
+ const char *func) {
PROTECT_ERRNO;
- log_assert(LOG_DEBUG, text, file, line, func, "Assertion '%s' failed at %s:%u, function %s(). Ignoring.");
+ log_assert(LOG_REALM_PLUS_LEVEL(realm, LOG_DEBUG), text, file, line, func,
+ "Assertion '%s' failed at %s:%u, function %s(). Ignoring.");
}
-int log_oom_internal(const char *file, int line, const char *func) {
- log_internal(LOG_ERR, ENOMEM, file, line, func, "Out of memory.");
+int log_oom_internal(LogRealm realm, const char *file, int line, const char *func) {
+ log_internal_realm(LOG_REALM_PLUS_LEVEL(realm, LOG_ERR),
+ ENOMEM, file, line, func, "Out of memory.");
return -ENOMEM;
}
@@ -867,13 +893,14 @@ int log_struct_internal(
char buf[LINE_MAX];
bool found = false;
+ LogRealm realm = LOG_REALM_REMOVE_LEVEL(level);
PROTECT_ERRNO;
va_list ap;
if (error < 0)
error = -error;
- if (_likely_(LOG_PRI(level) > log_max_level))
+ if (_likely_(LOG_PRI(level) > log_max_level[realm]))
return -error;
if (log_target == LOG_TARGET_NULL)
@@ -943,7 +970,7 @@ int log_struct_internal(
if (!found)
return -error;
- return log_dispatch(level, error, file, line, func, NULL, NULL, NULL, NULL, buf + 8);
+ return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, buf + 8);
}
int log_set_target_from_string(const char *e) {
@@ -957,14 +984,14 @@ int log_set_target_from_string(const char *e) {
return 0;
}
-int log_set_max_level_from_string(const char *e) {
+int log_set_max_level_from_string_realm(LogRealm realm, const char *e) {
int t;
t = log_level_from_string(e);
if (t < 0)
return -EINVAL;
- log_set_max_level(t);
+ log_set_max_level_realm(realm, t);
return 0;
}
@@ -1012,7 +1039,9 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
return 0;
}
-void log_parse_environment(void) {
+void log_parse_environment_realm(LogRealm realm) {
+ /* Do not call from library code. */
+
const char *e;
if (get_ctty_devnr(0, NULL) < 0)
@@ -1020,19 +1049,19 @@ void log_parse_environment(void) {
user stuff. */
(void) proc_cmdline_parse(parse_proc_cmdline_item, NULL, PROC_CMDLINE_STRIP_RD_PREFIX);
- e = secure_getenv("SYSTEMD_LOG_TARGET");
+ e = getenv("SYSTEMD_LOG_TARGET");
if (e && log_set_target_from_string(e) < 0)
log_warning("Failed to parse log target '%s'. Ignoring.", e);
- e = secure_getenv("SYSTEMD_LOG_LEVEL");
- if (e && log_set_max_level_from_string(e) < 0)
+ e = getenv("SYSTEMD_LOG_LEVEL");
+ if (e && log_set_max_level_from_string_realm(realm, e) < 0)
log_warning("Failed to parse log level '%s'. Ignoring.", e);
- e = secure_getenv("SYSTEMD_LOG_COLOR");
+ e = getenv("SYSTEMD_LOG_COLOR");
if (e && log_show_color_from_string(e) < 0)
log_warning("Failed to parse bool '%s'. Ignoring.", e);
- e = secure_getenv("SYSTEMD_LOG_LOCATION");
+ e = getenv("SYSTEMD_LOG_LOCATION");
if (e && log_show_location_from_string(e) < 0)
log_warning("Failed to parse bool '%s'. Ignoring.", e);
}
@@ -1041,8 +1070,8 @@ LogTarget log_get_target(void) {
return log_target;
}
-int log_get_max_level(void) {
- return log_max_level;
+int log_get_max_level_realm(LogRealm realm) {
+ return log_max_level[realm];
}
void log_show_color(bool b) {
@@ -1146,7 +1175,7 @@ int log_syntax_internal(
if (error < 0)
error = -error;
- if (_likely_(LOG_PRI(level) > log_max_level))
+ if (_likely_(LOG_PRI(level) > log_max_level[LOG_REALM_SYSTEMD]))
return -error;
if (log_target == LOG_TARGET_NULL)
@@ -1160,10 +1189,11 @@ int log_syntax_internal(
va_end(ap);
if (unit)
- unit_fmt = getpid() == 1 ? "UNIT=%s" : "USER_UNIT=%s";
+ unit_fmt = getpid_cached() == 1 ? "UNIT=%s" : "USER_UNIT=%s";
return log_struct_internal(
- level, error,
+ LOG_REALM_PLUS_LEVEL(LOG_REALM_SYSTEMD, level),
+ error,
file, line, func,
"MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR,
"CONFIG_FILE=%s", config_file,
diff --git a/src/basic/log.h b/src/basic/log.h
index 72714e02e5..186747ff8e 100644
--- a/src/basic/log.h
+++ b/src/basic/log.h
@@ -30,6 +30,17 @@
#include "sd-id128.h"
#include "macro.h"
+#include "process-util.h"
+
+typedef enum LogRealm {
+ LOG_REALM_SYSTEMD,
+ LOG_REALM_UDEV,
+ _LOG_REALM_MAX,
+} LogRealm;
+
+#ifndef LOG_REALM
+# define LOG_REALM LOG_REALM_SYSTEMD
+#endif
typedef enum LogTarget{
LOG_TARGET_CONSOLE,
@@ -44,14 +55,24 @@ typedef enum LogTarget{
LOG_TARGET_NULL,
_LOG_TARGET_MAX,
_LOG_TARGET_INVALID = -1
-} LogTarget;
+} LogTarget;
+
+#define LOG_REALM_PLUS_LEVEL(realm, level) \
+ ((realm) << 10 | (level))
+#define LOG_REALM_REMOVE_LEVEL(realm_level) \
+ ((realm_level >> 10))
void log_set_target(LogTarget target);
-void log_set_max_level(int level);
+void log_set_max_level_realm(LogRealm realm, int level);
+#define log_set_max_level(level) \
+ log_set_max_level_realm(LOG_REALM, (level))
+
void log_set_facility(int facility);
int log_set_target_from_string(const char *e);
-int log_set_max_level_from_string(const char *e);
+int log_set_max_level_from_string_realm(LogRealm realm, const char *e);
+#define log_set_max_level_from_string(e) \
+ log_set_max_level_from_string_realm(LOG_REALM, (e))
void log_show_color(bool b);
bool log_get_show_color(void) _pure_;
@@ -62,7 +83,14 @@ int log_show_color_from_string(const char *e);
int log_show_location_from_string(const char *e);
LogTarget log_get_target(void) _pure_;
-int log_get_max_level(void) _pure_;
+int log_get_max_level_realm(LogRealm realm) _pure_;
+#define log_get_max_level() \
+ log_get_max_level_realm(LOG_REALM)
+
+/* Functions below that open and close logs or configure logging based on the
+ * environment should not be called from library code — this is always a job
+ * for the application itself.
+ */
int log_open(void);
void log_close(void);
@@ -73,17 +101,33 @@ void log_close_journal(void);
void log_close_kmsg(void);
void log_close_console(void);
-void log_parse_environment(void);
+void log_parse_environment_realm(LogRealm realm);
+#define log_parse_environment() \
+ log_parse_environment_realm(LOG_REALM)
+
+int log_dispatch_internal(
+ int level,
+ int error,
+ const char *file,
+ int line,
+ const char *func,
+ const char *object_field,
+ const char *object,
+ const char *extra,
+ const char *extra_field,
+ char *buffer);
-int log_internal(
+int log_internal_realm(
int level,
int error,
const char *file,
int line,
const char *func,
const char *format, ...) _printf_(6,7);
+#define log_internal(level, ...) \
+ log_internal_realm(LOG_REALM_PLUS_LEVEL(LOG_REALM, (level)), __VA_ARGS__)
-int log_internalv(
+int log_internalv_realm(
int level,
int error,
const char *file,
@@ -91,7 +135,10 @@ int log_internalv(
const char *func,
const char *format,
va_list ap) _printf_(6,0);
+#define log_internalv(level, ...) \
+ log_internalv_realm(LOG_REALM_PLUS_LEVEL(LOG_REALM, (level)), __VA_ARGS__)
+/* Realm is fixed to LOG_REALM_SYSTEMD for those */
int log_object_internal(
int level,
int error,
@@ -115,7 +162,7 @@ int log_object_internalv(
const char *extra_field,
const char *extra,
const char *format,
- va_list ap) _printf_(9,0);
+ va_list ap) _printf_(10,0);
int log_struct_internal(
int level,
@@ -126,6 +173,7 @@ int log_struct_internal(
const char *format, ...) _printf_(6,0) _sentinel_;
int log_oom_internal(
+ LogRealm realm,
const char *file,
int line,
const char *func);
@@ -137,7 +185,7 @@ int log_format_iovec(
bool newline_separator,
int error,
const char *format,
- va_list ap);
+ va_list ap) _printf_(6, 0);
/* This modifies the buffer passed! */
int log_dump_internal(
@@ -149,34 +197,50 @@ int log_dump_internal(
char *buffer);
/* Logging for various assertions */
-noreturn void log_assert_failed(
+noreturn void log_assert_failed_realm(
+ LogRealm realm,
const char *text,
const char *file,
int line,
const char *func);
+#define log_assert_failed(text, ...) \
+ log_assert_failed_realm(LOG_REALM, (text), __VA_ARGS__)
-noreturn void log_assert_failed_unreachable(
+noreturn void log_assert_failed_unreachable_realm(
+ LogRealm realm,
const char *text,
const char *file,
int line,
const char *func);
+#define log_assert_failed_unreachable(text, ...) \
+ log_assert_failed_unreachable_realm(LOG_REALM, (text), __VA_ARGS__)
-void log_assert_failed_return(
+void log_assert_failed_return_realm(
+ LogRealm realm,
const char *text,
const char *file,
int line,
const char *func);
+#define log_assert_failed_return(text, ...) \
+ log_assert_failed_return_realm(LOG_REALM, (text), __VA_ARGS__)
+
+#define log_dispatch(level, error, buffer) \
+ log_dispatch_internal(level, error, __FILE__, __LINE__, __func__, NULL, NULL, NULL, NULL, buffer)
/* Logging with level */
-#define log_full_errno(level, error, ...) \
+#define log_full_errno_realm(realm, level, error, ...) \
({ \
int _level = (level), _e = (error); \
- (log_get_max_level() >= LOG_PRI(_level)) \
- ? log_internal(_level, _e, __FILE__, __LINE__, __func__, __VA_ARGS__) \
+ (log_get_max_level_realm((realm)) >= LOG_PRI(_level)) \
+ ? log_internal_realm(LOG_REALM_PLUS_LEVEL((realm), _level), _e, \
+ __FILE__, __LINE__, __func__, __VA_ARGS__) \
: -abs(_e); \
})
-#define log_full(level, ...) log_full_errno(level, 0, __VA_ARGS__)
+#define log_full_errno(level, error, ...) \
+ log_full_errno_realm(LOG_REALM, (level), (error), __VA_ARGS__)
+
+#define log_full(level, ...) log_full_errno((level), 0, __VA_ARGS__)
/* Normal logging */
#define log_debug(...) log_full(LOG_DEBUG, __VA_ARGS__)
@@ -184,7 +248,7 @@ void log_assert_failed_return(
#define log_notice(...) log_full(LOG_NOTICE, __VA_ARGS__)
#define log_warning(...) log_full(LOG_WARNING, __VA_ARGS__)
#define log_error(...) log_full(LOG_ERR, __VA_ARGS__)
-#define log_emergency(...) log_full(getpid() == 1 ? LOG_EMERG : LOG_ERR, __VA_ARGS__)
+#define log_emergency(...) log_full(getpid_cached() == 1 ? LOG_EMERG : LOG_ERR, __VA_ARGS__)
/* Logging triggered by an errno-like error */
#define log_debug_errno(error, ...) log_full_errno(LOG_DEBUG, error, __VA_ARGS__)
@@ -192,7 +256,7 @@ void log_assert_failed_return(
#define log_notice_errno(error, ...) log_full_errno(LOG_NOTICE, error, __VA_ARGS__)
#define log_warning_errno(error, ...) log_full_errno(LOG_WARNING, error, __VA_ARGS__)
#define log_error_errno(error, ...) log_full_errno(LOG_ERR, error, __VA_ARGS__)
-#define log_emergency_errno(error, ...) log_full_errno(getpid() == 1 ? LOG_EMERG : LOG_ERR, error, __VA_ARGS__)
+#define log_emergency_errno(error, ...) log_full_errno(getpid_cached() == 1 ? LOG_EMERG : LOG_ERR, error, __VA_ARGS__)
#ifdef LOG_TRACE
# define log_trace(...) log_debug(__VA_ARGS__)
@@ -201,13 +265,17 @@ void log_assert_failed_return(
#endif
/* Structured logging */
-#define log_struct(level, ...) log_struct_internal(level, 0, __FILE__, __LINE__, __func__, __VA_ARGS__)
-#define log_struct_errno(level, error, ...) log_struct_internal(level, error, __FILE__, __LINE__, __func__, __VA_ARGS__)
+#define log_struct_errno(level, error, ...) \
+ log_struct_internal(LOG_REALM_PLUS_LEVEL(LOG_REALM, level), \
+ error, __FILE__, __LINE__, __func__, __VA_ARGS__)
+#define log_struct(level, ...) log_struct_errno(level, 0, __VA_ARGS__)
/* This modifies the buffer passed! */
-#define log_dump(level, buffer) log_dump_internal(level, 0, __FILE__, __LINE__, __func__, buffer)
+#define log_dump(level, buffer) \
+ log_dump_internal(LOG_REALM_PLUS_LEVEL(LOG_REALM, level), \
+ 0, __FILE__, __LINE__, __func__, buffer)
-#define log_oom() log_oom_internal(__FILE__, __LINE__, __func__)
+#define log_oom() log_oom_internal(LOG_REALM, __FILE__, __LINE__, __func__)
bool log_on_console(void) _pure_;
diff --git a/src/basic/macro.h b/src/basic/macro.h
index 6b2aeb933f..a51562db35 100644
--- a/src/basic/macro.h
+++ b/src/basic/macro.h
@@ -19,7 +19,6 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <assert.h>
#include <inttypes.h>
#include <stdbool.h>
#include <sys/param.h>
diff --git a/src/basic/meson.build b/src/basic/meson.build
new file mode 100644
index 0000000000..065f0ac4af
--- /dev/null
+++ b/src/basic/meson.build
@@ -0,0 +1,281 @@
+basic_sources_plain = files('''
+ af-list.c
+ af-list.h
+ alloc-util.c
+ alloc-util.h
+ architecture.c
+ architecture.h
+ arphrd-list.c
+ arphrd-list.h
+ async.c
+ async.h
+ audit-util.c
+ audit-util.h
+ barrier.c
+ barrier.h
+ bitmap.c
+ bitmap.h
+ blkid-util.h
+ btrfs-ctree.h
+ btrfs-util.c
+ btrfs-util.h
+ build.h
+ bus-label.c
+ bus-label.h
+ calendarspec.c
+ calendarspec.h
+ capability-util.c
+ capability-util.h
+ cap-list.c
+ cap-list.h
+ cgroup-util.c
+ cgroup-util.h
+ chattr-util.c
+ chattr-util.h
+ clock-util.c
+ clock-util.h
+ conf-files.c
+ conf-files.h
+ copy.c
+ copy.h
+ cpu-set-util.c
+ cpu-set-util.h
+ def.h
+ device-nodes.c
+ device-nodes.h
+ dirent-util.c
+ dirent-util.h
+ env-util.c
+ env-util.h
+ errno-list.c
+ errno-list.h
+ escape.c
+ escape.h
+ ether-addr-util.c
+ ether-addr-util.h
+ exec-util.c
+ exec-util.h
+ exit-status.c
+ exit-status.h
+ extract-word.c
+ extract-word.h
+ fd-util.c
+ fd-util.h
+ fileio.c
+ fileio.h
+ fileio-label.c
+ fileio-label.h
+ format-util.h
+ fs-util.c
+ fs-util.h
+ glob-util.c
+ glob-util.h
+ gunicode.c
+ gunicode.h
+ hash-funcs.c
+ hash-funcs.h
+ hashmap.c
+ hashmap.h
+ hexdecoct.c
+ hexdecoct.h
+ hostname-util.c
+ hostname-util.h
+ in-addr-util.c
+ in-addr-util.h
+ ioprio.h
+ io-util.c
+ io-util.h
+ journal-importer.c
+ journal-importer.h
+ khash.c
+ khash.h
+ label.c
+ label.h
+ list.h
+ locale-util.c
+ locale-util.h
+ lockfile-util.c
+ lockfile-util.h
+ log.c
+ log.h
+ login-util.c
+ login-util.h
+ macro.h
+ memfd-util.c
+ memfd-util.h
+ mempool.c
+ mempool.h
+ missing_syscall.h
+ mkdir.c
+ mkdir.h
+ mkdir-label.c
+ mount-util.c
+ mount-util.h
+ MurmurHash2.c
+ MurmurHash2.h
+ nss-util.h
+ ordered-set.c
+ ordered-set.h
+ parse-util.c
+ parse-util.h
+ path-util.c
+ path-util.h
+ prioq.c
+ prioq.h
+ proc-cmdline.c
+ proc-cmdline.h
+ process-util.c
+ process-util.h
+ random-util.c
+ random-util.h
+ ratelimit.c
+ ratelimit.h
+ raw-clone.h
+ refcnt.h
+ replace-var.c
+ replace-var.h
+ rlimit-util.c
+ rlimit-util.h
+ rm-rf.c
+ rm-rf.h
+ securebits.h
+ selinux-util.c
+ selinux-util.h
+ set.h
+ sigbus.c
+ sigbus.h
+ signal-util.c
+ signal-util.h
+ siphash24.c
+ siphash24.h
+ smack-util.c
+ smack-util.h
+ socket-label.c
+ socket-util.c
+ socket-util.h
+ sparse-endian.h
+ special.h
+ stat-util.c
+ stat-util.h
+ stdio-util.h
+ strbuf.c
+ strbuf.h
+ string-table.c
+ string-table.h
+ string-util.c
+ string-util.h
+ strv.c
+ strv.h
+ strxcpyx.c
+ strxcpyx.h
+ syslog-util.c
+ syslog-util.h
+ terminal-util.c
+ terminal-util.h
+ time-util.c
+ time-util.h
+ umask-util.h
+ unaligned.h
+ unit-name.c
+ unit-name.h
+ user-util.c
+ user-util.h
+ utf8.c
+ utf8.h
+ util.c
+ util.h
+ verbs.c
+ verbs.h
+ virt.c
+ virt.h
+ web-util.c
+ web-util.h
+ xattr-util.c
+ xattr-util.h
+ xml.c
+ xml.h
+'''.split())
+
+missing_h = files('missing.h')
+
+generate_gperfs = find_program('generate-gperfs.py')
+
+generate_af_list = find_program('generate-af-list.sh')
+af_list_txt = custom_target(
+ 'af-list.txt',
+ output : 'af-list.txt',
+ command : [generate_af_list, cpp],
+ capture : true)
+
+generate_arphrd_list = find_program('generate-arphrd-list.sh')
+arphrd_list_txt = custom_target(
+ 'arphrd-list.txt',
+ output : 'arphrd-list.txt',
+ command : [generate_arphrd_list, cpp],
+ capture : true)
+
+generate_cap_list = find_program('generate-cap-list.sh')
+cap_list_txt = custom_target(
+ 'cap-list.txt',
+ output : 'cap-list.txt',
+ command : [generate_cap_list, cpp, config_h, missing_h],
+ capture : true)
+
+generate_errno_list = find_program('generate-errno-list.sh')
+errno_list_txt = custom_target(
+ 'errno-list.txt',
+ output : 'errno-list.txt',
+ command : [generate_errno_list, cpp],
+ capture : true)
+
+generated_gperf_headers = []
+foreach item : [['af', af_list_txt, 'af', ''],
+ ['arphrd', arphrd_list_txt, 'arphrd', 'ARPHRD_'],
+ ['cap', cap_list_txt, 'capability', ''],
+ ['errno', errno_list_txt, 'errno', '']]
+
+ fname = '@0@-from-name.gperf'.format(item[0])
+ gperf_file = custom_target(
+ fname,
+ input : item[1],
+ output : fname,
+ command : [generate_gperfs, item[2], item[3], '@INPUT@'],
+ capture : true)
+
+ fname = '@0@-from-name.h'.format(item[0])
+ target1 = custom_target(
+ fname,
+ input : gperf_file,
+ output : fname,
+ command : [gperf,
+ '-L', 'ANSI-C', '-t', '--ignore-case',
+ '-N', 'lookup_@0@'.format(item[2]),
+ '-H', 'hash_@0@_name'.format(item[2]),
+ '-p', '-C',
+ '@INPUT@'],
+ capture : true)
+
+ fname = '@0@-to-name.h'.format(item[0])
+ awkscript = '@0@-to-name.awk'.format(item[0])
+ target2 = custom_target(
+ fname,
+ input : [awkscript, item[1]],
+ output : fname,
+ command : [awk, '-f', '@INPUT0@', '@INPUT1@'],
+ capture : true)
+
+ generated_gperf_headers += [target1, target2]
+endforeach
+
+basic_sources = basic_sources_plain + [missing_h] + generated_gperf_headers
+
+libbasic = static_library(
+ 'basic',
+ basic_sources,
+ include_directories : includes,
+ dependencies : [threads,
+ libcap,
+ libblkid,
+ libselinux,
+ ],
+ install : false)
diff --git a/src/basic/missing.h b/src/basic/missing.h
index b797899a61..f3846da8bd 100644
--- a/src/basic/missing.h
+++ b/src/basic/missing.h
@@ -23,6 +23,7 @@
#include <errno.h>
#include <fcntl.h>
+#include <inttypes.h>
#include <linux/audit.h>
#include <linux/capability.h>
#include <linux/if_link.h>
@@ -68,8 +69,6 @@ struct sockaddr_vm {
};
#endif /* !HAVE_LINUX_VM_SOCKETS_H */
-#include "macro.h"
-
#ifndef RLIMIT_RTTIME
#define RLIMIT_RTTIME 15
#endif
@@ -571,6 +570,17 @@ struct btrfs_ioctl_quota_ctl_args {
# define EVIOCREVOKE _IOW('E', 0x91, int)
#endif
+#ifndef EVIOCSMASK
+
+struct input_mask {
+ uint32_t type;
+ uint32_t codes_size;
+ uint64_t codes_ptr;
+};
+
+#define EVIOCSMASK _IOW('E', 0x93, struct input_mask)
+#endif
+
#ifndef DRM_IOCTL_SET_MASTER
# define DRM_IOCTL_SET_MASTER _IO('d', 0x1e)
#endif
@@ -726,7 +736,7 @@ struct btrfs_ioctl_quota_ctl_args {
#define IFLA_VLAN_MAX (__IFLA_VLAN_MAX - 1)
#endif
-#if !HAVE_DECL_IFLA_VXLAN_REMCSUM_NOPARTIAL
+#if !HAVE_DECL_IFLA_VXLAN_GPE
#define IFLA_VXLAN_UNSPEC 0
#define IFLA_VXLAN_ID 1
#define IFLA_VXLAN_GROUP 2
@@ -752,11 +762,34 @@ struct btrfs_ioctl_quota_ctl_args {
#define IFLA_VXLAN_REMCSUM_RX 22
#define IFLA_VXLAN_GBP 23
#define IFLA_VXLAN_REMCSUM_NOPARTIAL 24
-#define __IFLA_VXLAN_MAX 25
+#define IFLA_VXLAN_COLLECT_METADATA 25
+#define IFLA_VXLAN_LABEL 26
+#define IFLA_VXLAN_GPE 27
+
+#define __IFLA_VXLAN_MAX 28
#define IFLA_VXLAN_MAX (__IFLA_VXLAN_MAX - 1)
#endif
+#if !HAVE_DECL_IFLA_GENEVE_LABEL
+#define IFLA_GENEVE_UNSPEC 0
+#define IFLA_GENEVE_ID 1
+#define IFLA_GENEVE_REMOTE 2
+#define IFLA_GENEVE_TTL 3
+#define IFLA_GENEVE_TOS 4
+#define IFLA_GENEVE_PORT 5
+#define IFLA_GENEVE_COLLECT_METADATA 6
+#define IFLA_GENEVE_REMOTE6 7
+#define IFLA_GENEVE_UDP_CSUM 8
+#define IFLA_GENEVE_UDP_ZERO_CSUM6_TX 9
+#define IFLA_GENEVE_UDP_ZERO_CSUM6_RX 10
+#define IFLA_GENEVE_LABEL 11
+
+#define __IFLA_GENEVE_MAX 12
+
+#define IFLA_GENEVE_MAX (__IFLA_GENEVE_MAX - 1)
+#endif
+
#if !HAVE_DECL_IFLA_IPTUN_ENCAP_DPORT
#define IFLA_IPTUN_UNSPEC 0
#define IFLA_IPTUN_LINK 1
@@ -1040,6 +1073,15 @@ struct btrfs_ioctl_quota_ctl_args {
#define INPUT_PROP_ACCELEROMETER 0x06
#endif
+#ifndef BTN_DPAD_UP
+#define BTN_DPAD_UP 0x220
+#define BTN_DPAD_RIGHT 0x223
+#endif
+
+#ifndef KEY_ALS_TOGGLE
+#define KEY_ALS_TOGGLE 0x230
+#endif
+
#ifndef HAVE_KEY_SERIAL_T
typedef int32_t key_serial_t;
#endif
diff --git a/src/basic/missing_syscall.h b/src/basic/missing_syscall.h
index 9fc4156564..898116c7b3 100644
--- a/src/basic/missing_syscall.h
+++ b/src/basic/missing_syscall.h
@@ -52,6 +52,8 @@ static inline int pivot_root(const char *new_root, const char *put_old) {
# endif
# elif defined __i386__
# define __NR_memfd_create 356
+# elif defined __arc__
+# define __NR_memfd_create 279
# else
# warning "__NR_memfd_create unknown for your architecture"
# endif
@@ -97,6 +99,8 @@ static inline int memfd_create(const char *name, unsigned int flags) {
# if _MIPS_SIM == _MIPS_SIM_ABI64
# define __NR_getrandom 5313
# endif
+# elif defined(__arc__)
+# define __NR_getrandom 278
# else
# warning "__NR_getrandom unknown for your architecture"
# endif
@@ -132,6 +136,8 @@ static inline pid_t gettid(void) {
# define __NR_name_to_handle_at 370
# elif defined(__powerpc__)
# define __NR_name_to_handle_at 345
+# elif defined(__arc__)
+# define __NR_name_to_handle_at 264
# else
# error "__NR_name_to_handle_at is not defined"
# endif
@@ -161,6 +167,8 @@ static inline int name_to_handle_at(int fd, const char *name, struct file_handle
# define __NR_setns 308
# elif defined(__i386__)
# define __NR_setns 346
+# elif defined(__arc__)
+# define __NR_setns 268
# else
# error "__NR_setns is not defined"
# endif
@@ -208,6 +216,12 @@ static inline pid_t raw_getpid(void) {
# endif
# elif defined __i386__
# define __NR_renameat2 353
+# elif defined __powerpc64__
+# define __NR_renameat2 357
+# elif defined __s390__ || defined __s390x__
+# define __NR_renameat2 347
+# elif defined __arc__
+# define __NR_renameat2 276
# else
# warning "__NR_renameat2 unknown for your architecture"
# endif
@@ -283,6 +297,8 @@ static inline key_serial_t request_key(const char *type, const char *description
# define __NR_copy_file_range 285
# elif defined __powerpc__
# define __NR_copy_file_range 379
+# elif defined __arc__
+# define __NR_copy_file_range 285
# else
# warning "__NR_copy_file_range not defined for your architecture"
# endif
diff --git a/src/basic/mount-util.c b/src/basic/mount-util.c
index a8fd63fb45..7b9400b47c 100644
--- a/src/basic/mount-util.c
+++ b/src/basic/mount-util.c
@@ -317,11 +317,16 @@ static int get_mount_flags(const char *path, unsigned long *flags) {
return 0;
}
-int bind_remount_recursive(const char *prefix, bool ro, char **blacklist) {
+/* Use this function only if do you have direct access to /proc/self/mountinfo
+ * and need the caller to open it for you. This is the case when /proc is
+ * masked or not mounted. Otherwise, use bind_remount_recursive. */
+int bind_remount_recursive_with_mountinfo(const char *prefix, bool ro, char **blacklist, FILE *proc_self_mountinfo) {
_cleanup_set_free_free_ Set *done = NULL;
_cleanup_free_ char *cleaned = NULL;
int r;
+ assert(proc_self_mountinfo);
+
/* Recursively remount a directory (and all its submounts) read-only or read-write. If the directory is already
* mounted, we reuse the mount and simply mark it MS_BIND|MS_RDONLY (or remove the MS_RDONLY for read-write
* operation). If it isn't we first make it one. Afterwards we apply MS_BIND|MS_RDONLY (or remove MS_RDONLY) to
@@ -344,7 +349,6 @@ int bind_remount_recursive(const char *prefix, bool ro, char **blacklist) {
return -ENOMEM;
for (;;) {
- _cleanup_fclose_ FILE *proc_self_mountinfo = NULL;
_cleanup_set_free_free_ Set *todo = NULL;
bool top_autofs = false;
char *x;
@@ -354,9 +358,7 @@ int bind_remount_recursive(const char *prefix, bool ro, char **blacklist) {
if (!todo)
return -ENOMEM;
- proc_self_mountinfo = fopen("/proc/self/mountinfo", "re");
- if (!proc_self_mountinfo)
- return -errno;
+ rewind(proc_self_mountinfo);
for (;;) {
_cleanup_free_ char *path = NULL, *p = NULL, *type = NULL;
@@ -495,6 +497,16 @@ int bind_remount_recursive(const char *prefix, bool ro, char **blacklist) {
}
}
+int bind_remount_recursive(const char *prefix, bool ro, char **blacklist) {
+ _cleanup_fclose_ FILE *proc_self_mountinfo = NULL;
+
+ proc_self_mountinfo = fopen("/proc/self/mountinfo", "re");
+ if (!proc_self_mountinfo)
+ return -errno;
+
+ return bind_remount_recursive_with_mountinfo(prefix, ro, blacklist, proc_self_mountinfo);
+}
+
int mount_move_root(const char *path) {
assert(path);
diff --git a/src/basic/mount-util.h b/src/basic/mount-util.h
index 1615c94e9a..2e24a184c5 100644
--- a/src/basic/mount-util.h
+++ b/src/basic/mount-util.h
@@ -36,6 +36,7 @@ int repeat_unmount(const char *path, int flags);
int umount_recursive(const char *target, int flags);
int bind_remount_recursive(const char *prefix, bool ro, char **blacklist);
+int bind_remount_recursive_with_mountinfo(const char *prefix, bool ro, char **blacklist, FILE *proc_self_mountinfo);
int mount_move_root(const char *path);
diff --git a/src/basic/parse-util.c b/src/basic/parse-util.c
index d86700736d..4532f222c8 100644
--- a/src/basic/parse-util.c
+++ b/src/basic/parse-util.c
@@ -589,3 +589,18 @@ int parse_ip_port(const char *s, uint16_t *ret) {
return 0;
}
+
+int parse_dev(const char *s, dev_t *ret) {
+ unsigned x, y;
+ dev_t d;
+
+ if (sscanf(s, "%u:%u", &x, &y) != 2)
+ return -EINVAL;
+
+ d = makedev(x, y);
+ if ((unsigned) major(d) != x || (unsigned) minor(d) != y)
+ return -EINVAL;
+
+ *ret = d;
+ return 0;
+}
diff --git a/src/basic/parse-util.h b/src/basic/parse-util.h
index 4d132f0de5..dc09782ca8 100644
--- a/src/basic/parse-util.h
+++ b/src/basic/parse-util.h
@@ -30,6 +30,7 @@
#define MODE_INVALID ((mode_t) -1)
int parse_boolean(const char *v) _pure_;
+int parse_dev(const char *s, dev_t *ret);
int parse_pid(const char *s, pid_t* ret_pid);
int parse_mode(const char *s, mode_t *ret);
int parse_ifindex(const char *s, int *ret);
diff --git a/src/basic/path-util.c b/src/basic/path-util.c
index 1313a52c9c..80fdda170f 100644
--- a/src/basic/path-util.c
+++ b/src/basic/path-util.c
@@ -442,8 +442,8 @@ bool path_equal(const char *a, const char *b) {
return path_compare(a, b) == 0;
}
-bool path_equal_or_files_same(const char *a, const char *b) {
- return path_equal(a, b) || files_same(a, b) > 0;
+bool path_equal_or_files_same(const char *a, const char *b, int flags) {
+ return path_equal(a, b) || files_same(a, b, flags) > 0;
}
char* path_join(const char *root, const char *path, const char *rest) {
diff --git a/src/basic/path-util.h b/src/basic/path-util.h
index 35aef3adc8..26f165fc38 100644
--- a/src/basic/path-util.h
+++ b/src/basic/path-util.h
@@ -46,7 +46,7 @@ char* path_kill_slashes(char *path);
char* path_startswith(const char *path, const char *prefix) _pure_;
int path_compare(const char *a, const char *b) _pure_;
bool path_equal(const char *a, const char *b) _pure_;
-bool path_equal_or_files_same(const char *a, const char *b);
+bool path_equal_or_files_same(const char *a, const char *b, int flags);
char* path_join(const char *root, const char *path, const char *rest);
static inline bool path_equal_ptr(const char *a, const char *b) {
diff --git a/src/basic/process-util.c b/src/basic/process-util.c
index 0df3fed640..ce6a59c8a4 100644
--- a/src/basic/process-util.c
+++ b/src/basic/process-util.c
@@ -807,14 +807,14 @@ int pid_from_same_root_fs(pid_t pid) {
root = procfs_file_alloca(pid, "root");
- return files_same(root, "/proc/1/root");
+ return files_same(root, "/proc/1/root", 0);
}
bool is_main_thread(void) {
static thread_local int cached = 0;
if (_unlikely_(cached == 0))
- cached = getpid() == gettid() ? 1 : -1;
+ cached = getpid_cached() == gettid() ? 1 : -1;
return cached > 0;
}
@@ -878,7 +878,7 @@ const char* personality_to_string(unsigned long p) {
void valgrind_summary_hack(void) {
#ifdef HAVE_VALGRIND_VALGRIND_H
- if (getpid() == 1 && RUNNING_ON_VALGRIND) {
+ if (getpid_cached() == 1 && RUNNING_ON_VALGRIND) {
pid_t pid;
pid = raw_clone(SIGCHLD);
if (pid < 0)
@@ -905,6 +905,85 @@ int pid_compare_func(const void *a, const void *b) {
return 0;
}
+int ioprio_parse_priority(const char *s, int *ret) {
+ int i, r;
+
+ assert(s);
+ assert(ret);
+
+ r = safe_atoi(s, &i);
+ if (r < 0)
+ return r;
+
+ if (!ioprio_priority_is_valid(i))
+ return -EINVAL;
+
+ *ret = i;
+ return 0;
+}
+
+/* The cached PID, possible values:
+ *
+ * == UNSET [0] → cache not initialized yet
+ * == BUSY [-1] → some thread is initializing it at the moment
+ * any other → the cached PID
+ */
+
+#define CACHED_PID_UNSET ((pid_t) 0)
+#define CACHED_PID_BUSY ((pid_t) -1)
+
+static pid_t cached_pid = CACHED_PID_UNSET;
+
+static void reset_cached_pid(void) {
+ /* Invoked in the child after a fork(), i.e. at the first moment the PID changed */
+ cached_pid = CACHED_PID_UNSET;
+}
+
+/* We use glibc __register_atfork() + __dso_handle directly here, as they are not included in the glibc
+ * headers. __register_atfork() is mostly equivalent to pthread_atfork(), but doesn't require us to link against
+ * libpthread, as it is part of glibc anyway. */
+extern int __register_atfork(void (*prepare) (void), void (*parent) (void), void (*child) (void), void * __dso_handle);
+extern void* __dso_handle __attribute__ ((__weak__));
+
+pid_t getpid_cached(void) {
+ pid_t current_value;
+
+ /* getpid_cached() is much like getpid(), but caches the value in local memory, to avoid having to invoke a
+ * system call each time. This restores glibc behaviour from before 2.24, when getpid() was unconditionally
+ * cached. Starting with 2.24 getpid() started to become prohibitively expensive when used for detecting when
+ * objects were used across fork()s. With this caching the old behaviour is somewhat restored.
+ *
+ * https://bugzilla.redhat.com/show_bug.cgi?id=1443976
+ * https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=1d2bc2eae969543b89850e35e532f3144122d80a
+ */
+
+ current_value = __sync_val_compare_and_swap(&cached_pid, CACHED_PID_UNSET, CACHED_PID_BUSY);
+
+ switch (current_value) {
+
+ case CACHED_PID_UNSET: { /* Not initialized yet, then do so now */
+ pid_t new_pid;
+
+ new_pid = getpid();
+
+ if (__register_atfork(NULL, NULL, reset_cached_pid, __dso_handle) != 0) {
+ /* OOM? Let's try again later */
+ cached_pid = CACHED_PID_UNSET;
+ return new_pid;
+ }
+
+ cached_pid = new_pid;
+ return new_pid;
+ }
+
+ case CACHED_PID_BUSY: /* Somebody else is currently initializing */
+ return getpid();
+
+ default: /* Properly initialized */
+ return current_value;
+ }
+}
+
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 d378901399..17746b4ebf 100644
--- a/src/basic/process-util.h
+++ b/src/basic/process-util.h
@@ -25,10 +25,11 @@
#include <stddef.h>
#include <stdio.h>
#include <string.h>
-#include <sys/types.h>
#include <sys/resource.h>
+#include <sys/types.h>
#include "format-util.h"
+#include "ioprio.h"
#include "macro.h"
#define procfs_file_alloca(pid, field) \
@@ -108,3 +109,15 @@ int pid_compare_func(const void *a, const void *b);
static inline bool nice_is_valid(int n) {
return n >= PRIO_MIN && n < PRIO_MAX;
}
+
+static inline bool ioprio_class_is_valid(int i) {
+ return IN_SET(i, IOPRIO_CLASS_NONE, IOPRIO_CLASS_RT, IOPRIO_CLASS_BE, IOPRIO_CLASS_IDLE);
+}
+
+static inline bool ioprio_priority_is_valid(int i) {
+ return i >= 0 && i < IOPRIO_BE_NR;
+}
+
+int ioprio_parse_priority(const char *s, int *ret);
+
+pid_t getpid_cached(void);
diff --git a/src/basic/random-util.c b/src/basic/random-util.c
index ad7b3eedf2..810eeab4d5 100644
--- a/src/basic/random-util.c
+++ b/src/basic/random-util.c
@@ -27,7 +27,13 @@
#include <stdint.h>
#ifdef HAVE_SYS_AUXV_H
-#include <sys/auxv.h>
+# include <sys/auxv.h>
+#endif
+
+#ifdef USE_SYS_RANDOM_H
+# include <sys/random.h>
+#else
+# include <linux/random.h>
#endif
#include "fd-util.h"
@@ -36,53 +42,59 @@
#include "random-util.h"
#include "time-util.h"
-int dev_urandom(void *p, size_t n) {
+int acquire_random_bytes(void *p, size_t n, bool high_quality_required) {
static int have_syscall = -1;
_cleanup_close_ int fd = -1;
+ unsigned already_done = 0;
int r;
- /* Gathers some randomness from the kernel. This call will
- * never block, and will always return some data from the
- * kernel, regardless if the random pool is fully initialized
- * or not. It thus makes no guarantee for the quality of the
- * returned entropy, but is good enough for our usual usecases
- * of seeding the hash functions for hashtable */
+ /* Gathers some randomness from the kernel. This call will never block. If
+ * high_quality_required, it will always return some data from the kernel,
+ * regardless of whether the random pool is fully initialized or not.
+ * Otherwise, it will return success if at least some random bytes were
+ * successfully acquired, and an error if the kernel has no entropy whatsover
+ * for us. */
- /* Use the getrandom() syscall unless we know we don't have
- * it, or when the requested size is too large for it. */
- if (have_syscall != 0 || (size_t) (int) n != n) {
+ /* Use the getrandom() syscall unless we know we don't have it. */
+ if (have_syscall != 0) {
r = getrandom(p, n, GRND_NONBLOCK);
- if (r == (int) n) {
+ if (r > 0) {
+ have_syscall = true;
+ if ((size_t) r == n)
+ return 0;
+ if (!high_quality_required) {
+ /* Fill in the remaing bytes using pseudorandom values */
+ pseudorandom_bytes((uint8_t*) p + r, n - r);
+ return 0;
+ }
+
+ already_done = r;
+ } else if (errno == ENOSYS)
+ /* We lack the syscall, continue with reading from /dev/urandom. */
+ have_syscall = false;
+ else if (errno == EAGAIN) {
+ /* The kernel has no entropy whatsoever. Let's remember to
+ * use the syscall the next time again though.
+ *
+ * If high_quality_required is false, return an error so that
+ * random_bytes() can produce some pseudorandom
+ * bytes. Otherwise, fall back to /dev/urandom, which we know
+ * is empty, but the kernel will produce some bytes for us on
+ * a best-effort basis. */
have_syscall = true;
- return 0;
- }
-
- if (r < 0) {
- if (errno == ENOSYS)
- /* we lack the syscall, continue with
- * reading from /dev/urandom */
- have_syscall = false;
- else if (errno == EAGAIN)
- /* not enough entropy for now. Let's
- * remember to use the syscall the
- * next time, again, but also read
- * from /dev/urandom for now, which
- * doesn't care about the current
- * amount of entropy. */
- have_syscall = true;
- else
- return -errno;
+
+ if (!high_quality_required)
+ return -ENODATA;
} else
- /* too short read? */
- return -ENODATA;
+ return -errno;
}
fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY);
if (fd < 0)
return errno == ENOENT ? -ENOSYS : -errno;
- return loop_read_exact(fd, p, n, true);
+ return loop_read_exact(fd, (uint8_t*) p + already_done, n - already_done, true);
}
void initialize_srand(void) {
@@ -96,12 +108,13 @@ void initialize_srand(void) {
return;
#ifdef HAVE_SYS_AUXV_H
- /* The kernel provides us with 16 bytes of entropy in auxv, so let's try to make use of that to seed the
- * pseudo-random generator. It's better than nothing... */
+ /* The kernel provides us with 16 bytes of entropy in auxv, so let's
+ * try to make use of that to seed the pseudo-random generator. It's
+ * better than nothing... */
auxv = (void*) getauxval(AT_RANDOM);
if (auxv) {
- assert_cc(sizeof(x) < 16);
+ assert_cc(sizeof(x) <= 16);
memcpy(&x, auxv, sizeof(x));
} else
#endif
@@ -115,19 +128,44 @@ void initialize_srand(void) {
srand_called = true;
}
-void random_bytes(void *p, size_t n) {
+/* INT_MAX gives us only 31 bits, so use 24 out of that. */
+#if RAND_MAX >= INT_MAX
+# define RAND_STEP 3
+#else
+/* SHORT_INT_MAX or lower gives at most 15 bits, we just just 8 out of that. */
+# define RAND_STEP 1
+#endif
+
+void pseudorandom_bytes(void *p, size_t n) {
uint8_t *q;
+
+ initialize_srand();
+
+ for (q = p; q < (uint8_t*) p + n; q += RAND_STEP) {
+ unsigned rr;
+
+ rr = (unsigned) rand();
+
+#if RAND_STEP >= 3
+ if ((size_t) (q - (uint8_t*) p + 2) < n)
+ q[2] = rr >> 16;
+#endif
+#if RAND_STEP >= 2
+ if ((size_t) (q - (uint8_t*) p + 1) < n)
+ q[1] = rr >> 8;
+#endif
+ q[0] = rr;
+ }
+}
+
+void random_bytes(void *p, size_t n) {
int r;
- r = dev_urandom(p, n);
+ r = acquire_random_bytes(p, n, false);
if (r >= 0)
return;
- /* If some idiot made /dev/urandom unavailable to us, he'll
- * get a PRNG instead. */
-
- initialize_srand();
-
- for (q = p; q < (uint8_t*) p + n; q ++)
- *q = rand();
+ /* If some idiot made /dev/urandom unavailable to us, or the
+ * kernel has no entropy, use a PRNG instead. */
+ return pseudorandom_bytes(p, n);
}
diff --git a/src/basic/random-util.h b/src/basic/random-util.h
index 3cee4c5014..804e225fc1 100644
--- a/src/basic/random-util.h
+++ b/src/basic/random-util.h
@@ -19,10 +19,12 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
-int dev_urandom(void *p, size_t n);
+int acquire_random_bytes(void *p, size_t n, bool high_quality_required);
+void pseudorandom_bytes(void *p, size_t n);
void random_bytes(void *p, size_t n);
void initialize_srand(void);
diff --git a/src/basic/rm-rf.c b/src/basic/rm-rf.c
index bdaca264ff..3f80ed263a 100644
--- a/src/basic/rm-rf.c
+++ b/src/basic/rm-rf.c
@@ -182,18 +182,11 @@ int rm_rf(const char *path, RemoveFlags flags) {
/* We refuse to clean the root file system with this
* call. This is extra paranoia to never cause a really
* seriously broken system. */
- if (path_equal(path, "/")) {
+ if (path_equal_or_files_same(path, "/", AT_SYMLINK_NOFOLLOW)) {
log_error("Attempted to remove entire root file system, and we can't allow that.");
return -EPERM;
}
- /* Another safe-check. Removing "/path/.." could easily remove entire root as well.
- * It's especially easy to do using globs in tmpfiles, like "/path/.*", which the glob()
- * function expands to both "/path/." and "/path/..".
- * Return -EINVAL to be consistent with rmdir("/path/."). */
- if (endswith(path, "/..") || endswith(path, "/../"))
- return -EINVAL;
-
if ((flags & (REMOVE_SUBVOLUME|REMOVE_ROOT|REMOVE_PHYSICAL)) == (REMOVE_SUBVOLUME|REMOVE_ROOT|REMOVE_PHYSICAL)) {
/* Try to remove as subvolume first */
r = btrfs_subvol_remove(path, BTRFS_REMOVE_RECURSIVE|BTRFS_REMOVE_QUOTA);
diff --git a/src/basic/selinux-util.c b/src/basic/selinux-util.c
index bc07654668..139e6e21e3 100644
--- a/src/basic/selinux-util.c
+++ b/src/basic/selinux-util.c
@@ -50,10 +50,10 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(context_t, context_free);
static int cached_use = -1;
static struct selabel_handle *label_hnd = NULL;
-#define log_enforcing(...) log_full(security_getenforce() == 1 ? LOG_ERR : LOG_DEBUG, __VA_ARGS__)
+#define log_enforcing(...) log_full_errno(security_getenforce() == 1 ? LOG_ERR : LOG_DEBUG, errno, __VA_ARGS__)
#endif
-bool mac_selinux_have(void) {
+bool mac_selinux_use(void) {
#ifdef HAVE_SELINUX
if (cached_use < 0)
cached_use = is_selinux_enabled() > 0;
@@ -64,16 +64,6 @@ bool mac_selinux_have(void) {
#endif
}
-bool mac_selinux_use(void) {
- if (!mac_selinux_have())
- return false;
-
- /* Never try to configure SELinux features if we aren't
- * root */
-
- return getuid() == 0;
-}
-
void mac_selinux_retest(void) {
#ifdef HAVE_SELINUX
cached_use = -1;
@@ -205,7 +195,7 @@ int mac_selinux_get_create_label_from_exe(const char *exe, char **label) {
assert(exe);
assert(label);
- if (!mac_selinux_have())
+ if (!mac_selinux_use())
return -EOPNOTSUPP;
r = getcon_raw(&mycon);
@@ -231,7 +221,7 @@ int mac_selinux_get_our_label(char **label) {
assert(label);
#ifdef HAVE_SELINUX
- if (!mac_selinux_have())
+ if (!mac_selinux_use())
return -EOPNOTSUPP;
r = getcon_raw(label);
@@ -255,7 +245,7 @@ int mac_selinux_get_child_mls_label(int socket_fd, const char *exe, const char *
assert(exe);
assert(label);
- if (!mac_selinux_have())
+ if (!mac_selinux_use())
return -EOPNOTSUPP;
r = getcon_raw(&mycon);
@@ -310,7 +300,7 @@ char* mac_selinux_free(char *label) {
if (!label)
return NULL;
- if (!mac_selinux_have())
+ if (!mac_selinux_use())
return NULL;
diff --git a/src/basic/selinux-util.h b/src/basic/selinux-util.h
index ce6bc8e44c..5bf72364b4 100644
--- a/src/basic/selinux-util.h
+++ b/src/basic/selinux-util.h
@@ -26,7 +26,6 @@
#include "macro.h"
bool mac_selinux_use(void);
-bool mac_selinux_have(void);
void mac_selinux_retest(void);
int mac_selinux_init(void);
diff --git a/src/basic/socket-util.c b/src/basic/socket-util.c
index e5847dce00..016e64aa03 100644
--- a/src/basic/socket-util.c
+++ b/src/basic/socket-util.c
@@ -48,6 +48,12 @@
#include "utf8.h"
#include "util.h"
+#ifdef ENABLE_IDN
+# define IDN_FLAGS (NI_IDN|NI_IDN_USE_STD3_ASCII_RULES)
+#else
+# define IDN_FLAGS 0
+#endif
+
int socket_address_parse(SocketAddress *a, const char *s) {
char *e, *n;
unsigned u;
@@ -406,7 +412,7 @@ bool socket_address_equal(const SocketAddress *a, const SocketAddress *b) {
return false;
if (a->sockaddr.un.sun_path[0]) {
- if (!path_equal_or_files_same(a->sockaddr.un.sun_path, b->sockaddr.un.sun_path))
+ if (!path_equal_or_files_same(a->sockaddr.un.sun_path, b->sockaddr.un.sun_path, 0))
return false;
} else {
if (a->size != b->size)
@@ -723,8 +729,7 @@ int socknameinfo_pretty(union sockaddr_union *sa, socklen_t salen, char **_ret)
assert(_ret);
- r = getnameinfo(&sa->sa, salen, host, sizeof(host), NULL, 0,
- NI_IDN|NI_IDN_USE_STD3_ASCII_RULES);
+ r = getnameinfo(&sa->sa, salen, host, sizeof(host), NULL, 0, IDN_FLAGS);
if (r != 0) {
int saved_errno = errno;
diff --git a/src/basic/stat-util.c b/src/basic/stat-util.c
index 7e1914aa14..d87370e672 100644
--- a/src/basic/stat-util.c
+++ b/src/basic/stat-util.c
@@ -169,16 +169,16 @@ int path_is_os_tree(const char *path) {
return 1;
}
-int files_same(const char *filea, const char *fileb) {
+int files_same(const char *filea, const char *fileb, int flags) {
struct stat a, b;
assert(filea);
assert(fileb);
- if (stat(filea, &a) < 0)
+ if (fstatat(AT_FDCWD, filea, &a, flags) < 0)
return -errno;
- if (stat(fileb, &b) < 0)
+ if (fstatat(AT_FDCWD, fileb, &b, flags) < 0)
return -errno;
return a.st_dev == b.st_dev &&
diff --git a/src/basic/stat-util.h b/src/basic/stat-util.h
index 5d571efe18..cd204ac6cb 100644
--- a/src/basic/stat-util.h
+++ b/src/basic/stat-util.h
@@ -49,7 +49,7 @@ int null_or_empty_fd(int fd);
int path_is_read_only_fs(const char *path);
int path_is_os_tree(const char *path);
-int files_same(const char *filea, const char *fileb);
+int files_same(const char *filea, const char *fileb, int flags);
/* The .f_type field of struct statfs is really weird defined on
* different archs. Let's give its type a name. */
diff --git a/src/basic/strv.c b/src/basic/strv.c
index 0eec868eed..c63f11c6ad 100644
--- a/src/basic/strv.c
+++ b/src/basic/strv.c
@@ -770,11 +770,7 @@ static int str_compare(const void *_a, const void *_b) {
}
char **strv_sort(char **l) {
-
- if (strv_isempty(l))
- return l;
-
- qsort(l, strv_length(l), sizeof(char*), str_compare);
+ qsort_safe(l, strv_length(l), sizeof(char*), str_compare);
return l;
}
diff --git a/src/basic/strxcpyx.c b/src/basic/strxcpyx.c
index aaf11d21f6..c6fbe79647 100644
--- a/src/basic/strxcpyx.c
+++ b/src/basic/strxcpyx.c
@@ -19,8 +19,13 @@
/*
* Concatenates/copies strings. In any case, terminates in all cases
- * with '\0' * and moves the @dest pointer forward to the added '\0'.
- * Returns the * remaining size, and 0 if the string was truncated.
+ * with '\0' and moves the @dest pointer forward to the added '\0'.
+ * Returns the remaining size, and 0 if the string was truncated.
+ *
+ * Due to the intended usage, these helpers silently noop invocations
+ * having zero size. This is technically an exception to the above
+ * statement "terminates in all cases". It's unexpected for such calls to
+ * occur outside of a loop where this is the preferred behavior.
*/
#include <stdarg.h>
@@ -32,6 +37,12 @@
size_t strpcpy(char **dest, size_t size, const char *src) {
size_t len;
+ assert(dest);
+ assert(src);
+
+ if (size == 0)
+ return 0;
+
len = strlen(src);
if (len >= size) {
if (size > 1)
@@ -51,23 +62,30 @@ size_t strpcpyf(char **dest, size_t size, const char *src, ...) {
va_list va;
int i;
+ assert(dest);
+ assert(src);
+
+ if (size == 0)
+ return 0;
+
va_start(va, src);
i = vsnprintf(*dest, size, src, va);
if (i < (int)size) {
*dest += i;
size -= i;
} else {
- *dest += size;
size = 0;
}
va_end(va);
- *dest[0] = '\0';
return size;
}
size_t strpcpyl(char **dest, size_t size, const char *src, ...) {
va_list va;
+ assert(dest);
+ assert(src);
+
va_start(va, src);
do {
size = strpcpy(dest, size, src);
@@ -80,6 +98,9 @@ size_t strpcpyl(char **dest, size_t size, const char *src, ...) {
size_t strscpy(char *dest, size_t size, const char *src) {
char *s;
+ assert(dest);
+ assert(src);
+
s = dest;
return strpcpy(&s, size, src);
}
@@ -88,6 +109,9 @@ size_t strscpyl(char *dest, size_t size, const char *src, ...) {
va_list va;
char *s;
+ assert(dest);
+ assert(src);
+
va_start(va, src);
s = dest;
do {
diff --git a/src/basic/terminal-util.c b/src/basic/terminal-util.c
index 9a8ef825c5..8a0419df75 100644
--- a/src/basic/terminal-util.c
+++ b/src/basic/terminal-util.c
@@ -1220,7 +1220,7 @@ bool colors_enabled(void) {
val = getenv_bool("SYSTEMD_COLORS");
if (val >= 0)
enabled = val;
- else if (getpid() == 1)
+ else if (getpid_cached() == 1)
/* PID1 outputs to the console without holding it open all the time */
enabled = !getenv_terminal_is_dumb();
else
diff --git a/src/basic/time-util.c b/src/basic/time-util.c
index a0db97c41a..68ba86f6a5 100644
--- a/src/basic/time-util.c
+++ b/src/basic/time-util.c
@@ -107,7 +107,7 @@ dual_timestamp* dual_timestamp_from_realtime(dual_timestamp *ts, usec_t u) {
ts->realtime = u;
delta = (int64_t) now(CLOCK_REALTIME) - (int64_t) u;
- ts->monotonic = usec_sub(now(CLOCK_MONOTONIC), delta);
+ ts->monotonic = usec_sub_signed(now(CLOCK_MONOTONIC), delta);
return ts;
}
@@ -124,8 +124,8 @@ triple_timestamp* triple_timestamp_from_realtime(triple_timestamp *ts, usec_t u)
ts->realtime = u;
delta = (int64_t) now(CLOCK_REALTIME) - (int64_t) u;
- ts->monotonic = usec_sub(now(CLOCK_MONOTONIC), delta);
- ts->boottime = clock_boottime_supported() ? usec_sub(now(CLOCK_BOOTTIME), delta) : USEC_INFINITY;
+ ts->monotonic = usec_sub_signed(now(CLOCK_MONOTONIC), delta);
+ ts->boottime = clock_boottime_supported() ? usec_sub_signed(now(CLOCK_BOOTTIME), delta) : USEC_INFINITY;
return ts;
}
@@ -141,7 +141,7 @@ dual_timestamp* dual_timestamp_from_monotonic(dual_timestamp *ts, usec_t u) {
ts->monotonic = u;
delta = (int64_t) now(CLOCK_MONOTONIC) - (int64_t) u;
- ts->realtime = usec_sub(now(CLOCK_REALTIME), delta);
+ ts->realtime = usec_sub_signed(now(CLOCK_REALTIME), delta);
return ts;
}
@@ -156,8 +156,8 @@ dual_timestamp* dual_timestamp_from_boottime_or_monotonic(dual_timestamp *ts, us
dual_timestamp_get(ts);
delta = (int64_t) now(clock_boottime_or_monotonic()) - (int64_t) u;
- ts->realtime = usec_sub(ts->realtime, delta);
- ts->monotonic = usec_sub(ts->monotonic, delta);
+ ts->realtime = usec_sub_signed(ts->realtime, delta);
+ ts->monotonic = usec_sub_signed(ts->monotonic, delta);
return ts;
}
@@ -241,7 +241,7 @@ usec_t timeval_load(const struct timeval *tv) {
struct timeval *timeval_store(struct timeval *tv, usec_t u) {
assert(tv);
- if (u == USEC_INFINITY||
+ if (u == USEC_INFINITY ||
u / USEC_PER_SEC > TIME_T_MAX) {
tv->tv_sec = (time_t) -1;
tv->tv_usec = (suseconds_t) -1;
@@ -555,15 +555,29 @@ void dual_timestamp_serialize(FILE *f, const char *name, dual_timestamp *t) {
int dual_timestamp_deserialize(const char *value, dual_timestamp *t) {
uint64_t a, b;
+ int r, pos;
assert(value);
assert(t);
- if (sscanf(value, "%" PRIu64 "%" PRIu64, &a, &b) != 2) {
- log_debug("Failed to parse dual timestamp value \"%s\": %m", value);
+ pos = strspn(value, WHITESPACE);
+ if (value[pos] == '-')
+ return -EINVAL;
+ pos += strspn(value + pos, DIGITS);
+ pos += strspn(value + pos, WHITESPACE);
+ if (value[pos] == '-')
+ return -EINVAL;
+
+ r = sscanf(value, "%" PRIu64 "%" PRIu64 "%n", &a, &b, &pos);
+ if (r != 2) {
+ log_debug("Failed to parse dual timestamp value \"%s\".", value);
return -EINVAL;
}
+ if (value[pos] != '\0')
+ /* trailing garbage */
+ return -EINVAL;
+
t->realtime = a;
t->monotonic = b;
@@ -850,10 +864,10 @@ finish:
if (ret > USEC_TIMESTAMP_FORMATTABLE_MAX)
return -EINVAL;
- if (ret > minus)
+ if (ret >= minus)
ret -= minus;
else
- ret = 0;
+ return -EINVAL;
*usec = ret;
@@ -995,6 +1009,16 @@ int parse_sec(const char *t, usec_t *usec) {
return parse_time(t, usec, USEC_PER_SEC);
}
+int parse_sec_fix_0(const char *t, usec_t *usec) {
+ t += strspn(t, WHITESPACE);
+ if (streq(t, "0")) {
+ *usec = USEC_INFINITY;
+ return 0;
+ }
+
+ return parse_sec(t, usec);
+}
+
int parse_nsec(const char *t, nsec_t *nsec) {
static const struct {
const char *suffix;
@@ -1337,3 +1361,22 @@ unsigned long usec_to_jiffies(usec_t u) {
return DIV_ROUND_UP(u , USEC_PER_SEC / hz);
}
+
+usec_t usec_shift_clock(usec_t x, clockid_t from, clockid_t to) {
+ usec_t a, b;
+
+ if (x == USEC_INFINITY)
+ return USEC_INFINITY;
+ if (map_clock_id(from) == map_clock_id(to))
+ return x;
+
+ a = now(from);
+ b = now(to);
+
+ if (x > a)
+ /* x lies in the future */
+ return usec_add(b, usec_sub_unsigned(x, a));
+ else
+ /* x lies in the past */
+ return usec_sub_unsigned(b, usec_sub_unsigned(a, x));
+}
diff --git a/src/basic/time-util.h b/src/basic/time-util.h
index 7463507f51..3b7f0e99c0 100644
--- a/src/basic/time-util.h
+++ b/src/basic/time-util.h
@@ -133,6 +133,7 @@ int timestamp_deserialize(const char *value, usec_t *timestamp);
int parse_timestamp(const char *t, usec_t *usec);
int parse_sec(const char *t, usec_t *usec);
+int parse_sec_fix_0(const char *t, usec_t *usec);
int parse_time(const char *t, usec_t *usec, usec_t default_unit);
int parse_nsec(const char *t, nsec_t *nsec);
@@ -145,6 +146,8 @@ bool clock_boottime_supported(void);
bool clock_supported(clockid_t clock);
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")
@@ -169,19 +172,23 @@ static inline usec_t usec_add(usec_t a, usec_t b) {
return c;
}
-static inline usec_t usec_sub(usec_t timestamp, int64_t delta) {
- if (delta < 0)
- return usec_add(timestamp, (usec_t) (-delta));
+static inline usec_t usec_sub_unsigned(usec_t timestamp, usec_t delta) {
if (timestamp == USEC_INFINITY) /* Make sure infinity doesn't degrade */
return USEC_INFINITY;
-
- if (timestamp < (usec_t) delta)
+ if (timestamp < delta)
return 0;
return timestamp - delta;
}
+static inline usec_t usec_sub_signed(usec_t timestamp, int64_t delta) {
+ if (delta < 0)
+ return usec_add(timestamp, (usec_t) (-delta));
+ else
+ return usec_sub_unsigned(timestamp, (usec_t) delta);
+}
+
#if SIZEOF_TIME_T == 8
/* The last second we can format is 31. Dec 9999, 1s before midnight, because otherwise we'd enter 5 digit year
* territory. However, since we want to stay away from this in all timezones we take one day off. */
diff --git a/src/basic/unit-name.c b/src/basic/unit-name.c
index 0a6efa449a..920ca0d9f5 100644
--- a/src/basic/unit-name.c
+++ b/src/basic/unit-name.c
@@ -1047,3 +1047,12 @@ static const char* const unit_dependency_table[_UNIT_DEPENDENCY_MAX] = {
};
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 44eadf0347..0f164a6aa9 100644
--- a/src/basic/unit-name.h
+++ b/src/basic/unit-name.h
@@ -257,6 +257,15 @@ typedef enum UnitDependency {
_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 */
@@ -365,3 +374,6 @@ 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/util.c b/src/basic/util.c
index 3dce0ea92e..2f45128ed4 100644
--- a/src/basic/util.c
+++ b/src/basic/util.c
@@ -219,7 +219,7 @@ int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *pa
/* Spawns a temporary TTY agent, making sure it goes away when
* we go away */
- parent_pid = getpid();
+ parent_pid = getpid_cached();
/* First we temporarily block all signals, so that the new
* child has them blocked initially. This way, we can be sure
@@ -541,7 +541,7 @@ int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int
if (asprintf(&userns_fd_path, "/proc/self/fd/%d", userns_fd) < 0)
return -ENOMEM;
- r = files_same(userns_fd_path, "/proc/self/ns/user");
+ r = files_same(userns_fd_path, "/proc/self/ns/user", 0);
if (r < 0)
return r;
if (r)
diff --git a/src/basic/virt.c b/src/basic/virt.c
index ff4491d6d6..b91c7a78e4 100644
--- a/src/basic/virt.c
+++ b/src/basic/virt.c
@@ -421,7 +421,7 @@ int detect_container(void) {
goto finish;
}
- if (getpid() == 1) {
+ if (getpid_cached() == 1) {
/* If we are PID 1 we can just check our own environment variable, and that's authoritative. */
e = getenv("container");
@@ -574,7 +574,7 @@ int running_in_chroot(void) {
if (getenv_bool("SYSTEMD_IGNORE_CHROOT") > 0)
return 0;
- ret = files_same("/proc/1/root", "/");
+ ret = files_same("/proc/1/root", "/", 0);
if (ret < 0)
return ret;
diff --git a/src/boot/bootctl.c b/src/boot/bootctl.c
index 297dcb535a..68fe5552c9 100644
--- a/src/boot/bootctl.c
+++ b/src/boot/bootctl.c
@@ -18,8 +18,7 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <assert.h>
-#include <blkid/blkid.h>
+#include <blkid.h>
#include <ctype.h>
#include <dirent.h>
#include <errno.h>
@@ -74,17 +73,23 @@ static int verify_esp(
struct statfs sfs;
sd_id128_t uuid = SD_ID128_NULL;
uint32_t part = 0;
+ bool quiet;
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_error_errno(errno, "Failed to check file system type of \"%s\": %m", p);
+ 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)) {
@@ -97,7 +102,8 @@ static int verify_esp(
}
if (stat(p, &st) < 0)
- return log_error_errno(errno, "Failed to determine block device node of \"%s\": %m", p);
+ 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);
@@ -107,7 +113,8 @@ static int verify_esp(
t2 = strjoina(p, "/..");
r = stat(t2, &st2);
if (r < 0)
- return log_error_errno(errno, "Failed to determine block device node of parent of \"%s\": %m", p);
+ 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);
@@ -115,8 +122,8 @@ static int verify_esp(
}
/* 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. */
- if (detect_container() > 0)
+ * 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));
@@ -340,7 +347,15 @@ static int status_binaries(const char *esp_path, sd_id128_t partition) {
printf("Boot Loader Binaries:\n");
- printf(" ESP: /dev/disk/by-partuuid/%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n", SD_ID128_FORMAT_VAL(partition));
+ if (!esp_path) {
+ printf(" ESP: Cannot find or access mount point of ESP.\n\n");
+ return -ENOENT;
+ }
+
+ printf(" ESP: %s", esp_path);
+ if (!sd_id128_is_null(partition))
+ printf(" (/dev/disk/by-partuuid/%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x)", SD_ID128_FORMAT_VAL(partition));
+ printf("\n");
r = enumerate_binaries(esp_path, "EFI/systemd", NULL);
if (r == 0)
@@ -391,11 +406,6 @@ static int status_variables(void) {
_cleanup_free_ uint16_t *options = NULL, *order = NULL;
int i;
- if (!is_efi_boot()) {
- log_notice("Not booted with EFI, not showing EFI variables.");
- return 0;
- }
-
n_options = efi_get_boot_options(&options);
if (n_options == -ENOENT)
return log_error_errno(n_options,
@@ -1027,15 +1037,9 @@ static int must_be_root(void) {
static int verb_status(int argc, char *argv[], void *userdata) {
sd_id128_t uuid = SD_ID128_NULL;
- int r;
+ int r, r2;
- r = must_be_root();
- if (r < 0)
- return r;
-
- r = find_esp(NULL, NULL, NULL, &uuid);
- if (r < 0)
- return r;
+ r2 = find_esp(NULL, NULL, NULL, &uuid);
if (is_efi_boot()) {
_cleanup_free_ char *fw_type = NULL, *fw_info = NULL, *loader = NULL, *loader_path = NULL;
@@ -1051,44 +1055,47 @@ static int verb_status(int argc, char *argv[], void *userdata) {
r = efi_loader_get_device_part_uuid(&loader_part_uuid);
if (r < 0 && r != -ENOENT)
- log_warning_errno(r, "Failed to read EFI variable LoaderDevicePartUUID: %m");
+ r2 = log_warning_errno(r, "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)
- log_warning_errno(r, "Failed to query secure boot status: %m");
+ r2 = log_warning_errno(r, "Failed to query secure boot status: %m");
else
printf(" Secure Boot: %sd\n", enable_disable(r));
r = is_efi_secure_boot_setup_mode();
if (r < 0)
- log_warning_errno(r, "Failed to query secure boot mode: %m");
+ r2 = log_warning_errno(r, "Failed to query secure boot mode: %m");
else
printf(" Setup Mode: %s\n", r ? "setup" : "user");
printf("\n");
- printf("Loader:\n");
+ printf("Current Loader:\n");
printf(" Product: %s\n", strna(loader));
if (!sd_id128_is_null(loader_part_uuid))
- printf(" Partition: /dev/disk/by-partuuid/%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
+ printf(" ESP: /dev/disk/by-partuuid/%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
SD_ID128_FORMAT_VAL(loader_part_uuid));
else
- printf(" Partition: n/a\n");
+ printf(" ESP: n/a\n");
printf(" File: %s%s\n", special_glyph(TREE_RIGHT), strna(loader_path));
printf("\n");
} else
- printf("System:\n Not booted with EFI\n");
+ printf("System:\n Not booted with EFI\n\n");
r = status_binaries(arg_path, uuid);
if (r < 0)
- return r;
+ r2 = r;
- if (arg_touch_variables)
+ if (is_efi_boot()) {
r = status_variables();
+ if (r < 0)
+ r2 = r;
+ }
- return r;
+ return r2;
}
static int verb_install(int argc, char *argv[], void *userdata) {
diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c
index 681e783f2e..1e990b3825 100644
--- a/src/boot/efi/boot.c
+++ b/src/boot/efi/boot.c
@@ -20,16 +20,17 @@
#include "disk.h"
#include "graphics.h"
#include "linux.h"
-#include "pefile.h"
-#include "util.h"
#include "measure.h"
+#include "pe.h"
+#include "shim.h"
+#include "util.h"
#ifndef EFI_OS_INDICATIONS_BOOT_TO_FW_UI
#define EFI_OS_INDICATIONS_BOOT_TO_FW_UI 0x0000000000000001ULL
#endif
/* magic string to find in the binary image */
-static const char __attribute__((used)) magic[] = "#### LoaderInfo: systemd-boot " VERSION " ####";
+static const char __attribute__((used)) magic[] = "#### LoaderInfo: systemd-boot " PACKAGE_VERSION " ####";
static const EFI_GUID global_guid = EFI_GLOBAL_VARIABLE;
@@ -363,7 +364,7 @@ static VOID print_status(Config *config, CHAR16 *loaded_image_path) {
uefi_call_wrapper(ST->ConOut->SetAttribute, 2, ST->ConOut, EFI_LIGHTGRAY|EFI_BACKGROUND_BLACK);
uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
- Print(L"systemd-boot version: " VERSION "\n");
+ Print(L"systemd-boot version: " PACKAGE_VERSION "\n");
Print(L"architecture: " EFI_MACHINE_TYPE_NAME "\n");
Print(L"loaded image: %s\n", loaded_image_path);
Print(L"UEFI specification: %d.%02d\n", ST->Hdr.Revision >> 16, ST->Hdr.Revision & 0xffff);
@@ -383,6 +384,9 @@ static VOID print_status(Config *config, CHAR16 *loaded_image_path) {
FreePool(b);
}
+ if (shim_loaded())
+ Print(L"Shim: present\n");
+
if (efivar_get_raw(&global_guid, L"OsIndicationsSupported", &b, &size) == EFI_SUCCESS) {
Print(L"OsIndicationsSupported: %d\n", (UINT64)*b);
FreePool(b);
@@ -781,7 +785,7 @@ static BOOLEAN menu_run(Config *config, ConfigEntry **chosen_entry, CHAR16 *load
break;
case KEYPRESS(0, 0, 'v'):
- status = PoolPrint(L"systemd-boot " VERSION " (" EFI_MACHINE_TYPE_NAME "), UEFI Specification %d.%02d, Vendor %s %d.%02d",
+ status = PoolPrint(L"systemd-boot " PACKAGE_VERSION " (" EFI_MACHINE_TYPE_NAME "), UEFI Specification %d.%02d, Vendor %s %d.%02d",
ST->Hdr.Revision >> 16, ST->Hdr.Revision & 0xffff,
ST->FirmwareVendor, ST->FirmwareRevision >> 16, ST->FirmwareRevision & 0xffff);
break;
@@ -1539,7 +1543,7 @@ static VOID config_entry_add_linux( Config *config, EFI_LOADED_IMAGE *loaded_ima
continue;
/* look for .osrel and .cmdline sections in the .efi binary */
- err = pefile_locate_sections(linux_dir, f->FileName, sections, addrs, offs, szs);
+ err = pe_file_locate_sections(linux_dir, f->FileName, sections, addrs, offs, szs);
if (EFI_ERROR(err))
continue;
@@ -1718,7 +1722,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
InitializeLib(image, sys_table);
init_usec = time_usec();
efivar_set_time_usec(L"LoaderTimeInitUSec", init_usec);
- efivar_set(L"LoaderInfo", L"systemd-boot " VERSION, FALSE);
+ efivar_set(L"LoaderInfo", L"systemd-boot " PACKAGE_VERSION, FALSE);
s = PoolPrint(L"%s %d.%02d", ST->FirmwareVendor, ST->FirmwareRevision >> 16, ST->FirmwareRevision & 0xffff);
efivar_set(L"LoaderFirmwareInfo", s, FALSE);
FreePool(s);
@@ -1745,6 +1749,14 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
return EFI_LOAD_ERROR;
}
+ if (secure_boot_enabled() && shim_loaded()) {
+ err = security_policy_install();
+ if (EFI_ERROR(err)) {
+ Print(L"Error installing security policy: %r ", err);
+ uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
+ return err;
+ }
+ }
/* the filesystem path to this image, to prevent adding ourselves to the menu */
loaded_image_path = DevicePathToStr(loaded_image->FilePath);
diff --git a/src/boot/efi/measure.c b/src/boot/efi/measure.c
index 4ac11a9bb0..b22d37b62d 100644
--- a/src/boot/efi/measure.c
+++ b/src/boot/efi/measure.c
@@ -199,7 +199,7 @@ static EFI_STATUS tpm1_measure_to_pcr_and_event_log(const EFI_TCG *tcg, UINT32 p
event_number = 1;
status = uefi_call_wrapper(tcg->HashLogExtendEvent, 7,
- tcg, buffer, buffer_size, TCG_ALG_SHA, tcg_event, &event_number, &event_log_last);
+ (EFI_TCG *) tcg, buffer, buffer_size, TCG_ALG_SHA, tcg_event, &event_number, &event_log_last);
if (EFI_ERROR(status))
return status;
@@ -219,7 +219,7 @@ static EFI_STATUS tpm1_measure_to_pcr_and_event_log(const EFI_TCG *tcg, UINT32 p
*/
static EFI_STATUS trigger_tcg2_final_events_table(const EFI_TCG2 *tcg)
{
- return uefi_call_wrapper(tcg->GetEventLog, 5, tcg,
+ return uefi_call_wrapper(tcg->GetEventLog, 5, (EFI_TCG2 *) tcg,
EFI_TCG2_EVENT_LOG_FORMAT_TCG_2, NULL,
NULL, NULL);
}
@@ -254,7 +254,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, tcg, 0, buffer, buffer_size, tcg_event);
+ status = uefi_call_wrapper(tcg->HashLogExtendEvent, 5, (EFI_TCG2 *) tcg, 0, buffer, buffer_size, tcg_event);
uefi_call_wrapper(BS->FreePool, 1, tcg_event);
diff --git a/src/boot/efi/measure.h b/src/boot/efi/measure.h
index a2cfe817d0..43aa8a0058 100644
--- a/src/boot/efi/measure.h
+++ b/src/boot/efi/measure.h
@@ -13,9 +13,6 @@
#ifndef __SDBOOT_MEASURE_H
#define __SDBOOT_MEASURE_H
-#ifndef SD_TPM_PCR
-#define SD_TPM_PCR 8
-#endif
-
EFI_STATUS tpm_log_event(UINT32 pcrindex, const EFI_PHYSICAL_ADDRESS buffer, UINTN buffer_size, const CHAR16 *description);
+
#endif
diff --git a/src/boot/efi/meson.build b/src/boot/efi/meson.build
new file mode 100644
index 0000000000..5ef5b2d20b
--- /dev/null
+++ b/src/boot/efi/meson.build
@@ -0,0 +1,205 @@
+efi_headers = files('''
+ console.h
+ disk.h
+ graphics.h
+ linux.h
+ measure.h
+ pe.h
+ splash.h
+ util.h
+ shim.h
+'''.split())
+
+common_sources = '''
+ disk.c
+ graphics.c
+ measure.c
+ pe.c
+ util.c
+'''.split()
+
+systemd_boot_sources = '''
+ boot.c
+ console.c
+ shim.c
+'''.split()
+
+stub_sources = '''
+ linux.c
+ splash.c
+ stub.c
+'''.split()
+
+if conf.get('ENABLE_EFI', false) and get_option('gnu-efi') != 'false'
+ efi_cc = get_option('efi-cc')
+ efi_ld = get_option('efi-ld')
+
+ efi_incdir = get_option('efi-includedir')
+ have_header = (gnu_efi_arch != '' and
+ cc.has_header('@0@/@1@/efibind.h'.format(efi_incdir, gnu_efi_arch)))
+
+ if have_header and EFI_MACHINE_TYPE_NAME == ''
+ error('gnu-efi is available, but EFI_MACHINE_TYPE_NAME is unknown')
+ endif
+
+ efi_libdir = get_option('efi-libdir')
+ if efi_libdir == ''
+ cmd = 'cd /usr/lib/$(@0@ -print-multi-os-directory) && pwd'.format(efi_cc)
+ ret = run_command('sh', '-c', cmd)
+ if ret.returncode() == 0
+ efi_libdir = ret.stdout().strip()
+ endif
+ endif
+
+ have_gnu_efi = have_header and efi_libdir != ''
+else
+ have_gnu_efi = false
+endif
+
+if get_option('gnu-efi') == 'true' and not have_gnu_efi
+ error('gnu-efi support requested, but headers were not found')
+endif
+
+if have_gnu_efi
+ efi_conf = configuration_data()
+ efi_conf.set_quoted('PACKAGE_VERSION', meson.project_version())
+ efi_conf.set_quoted('EFI_MACHINE_TYPE_NAME', EFI_MACHINE_TYPE_NAME)
+ efi_conf.set('SD_BOOT_LOG_TPM', get_option('tpm'))
+ efi_conf.set('SD_TPM_PCR', get_option('tpm-pcrindex'))
+
+ efi_config_h = configure_file(
+ output : 'efi_config.h',
+ configuration : efi_conf)
+
+ objcopy = find_program('objcopy')
+
+ efi_ldsdir = get_option('efi-ldsdir')
+ arch_lds = 'elf_@0@_efi.lds'.format(gnu_efi_arch)
+ if efi_ldsdir == ''
+ efi_ldsdir = join_paths(efi_libdir, 'gnuefi')
+ cmd = run_command('test', '-f', join_paths(efi_ldsdir, arch_lds))
+ if cmd.returncode() != 0
+ efi_ldsdir = efi_libdir
+ cmd = run_command('test', '-f', join_paths(efi_ldsdir, arch_lds))
+ if cmd.returncode() != 0
+ error('Cannot find @0@'.format(arch_lds))
+ endif
+ endif
+ endif
+
+ message('efi-libdir: "@0@"'.format(efi_libdir))
+ message('efi-ldsdir: "@0@"'.format(efi_ldsdir))
+ message('efi-includedir: "@0@"'.format(efi_incdir))
+
+ compile_args = ['-Wall',
+ '-Wextra',
+ '-std=gnu90',
+ '-nostdinc',
+ '-ggdb', '-O0',
+ '-fpic',
+ '-fshort-wchar',
+ '-ffreestanding',
+ '-fno-strict-aliasing',
+ '-fno-stack-protector',
+ '-Wsign-compare',
+ '-Wno-missing-field-initializers',
+ '-isystem', efi_incdir,
+ '-isystem', join_paths(efi_incdir, gnu_efi_arch),
+ '-include', efi_config_h]
+ if efi_arch == 'x86_64'
+ compile_args += ['-mno-red-zone',
+ '-mno-sse',
+ '-mno-mmx',
+ '-DEFI_FUNCTION_WRAPPER',
+ '-DGNU_EFI_USE_MS_ABI']
+ elif efi_arch == 'ia32'
+ compile_args += ['-mno-sse',
+ '-mno-mmx']
+ endif
+
+ efi_ldflags = ['-T',
+ join_paths(efi_ldsdir, arch_lds),
+ '-shared',
+ '-Bsymbolic',
+ '-nostdlib',
+ '-znocombreloc',
+ '-L', efi_libdir,
+ join_paths(efi_ldsdir, 'crt0-efi-@0@.o'.format(gnu_efi_arch))]
+ if efi_arch == 'aarch64' or efi_arch == 'arm'
+ # Aarch64 and ARM32 don't have an EFI capable objcopy. Use 'binary'
+ # instead, and add required symbols manually.
+ efi_ldflags += ['--defsym=EFI_SUBSYSTEM=0xa']
+ efi_format = ['-O', 'binary']
+ else
+ efi_format = ['--target=efi-app-@0@'.format(gnu_efi_arch)]
+ endif
+
+ systemd_boot_objects = []
+ stub_objects = []
+ foreach file : common_sources + systemd_boot_sources + stub_sources
+ o_file = custom_target(file + '.o',
+ input : file,
+ output : file + '.o',
+ command : [efi_cc, '-c', '@INPUT@', '-o', '@OUTPUT@']
+ + compile_args,
+ depend_files : efi_headers)
+ if (common_sources + systemd_boot_sources).contains(file)
+ systemd_boot_objects += [o_file]
+ endif
+ if (common_sources + stub_sources).contains(file)
+ stub_objects += [o_file]
+ endif
+ endforeach
+
+ libgcc_file_name = run_command(efi_cc, '-print-libgcc-file-name').stdout().strip()
+ systemd_boot_efi_name = 'systemd-boot@0@.efi'.format(EFI_MACHINE_TYPE_NAME)
+ stub_efi_name = 'linux@0@.efi.stub'.format(EFI_MACHINE_TYPE_NAME)
+ no_undefined_symbols = find_program('no-undefined-symbols.sh')
+
+ foreach tuple : [['systemd_boot.so', systemd_boot_efi_name, systemd_boot_objects],
+ ['stub.so', stub_efi_name, stub_objects]]
+ so = custom_target(
+ tuple[0],
+ input : tuple[2],
+ output : tuple[0],
+ command : [efi_ld, '-o', '@OUTPUT@'] +
+ efi_ldflags + tuple[2] +
+ ['-lefi', '-lgnuefi', libgcc_file_name])
+
+ test('no-undefined-symbols-' + tuple[0],
+ no_undefined_symbols,
+ args : [so])
+
+ stub = custom_target(
+ tuple[1],
+ input : so,
+ output : tuple[1],
+ command : [objcopy,
+ '-j', '.text',
+ '-j', '.sdata',
+ '-j', '.data',
+ '-j', '.dynamic',
+ '-j', '.dynsym',
+ '-j', '.rel',
+ '-j', '.rela',
+ '-j', '.reloc']
+ + efi_format +
+ ['@INPUT@', '@OUTPUT@'],
+ install : true,
+ install_dir : bootlibdir)
+
+ set_variable(tuple[0].underscorify(), so)
+ set_variable(tuple[0].underscorify() + '_stub', stub)
+ endforeach
+endif
+
+############################################################
+
+if have_gnu_efi
+ test_efi_disk_img = custom_target(
+ 'test-efi-disk.img',
+ input : [systemd_boot_so, stub_so_stub],
+ output : 'test-efi-disk.img',
+ command : [test_efi_create_disk_sh, '@OUTPUT@',
+ '@INPUT0@', '@INPUT1@', splash_bmp])
+endif
diff --git a/src/boot/efi/no-undefined-symbols.sh b/src/boot/efi/no-undefined-symbols.sh
new file mode 100755
index 0000000000..08b266c455
--- /dev/null
+++ b/src/boot/efi/no-undefined-symbols.sh
@@ -0,0 +1,6 @@
+#!/bin/sh -eu
+
+if nm -D -u "$1" | grep ' U '; then
+ echo "Undefined symbols detected!"
+ exit 1
+fi
diff --git a/src/boot/efi/pefile.c b/src/boot/efi/pe.c
index 77fff77b69..054e8edbc6 100644
--- a/src/boot/efi/pefile.c
+++ b/src/boot/efi/pe.c
@@ -15,7 +15,7 @@
#include <efi.h>
#include <efilib.h>
-#include "pefile.h"
+#include "pe.h"
#include "util.h"
struct DosFileHeader {
@@ -52,6 +52,11 @@ struct PeFileHeader {
UINT16 Characteristics;
} __attribute__((packed));
+struct PeHeader {
+ UINT8 Magic[4];
+ struct PeFileHeader FileHeader;
+} __attribute__((packed));
+
struct PeSectionHeader {
UINT8 Name[8];
UINT32 VirtualSize;
@@ -65,15 +70,61 @@ struct PeSectionHeader {
UINT32 Characteristics;
} __attribute__((packed));
+EFI_STATUS pe_memory_locate_sections(CHAR8 *base, CHAR8 **sections, UINTN *addrs, UINTN *offsets, UINTN *sizes) {
+ struct DosFileHeader *dos;
+ struct PeHeader *pe;
+ UINTN i;
+ UINTN offset;
+
+ dos = (struct DosFileHeader *)base;
+
+ if (CompareMem(dos->Magic, "MZ", 2) != 0)
+ return EFI_LOAD_ERROR;
+
+ pe = (struct PeHeader *)&base[dos->ExeHeader];
+ if (CompareMem(pe->Magic, "PE\0\0", 4) != 0)
+ return EFI_LOAD_ERROR;
+
+ /* PE32+ Subsystem type */
+ if (pe->FileHeader.Machine != PE_HEADER_MACHINE_X64 &&
+ pe->FileHeader.Machine != PE_HEADER_MACHINE_I386)
+ return EFI_LOAD_ERROR;
+
+ if (pe->FileHeader.NumberOfSections > 96)
+ return EFI_LOAD_ERROR;
+
+ offset = dos->ExeHeader + sizeof(*pe) + pe->FileHeader.SizeOfOptionalHeader;
+
+ for (i = 0; i < pe->FileHeader.NumberOfSections; i++) {
+ struct PeSectionHeader *sect;
+ UINTN j;
+
+ sect = (struct PeSectionHeader *)&base[offset];
+ for (j = 0; sections[j]; j++) {
+ if (CompareMem(sect->Name, sections[j], strlena(sections[j])) != 0)
+ continue;
-EFI_STATUS pefile_locate_sections(EFI_FILE *dir, CHAR16 *path, CHAR8 **sections, UINTN *addrs, UINTN *offsets, UINTN *sizes) {
+ if (addrs)
+ addrs[j] = (UINTN)sect->VirtualAddress;
+ if (offsets)
+ offsets[j] = (UINTN)sect->PointerToRawData;
+ if (sizes)
+ sizes[j] = (UINTN)sect->VirtualSize;
+ }
+ offset += sizeof(*sect);
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS pe_file_locate_sections(EFI_FILE *dir, CHAR16 *path, CHAR8 **sections, UINTN *addrs, UINTN *offsets, UINTN *sizes) {
EFI_FILE_HANDLE handle;
struct DosFileHeader dos;
- uint8_t magic[4];
- struct PeFileHeader pe;
+ struct PeHeader pe;
UINTN len;
- UINTN i;
+ UINTN headerlen;
EFI_STATUS err;
+ CHAR8 *header = NULL;
err = uefi_call_wrapper(dir->Open, 5, dir, &handle, path, EFI_FILE_MODE_READ, 0ULL);
if (EFI_ERROR(err))
@@ -89,30 +140,10 @@ EFI_STATUS pefile_locate_sections(EFI_FILE *dir, CHAR16 *path, CHAR8 **sections,
goto out;
}
- if (CompareMem(dos.Magic, "MZ", 2) != 0) {
- err = EFI_LOAD_ERROR;
- goto out;
- }
-
err = uefi_call_wrapper(handle->SetPosition, 2, handle, dos.ExeHeader);
if (EFI_ERROR(err))
goto out;
- /* PE header */
- len = sizeof(magic);
- err = uefi_call_wrapper(handle->Read, 3, handle, &len, &magic);
- if (EFI_ERROR(err))
- goto out;
- if (len != sizeof(magic)) {
- err = EFI_LOAD_ERROR;
- goto out;
- }
-
- if (CompareMem(magic, "PE\0\0", 2) != 0) {
- err = EFI_LOAD_ERROR;
- goto out;
- }
-
len = sizeof(pe);
err = uefi_call_wrapper(handle->Read, 3, handle, &len, &pe);
if (EFI_ERROR(err))
@@ -122,49 +153,30 @@ EFI_STATUS pefile_locate_sections(EFI_FILE *dir, CHAR16 *path, CHAR8 **sections,
goto out;
}
- /* PE32+ Subsystem type */
- if (pe.Machine != PE_HEADER_MACHINE_X64 &&
- pe.Machine != PE_HEADER_MACHINE_I386) {
- err = EFI_LOAD_ERROR;
+ headerlen = sizeof(dos) + sizeof(pe) + pe.FileHeader.SizeOfOptionalHeader + pe.FileHeader.NumberOfSections * sizeof(struct PeSectionHeader);
+ header = AllocatePool(headerlen);
+ if (!header) {
+ err = EFI_OUT_OF_RESOURCES;
goto out;
}
+ len = headerlen;
+ err = uefi_call_wrapper(handle->SetPosition, 2, handle, 0);
+ if (EFI_ERROR(err))
+ goto out;
- if (pe.NumberOfSections > 96) {
- err = EFI_LOAD_ERROR;
+ err = uefi_call_wrapper(handle->Read, 3, handle, &len, header);
+ if (EFI_ERROR(err)) {
goto out;
}
-
- /* the sections start directly after the headers */
- err = uefi_call_wrapper(handle->SetPosition, 2, handle, dos.ExeHeader + sizeof(magic) + sizeof(pe) + pe.SizeOfOptionalHeader);
- if (EFI_ERROR(err))
+ if (len != headerlen) {
+ err = EFI_LOAD_ERROR;
goto out;
-
- for (i = 0; i < pe.NumberOfSections; i++) {
- struct PeSectionHeader sect;
- UINTN j;
-
- len = sizeof(sect);
- err = uefi_call_wrapper(handle->Read, 3, handle, &len, &sect);
- if (EFI_ERROR(err))
- goto out;
- if (len != sizeof(sect)) {
- err = EFI_LOAD_ERROR;
- goto out;
- }
- for (j = 0; sections[j]; j++) {
- if (CompareMem(sect.Name, sections[j], strlena(sections[j])) != 0)
- continue;
-
- if (addrs)
- addrs[j] = (UINTN)sect.VirtualAddress;
- if (offsets)
- offsets[j] = (UINTN)sect.PointerToRawData;
- if (sizes)
- sizes[j] = (UINTN)sect.VirtualSize;
- }
}
+ err = pe_memory_locate_sections(header, sections, addrs, offsets, sizes);
out:
+ if (header)
+ FreePool(header);
uefi_call_wrapper(handle->Close, 1, handle);
return err;
}
diff --git a/src/boot/efi/pefile.h b/src/boot/efi/pe.h
index 2e445ede17..fa8feea758 100644
--- a/src/boot/efi/pefile.h
+++ b/src/boot/efi/pe.h
@@ -15,6 +15,8 @@
#ifndef __SDBOOT_PEFILE_H
#define __SDBOOT_PEFILE_H
-EFI_STATUS pefile_locate_sections(EFI_FILE *dir, CHAR16 *path,
- CHAR8 **sections, UINTN *addrs, UINTN *offsets, UINTN *sizes);
+EFI_STATUS pe_memory_locate_sections(CHAR8 *base,
+ CHAR8 **sections, UINTN *addrs, UINTN *offsets, UINTN *sizes);
+EFI_STATUS pe_file_locate_sections(EFI_FILE *dir, CHAR16 *path,
+ CHAR8 **sections, UINTN *addrs, UINTN *offsets, UINTN *sizes);
#endif
diff --git a/src/boot/efi/shim.c b/src/boot/efi/shim.c
new file mode 100644
index 0000000000..0f73be9549
--- /dev/null
+++ b/src/boot/efi/shim.c
@@ -0,0 +1,262 @@
+/*
+ * 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
+ * (at your option) any later version.
+ *
+ * This program 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.
+ *
+ * Port to systemd-boot
+ * Copyright 2017 Max Resch <resch.max@gmail.com>
+ *
+ * Security Policy Handling
+ * Copyright 2012 <James.Bottomley@HansenPartnership.com>
+ * https://github.com/mjg59/efitools
+ */
+
+#include <efi.h>
+#include <efilib.h>
+
+#include "util.h"
+#include "shim.h"
+
+/* well known shim lock guid */
+#define SHIM_LOCK_GUID
+
+struct ShimLock {
+ EFI_STATUS __attribute__((sysv_abi)) (*shim_verify) (VOID *buffer, UINT32 size);
+
+ /* context is actually a struct for the PE header, but it isn't needed so void is sufficient just do define the interface
+ * see shim.c/shim.h and PeHeader.h in the github shim repo */
+ EFI_STATUS __attribute__((sysv_abi)) (*generate_hash) (VOID *data, UINT32 datasize, VOID *context, UINT8 *sha256hash, UINT8 *sha1hash);
+
+ EFI_STATUS __attribute__((sysv_abi)) (*read_header) (VOID *data, UINT32 datasize, VOID *context);
+};
+
+static const EFI_GUID simple_fs_guid = SIMPLE_FILE_SYSTEM_PROTOCOL;
+static const EFI_GUID global_guid = EFI_GLOBAL_VARIABLE;
+
+static const EFI_GUID security_protocol_guid = { 0xa46423e3, 0x4617, 0x49f1, {0xb9, 0xff, 0xd1, 0xbf, 0xa9, 0x11, 0x58, 0x39 } };
+static const EFI_GUID security2_protocol_guid = { 0x94ab2f58, 0x1438, 0x4ef1, {0x91, 0x52, 0x18, 0x94, 0x1a, 0x3a, 0x0e, 0x68 } };
+static const EFI_GUID shim_lock_guid = { 0x605dab50, 0xe046, 0x4300, {0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23} };
+
+BOOLEAN shim_loaded(void) {
+ struct ShimLock *shim_lock;
+
+ return uefi_call_wrapper(BS->LocateProtocol, 3, (EFI_GUID*) &shim_lock_guid, NULL, (VOID**) &shim_lock) == EFI_SUCCESS;
+}
+
+static BOOLEAN shim_validate(VOID *data, UINT32 size) {
+ struct ShimLock *shim_lock;
+
+ if (!data)
+ return FALSE;
+
+ if (uefi_call_wrapper(BS->LocateProtocol, 3, (EFI_GUID*) &shim_lock_guid, NULL, (VOID**) &shim_lock) != EFI_SUCCESS)
+ return FALSE;
+
+ if (!shim_lock)
+ return FALSE;
+
+ if (shim_lock->shim_verify(data, size) == EFI_SUCCESS)
+ return TRUE;
+
+ return FALSE;
+}
+
+BOOLEAN secure_boot_enabled(void) {
+ CHAR8 *b;
+ UINTN size;
+ BOOLEAN result;
+
+ if (efivar_get_raw(&global_guid, L"SecureBoot", &b, &size) == EFI_SUCCESS) {
+ result = *b > 0;
+ FreePool(b);
+ return result;
+ }
+
+ return FALSE;
+}
+
+/*
+ * See the UEFI Platform Initialization manual (Vol2: DXE) for this
+ */
+struct _EFI_SECURITY2_PROTOCOL;
+struct _EFI_SECURITY_PROTOCOL;
+struct _EFI_DEVICE_PATH_PROTOCOL;
+
+typedef struct _EFI_SECURITY2_PROTOCOL EFI_SECURITY2_PROTOCOL;
+typedef struct _EFI_SECURITY_PROTOCOL EFI_SECURITY_PROTOCOL;
+typedef struct _EFI_DEVICE_PATH_PROTOCOL EFI_DEVICE_PATH_PROTOCOL;
+
+typedef EFI_STATUS (EFIAPI *EFI_SECURITY_FILE_AUTHENTICATION_STATE) (
+ const EFI_SECURITY_PROTOCOL *This,
+ UINT32 AuthenticationStatus,
+ const EFI_DEVICE_PATH_PROTOCOL *File
+);
+
+typedef EFI_STATUS (EFIAPI *EFI_SECURITY2_FILE_AUTHENTICATION) (
+ const EFI_SECURITY2_PROTOCOL *This,
+ const EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ VOID *FileBuffer,
+ UINTN FileSize,
+ BOOLEAN BootPolicy
+);
+
+struct _EFI_SECURITY2_PROTOCOL {
+ EFI_SECURITY2_FILE_AUTHENTICATION FileAuthentication;
+};
+
+struct _EFI_SECURITY_PROTOCOL {
+ EFI_SECURITY_FILE_AUTHENTICATION_STATE FileAuthenticationState;
+};
+
+/* Handle to the original authenticator for security1 protocol */
+static EFI_SECURITY_FILE_AUTHENTICATION_STATE esfas = NULL;
+
+/* Handle to the original authenticator for security2 protocol */
+static EFI_SECURITY2_FILE_AUTHENTICATION es2fa = NULL;
+
+/*
+ * Perform shim/MOK and Secure Boot authentication on a binary that's already been
+ * loaded into memory. This function does the platform SB authentication first
+ * but preserves its return value in case of its failure, so that it can be
+ * returned in case of a shim/MOK authentication failure. This is done because
+ * the SB failure code seems to vary from one implementation to another, and I
+ * don't want to interfere with that at this time.
+ */
+static EFIAPI EFI_STATUS security2_policy_authentication (const EFI_SECURITY2_PROTOCOL *this,
+ const EFI_DEVICE_PATH_PROTOCOL *device_path,
+ VOID *file_buffer, UINTN file_size, BOOLEAN boot_policy) {
+ EFI_STATUS status;
+
+ /* Chain original security policy */
+ status = uefi_call_wrapper(es2fa, 5, this, device_path, file_buffer, file_size, boot_policy);
+
+ /* if OK, don't bother with MOK check */
+ if (status == EFI_SUCCESS)
+ return status;
+
+ if (shim_validate(file_buffer, file_size))
+ return EFI_SUCCESS;
+
+ return status;
+}
+
+/*
+ * Perform both shim/MOK and platform Secure Boot authentication. This function loads
+ * the file and performs shim/MOK authentication first simply to avoid double loads
+ * of Linux kernels, which are much more likely to be shim/MOK-signed than platform-signed,
+ * since kernels are big and can take several seconds to load on some computers and
+ * filesystems. This also has the effect of returning whatever the platform code is for
+ * authentication failure, be it EFI_ACCESS_DENIED, EFI_SECURITY_VIOLATION, or something
+ * else. (This seems to vary between implementations.)
+ */
+static EFIAPI EFI_STATUS security_policy_authentication (const EFI_SECURITY_PROTOCOL *this, UINT32 authentication_status,
+ const EFI_DEVICE_PATH_PROTOCOL *device_path_const) {
+ EFI_STATUS status;
+ EFI_DEVICE_PATH *dev_path;
+ EFI_HANDLE h;
+ EFI_FILE *root;
+ VOID *file_buffer = NULL;
+ UINTN file_size;
+ CHAR16 *dev_path_str;
+
+ if (!device_path_const)
+ return EFI_INVALID_PARAMETER;
+
+ dev_path = DuplicateDevicePath((EFI_DEVICE_PATH*) device_path_const);
+
+ status = uefi_call_wrapper(BS->LocateDevicePath, 3, (EFI_GUID*) &simple_fs_guid, &dev_path, &h);
+ if (status != EFI_SUCCESS) {
+ FreePool(dev_path);
+ return status;
+ }
+
+ /* No need to check return value, this already happend in efi_main() */
+ root = LibOpenRoot(h);
+ dev_path_str = DevicePathToStr(dev_path);
+ FreePool(dev_path);
+
+ 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)
+ status = uefi_call_wrapper(esfas, 3, this, authentication_status, device_path_const);
+
+ return status;
+}
+
+EFI_STATUS security_policy_install(void) {
+ EFI_SECURITY_PROTOCOL *security_protocol;
+ EFI_SECURITY2_PROTOCOL *security2_protocol = NULL;
+ EFI_STATUS status;
+
+ /* Already Installed */
+ if (esfas)
+ 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
+ */
+ uefi_call_wrapper(BS->LocateProtocol, 3, (EFI_GUID*) &security2_protocol_guid, NULL, (VOID**) &security2_protocol);
+
+ status = uefi_call_wrapper(BS->LocateProtocol, 3, (EFI_GUID*) &security_protocol_guid, NULL, (VOID**) &security_protocol);
+ /* This one is mandatory, so there's a serious problem */
+ if (status != EFI_SUCCESS)
+ return status;
+
+ 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;
+}
+
+EFI_STATUS security_policy_uninstall(void) {
+ EFI_STATUS status;
+
+ if (esfas) {
+ EFI_SECURITY_PROTOCOL *security_protocol;
+
+ status = uefi_call_wrapper(BS->LocateProtocol, 3, (EFI_GUID*) &security_protocol_guid, NULL, (VOID**) &security_protocol);
+
+ if (status != EFI_SUCCESS)
+ return status;
+
+ security_protocol->FileAuthenticationState = esfas;
+ esfas = NULL;
+ } else
+ /* nothing installed */
+ return EFI_NOT_STARTED;
+
+ if (es2fa) {
+ EFI_SECURITY2_PROTOCOL *security2_protocol;
+
+ status = uefi_call_wrapper(BS->LocateProtocol, 3, (EFI_GUID*) &security2_protocol_guid, NULL, (VOID**) &security2_protocol);
+
+ if (status != EFI_SUCCESS)
+ return status;
+
+ security2_protocol->FileAuthentication = es2fa;
+ es2fa = NULL;
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/src/boot/efi/shim.h b/src/boot/efi/shim.h
new file mode 100644
index 0000000000..2dcf48dcd5
--- /dev/null
+++ b/src/boot/efi/shim.h
@@ -0,0 +1,31 @@
+/*
+ * 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
+ * (at your option) any later version.
+ *
+ * This program 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.
+ *
+ * Port to systemd-boot
+ * Copyright 2017 Max Resch <resch.max@gmail.com>
+ *
+ * Security Policy Handling
+ * Copyright 2012 <James.Bottomley@HansenPartnership.com>
+ * https://github.com/mjg59/efitools
+ */
+
+#ifndef __SDBOOT_SHIM_H
+#define __SDBOOT_SHIM_H
+
+BOOLEAN shim_loaded(void);
+
+BOOLEAN secure_boot_enabled(void);
+
+EFI_STATUS security_policy_install(void);
+
+EFI_STATUS security_policy_uninstall(void);
+
+#endif
diff --git a/src/boot/efi/stub.c b/src/boot/efi/stub.c
index b7d5d3cdae..bab5d46de9 100644
--- a/src/boot/efi/stub.c
+++ b/src/boot/efi/stub.c
@@ -17,20 +17,18 @@
#include "disk.h"
#include "graphics.h"
#include "linux.h"
-#include "pefile.h"
+#include "measure.h"
+#include "pe.h"
#include "splash.h"
#include "util.h"
-#include "measure.h"
/* magic string to find in the binary image */
-static const char __attribute__((used)) magic[] = "#### LoaderInfo: systemd-stub " VERSION " ####";
+static const char __attribute__((used)) magic[] = "#### LoaderInfo: systemd-stub " PACKAGE_VERSION " ####";
static const EFI_GUID global_guid = EFI_GLOBAL_VARIABLE;
EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
EFI_LOADED_IMAGE *loaded_image;
- EFI_FILE *root_dir;
- CHAR16 *loaded_image_path;
CHAR8 *b;
UINTN size;
BOOLEAN secure = FALSE;
@@ -59,22 +57,12 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
return err;
}
- root_dir = LibOpenRoot(loaded_image->DeviceHandle);
- if (!root_dir) {
- Print(L"Unable to open root directory: %r ", err);
- uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
- return EFI_LOAD_ERROR;
- }
-
- loaded_image_path = DevicePathToStr(loaded_image->FilePath);
-
if (efivar_get_raw(&global_guid, L"SecureBoot", &b, &size) == EFI_SUCCESS) {
if (*b > 0)
secure = TRUE;
FreePool(b);
}
-
- err = pefile_locate_sections(root_dir, loaded_image_path, sections, addrs, offs, szs);
+ err = pe_memory_locate_sections(loaded_image->ImageBase, sections, addrs, offs, szs);
if (EFI_ERROR(err)) {
Print(L"Unable to locate embedded .linux section: %r ", err);
uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
diff --git a/src/libsystemd/sd-bus/busctl-introspect.c b/src/busctl/busctl-introspect.c
index a05794941f..a05794941f 100644
--- a/src/libsystemd/sd-bus/busctl-introspect.c
+++ b/src/busctl/busctl-introspect.c
diff --git a/src/libsystemd/sd-bus/busctl-introspect.h b/src/busctl/busctl-introspect.h
index d922e352db..d922e352db 100644
--- a/src/libsystemd/sd-bus/busctl-introspect.h
+++ b/src/busctl/busctl-introspect.h
diff --git a/src/libsystemd/sd-bus/busctl.c b/src/busctl/busctl.c
index 9dd3828364..b38d6c7267 100644
--- a/src/libsystemd/sd-bus/busctl.c
+++ b/src/busctl/busctl.c
@@ -1083,6 +1083,8 @@ static int monitor(sd_bus *bus, char *argv[], int (*dump)(sd_bus_message *m, FIL
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
char **i;
uint32_t flags = 0;
+ const char *unique_name;
+ bool is_monitor = false;
int r;
/* upgrade connection; it's not used for anything else after this call */
@@ -1140,6 +1142,10 @@ static int monitor(sd_bus *bus, char *argv[], int (*dump)(sd_bus_message *m, FIL
return r;
}
+ r = sd_bus_get_unique_name(bus, &unique_name);
+ if (r < 0)
+ return log_error_errno(r, "Failed to get unique name: %m");
+
log_info("Monitoring bus message stream.");
for (;;) {
@@ -1149,6 +1155,23 @@ static int monitor(sd_bus *bus, char *argv[], int (*dump)(sd_bus_message *m, FIL
if (r < 0)
return log_error_errno(r, "Failed to process bus: %m");
+ if (!is_monitor) {
+ const char *name;
+
+ /* wait until we lose our unique name */
+ if (sd_bus_message_is_signal(m, "org.freedesktop.DBus", "NameLost") <= 0)
+ continue;
+
+ r = sd_bus_message_read(m, "s", &name);
+ if (r < 0)
+ return log_error_errno(r, "Failed to read lost name: %m");
+
+ if (streq(name, unique_name))
+ is_monitor = true;
+
+ continue;
+ }
+
if (m) {
dump(m, stdout);
fflush(stdout);
diff --git a/src/cgtop/cgtop.c b/src/cgtop/cgtop.c
index 67f3a99860..7ebb02fa8c 100644
--- a/src/cgtop/cgtop.c
+++ b/src/cgtop/cgtop.c
@@ -75,6 +75,7 @@ static usec_t arg_delay = 1*USEC_PER_SEC;
static char* arg_machine = NULL;
static char* arg_root = NULL;
static bool arg_recursive = true;
+static bool arg_recursive_unset = false;
static enum {
COUNT_PIDS,
@@ -732,7 +733,6 @@ static int parse_argv(int argc, char *argv[]) {
{}
};
- bool recursive_unset = false;
int c, r;
assert(argc >= 1);
@@ -852,7 +852,7 @@ static int parse_argv(int argc, char *argv[]) {
}
arg_recursive = r;
- recursive_unset = r == 0;
+ arg_recursive_unset = r == 0;
break;
case 'M':
@@ -873,11 +873,6 @@ static int parse_argv(int argc, char *argv[]) {
return -EINVAL;
}
- if (recursive_unset && arg_count == COUNT_PIDS) {
- log_error("Non-recursive counting is only supported when counting processes, not tasks. Use -P or -k.");
- return -EINVAL;
- }
-
return 1;
}
@@ -902,6 +897,10 @@ int main(int argc, char *argv[]) {
log_parse_environment();
log_open();
+ r = parse_argv(argc, argv);
+ if (r <= 0)
+ goto finish;
+
r = cg_mask_supported(&mask);
if (r < 0) {
log_error_errno(r, "Failed to determine supported controllers: %m");
@@ -910,9 +909,10 @@ int main(int argc, char *argv[]) {
arg_count = (mask & CGROUP_MASK_PIDS) ? COUNT_PIDS : COUNT_USERSPACE_PROCESSES;
- r = parse_argv(argc, argv);
- if (r <= 0)
- goto finish;
+ if (arg_recursive_unset && arg_count == COUNT_PIDS) {
+ log_error("Non-recursive counting is only supported when counting processes, not tasks. Use -P or -k.");
+ return -EINVAL;
+ }
r = show_cgroup_get_path_and_warn(arg_machine, arg_root, &root);
if (r < 0) {
diff --git a/src/core/audit-fd.c b/src/core/audit-fd.c
index 76afe3fe15..a91906b626 100644
--- a/src/core/audit-fd.c
+++ b/src/core/audit-fd.c
@@ -27,6 +27,7 @@
#include <libaudit.h>
#include <stdbool.h>
+#include "capability-util.h"
#include "fd-util.h"
#include "log.h"
#include "util.h"
@@ -37,6 +38,13 @@ static int audit_fd;
int get_audit_fd(void) {
if (!initialized) {
+ if (have_effective_cap(CAP_AUDIT_WRITE) == 0) {
+ audit_fd = -EPERM;
+ initialized = true;
+
+ return audit_fd;
+ }
+
audit_fd = audit_open();
if (audit_fd < 0) {
diff --git a/src/core/automount.c b/src/core/automount.c
index ccc113b598..96de933e23 100644
--- a/src/core/automount.c
+++ b/src/core/automount.c
@@ -474,10 +474,10 @@ static int automount_send_ready(Automount *a, Set *tokens, int status) {
while ((token = PTR_TO_UINT(set_steal_first(tokens)))) {
int k;
- /* Autofs fun fact II:
+ /* Autofs fun fact:
*
- * if you pass a positive status code here, the kernel will
- * freeze! Yay! */
+ * if you pass a positive status code here, kernels
+ * prior to 4.12 will freeze! Yay! */
k = autofs_send_ready(UNIT(a)->manager->dev_autofs_fd,
ioctl_fd,
@@ -590,7 +590,7 @@ static void automount_enter_waiting(Automount *a) {
}
xsprintf(options, "fd=%i,pgrp="PID_FMT",minproto=5,maxproto=5,direct", p[1], getpgrp());
- xsprintf(name, "systemd-"PID_FMT, getpid());
+ xsprintf(name, "systemd-"PID_FMT, getpid_cached());
if (mount(name, a->where, "autofs", 0, options) < 0) {
r = -errno;
goto fail;
@@ -619,12 +619,6 @@ static void automount_enter_waiting(Automount *a) {
if (r < 0)
goto fail;
- /* Autofs fun fact:
- *
- * Unless we close the ioctl fd here, for some weird reason
- * the direct mount will not receive events from the
- * kernel. */
-
r = sd_event_add_io(UNIT(a)->manager->event, &a->pipe_event_source, p[0], EPOLLIN, automount_dispatch_io, a);
if (r < 0)
goto fail;
@@ -745,8 +739,9 @@ static void automount_stop_expire(Automount *a) {
(void) sd_event_source_set_enabled(a->expire_event_source, SD_EVENT_OFF);
}
-static void automount_enter_runnning(Automount *a) {
+static void automount_enter_running(Automount *a) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ Unit *trigger;
struct stat st;
int r;
@@ -775,22 +770,24 @@ static void automount_enter_runnning(Automount *a) {
goto fail;
}
- if (!S_ISDIR(st.st_mode) || st.st_dev != a->dev_id)
+ /* The mount unit may have been explicitly started before we got the
+ * autofs request. Ack it to unblock anything waiting on the mount point. */
+ if (!S_ISDIR(st.st_mode) || st.st_dev != a->dev_id) {
log_unit_info(UNIT(a), "Automount point already active?");
- else {
- Unit *trigger;
+ automount_send_ready(a, a->tokens, 0);
+ return;
+ }
- trigger = UNIT_TRIGGER(UNIT(a));
- if (!trigger) {
- log_unit_error(UNIT(a), "Unit to trigger vanished.");
- goto fail;
- }
+ trigger = UNIT_TRIGGER(UNIT(a));
+ if (!trigger) {
+ log_unit_error(UNIT(a), "Unit to trigger vanished.");
+ goto fail;
+ }
- r = manager_add_job(UNIT(a)->manager, JOB_START, trigger, JOB_REPLACE, &error, NULL);
- if (r < 0) {
- log_unit_warning(UNIT(a), "Failed to queue mount startup job: %s", bus_error_message(&error, r));
- goto fail;
- }
+ r = manager_add_job(UNIT(a)->manager, JOB_START, trigger, JOB_REPLACE, &error, NULL);
+ if (r < 0) {
+ log_unit_warning(UNIT(a), "Failed to queue mount startup job: %s", bus_error_message(&error, r));
+ goto fail;
}
automount_set_state(a, AUTOMOUNT_RUNNING);
@@ -973,7 +970,6 @@ static int automount_dispatch_io(sd_event_source *s, int fd, uint32_t events, vo
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
union autofs_v5_packet_union packet;
Automount *a = AUTOMOUNT(userdata);
- struct stat st;
Unit *trigger;
int r;
@@ -1015,7 +1011,7 @@ static int automount_dispatch_io(sd_event_source *s, int fd, uint32_t events, vo
goto fail;
}
- automount_enter_runnning(a);
+ automount_enter_running(a);
break;
case autofs_ptype_expire_direct:
@@ -1035,18 +1031,6 @@ static int automount_dispatch_io(sd_event_source *s, int fd, uint32_t events, vo
goto fail;
}
- /* Before we do anything, let's see if somebody is playing games with us? */
- if (lstat(a->where, &st) < 0) {
- log_unit_warning_errno(UNIT(a), errno, "Failed to stat automount point: %m");
- goto fail;
- }
-
- if (!S_ISDIR(st.st_mode) || st.st_dev == a->dev_id) {
- log_unit_info(UNIT(a), "Automount point already unmounted?");
- automount_send_ready(a, a->expire_tokens, 0);
- break;
- }
-
trigger = UNIT_TRIGGER(UNIT(a));
if (!trigger) {
log_unit_error(UNIT(a), "Unit to trigger vanished.");
diff --git a/src/core/busname.c b/src/core/busname.c
index 88b758eecb..955f6f88d8 100644
--- a/src/core/busname.c
+++ b/src/core/busname.c
@@ -764,7 +764,7 @@ static int busname_peek_message(BusName *n) {
struct kdbus_item *d;
struct kdbus_msg *k;
size_t start, ps, sz, delta;
- void *p = NULL;
+ void *p = MAP_FAILED;
pid_t pid = 0;
int r;
@@ -825,7 +825,7 @@ static int busname_peek_message(BusName *n) {
r = 0;
finish:
- if (p)
+ if (p != MAP_FAILED)
(void) munmap(p, sz);
cmd_free.offset = cmd_recv.msg.offset;
diff --git a/src/core/cgroup.c b/src/core/cgroup.c
index 774b832a63..fc8b9565a2 100644
--- a/src/core/cgroup.c
+++ b/src/core/cgroup.c
@@ -398,8 +398,7 @@ static int whitelist_major(const char *path, const char *name, char type, const
return 0;
fail:
- log_warning_errno(errno, "Failed to read /proc/devices: %m");
- return -errno;
+ return log_warning_errno(errno, "Failed to read /proc/devices: %m");
}
static bool cgroup_context_has_cpu_weight(CGroupContext *c) {
@@ -1594,7 +1593,7 @@ int unit_search_main_pid(Unit *u, pid_t *ret) {
if (r < 0)
return r;
- mypid = getpid();
+ mypid = getpid_cached();
while (cg_read_pid(f, &npid) > 0) {
pid_t ppid;
diff --git a/src/core/dbus-cgroup.c b/src/core/dbus-cgroup.c
index c4067a95bf..12d3ca076b 100644
--- a/src/core/dbus-cgroup.c
+++ b/src/core/dbus-cgroup.c
@@ -407,7 +407,15 @@ int bus_cgroup_set_property(
if (mode != UNIT_CHECK) {
c->cpu_quota_per_sec_usec = u64;
unit_invalidate_cgroup(u, CGROUP_MASK_CPU);
- unit_write_drop_in_private_format(u, mode, "CPUQuota", "CPUQuota=%0.f%%", (double) (c->cpu_quota_per_sec_usec / 10000));
+ if (c->cpu_quota_per_sec_usec == USEC_INFINITY)
+ unit_write_drop_in_private_format(u, mode, "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));
}
return 1;
diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c
index 0454a28e12..c041a7d94c 100644
--- a/src/core/dbus-execute.c
+++ b/src/core/dbus-execute.c
@@ -45,6 +45,7 @@
#endif
#include "strv.h"
#include "syslog-util.h"
+#include "unit-printf.h"
#include "user-util.h"
#include "utf8.h"
@@ -159,21 +160,50 @@ static int property_get_ioprio(
ExecContext *c = userdata;
- int32_t n;
assert(bus);
assert(reply);
assert(c);
- if (c->ioprio_set)
- n = c->ioprio;
- else {
- n = ioprio_get(IOPRIO_WHO_PROCESS, 0);
- if (n < 0)
- n = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 4);
- }
+ return sd_bus_message_append(reply, "i", exec_context_get_effective_ioprio(c));
+}
- return sd_bus_message_append(reply, "i", n);
+static int property_get_ioprio_class(
+ 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;
+
+ assert(bus);
+ assert(reply);
+ assert(c);
+
+ return sd_bus_message_append(reply, "i", IOPRIO_PRIO_CLASS(exec_context_get_effective_ioprio(c)));
+}
+
+static int property_get_ioprio_priority(
+ 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;
+
+ assert(bus);
+ assert(reply);
+ assert(c);
+
+ return sd_bus_message_append(reply, "i", IOPRIO_PRIO_DATA(exec_context_get_effective_ioprio(c)));
}
static int property_get_cpu_sched_policy(
@@ -761,7 +791,8 @@ const sd_bus_vtable bus_exec_vtable[] = {
SD_BUS_PROPERTY("RootImage", "s", NULL, offsetof(ExecContext, root_image), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("OOMScoreAdjust", "i", property_get_oom_score_adjust, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Nice", "i", property_get_nice, 0, SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("IOScheduling", "i", property_get_ioprio, 0, SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("IOSchedulingClass", "i", property_get_ioprio_class, 0, SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("IOSchedulingPriority", "i", property_get_ioprio_priority, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("CPUSchedulingPolicy", "i", property_get_cpu_sched_policy, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("CPUSchedulingPriority", "i", property_get_cpu_sched_priority, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("CPUAffinity", "ay", property_get_cpu_affinity, 0, SD_BUS_VTABLE_PROPERTY_CONST),
@@ -783,7 +814,6 @@ 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("Capabilities", "s", property_get_empty_string, 0, SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
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),
@@ -793,9 +823,6 @@ const sd_bus_vtable bus_exec_vtable[] = {
SD_BUS_PROPERTY("RemoveIPC", "b", bus_property_get_bool, offsetof(ExecContext, remove_ipc), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("SupplementaryGroups", "as", NULL, offsetof(ExecContext, supplementary_groups), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("PAMName", "s", NULL, offsetof(ExecContext, pam_name), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("ReadWriteDirectories", "as", NULL, offsetof(ExecContext, read_write_paths), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
- SD_BUS_PROPERTY("ReadOnlyDirectories", "as", NULL, offsetof(ExecContext, read_only_paths), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
- SD_BUS_PROPERTY("InaccessibleDirectories", "as", NULL, offsetof(ExecContext, inaccessible_paths), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
SD_BUS_PROPERTY("ReadWritePaths", "as", NULL, offsetof(ExecContext, read_write_paths), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("ReadOnlyPaths", "as", NULL, offsetof(ExecContext, read_only_paths), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("InaccessiblePaths", "as", NULL, offsetof(ExecContext, inaccessible_paths), SD_BUS_VTABLE_PROPERTY_CONST),
@@ -830,6 +857,14 @@ const sd_bus_vtable bus_exec_vtable[] = {
SD_BUS_PROPERTY("BindPaths", "a(ssbt)", property_get_bind_paths, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("BindReadOnlyPaths", "a(ssbt)", property_get_bind_paths, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("MountAPIVFS", "b", bus_property_get_bool, offsetof(ExecContext, mount_apivfs), SD_BUS_VTABLE_PROPERTY_CONST),
+
+ /* Obsolete/redundant properties: */
+ SD_BUS_PROPERTY("Capabilities", "s", property_get_empty_string, 0, SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
+ SD_BUS_PROPERTY("ReadWriteDirectories", "as", NULL, offsetof(ExecContext, read_write_paths), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
+ SD_BUS_PROPERTY("ReadOnlyDirectories", "as", NULL, offsetof(ExecContext, read_only_paths), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
+ SD_BUS_PROPERTY("InaccessibleDirectories", "as", NULL, offsetof(ExecContext, inaccessible_paths), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
+ SD_BUS_PROPERTY("IOScheduling", "i", property_get_ioprio, 0, SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
+
SD_BUS_VTABLE_END
};
@@ -1001,7 +1036,7 @@ int bus_exec_context_set_transient_property(
return 1;
} else if (streq(name, "SyslogLevel")) {
- int level;
+ int32_t level;
r = sd_bus_message_read(message, "i", &level);
if (r < 0)
@@ -1017,7 +1052,7 @@ int bus_exec_context_set_transient_property(
return 1;
} else if (streq(name, "SyslogFacility")) {
- int facility;
+ int32_t facility;
r = sd_bus_message_read(message, "i", &facility);
if (r < 0)
@@ -1033,7 +1068,7 @@ int bus_exec_context_set_transient_property(
return 1;
} else if (streq(name, "Nice")) {
- int n;
+ int32_t n;
r = sd_bus_message_read(message, "i", &n);
if (r < 0)
@@ -1049,6 +1084,50 @@ int bus_exec_context_set_transient_property(
return 1;
+ } else if (streq(name, "IOSchedulingClass")) {
+ int32_t q;
+
+ r = sd_bus_message_read(message, "i", &q);
+ if (r < 0)
+ return r;
+
+ 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) {
+ _cleanup_free_ char *s = NULL;
+
+ r = ioprio_class_to_string_alloc(q, &s);
+ if (r < 0)
+ return r;
+
+ 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);
+ }
+
+ return 1;
+
+ } else if (streq(name, "IOSchedulingPriority")) {
+ int32_t p;
+
+ r = sd_bus_message_read(message, "i", &p);
+ if (r < 0)
+ return r;
+
+ 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) {
+ 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);
+ }
+
+ return 1;
+
} else if (STR_IN_SET(name, "TTYPath", "RootDirectory", "RootImage")) {
const char *s;
@@ -1317,7 +1396,7 @@ int bus_exec_context_set_transient_property(
} else if (streq(name, "Environment")) {
- _cleanup_strv_free_ char **l = NULL;
+ _cleanup_strv_free_ char **l = NULL, **q = NULL;
r = sd_bus_message_read_strv(message, &l);
if (r < 0)
@@ -1326,22 +1405,27 @@ int bus_exec_context_set_transient_property(
if (!strv_env_is_valid(l))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment block.");
- if (mode != UNIT_CHECK) {
- _cleanup_free_ char *joined = NULL;
- char **e;
+ r = unit_full_printf_strv(u, l, &q);
+ if (r < 0)
+ return r;
- if (strv_length(l) == 0) {
+ if (mode != UNIT_CHECK) {
+ if (strv_length(q) == 0) {
c->environment = strv_free(c->environment);
unit_write_drop_in_private_format(u, mode, name, "Environment=");
} else {
- e = strv_env_merge(2, c->environment, l);
+ _cleanup_free_ char *joined = NULL;
+ char **e;
+
+ e = strv_env_merge(2, c->environment, q);
if (!e)
return -ENOMEM;
strv_free(c->environment);
c->environment = e;
- joined = strv_join_quoted(c->environment);
+ /* We write just the new settings out to file, with unresolved specifiers */
+ joined = strv_join_quoted(q);
if (!joined)
return -ENOMEM;
diff --git a/src/core/dbus-service.c b/src/core/dbus-service.c
index 85b67318ed..6458ee5c12 100644
--- a/src/core/dbus-service.c
+++ b/src/core/dbus-service.c
@@ -199,6 +199,39 @@ static int bus_service_set_transient_property(
return 1;
+ } else if (streq(name, "FileDescriptorStoreMax")) {
+ uint32_t u;
+
+ r = sd_bus_message_read(message, "u", &u);
+ if (r < 0)
+ return r;
+
+ if (mode != UNIT_CHECK) {
+ s->n_fd_store_max = (unsigned) u;
+ unit_write_drop_in_private_format(UNIT(s), mode, name, "FileDescriptorStoreMax=%" PRIu32, u);
+ }
+
+ return 1;
+
+ } else if (streq(name, "NotifyAccess")) {
+ const char *t;
+ NotifyAccess k;
+
+ r = sd_bus_message_read(message, "s", &t);
+ if (r < 0)
+ return r;
+
+ k = notify_access_from_string(t);
+ if (k < 0)
+ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid notify access setting %s", t);
+
+ if (mode != UNIT_CHECK) {
+ s->notify_access = k;
+ unit_write_drop_in_private_format(UNIT(s), mode, name, "NotifyAccess=%s", notify_access_to_string(s->notify_access));
+ }
+
+ return 1;
+
} else if (streq(name, "ExecStart")) {
unsigned n = 0;
diff --git a/src/core/dbus-timer.c b/src/core/dbus-timer.c
index efbb0e8915..c98282a5d4 100644
--- a/src/core/dbus-timer.c
+++ b/src/core/dbus-timer.c
@@ -144,28 +144,14 @@ static int property_get_next_elapse_monotonic(
sd_bus_error *error) {
Timer *t = userdata;
- usec_t x;
assert(bus);
assert(reply);
assert(t);
- if (t->next_elapse_monotonic_or_boottime <= 0)
- x = 0;
- else if (t->wake_system) {
- usec_t a, b;
-
- a = now(CLOCK_MONOTONIC);
- b = now(clock_boottime_or_monotonic());
-
- if (t->next_elapse_monotonic_or_boottime + a > b)
- x = t->next_elapse_monotonic_or_boottime + a - b;
- else
- x = 0;
- } else
- x = t->next_elapse_monotonic_or_boottime;
-
- return sd_bus_message_append(reply, "t", x);
+ return sd_bus_message_append(reply, "t",
+ (uint64_t) usec_shift_clock(t->next_elapse_monotonic_or_boottime,
+ TIMER_MONOTONIC_CLOCK(t), CLOCK_MONOTONIC));
}
const sd_bus_vtable bus_timer_vtable[] = {
diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c
index f15bb2196c..b0645ce294 100644
--- a/src/core/dbus-unit.c
+++ b/src/core/dbus-unit.c
@@ -748,6 +748,7 @@ const sd_bus_vtable bus_unit_vtable[] = {
SD_BUS_PROPERTY("IgnoreOnIsolate", "b", bus_property_get_bool, offsetof(Unit, ignore_on_isolate), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("NeedDaemonReload", "b", property_get_need_daemon_reload, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("JobTimeoutUSec", "t", bus_property_get_usec, offsetof(Unit, job_timeout), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("JobRunningTimeoutUSec", "t", bus_property_get_usec, offsetof(Unit, job_running_timeout), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("JobTimeoutAction", "s", property_get_emergency_action, offsetof(Unit, job_timeout_action), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("JobTimeoutRebootArgument", "s", NULL, offsetof(Unit, job_timeout_reboot_arg), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("ConditionResult", "b", bus_property_get_bool, offsetof(Unit, condition_result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
diff --git a/src/core/dbus.c b/src/core/dbus.c
index cfc045d282..96bf975f88 100644
--- a/src/core/dbus.c
+++ b/src/core/dbus.c
@@ -967,7 +967,7 @@ static int bus_init_private(Manager *m) {
if (MANAGER_IS_SYSTEM(m)) {
/* We want the private bus only when running as init */
- if (getpid() != 1)
+ if (getpid_cached() != 1)
return 0;
strcpy(sa.un.sun_path, "/run/systemd/private");
diff --git a/src/core/device.c b/src/core/device.c
index 0e67c96552..77601c5520 100644
--- a/src/core/device.c
+++ b/src/core/device.c
@@ -112,7 +112,7 @@ static void device_init(Unit *u) {
* indefinitely for plugged in devices, something which cannot
* happen for the other units since their operations time out
* anyway. */
- u->job_timeout = u->manager->default_timeout_start_usec;
+ u->job_running_timeout = u->manager->default_timeout_start_usec;
u->ignore_on_isolate = true;
}
@@ -501,12 +501,16 @@ static void device_update_found_one(Device *d, bool add, DeviceFound found, bool
* now referenced by the kernel, then we assume the
* kernel knows it now, and udev might soon too. */
device_set_state(d, DEVICE_TENTATIVE);
- else
+ else {
/* If nobody sees the device, or if the device was
* previously seen by udev and now is only referenced
* from the kernel, then we consider the device is
* gone, the kernel just hasn't noticed it yet. */
+
device_set_state(d, DEVICE_DEAD);
+ device_unset_sysfs(d);
+ }
+
}
static int device_update_found_by_sysfs(Manager *m, const char *sysfs, bool add, DeviceFound found, bool now) {
diff --git a/src/core/execute.c b/src/core/execute.c
index 08b95f7d4f..f1b75c9f75 100644
--- a/src/core/execute.c
+++ b/src/core/execute.c
@@ -157,22 +157,26 @@ static int shift_fds(int fds[], unsigned n_fds) {
return 0;
}
-static int flags_fds(const int fds[], unsigned n_fds, bool nonblock) {
- unsigned i;
+static int flags_fds(const int fds[], unsigned n_storage_fds, unsigned n_socket_fds, bool nonblock) {
+ unsigned i, n_fds;
int r;
+ n_fds = n_storage_fds + n_socket_fds;
if (n_fds <= 0)
return 0;
assert(fds);
- /* Drops/Sets O_NONBLOCK and FD_CLOEXEC from the file flags */
+ /* Drops/Sets O_NONBLOCK and FD_CLOEXEC from the file flags.
+ * O_NONBLOCK only applies to socket activation though. */
for (i = 0; i < n_fds; i++) {
- r = fd_nonblock(fds[i], nonblock);
- if (r < 0)
- return r;
+ if (i < n_socket_fds) {
+ r = fd_nonblock(fds[i], nonblock);
+ if (r < 0)
+ return r;
+ }
/* We unconditionally drop FD_CLOEXEC from the fds,
* since after all we want to pass these fds to our
@@ -1095,7 +1099,7 @@ static int setup_pam(
assert_se(sigprocmask_many(SIG_BLOCK, &old_ss, SIGTERM, -1) >= 0);
- parent_pid = getpid();
+ parent_pid = getpid_cached();
pam_pid = fork();
if (pam_pid < 0) {
@@ -1502,7 +1506,7 @@ static int build_environment(
if (n_fds > 0) {
_cleanup_free_ char *joined = NULL;
- if (asprintf(&x, "LISTEN_PID="PID_FMT, getpid()) < 0)
+ if (asprintf(&x, "LISTEN_PID="PID_FMT, getpid_cached()) < 0)
return -ENOMEM;
our_env[n_env++] = x;
@@ -1521,7 +1525,7 @@ static int build_environment(
}
if ((p->flags & EXEC_SET_WATCHDOG) && p->watchdog_usec > 0) {
- if (asprintf(&x, "WATCHDOG_PID="PID_FMT, getpid()) < 0)
+ if (asprintf(&x, "WATCHDOG_PID="PID_FMT, getpid_cached()) < 0)
return -ENOMEM;
our_env[n_env++] = x;
@@ -1670,7 +1674,7 @@ static bool exec_needs_mount_namespace(
context->protect_control_groups)
return true;
- if (context->mount_apivfs)
+ if (context->mount_apivfs && (context->root_image || context->root_directory))
return true;
return false;
@@ -2188,7 +2192,9 @@ static int exec_child(
char **argv,
int socket_fd,
int named_iofds[3],
- int *fds, unsigned n_fds,
+ int *fds,
+ unsigned n_storage_fds,
+ unsigned n_socket_fds,
char **files_env,
int user_lookup_fd,
int *exit_status,
@@ -2205,6 +2211,7 @@ static int exec_child(
uid_t uid = UID_INVALID;
gid_t gid = GID_INVALID;
int i, r, ngids = 0;
+ unsigned n_fds;
assert(unit);
assert(command);
@@ -2245,6 +2252,7 @@ static int exec_child(
log_forget_fds();
+ n_fds = n_storage_fds + n_socket_fds;
r = close_remaining_fds(params, runtime, dcreds, user_lookup_fd, socket_fd, fds, n_fds);
if (r < 0) {
*exit_status = EXIT_FDS;
@@ -2458,7 +2466,7 @@ static int exec_child(
}
if (context->utmp_id)
- utmp_put_init_process(context->utmp_id, getpid(), getsid(0),
+ utmp_put_init_process(context->utmp_id, getpid_cached(), getsid(0),
context->tty_path,
context->utmp_mode == EXEC_UTMP_INIT ? INIT_PROCESS :
context->utmp_mode == EXEC_UTMP_LOGIN ? LOGIN_PROCESS :
@@ -2610,7 +2618,7 @@ static int exec_child(
if (r >= 0)
r = shift_fds(fds, n_fds);
if (r >= 0)
- r = flags_fds(fds, n_fds, context->non_blocking);
+ r = flags_fds(fds, n_storage_fds, n_socket_fds, context->non_blocking);
if (r < 0) {
*exit_status = EXIT_FDS;
return r;
@@ -2828,9 +2836,9 @@ static int exec_child(
if (line) {
log_open();
log_struct(LOG_DEBUG,
- LOG_UNIT_ID(unit),
"EXECUTABLE=%s", command->path,
LOG_UNIT_MESSAGE(unit, "Executing: %s", line),
+ LOG_UNIT_ID(unit),
NULL);
log_close();
}
@@ -2850,7 +2858,8 @@ int exec_spawn(Unit *unit,
pid_t *ret) {
_cleanup_strv_free_ char **files_env = NULL;
- int *fds = NULL; unsigned n_fds = 0;
+ int *fds = NULL;
+ unsigned n_storage_fds = 0, n_socket_fds = 0;
_cleanup_free_ char *line = NULL;
int socket_fd, r;
int named_iofds[3] = { -1, -1, -1 };
@@ -2862,18 +2871,18 @@ int exec_spawn(Unit *unit,
assert(context);
assert(ret);
assert(params);
- assert(params->fds || params->n_fds <= 0);
+ assert(params->fds || (params->n_storage_fds + params->n_socket_fds <= 0));
if (context->std_input == EXEC_INPUT_SOCKET ||
context->std_output == EXEC_OUTPUT_SOCKET ||
context->std_error == EXEC_OUTPUT_SOCKET) {
- if (params->n_fds > 1) {
+ if (params->n_socket_fds > 1) {
log_unit_error(unit, "Got more than one socket.");
return -EINVAL;
}
- if (params->n_fds == 0) {
+ if (params->n_socket_fds == 0) {
log_unit_error(unit, "Got no socket.");
return -EINVAL;
}
@@ -2882,7 +2891,8 @@ int exec_spawn(Unit *unit,
} else {
socket_fd = -1;
fds = params->fds;
- n_fds = params->n_fds;
+ n_storage_fds = params->n_storage_fds;
+ n_socket_fds = params->n_socket_fds;
}
r = exec_context_named_iofds(unit, context, params, named_iofds);
@@ -2899,9 +2909,9 @@ int exec_spawn(Unit *unit,
return log_oom();
log_struct(LOG_DEBUG,
- LOG_UNIT_ID(unit),
LOG_UNIT_MESSAGE(unit, "About to execute: %s", line),
"EXECUTABLE=%s", command->path,
+ LOG_UNIT_ID(unit),
NULL);
pid = fork();
if (pid < 0)
@@ -2920,7 +2930,9 @@ int exec_spawn(Unit *unit,
argv,
socket_fd,
named_iofds,
- fds, n_fds,
+ fds,
+ n_storage_fds,
+ n_socket_fds,
files_env,
unit->manager->user_lookup_fds[1],
&exit_status,
@@ -2935,6 +2947,14 @@ int exec_spawn(Unit *unit,
error_message),
"EXECUTABLE=%s", command->path,
NULL);
+ else if (r == -ENOENT && command->ignore)
+ log_struct_errno(LOG_INFO, r,
+ "MESSAGE_ID=" SD_MESSAGE_SPAWN_FAILED_STR,
+ LOG_UNIT_ID(unit),
+ LOG_UNIT_MESSAGE(unit, "Skipped spawning %s: %m",
+ command->path),
+ "EXECUTABLE=%s", command->path,
+ NULL);
else
log_struct_errno(LOG_ERR, r,
"MESSAGE_ID=" SD_MESSAGE_SPAWN_FAILED_STR,
@@ -3020,6 +3040,7 @@ void exec_context_done(ExecContext *c) {
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_archs = set_free(c->syscall_archs);
@@ -3121,6 +3142,7 @@ const char* exec_context_fdname(const ExecContext *c, int fd_index) {
int exec_context_named_iofds(Unit *unit, const ExecContext *c, const ExecParameters *p, int named_iofds[3]) {
unsigned i, targets;
const char* stdio_fdname[3];
+ unsigned n_fds;
assert(c);
assert(p);
@@ -3132,7 +3154,9 @@ int exec_context_named_iofds(Unit *unit, const ExecContext *c, const ExecParamet
for (i = 0; i < 3; i++)
stdio_fdname[i] = exec_context_fdname(c, i);
- for (i = 0; i < p->n_fds && targets > 0; i++)
+ n_fds = p->n_storage_fds + p->n_socket_fds;
+
+ for (i = 0; i < n_fds && targets > 0; i++)
if (named_iofds[STDIN_FILENO] < 0 &&
c->std_input == EXEC_INPUT_NAMED_FD &&
stdio_fdname[STDIN_FILENO] &&
@@ -3170,10 +3194,10 @@ int exec_context_load_environment(Unit *unit, const ExecContext *c, char ***l) {
STRV_FOREACH(i, c->environment_files) {
char *fn;
int k;
+ unsigned n;
bool ignore = false;
char **p;
_cleanup_globfree_ glob_t pglob = {};
- int count, n;
fn = *i;
@@ -3191,23 +3215,19 @@ int exec_context_load_environment(Unit *unit, const ExecContext *c, char ***l) {
}
/* Filename supports globbing, take all matching files */
- errno = 0;
- if (glob(fn, 0, NULL, &pglob) != 0) {
+ k = safe_glob(fn, 0, &pglob);
+ if (k < 0) {
if (ignore)
continue;
strv_free(r);
- return errno > 0 ? -errno : -EINVAL;
+ return k;
}
- count = pglob.gl_pathc;
- if (count == 0) {
- if (ignore)
- continue;
- strv_free(r);
- return -EINVAL;
- }
- for (n = 0; n < count; n++) {
+ /* When we don't match anything, -ENOENT should be returned */
+ assert(pglob.gl_pathc > 0);
+
+ for (n = 0; n < pglob.gl_pathc; n++) {
k = load_env_file(NULL, pglob.gl_pathv[n], NULL, &p);
if (k < 0) {
if (ignore)
@@ -3535,6 +3555,16 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) {
"%sSELinuxContext: %s%s\n",
prefix, c->selinux_context_ignore ? "-" : "", c->selinux_context);
+ if (c->apparmor_profile)
+ fprintf(f,
+ "%sAppArmorProfile: %s%s\n",
+ prefix, c->apparmor_profile_ignore ? "-" : "", c->apparmor_profile);
+
+ if (c->smack_process_label)
+ fprintf(f,
+ "%sSmackProcessLabel: %s%s\n",
+ prefix, c->smack_process_label_ignore ? "-" : "", c->smack_process_label);
+
if (c->personality != PERSONALITY_INVALID)
fprintf(f,
"%sPersonality: %s\n",
@@ -3623,6 +3653,21 @@ bool exec_context_maintains_privileges(ExecContext *c) {
return false;
}
+int exec_context_get_effective_ioprio(ExecContext *c) {
+ int p;
+
+ assert(c);
+
+ if (c->ioprio_set)
+ return c->ioprio;
+
+ p = ioprio_get(IOPRIO_WHO_PROCESS, 0);
+ if (p < 0)
+ return IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 4);
+
+ return p;
+}
+
void exec_status_start(ExecStatus *s, pid_t pid) {
assert(s);
diff --git a/src/core/execute.h b/src/core/execute.h
index c2e41f3695..157495af35 100644
--- a/src/core/execute.h
+++ b/src/core/execute.h
@@ -245,7 +245,8 @@ struct ExecParameters {
int *fds;
char **fd_names;
- unsigned n_fds;
+ unsigned n_storage_fds;
+ unsigned n_socket_fds;
ExecFlags flags;
bool selinux_context_net:1;
@@ -305,6 +306,8 @@ const char* exec_context_fdname(const ExecContext *c, int fd_index);
bool exec_context_may_touch_console(ExecContext *c);
bool exec_context_maintains_privileges(ExecContext *c);
+int exec_context_get_effective_ioprio(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/ima-setup.c b/src/core/ima-setup.c
index 94ae429f46..7b5c98a57c 100644
--- a/src/core/ima-setup.c
+++ b/src/core/ima-setup.c
@@ -49,6 +49,11 @@ int ima_setup(void) {
return 0;
}
+ if (access(IMA_POLICY_PATH, F_OK) < 0) {
+ log_debug("No IMA custom policy file "IMA_POLICY_PATH", ignoring.");
+ return 0;
+ }
+
imafd = open(IMA_SECFS_POLICY, O_WRONLY|O_CLOEXEC);
if (imafd < 0) {
log_error_errno(errno, "Failed to open the IMA kernel interface "IMA_SECFS_POLICY", ignoring: %m");
@@ -62,8 +67,7 @@ int ima_setup(void) {
/* fall back to copying the policy line-by-line */
input = fopen(IMA_POLICY_PATH, "re");
if (!input) {
- log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_WARNING, errno,
- "Failed to open the IMA custom policy file "IMA_POLICY_PATH", ignoring: %m");
+ log_warning_errno(errno, "Failed to open the IMA custom policy file "IMA_POLICY_PATH", ignoring: %m");
return 0;
}
diff --git a/src/core/job.c b/src/core/job.c
index 82c0ed80b4..8e2039d321 100644
--- a/src/core/job.c
+++ b/src/core/job.c
@@ -576,6 +576,7 @@ int job_run_and_invalidate(Job *j) {
if (!job_is_runnable(j))
return -EAGAIN;
+ job_start_timer(j, true);
job_set_state(j, JOB_RUNNING);
job_add_to_dbus_queue(j);
@@ -745,7 +746,7 @@ static void job_print_status_message(Unit *u, JobType t, JobResult result) {
if (t == JOB_START && result == JOB_FAILED) {
_cleanup_free_ char *quoted;
- quoted = shell_maybe_quote(u->id);
+ quoted = shell_maybe_quote(u->id, ESCAPE_BACKSLASH);
manager_status_printf(u->manager, STATUS_TYPE_NORMAL, NULL, "See 'systemctl status %s' for details.", strna(quoted));
}
}
@@ -804,18 +805,18 @@ static void job_log_status_message(Unit *u, JobType t, JobResult result) {
default:
log_struct(job_result_log_level[result],
- LOG_UNIT_ID(u),
LOG_MESSAGE("%s", buf),
"RESULT=%s", job_result_to_string(result),
+ LOG_UNIT_ID(u),
NULL);
return;
}
log_struct(job_result_log_level[result],
- mid,
- LOG_UNIT_ID(u),
LOG_MESSAGE("%s", buf),
"RESULT=%s", job_result_to_string(result),
+ LOG_UNIT_ID(u),
+ mid,
NULL);
}
@@ -953,22 +954,46 @@ static int job_dispatch_timer(sd_event_source *s, uint64_t monotonic, void *user
return 0;
}
-int job_start_timer(Job *j) {
+int job_start_timer(Job *j, bool job_running) {
int r;
+ usec_t timeout_time, old_timeout_time;
- if (j->timer_event_source)
- return 0;
+ if (job_running) {
+ j->begin_running_usec = now(CLOCK_MONOTONIC);
- j->begin_usec = now(CLOCK_MONOTONIC);
+ if (j->unit->job_running_timeout == USEC_INFINITY)
+ return 0;
- if (j->unit->job_timeout == USEC_INFINITY)
- return 0;
+ timeout_time = usec_add(j->begin_running_usec, j->unit->job_running_timeout);
+
+ if (j->timer_event_source) {
+ /* Update only if JobRunningTimeoutSec= results in earlier timeout */
+ r = sd_event_source_get_time(j->timer_event_source, &old_timeout_time);
+ if (r < 0)
+ return r;
+
+ if (old_timeout_time <= timeout_time)
+ return 0;
+
+ return sd_event_source_set_time(j->timer_event_source, timeout_time);
+ }
+ } else {
+ if (j->timer_event_source)
+ return 0;
+
+ j->begin_usec = now(CLOCK_MONOTONIC);
+
+ if (j->unit->job_timeout == USEC_INFINITY)
+ return 0;
+
+ timeout_time = usec_add(j->begin_usec, j->unit->job_timeout);
+ }
r = sd_event_add_time(
j->manager->event,
&j->timer_event_source,
CLOCK_MONOTONIC,
- usec_add(j->begin_usec, j->unit->job_timeout), 0,
+ timeout_time, 0,
job_dispatch_timer, j);
if (r < 0)
return r;
@@ -1031,6 +1056,8 @@ int job_serialize(Job *j, FILE *f) {
if (j->begin_usec > 0)
fprintf(f, "job-begin="USEC_FMT"\n", j->begin_usec);
+ if (j->begin_running_usec > 0)
+ fprintf(f, "job-begin-running="USEC_FMT"\n", j->begin_running_usec);
bus_track_serialize(j->bus_track, f, "subscribed");
@@ -1128,6 +1155,14 @@ int job_deserialize(Job *j, FILE *f) {
else
j->begin_usec = ull;
+ } else if (streq(l, "job-begin-running")) {
+ unsigned long long ull;
+
+ if (sscanf(v, "%llu", &ull) != 1)
+ log_debug("Failed to parse job-begin-running value %s", v);
+ else
+ j->begin_running_usec = ull;
+
} else if (streq(l, "subscribed")) {
if (strv_extend(&j->deserialized_clients, v) < 0)
@@ -1138,6 +1173,7 @@ int job_deserialize(Job *j, FILE *f) {
int job_coldplug(Job *j) {
int r;
+ usec_t timeout_time = USEC_INFINITY;
assert(j);
@@ -1151,7 +1187,18 @@ int job_coldplug(Job *j) {
/* Maybe due to new dependencies we don't actually need this job anymore? */
job_add_to_gc_queue(j);
- if (j->begin_usec == 0 || j->unit->job_timeout == USEC_INFINITY)
+ /* Create timer only when job began or began running and the respective timeout is finite.
+ * Follow logic of job_start_timer() if both timeouts are finite */
+ if (j->begin_usec == 0)
+ return 0;
+
+ if (j->unit->job_timeout != USEC_INFINITY)
+ timeout_time = usec_add(j->begin_usec, j->unit->job_timeout);
+
+ if (j->begin_running_usec > 0 && j->unit->job_running_timeout != USEC_INFINITY)
+ timeout_time = MIN(timeout_time, usec_add(j->begin_running_usec, j->unit->job_running_timeout));
+
+ if (timeout_time == USEC_INFINITY)
return 0;
j->timer_event_source = sd_event_source_unref(j->timer_event_source);
@@ -1160,7 +1207,7 @@ int job_coldplug(Job *j) {
j->manager->event,
&j->timer_event_source,
CLOCK_MONOTONIC,
- usec_add(j->begin_usec, j->unit->job_timeout), 0,
+ timeout_time, 0,
job_dispatch_timer, j);
if (r < 0)
log_debug_errno(r, "Failed to restart timeout for job: %m");
diff --git a/src/core/job.h b/src/core/job.h
index bea743f462..b17001889e 100644
--- a/src/core/job.h
+++ b/src/core/job.h
@@ -150,6 +150,7 @@ struct Job {
sd_event_source *timer_event_source;
usec_t begin_usec;
+ usec_t begin_running_usec;
/*
* This tracks where to send signals, and also which clients
@@ -220,7 +221,7 @@ int job_type_merge_and_collapse(JobType *a, JobType b, Unit *u);
void job_add_to_run_queue(Job *j);
void job_add_to_dbus_queue(Job *j);
-int job_start_timer(Job *j);
+int job_start_timer(Job *j, bool job_running);
int job_run_and_invalidate(Job *j);
int job_finish_and_invalidate(Job *j, JobResult result, bool recursive, bool already);
diff --git a/src/core/load-dropin.c b/src/core/load-dropin.c
index 3180f911bb..00f09ce60a 100644
--- a/src/core/load-dropin.c
+++ b/src/core/load-dropin.c
@@ -29,27 +29,27 @@
#include "unit-name.h"
#include "unit.h"
-static bool unit_name_compatible(const char *a, const char *b) {
+static int unit_name_compatible(const char *a, const char *b) {
_cleanup_free_ char *prefix = NULL;
int r;
/* the straightforward case: the symlink name matches the target */
if (streq(a, b))
- return true;
+ return 1;
r = unit_name_template(a, &prefix);
if (r == -EINVAL)
/* not a template */
- return false;
+ return 0;
if (r < 0)
/* oom, or some other failure. Just skip the warning. */
- return true;
+ return r;
/* an instance name points to a target that is just the template name */
if (streq(prefix, b))
- return true;
+ return 1;
- return false;
+ return 0;
}
static int process_deps(Unit *u, UnitDependency dependency, const char *dir_suffix) {
@@ -106,7 +106,12 @@ static int process_deps(Unit *u, UnitDependency dependency, const char *dir_suff
/* We don't treat this as an error, especially because we didn't check this for a
* long time. Nevertheless, we warn, because such mismatch can be mighty confusing. */
- if (!unit_name_compatible(entry, basename(target)))
+ r = unit_name_compatible(entry, basename(target));
+ if (r < 0) {
+ log_unit_warning_errno(u, r, "Can't check if names %s and %s are compatible, ignoring: %m", entry, basename(target));
+ continue;
+ }
+ if (r == 0)
log_unit_warning(u, "%s dependency dropin %s target %s has different name",
unit_dependency_to_string(dependency), *p, target);
diff --git a/src/core/load-fragment-gperf-nulstr.awk b/src/core/load-fragment-gperf-nulstr.awk
new file mode 100644
index 0000000000..b52438abe3
--- /dev/null
+++ b/src/core/load-fragment-gperf-nulstr.awk
@@ -0,0 +1,14 @@
+BEGIN{
+ keywords=0 ; FS="," ;
+ print "extern const char load_fragment_gperf_nulstr[];" ;
+ print "const char load_fragment_gperf_nulstr[] ="
+}
+keyword==1 {
+ print "\"" $$1 "\\0\""
+}
+/%%/ {
+ keyword=1
+}
+END {
+ print ";"
+}
diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
index 3f7cbaa0d0..7fb39cf948 100644
--- a/src/core/load-fragment-gperf.gperf.m4
+++ b/src/core/load-fragment-gperf.gperf.m4
@@ -18,8 +18,8 @@ struct ConfigPerfItem;
m4_dnl Define the context options only once
m4_define(`EXEC_CONTEXT_CONFIG_ITEMS',
`$1.WorkingDirectory, config_parse_working_directory, 0, offsetof($1, exec_context)
-$1.RootDirectory, config_parse_unit_path_printf, 0, offsetof($1, exec_context.root_directory)
-$1.RootImage, config_parse_unit_path_printf, 0, offsetof($1, exec_context.root_image)
+$1.RootDirectory, config_parse_unit_path_printf, true, offsetof($1, exec_context.root_directory)
+$1.RootImage, config_parse_unit_path_printf, true, offsetof($1, exec_context.root_image)
$1.User, config_parse_user_group, 0, offsetof($1, exec_context.user)
$1.Group, config_parse_user_group, 0, offsetof($1, exec_context.group)
$1.SupplementaryGroups, config_parse_user_group_strv, 0, offsetof($1, exec_context.supplementary_groups)
@@ -35,7 +35,7 @@ $1.UMask, config_parse_mode, 0,
$1.Environment, config_parse_environ, 0, offsetof($1, exec_context.environment)
$1.EnvironmentFile, config_parse_unit_env_file, 0, offsetof($1, exec_context.environment_files)
$1.PassEnvironment, config_parse_pass_environ, 0, offsetof($1, exec_context.pass_environment)
-$1.DynamicUser, config_parse_bool, 0, offsetof($1, exec_context.dynamic_user)
+$1.DynamicUser, config_parse_bool, true, offsetof($1, exec_context.dynamic_user)
$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)
@@ -194,6 +194,7 @@ Unit.OnFailureIsolate, config_parse_job_mode_isolate, 0,
Unit.IgnoreOnIsolate, config_parse_bool, 0, offsetof(Unit, ignore_on_isolate)
Unit.IgnoreOnSnapshot, config_parse_warn_compat, DISABLED_LEGACY, 0
Unit.JobTimeoutSec, config_parse_sec_fix_0, 0, offsetof(Unit, job_timeout)
+Unit.JobRunningTimeoutSec, config_parse_sec_fix_0, 0, offsetof(Unit, job_running_timeout)
Unit.JobTimeoutAction, config_parse_emergency_action, 0, offsetof(Unit, job_timeout_action)
Unit.JobTimeoutRebootArgument, config_parse_unit_string_printf, 0, offsetof(Unit, job_timeout_reboot_arg)
Unit.StartLimitIntervalSec, config_parse_sec, 0, offsetof(Unit, start_limit.interval)
@@ -220,6 +221,8 @@ Unit.ConditionSecurity, config_parse_unit_condition_string, CONDITION_S
Unit.ConditionCapability, config_parse_unit_condition_string, CONDITION_CAPABILITY, offsetof(Unit, conditions)
Unit.ConditionHost, config_parse_unit_condition_string, CONDITION_HOST, offsetof(Unit, conditions)
Unit.ConditionACPower, config_parse_unit_condition_string, CONDITION_AC_POWER, offsetof(Unit, conditions)
+Unit.ConditionUser, config_parse_unit_condition_string, CONDITION_USER, offsetof(Unit, conditions)
+Unit.ConditionGroup, config_parse_unit_condition_string, CONDITION_GROUP, offsetof(Unit, conditions)
Unit.ConditionNull, config_parse_unit_condition_null, 0, offsetof(Unit, conditions)
Unit.AssertPathExists, config_parse_unit_condition_path, CONDITION_PATH_EXISTS, offsetof(Unit, asserts)
Unit.AssertPathExistsGlob, config_parse_unit_condition_path, CONDITION_PATH_EXISTS_GLOB, offsetof(Unit, asserts)
@@ -239,6 +242,8 @@ Unit.AssertSecurity, config_parse_unit_condition_string, CONDITION_S
Unit.AssertCapability, config_parse_unit_condition_string, CONDITION_CAPABILITY, offsetof(Unit, asserts)
Unit.AssertHost, config_parse_unit_condition_string, CONDITION_HOST, offsetof(Unit, asserts)
Unit.AssertACPower, config_parse_unit_condition_string, CONDITION_AC_POWER, offsetof(Unit, asserts)
+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)
m4_dnl
Service.PIDFile, config_parse_unit_path_printf, 0, offsetof(Service, pid_file)
diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
index 5b7471c0d0..9d5c39b3dd 100644
--- a/src/core/load-fragment.c
+++ b/src/core/load-fragment.c
@@ -242,6 +242,7 @@ int config_parse_unit_path_printf(
_cleanup_free_ char *k = NULL;
Unit *u = userdata;
int r;
+ bool fatal = ltype;
assert(filename);
assert(lvalue);
@@ -250,8 +251,10 @@ int config_parse_unit_path_printf(
r = unit_full_printf(u, rvalue, &k);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers on %s, ignoring: %m", rvalue);
- return 0;
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "Failed to resolve unit specifiers on %s%s: %m",
+ fatal ? "" : ", ignoring", rvalue);
+ return fatal ? -ENOEXEC : 0;
}
return config_parse_path(unit, filename, line, section, section_line, lvalue, ltype, k, data, userdata);
@@ -392,7 +395,9 @@ int config_parse_socket_listen(const char *unit,
r = socket_address_parse_and_warn(&p->address, k);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse address value, ignoring: %s", rvalue);
+ if (r != -EAFNOSUPPORT)
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse address value, ignoring: %s", rvalue);
+
return 0;
}
@@ -634,26 +639,36 @@ int config_parse_exec(
r = unit_full_printf(u, f, &path);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers on %s, ignoring: %m", f);
- return 0;
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "Failed to resolve unit specifiers on %s%s: %m",
+ f, ignore ? ", ignoring" : "");
+ return ignore ? 0 : -ENOEXEC;
}
if (isempty(path)) {
/* First word is either "-" or "@" with no command. */
- log_syntax(unit, LOG_ERR, filename, line, 0, "Empty path in command line, ignoring: \"%s\"", rvalue);
- return 0;
+ log_syntax(unit, LOG_ERR, filename, line, 0,
+ "Empty path in command line%s: \"%s\"",
+ ignore ? ", ignoring" : "", rvalue);
+ return ignore ? 0 : -ENOEXEC;
}
if (!string_is_safe(path)) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Executable path contains special characters, ignoring: %s", rvalue);
- return 0;
+ log_syntax(unit, LOG_ERR, filename, line, 0,
+ "Executable path contains special characters%s: %s",
+ ignore ? ", ignoring" : "", rvalue);
+ return ignore ? 0 : -ENOEXEC;
}
if (!path_is_absolute(path)) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Executable path is not absolute, ignoring: %s", rvalue);
- return 0;
+ log_syntax(unit, LOG_ERR, filename, line, 0,
+ "Executable path is not absolute%s: %s",
+ ignore ? ", ignoring" : "", rvalue);
+ return ignore ? 0 : -ENOEXEC;
}
if (endswith(path, "/")) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Executable path specifies a directory, ignoring: %s", rvalue);
- return 0;
+ log_syntax(unit, LOG_ERR, filename, line, 0,
+ "Executable path specifies a directory%s: %s",
+ ignore ? ", ignoring" : "", rvalue);
+ return ignore ? 0 : -ENOEXEC;
}
if (!separate_argv0) {
@@ -706,12 +721,14 @@ int config_parse_exec(
if (r == 0)
break;
if (r < 0)
- return 0;
+ return ignore ? 0 : -ENOEXEC;
r = unit_full_printf(u, word, &resolved);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to resolve unit specifiers on %s, ignoring: %m", word);
- return 0;
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "Failed to resolve unit specifiers on %s%s: %m",
+ word, ignore ? ", ignoring" : "");
+ return ignore ? 0 : -ENOEXEC;
}
if (!GREEDY_REALLOC(n, nbufsize, nlen + 2))
@@ -722,8 +739,10 @@ int config_parse_exec(
}
if (!n || !n[0]) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Empty executable name or zeroeth argument, ignoring: %s", rvalue);
- return 0;
+ log_syntax(unit, LOG_ERR, filename, line, 0,
+ "Empty executable name or zeroeth argument%s: %s",
+ ignore ? ", ignoring" : "", rvalue);
+ return ignore ? 0 : -ENOEXEC;
}
nce = new0(ExecCommand, 1);
@@ -938,8 +957,8 @@ int config_parse_exec_io_priority(const char *unit,
assert(rvalue);
assert(data);
- r = safe_atoi(rvalue, &i);
- if (r < 0 || i < 0 || i >= IOPRIO_BE_NR) {
+ r = ioprio_parse_priority(rvalue, &i);
+ if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse IO priority, ignoring: %s", rvalue);
return 0;
}
@@ -1330,8 +1349,10 @@ int config_parse_exec_selinux_context(
r = unit_full_printf(u, rvalue, &k);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers, ignoring: %m");
- return 0;
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "Failed to resolve specifiers%s: %m",
+ ignore ? ", ignoring" : "");
+ return ignore ? 0 : -ENOEXEC;
}
free(c->selinux_context);
@@ -1378,8 +1399,10 @@ int config_parse_exec_apparmor_profile(
r = unit_full_printf(u, rvalue, &k);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers, ignoring: %m");
- return 0;
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "Failed to resolve specifiers%s: %m",
+ ignore ? ", ignoring" : "");
+ return ignore ? 0 : -ENOEXEC;
}
free(c->apparmor_profile);
@@ -1426,8 +1449,10 @@ int config_parse_exec_smack_process_label(
r = unit_full_printf(u, rvalue, &k);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers, ignoring: %m");
- return 0;
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "Failed to resolve specifiers%s: %m",
+ ignore ? ", ignoring" : "");
+ return ignore ? 0 : -ENOEXEC;
}
free(c->smack_process_label);
@@ -1645,19 +1670,19 @@ int config_parse_socket_service(
r = unit_name_printf(UNIT(s), rvalue, &p);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers, ignoring: %s", rvalue);
- return 0;
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers: %s", rvalue);
+ return -ENOEXEC;
}
if (!endswith(p, ".service")) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Unit must be of type service, ignoring: %s", rvalue);
- return 0;
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Unit must be of type service: %s", rvalue);
+ return -ENOEXEC;
}
r = manager_load_unit(UNIT(s)->manager, p, NULL, &error, &x);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Failed to load unit %s, ignoring: %s", rvalue, bus_error_message(&error, r));
- return 0;
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to load unit %s: %s", rvalue, bus_error_message(&error, r));
+ return -ENOEXEC;
}
unit_ref_set(&s->service, x);
@@ -1868,15 +1893,12 @@ int config_parse_sec_fix_0(
* compatibility with older versions of systemd where 0 instead of infinity was used as indicator to turn off a
* timeout. */
- r = parse_sec(rvalue, usec);
+ r = parse_sec_fix_0(rvalue, usec);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse %s= parameter, ignoring: %s", lvalue, rvalue);
return 0;
}
- if (*usec <= 0)
- *usec = USEC_INFINITY;
-
return 0;
}
@@ -1908,13 +1930,13 @@ int config_parse_user_group(
r = unit_full_printf(u, rvalue, &k);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in %s, ignoring: %m", rvalue);
- return 0;
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in %s: %m", rvalue);
+ return -ENOEXEC;
}
if (!valid_user_group_name_or_id(k)) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid user/group name or numeric ID, ignoring: %s", k);
- return 0;
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid user/group name or numeric ID: %s", k);
+ return -ENOEXEC;
}
n = k;
@@ -1972,19 +1994,19 @@ int config_parse_user_group_strv(
if (r == -ENOMEM)
return log_oom();
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Invalid syntax, ignoring: %s", rvalue);
- break;
+ log_syntax(unit, LOG_ERR, filename, line, r, "Invalid syntax: %s", rvalue);
+ return -ENOEXEC;
}
r = unit_full_printf(u, word, &k);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in %s, ignoring: %m", word);
- continue;
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in %s: %m", word);
+ return -ENOEXEC;
}
if (!valid_user_group_name_or_id(k)) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid user/group name or numeric ID, ignoring: %s", k);
- continue;
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid user/group name or numeric ID: %s", k);
+ return -ENOEXEC;
}
r = strv_push(users, k);
@@ -2143,25 +2165,28 @@ int config_parse_working_directory(
r = unit_full_printf(u, rvalue, &k);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in working directory path '%s', ignoring: %m", rvalue);
- return 0;
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "Failed to resolve unit specifiers in working directory path '%s'%s: %m",
+ rvalue, missing_ok ? ", ignoring" : "");
+ return missing_ok ? 0 : -ENOEXEC;
}
path_kill_slashes(k);
if (!utf8_is_valid(k)) {
log_syntax_invalid_utf8(unit, LOG_ERR, filename, line, rvalue);
- return 0;
+ return missing_ok ? 0 : -ENOEXEC;
}
if (!path_is_absolute(k)) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Working directory path '%s' is not absolute, ignoring.", rvalue);
- return 0;
+ log_syntax(unit, LOG_ERR, filename, line, 0,
+ "Working directory path '%s' is not absolute%s.",
+ rvalue, missing_ok ? ", ignoring" : "");
+ return missing_ok ? 0 : -ENOEXEC;
}
- free_and_replace(c->working_directory, k);
-
c->working_directory_home = false;
+ free_and_replace(c->working_directory, k);
}
c->working_directory_missing_ok = missing_ok;
@@ -3907,6 +3932,7 @@ int config_parse_bind_paths(
void *userdata) {
ExecContext *c = data;
+ Unit *u = userdata;
const char *p;
int r;
@@ -3926,6 +3952,7 @@ int config_parse_bind_paths(
p = rvalue;
for (;;) {
_cleanup_free_ char *source = NULL, *destination = NULL;
+ _cleanup_free_ char *sresolved = NULL, *dresolved = NULL;
char *s = NULL, *d = NULL;
bool rbind = true, ignore_enoent = false;
@@ -3939,7 +3966,14 @@ int config_parse_bind_paths(
return 0;
}
- s = source;
+ r = unit_full_printf(u, source, &sresolved);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "Failed to resolved specifiers in \"%s\", ignoring: %m", source);
+ return 0;
+ }
+
+ s = sresolved;
if (s[0] == '-') {
ignore_enoent = true;
s++;
@@ -3970,16 +4004,23 @@ int config_parse_bind_paths(
return 0;
}
- if (!utf8_is_valid(destination)) {
- log_syntax_invalid_utf8(unit, LOG_ERR, filename, line, destination);
+ r = unit_full_printf(u, destination, &dresolved);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "Failed to resolved specifiers in \"%s\", ignoring: %m", destination);
+ return 0;
+ }
+
+ if (!utf8_is_valid(dresolved)) {
+ log_syntax_invalid_utf8(unit, LOG_ERR, filename, line, dresolved);
return 0;
}
- if (!path_is_absolute(destination)) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Not an absolute destination path, ignoring: %s", destination);
+ if (!path_is_absolute(dresolved)) {
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Not an absolute destination path, ignoring: %s", dresolved);
return 0;
}
- d = path_kill_slashes(destination);
+ d = path_kill_slashes(dresolved);
/* Optionally, there's also a short option string specified */
if (p && p[-1] == ':') {
@@ -4441,8 +4482,11 @@ int unit_load_fragment(Unit *u) {
return r;
r = load_from_path(u, k);
- if (r < 0)
+ if (r < 0) {
+ if (r == -ENOEXEC)
+ log_unit_notice(u, "Unit configuration has fatal error, unit will not be started.");
return r;
+ }
if (u->load_state == UNIT_STUB) {
SET_FOREACH(t, u->names, i) {
diff --git a/src/core/loopback-setup.c b/src/core/loopback-setup.c
index 04062a7910..c167305ca9 100644
--- a/src/core/loopback-setup.c
+++ b/src/core/loopback-setup.c
@@ -26,10 +26,36 @@
#include "missing.h"
#include "netlink-util.h"
-static int start_loopback(sd_netlink *rtnl) {
+#define LOOPBACK_SETUP_TIMEOUT_USEC (5 * USEC_PER_SEC)
+
+struct state {
+ unsigned n_messages;
+ int rcode;
+ const char *title;
+};
+
+static int generic_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
+ struct state *s = userdata;
+
+ assert(s);
+ assert(s->n_messages > 0);
+ s->n_messages--;
+
+ errno = 0;
+ log_debug_errno(sd_netlink_message_get_errno(m), "Failed to %s: %m", s->title);
+
+ s->rcode = sd_netlink_message_get_errno(m);
+
+ return 0;
+}
+
+static int start_loopback(sd_netlink *rtnl, struct state *s) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
int r;
+ assert(rtnl);
+ assert(s);
+
r = sd_rtnl_message_new_link(rtnl, &req, RTM_SETLINK, LOOPBACK_IFINDEX);
if (r < 0)
return r;
@@ -38,10 +64,81 @@ static int start_loopback(sd_netlink *rtnl) {
if (r < 0)
return r;
- r = sd_netlink_call(rtnl, req, 0, NULL);
+ r = sd_netlink_call_async(rtnl, req, generic_handler, s, LOOPBACK_SETUP_TIMEOUT_USEC, NULL);
+ if (r < 0)
+ return r;
+
+ s->n_messages ++;
+ return 0;
+}
+
+static int add_ipv4_address(sd_netlink *rtnl, struct state *s) {
+ _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
+ int r;
+
+ assert(rtnl);
+ assert(s);
+
+ r = sd_rtnl_message_new_addr(rtnl, &req, RTM_NEWADDR, LOOPBACK_IFINDEX, AF_INET);
+ if (r < 0)
+ return r;
+
+ r = sd_rtnl_message_addr_set_prefixlen(req, 8);
+ if (r < 0)
+ return r;
+
+ r = sd_rtnl_message_addr_set_flags(req, IFA_F_PERMANENT);
+ if (r < 0)
+ return r;
+
+ r = sd_rtnl_message_addr_set_scope(req, RT_SCOPE_HOST);
+ if (r < 0)
+ return r;
+
+ r = sd_netlink_message_append_in_addr(req, IFA_LOCAL, &(struct in_addr) { .s_addr = htobe32(INADDR_LOOPBACK) } );
+ if (r < 0)
+ return r;
+
+ r = sd_netlink_call_async(rtnl, req, generic_handler, s, USEC_INFINITY, NULL);
if (r < 0)
return r;
+ s->n_messages ++;
+ return 0;
+}
+
+static int add_ipv6_address(sd_netlink *rtnl, struct state *s) {
+ _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
+ int r;
+
+ assert(rtnl);
+ assert(s);
+
+ r = sd_rtnl_message_new_addr(rtnl, &req, RTM_NEWADDR, LOOPBACK_IFINDEX, AF_INET6);
+ if (r < 0)
+ return r;
+
+ r = sd_rtnl_message_addr_set_prefixlen(req, 128);
+ if (r < 0)
+ return r;
+
+ r = sd_rtnl_message_addr_set_flags(req, IFA_F_PERMANENT);
+ if (r < 0)
+ return r;
+
+ r = sd_rtnl_message_addr_set_scope(req, RT_SCOPE_HOST);
+ if (r < 0)
+ return r;
+
+ r = sd_netlink_message_append_in6_addr(req, IFA_LOCAL, &in6addr_loopback);
+ if (r < 0)
+ return r;
+
+ r = sd_netlink_call_async(rtnl, req, generic_handler, s, USEC_INFINITY, NULL);
+ if (r < 0)
+ return r;
+
+ s->n_messages ++;
return 0;
}
@@ -54,7 +151,7 @@ static bool check_loopback(sd_netlink *rtnl) {
if (r < 0)
return false;
- r = sd_netlink_call(rtnl, req, 0, &reply);
+ r = sd_netlink_call(rtnl, req, USEC_INFINITY, &reply);
if (r < 0)
return false;
@@ -67,23 +164,52 @@ static bool check_loopback(sd_netlink *rtnl) {
int loopback_setup(void) {
_cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
+ struct state state_4 = { .title = "add address 127.0.0.1 to loopback interface" },
+ state_6 = { .title = "add address ::1 to loopback interface"},
+ state_up = { .title = "bring loopback interface up" };
int r;
r = sd_netlink_open(&rtnl);
if (r < 0)
- return r;
+ return log_error_errno(r, "Failed to open netlink: %m");
+
+ /* Note that we add the IP addresses here explicitly even though the kernel does that too implicitly when
+ * setting up the loopback device. The reason we do this here a second time (and possibly race against the
+ * kernel) is that we want to synchronously wait until the IP addresses are set up correctly, see
+ *
+ * https://github.com/systemd/systemd/issues/5641 */
- r = start_loopback(rtnl);
- if (r < 0) {
+ r = add_ipv4_address(rtnl, &state_4);
+ if (r < 0)
+ return log_error_errno(r, "Failed to enqueue IPv4 loopback address add request: %m");
+
+ r = add_ipv6_address(rtnl, &state_6);
+ if (r < 0)
+ return log_error_errno(r, "Failed to enqueue IPv6 loopback address add request: %m");
+
+ r = start_loopback(rtnl, &state_up);
+ if (r < 0)
+ return log_error_errno(r, "Failed to enqueue loopback interface start request: %m");
+
+ while (state_4.n_messages + state_6.n_messages + state_up.n_messages > 0) {
+ r = sd_netlink_wait(rtnl, LOOPBACK_SETUP_TIMEOUT_USEC);
+ if (r < 0)
+ return log_error_errno(r, "Failed to wait for netlink event: %m");
+
+ r = sd_netlink_process(rtnl, NULL);
+ if (r < 0)
+ return log_warning_errno(r, "Failed to process netlink event: %m");
+ }
- /* If we lack the permissions to configure the
- * loopback device, but we find it to be already
- * configured, let's exit cleanly, in order to
- * supported unprivileged containers. */
- if (r == -EPERM && check_loopback(rtnl))
+ /* Note that we don't really care whether the addresses could be added or not */
+ if (state_up.rcode != 0) {
+ /* If we lack the permissions to configure the loopback device,
+ * but we find it to be already configured, let's exit cleanly,
+ * in order to supported unprivileged containers. */
+ if (state_up.rcode == -EPERM && check_loopback(rtnl))
return 0;
- return log_warning_errno(r, "Failed to configure loopback device: %m");
+ return log_warning_errno(state_up.rcode, "Failed to configure loopback device: %m");
}
return 0;
diff --git a/src/core/main.c b/src/core/main.c
index b660938271..0eadaed0d9 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -154,7 +154,7 @@ noreturn static void crash(int sig) {
struct sigaction sa;
pid_t pid;
- if (getpid() != 1)
+ if (getpid_cached() != 1)
/* Pass this on immediately, if this is not PID 1 */
(void) raise(sig);
else if (!arg_dump_core)
@@ -536,7 +536,7 @@ static int config_parse_cpu_affinity2(
return ncpus;
if (sched_setaffinity(0, CPU_ALLOC_SIZE(ncpus), c) < 0)
- log_warning("Failed to set CPU affinity: %m");
+ log_warning_errno(errno, "Failed to set CPU affinity: %m");
return 0;
}
@@ -860,7 +860,7 @@ static int parse_argv(int argc, char *argv[]) {
assert(argc >= 1);
assert(argv);
- if (getpid() == 1)
+ if (getpid_cached() == 1)
opterr = 0;
while ((c = getopt_long(argc, argv, "hDbsz:", options, NULL)) >= 0)
@@ -1066,7 +1066,7 @@ static int parse_argv(int argc, char *argv[]) {
* parse_proc_cmdline_word() or ignore. */
case '?':
- if (getpid() != 1)
+ if (getpid_cached() != 1)
return -EINVAL;
else
return 0;
@@ -1075,7 +1075,7 @@ static int parse_argv(int argc, char *argv[]) {
assert_not_reached("Unhandled option code.");
}
- if (optind < argc && getpid() != 1) {
+ if (optind < argc && getpid_cached() != 1) {
/* Hmm, when we aren't run as init system
* let's complain about excess arguments */
@@ -1091,6 +1091,7 @@ static int help(void) {
printf("%s [OPTIONS...]\n\n"
"Starts up and maintains the system or user services.\n\n"
" -h --help Show this help\n"
+ " --version Show version\n"
" --test Determine startup sequence, dump it and exit\n"
" --no-pager Do not pipe output into a pager\n"
" --dump-configuration-items Dump understood unit configuration items\n"
@@ -1162,6 +1163,8 @@ static int prepare_reexecute(Manager *m, FILE **_f, FDSet **_fds, bool switching
static int bump_rlimit_nofile(struct rlimit *saved_rlimit) {
struct rlimit nl;
int r;
+ int min_max;
+ _cleanup_free_ char *nr_open = NULL;
assert(saved_rlimit);
@@ -1182,8 +1185,16 @@ static int bump_rlimit_nofile(struct rlimit *saved_rlimit) {
arg_default_rlimit[RLIMIT_NOFILE] = rl;
}
+ /* Get current RLIMIT_NOFILE maximum compiled into the kernel. */
+ r = read_one_line_file("/proc/sys/fs/nr_open", &nr_open);
+ 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)
+ min_max = 1024 * 1024;
+
/* Bump up the resource limit for ourselves substantially */
- nl.rlim_cur = nl.rlim_max = 64*1024;
+ nl.rlim_cur = nl.rlim_max = min_max;
r = setrlimit_closest(RLIMIT_NOFILE, &nl);
if (r < 0)
return log_warning_errno(r, "Setting RLIMIT_NOFILE failed, ignoring: %m");
@@ -1378,7 +1389,7 @@ int main(int argc, char *argv[]) {
const char *error_message = NULL;
#ifdef HAVE_SYSV_COMPAT
- if (getpid() != 1 && strstr(program_invocation_short_name, "init")) {
+ 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. */
@@ -1414,7 +1425,7 @@ int main(int argc, char *argv[]) {
log_set_upgrade_syslog_to_journal(true);
- if (getpid() == 1) {
+ if (getpid_cached() == 1) {
/* Disable the umask logic */
umask(0);
@@ -1425,7 +1436,7 @@ int main(int argc, char *argv[]) {
log_set_always_reopen_console(true);
}
- if (getpid() == 1 && detect_container() <= 0) {
+ if (getpid_cached() == 1 && detect_container() <= 0) {
/* Running outside of a container as PID 1 */
arg_system = true;
@@ -1510,7 +1521,7 @@ int main(int argc, char *argv[]) {
* might redirect output elsewhere. */
log_set_target(LOG_TARGET_JOURNAL_OR_KMSG);
- } else if (getpid() == 1) {
+ } else if (getpid_cached() == 1) {
/* Running inside a container, as PID 1 */
arg_system = true;
log_set_target(LOG_TARGET_CONSOLE);
@@ -1534,7 +1545,7 @@ int main(int argc, char *argv[]) {
kernel_timestamp = DUAL_TIMESTAMP_NULL;
}
- if (getpid() == 1) {
+ 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)
@@ -1569,7 +1580,7 @@ int main(int argc, char *argv[]) {
/* Mount /proc, /sys and friends, so that /proc/cmdline and
* /proc/$PID/fd is available. */
- if (getpid() == 1) {
+ if (getpid_cached() == 1) {
/* Load the kernel modules early, so that we kdbus.ko is loaded before kdbusfs shall be mounted */
if (!skip_setup)
@@ -1695,7 +1706,7 @@ int main(int argc, char *argv[]) {
* tty. */
release_terminal();
- if (getpid() == 1 && !skip_setup)
+ if (getpid_cached() == 1 && !skip_setup)
console_setup();
}
@@ -1707,7 +1718,7 @@ int main(int argc, char *argv[]) {
/* Make sure we leave a core dump without panicing the
* kernel. */
- if (getpid() == 1) {
+ if (getpid_cached() == 1) {
install_crash_handler();
r = mount_cgroup_controllers(arg_join_controllers);
@@ -1770,7 +1781,7 @@ int main(int argc, char *argv[]) {
if (prctl(PR_SET_TIMERSLACK, arg_timer_slack_nsec) < 0)
log_error_errno(errno, "Failed to adjust timer slack: %m");
- if (!cap_test_all(arg_capability_bounding_set)) {
+ 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");
@@ -2141,7 +2152,7 @@ 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() == 1 && RUNNING_ON_VALGRIND)
+ if (getpid_cached() == 1 && RUNNING_ON_VALGRIND)
return 0;
#endif
@@ -2217,10 +2228,10 @@ finish:
execve(SYSTEMD_SHUTDOWN_BINARY_PATH, (char **) command_line, env_block);
log_error_errno(errno, "Failed to execute shutdown binary, %s: %m",
- getpid() == 1 ? "freezing" : "quitting");
+ getpid_cached() == 1 ? "freezing" : "quitting");
}
- if (getpid() == 1) {
+ if (getpid_cached() == 1) {
if (error_message)
manager_status_printf(NULL, STATUS_TYPE_EMERGENCY,
ANSI_HIGHLIGHT_RED "!!!!!!" ANSI_NORMAL,
diff --git a/src/core/manager.c b/src/core/manager.c
index cff38e28de..283720750f 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -2319,7 +2319,10 @@ int manager_load_unit_from_dbus_path(Manager *m, const char *s, sd_bus_error *e,
return sd_bus_error_setf(e, BUS_ERROR_NO_UNIT_FOR_INVOCATION_ID, "No unit with the specified invocation ID " SD_ID128_FORMAT_STR " known.", SD_ID128_FORMAT_VAL(invocation_id));
}
- /* If this didn't work, we use the suffix as unit name. */
+ /* If this didn't work, we check if this is a unit name */
+ if (!unit_name_is_valid(n, UNIT_NAME_PLAIN|UNIT_NAME_INSTANCE))
+ return sd_bus_error_setf(e, SD_BUS_ERROR_INVALID_ARGS, "Unit name %s is neither a valid invocation ID nor unit name.", n);
+
r = manager_load_unit(m, n, NULL, e, &u);
if (r < 0)
return r;
@@ -2585,8 +2588,8 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
m->n_reloading++;
for (;;) {
- char line[LINE_MAX], *l;
- const char *val;
+ char line[LINE_MAX];
+ const char *val, *l;
if (!fgets(line, sizeof(line), f)) {
if (feof(f))
@@ -2607,7 +2610,7 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
uint32_t id;
if (safe_atou32(val, &id) < 0)
- log_debug("Failed to parse current job id value %s", val);
+ log_notice("Failed to parse current job id value %s", val);
else
m->current_job_id = MAX(m->current_job_id, id);
@@ -2615,7 +2618,7 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
uint32_t n;
if (safe_atou32(val, &n) < 0)
- log_debug("Failed to parse installed jobs counter %s", val);
+ log_notice("Failed to parse installed jobs counter %s", val);
else
m->n_installed_jobs += n;
@@ -2623,7 +2626,7 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
uint32_t n;
if (safe_atou32(val, &n) < 0)
- log_debug("Failed to parse failed jobs counter %s", val);
+ log_notice("Failed to parse failed jobs counter %s", val);
else
m->n_failed_jobs += n;
@@ -2632,7 +2635,7 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
b = parse_boolean(val);
if (b < 0)
- log_debug("Failed to parse taint /usr flag %s", val);
+ log_notice("Failed to parse taint /usr flag %s", val);
else
m->taint_usr = m->taint_usr || b;
@@ -2662,14 +2665,16 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
dual_timestamp_deserialize(val, &m->units_load_finish_timestamp);
else if (startswith(l, "env=")) {
r = deserialize_environment(&m->environment, l);
+ if (r == -ENOMEM)
+ goto finish;
if (r < 0)
- return r;
+ log_notice_errno(r, "Failed to parse environment entry: \"%s\": %m", l);
} else if ((val = startswith(l, "notify-fd="))) {
int fd;
if (safe_atoi(val, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
- log_debug("Failed to parse notify fd: %s", val);
+ log_notice("Failed to parse notify fd: \"%s\"", val);
else {
m->notify_event_source = sd_event_source_unref(m->notify_event_source);
safe_close(m->notify_fd);
@@ -2692,7 +2697,7 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
int fd;
if (safe_atoi(val, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
- log_debug("Failed to parse cgroups agent fd: %s", val);
+ log_notice("Failed to parse cgroups agent fd: %s", val);
else {
m->cgroups_agent_event_source = sd_event_source_unref(m->cgroups_agent_event_source);
safe_close(m->cgroups_agent_fd);
@@ -2703,7 +2708,7 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
int fd0, fd1;
if (sscanf(val, "%i %i", &fd0, &fd1) != 2 || fd0 < 0 || fd1 < 0 || fd0 == fd1 || !fdset_contains(fds, fd0) || !fdset_contains(fds, fd1))
- log_debug("Failed to parse user lookup fd: %s", val);
+ log_notice("Failed to parse user lookup fd: %s", val);
else {
m->user_lookup_event_source = sd_event_source_unref(m->user_lookup_event_source);
safe_close_pair(m->user_lookup_fds);
@@ -2723,7 +2728,7 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
log_oom();
} else if (!startswith(l, "kdbus-fd=")) /* ignore this one */
- log_debug("Unknown serialization item '%s'", l);
+ log_notice("Unknown serialization item '%s'", l);
}
for (;;) {
diff --git a/src/core/meson.build b/src/core/meson.build
new file mode 100644
index 0000000000..fb8f9dc36b
--- /dev/null
+++ b/src/core/meson.build
@@ -0,0 +1,235 @@
+libcore_la_sources = '''
+ unit.c
+ unit.h
+ unit-printf.c
+ unit-printf.h
+ job.c
+ job.h
+ manager.c
+ manager.h
+ transaction.c
+ transaction.h
+ load-fragment.c
+ load-fragment.h
+ service.c
+ service.h
+ socket.c
+ socket.h
+ busname.c
+ busname.h
+ bus-policy.c
+ bus-policy.h
+ target.c
+ target.h
+ device.c
+ device.h
+ mount.c
+ mount.h
+ automount.c
+ automount.h
+ swap.c
+ swap.h
+ timer.c
+ timer.h
+ path.c
+ path.h
+ slice.c
+ slice.h
+ scope.c
+ scope.h
+ load-dropin.c
+ load-dropin.h
+ execute.c
+ execute.h
+ dynamic-user.c
+ dynamic-user.h
+ kill.c
+ kill.h
+ dbus.c
+ dbus.h
+ dbus-manager.c
+ dbus-manager.h
+ dbus-unit.c
+ dbus-unit.h
+ dbus-job.c
+ dbus-job.h
+ dbus-service.c
+ dbus-service.h
+ dbus-socket.c
+ dbus-socket.h
+ dbus-busname.c
+ dbus-busname.h
+ dbus-target.c
+ dbus-target.h
+ dbus-device.c
+ dbus-device.h
+ dbus-mount.c
+ dbus-mount.h
+ dbus-automount.c
+ dbus-automount.h
+ dbus-swap.c
+ dbus-swap.h
+ dbus-timer.c
+ dbus-timer.h
+ dbus-path.c
+ dbus-path.h
+ dbus-slice.c
+ dbus-slice.h
+ dbus-scope.c
+ dbus-scope.h
+ dbus-execute.c
+ dbus-execute.h
+ dbus-kill.c
+ dbus-kill.h
+ dbus-cgroup.c
+ dbus-cgroup.h
+ cgroup.c
+ cgroup.h
+ selinux-access.c
+ selinux-access.h
+ selinux-setup.c
+ selinux-setup.h
+ smack-setup.c
+ smack-setup.h
+ ima-setup.c
+ ima-setup.h
+ locale-setup.h
+ locale-setup.c
+ hostname-setup.c
+ hostname-setup.h
+ machine-id-setup.c
+ machine-id-setup.h
+ mount-setup.c
+ mount-setup.h
+ kmod-setup.c
+ kmod-setup.h
+ loopback-setup.h
+ loopback-setup.c
+ namespace.c
+ namespace.h
+ killall.h
+ killall.c
+ audit-fd.c
+ audit-fd.h
+ show-status.c
+ show-status.h
+ emergency-action.c
+ emergency-action.h
+'''.split()
+
+load_fragment_gperf_gperf = custom_target(
+ 'load-fragment-gperf.gperf',
+ input : 'load-fragment-gperf.gperf.m4',
+ output: 'load-fragment-gperf.gperf',
+ command : [m4, '-P'] + m4_defines + ['@INPUT@'],
+ capture : true)
+
+load_fragment_gperf_c = custom_target(
+ 'load-fragment-gperf.c',
+ input : load_fragment_gperf_gperf,
+ output : 'load-fragment-gperf.c',
+ command : [gperf, '@INPUT@', '--output-file', '@OUTPUT@'])
+
+awkscript = 'load-fragment-gperf-nulstr.awk'
+load_fragment_gperf_nulstr_c = custom_target(
+ 'load-fragment-gperf-nulstr.c',
+ input : [awkscript, load_fragment_gperf_gperf],
+ output : 'load-fragment-gperf-nulstr.c',
+ command : [awk, '-f', '@INPUT0@', '@INPUT1@'],
+ capture : true)
+
+libcore = static_library(
+ 'core',
+ libcore_la_sources,
+ load_fragment_gperf_c,
+ load_fragment_gperf_nulstr_c,
+ include_directories : includes,
+ link_with : [libshared_static],
+ dependencies : [threads,
+ libseccomp,
+ libpam,
+ libaudit,
+ libkmod,
+ libapparmor,
+ libmount])
+
+systemd_sources = files('main.c')
+
+systemd_shutdown_sources = files('''
+ shutdown.c
+ umount.c
+ umount.h
+ mount-setup.c
+ mount-setup.h
+ killall.c
+ killall.h
+'''.split())
+
+in_files = [['macros.systemd', rpmmacrosdir],
+ ['triggers.systemd', ''],
+ ['systemd.pc', pkgconfigdatadir]]
+
+foreach item : in_files
+ file = item[0]
+ dir = item[1]
+
+ # If 'no', disable generation completely.
+ # If '', generate, but do not install.
+ if dir != 'no'
+ gen = configure_file(
+ input : file + '.in',
+ output : file,
+ configuration : substs)
+ if dir != ''
+ install_data(gen,
+ install_dir : dir)
+ endif
+ endif
+endforeach
+
+install_data('org.freedesktop.systemd1.conf',
+ install_dir : dbuspolicydir)
+install_data('org.freedesktop.systemd1.service',
+ install_dir : dbussystemservicedir)
+
+policy_in = configure_file(
+ input : 'org.freedesktop.systemd1.policy.in.in',
+ output : 'org.freedesktop.systemd1.policy.in',
+ configuration : substs)
+
+custom_target(
+ 'org.freedesktop.systemd1.policy',
+ input : policy_in,
+ output : 'org.freedesktop.systemd1.policy',
+ command : intltool_command,
+ 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)
+
+meson.add_install_script('sh', '-c', mkdir_p.format(systemshutdowndir))
+meson.add_install_script('sh', '-c', mkdir_p.format(systemsleepdir))
+meson.add_install_script('sh', '-c', mkdir_p.format(systemgeneratordir))
+meson.add_install_script('sh', '-c', mkdir_p.format(usergeneratordir))
+
+meson.add_install_script('sh', '-c',
+ mkdir_p.format(join_paths(pkgsysconfdir, 'system/multi-user.target.wants')))
+meson.add_install_script('sh', '-c',
+ mkdir_p.format(join_paths(pkgsysconfdir, 'system/getty.target.wants')))
+meson.add_install_script('sh', '-c',
+ mkdir_p.format(join_paths(pkgsysconfdir, 'user')))
+meson.add_install_script('sh', '-c',
+ mkdir_p.format(join_paths(sysconfdir, 'xdg/systemd')))
diff --git a/src/core/namespace.c b/src/core/namespace.c
index 4f29217bc4..05175e9552 100644
--- a/src/core/namespace.c
+++ b/src/core/namespace.c
@@ -27,6 +27,7 @@
#include <linux/fs.h>
#include "alloc-util.h"
+#include "base-filesystem.h"
#include "dev-setup.h"
#include "fd-util.h"
#include "fs-util.h"
@@ -792,13 +793,14 @@ static int apply_mount(
return 0;
}
-static int make_read_only(MountEntry *m, char **blacklist) {
+static int make_read_only(MountEntry *m, char **blacklist, FILE *proc_self_mountinfo) {
int r = 0;
assert(m);
+ assert(proc_self_mountinfo);
if (mount_entry_read_only(m))
- r = bind_remount_recursive(mount_entry_path(m), true, blacklist);
+ r = bind_remount_recursive_with_mountinfo(mount_entry_path(m), true, blacklist, proc_self_mountinfo);
else if (m->mode == PRIVATE_DEV) { /* Superblock can be readonly but the submounts can't */
if (mount(NULL, mount_entry_path(m), NULL, MS_REMOUNT|DEV_MOUNT_OPTIONS|MS_RDONLY, NULL) < 0)
r = -errno;
@@ -815,18 +817,24 @@ static int make_read_only(MountEntry *m, char **blacklist) {
return r;
}
-static bool namespace_info_mount_apivfs(const NameSpaceInfo *ns_info) {
+static bool namespace_info_mount_apivfs(const char *root_directory, const NameSpaceInfo *ns_info) {
assert(ns_info);
- /* ProtectControlGroups= and ProtectKernelTunables= imply MountAPIVFS=, since to protect the API VFS mounts,
- * they need to be around in the first place... */
+ /*
+ * ProtectControlGroups= and ProtectKernelTunables= imply MountAPIVFS=,
+ * since to protect the API VFS mounts, they need to be around in the
+ * first place... and RootDirectory= or RootImage= need to be set.
+ */
- return ns_info->mount_apivfs ||
- ns_info->protect_control_groups ||
- ns_info->protect_kernel_tunables;
+ /* root_directory should point to a mount point */
+ return root_directory &&
+ (ns_info->mount_apivfs ||
+ ns_info->protect_control_groups ||
+ ns_info->protect_kernel_tunables);
}
static unsigned namespace_calculate_mounts(
+ const char* root_directory,
const NameSpaceInfo *ns_info,
char** read_write_paths,
char** read_only_paths,
@@ -863,7 +871,7 @@ static unsigned namespace_calculate_mounts(
(ns_info->protect_control_groups ? 1 : 0) +
(ns_info->protect_kernel_modules ? ELEMENTSOF(protect_kernel_modules_table) : 0) +
protect_home_cnt + protect_system_cnt +
- (namespace_info_mount_apivfs(ns_info) ? ELEMENTSOF(apivfs_table) : 0);
+ (namespace_info_mount_apivfs(root_directory, ns_info) ? ELEMENTSOF(apivfs_table) : 0);
}
int setup_namespace(
@@ -931,6 +939,7 @@ int setup_namespace(
}
n_mounts = namespace_calculate_mounts(
+ root_directory,
ns_info,
read_write_paths,
read_only_paths,
@@ -1009,7 +1018,7 @@ int setup_namespace(
if (r < 0)
goto finish;
- if (namespace_info_mount_apivfs(ns_info)) {
+ if (namespace_info_mount_apivfs(root_directory, ns_info)) {
r = append_static_mounts(&m, apivfs_table, ELEMENTSOF(apivfs_table), ns_info->ignore_protect_paths);
if (r < 0)
goto finish;
@@ -1044,6 +1053,10 @@ int setup_namespace(
}
}
+ /* Try to set up the new root directory before mounting anything there */
+ if (root_directory)
+ (void) base_filesystem_create(root_directory, UID_INVALID, GID_INVALID);
+
if (root_image) {
r = dissected_image_mount(dissected_image, root_directory, dissect_image_flags);
if (r < 0)
@@ -1070,9 +1083,18 @@ int setup_namespace(
}
if (n_mounts > 0) {
+ _cleanup_fclose_ FILE *proc_self_mountinfo = NULL;
char **blacklist;
unsigned j;
+ /* Open /proc/self/mountinfo now as it may become unavailable if we mount anything on top of /proc.
+ * For example, this is the case with the option: 'InaccessiblePaths=/proc' */
+ proc_self_mountinfo = fopen("/proc/self/mountinfo", "re");
+ if (!proc_self_mountinfo) {
+ r = -errno;
+ goto finish;
+ }
+
/* First round, add in all special mounts we need */
for (m = mounts; m < mounts + n_mounts; ++m) {
r = apply_mount(root_directory, m, tmp_dir, var_tmp_dir);
@@ -1088,7 +1110,7 @@ int setup_namespace(
/* Second round, flip the ro bits if necessary. */
for (m = mounts; m < mounts + n_mounts; ++m) {
- r = make_read_only(m, blacklist);
+ r = make_read_only(m, blacklist, proc_self_mountinfo);
if (r < 0)
goto finish;
}
diff --git a/src/core/selinux-access.c b/src/core/selinux-access.c
index 2b96a9551b..0f8a2d68e2 100644
--- a/src/core/selinux-access.c
+++ b/src/core/selinux-access.c
@@ -135,7 +135,12 @@ _printf_(2, 3) static int log_callback(int type, const char *fmt, ...) {
fmt2 = strjoina("selinux: ", fmt);
va_start(ap, fmt);
- log_internalv(LOG_AUTH | callback_type_to_priority(type), 0, __FILE__, __LINE__, __FUNCTION__, fmt2, ap);
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat-nonliteral"
+ log_internalv(LOG_AUTH | callback_type_to_priority(type),
+ 0, __FILE__, __LINE__, __FUNCTION__,
+ fmt2, ap);
+#pragma GCC diagnostic pop
va_end(ap);
return 0;
diff --git a/src/core/service.c b/src/core/service.c
index 874f2be931..3a348c760d 100644
--- a/src/core/service.c
+++ b/src/core/service.c
@@ -45,6 +45,7 @@
#include "service.h"
#include "signal-util.h"
#include "special.h"
+#include "stdio-util.h"
#include "string-table.h"
#include "string-util.h"
#include "strv.h"
@@ -156,7 +157,7 @@ static int service_set_main_pid(Service *s, pid_t pid) {
if (pid <= 1)
return -EINVAL;
- if (pid == getpid())
+ if (pid == getpid_cached())
return -EINVAL;
if (s->main_pid == pid && s->main_pid_known)
@@ -170,7 +171,7 @@ static int service_set_main_pid(Service *s, pid_t pid) {
s->main_pid = pid;
s->main_pid_known = true;
- if (get_process_ppid(pid, &ppid) >= 0 && ppid != getpid()) {
+ if (get_process_ppid(pid, &ppid) >= 0 && ppid != getpid_cached()) {
log_unit_warning(UNIT(s), "Supervising process "PID_FMT" which is not our child. We'll most likely not notice when it exits.", pid);
s->main_pid_alien = true;
} else
@@ -412,13 +413,12 @@ static int service_add_fd_store(Service *s, int fd, const char *name) {
}
r = sd_event_add_io(UNIT(s)->manager->event, &fs->event_source, fd, 0, on_fd_store_io, fs);
- if (r < 0) {
+ if (r < 0 && r != -EPERM) { /* EPERM indicates fds that aren't pollable, which is OK */
free(fs->fdname);
free(fs);
return r;
- }
-
- (void) sd_event_source_set_description(fs->event_source, "service-fd-store");
+ } else if (r >= 0)
+ (void) sd_event_source_set_description(fs->event_source, "service-fd-store");
LIST_PREPEND(fd_store, s->fd_store, fs);
s->n_fd_store++;
@@ -1067,14 +1067,21 @@ static int service_coldplug(Unit *u) {
return 0;
}
-static int service_collect_fds(Service *s, int **fds, char ***fd_names) {
+static int service_collect_fds(Service *s,
+ int **fds,
+ char ***fd_names,
+ unsigned *n_storage_fds,
+ unsigned *n_socket_fds) {
+
_cleanup_strv_free_ char **rfd_names = NULL;
_cleanup_free_ int *rfds = NULL;
- int rn_fds = 0, r;
+ unsigned rn_socket_fds = 0, rn_storage_fds = 0;
+ int r;
assert(s);
assert(fds);
assert(fd_names);
+ assert(n_socket_fds);
if (s->socket_fd >= 0) {
@@ -1089,7 +1096,7 @@ static int service_collect_fds(Service *s, int **fds, char ***fd_names) {
if (!rfd_names)
return -ENOMEM;
- rn_fds = 1;
+ rn_socket_fds = 1;
} else {
Iterator i;
Unit *u;
@@ -1115,20 +1122,20 @@ static int service_collect_fds(Service *s, int **fds, char ***fd_names) {
if (!rfds) {
rfds = cfds;
- rn_fds = cn_fds;
+ rn_socket_fds = cn_fds;
cfds = NULL;
} else {
int *t;
- t = realloc(rfds, (rn_fds + cn_fds) * sizeof(int));
+ t = realloc(rfds, (rn_socket_fds + cn_fds) * sizeof(int));
if (!t)
return -ENOMEM;
- memcpy(t + rn_fds, cfds, cn_fds * sizeof(int));
+ memcpy(t + rn_socket_fds, cfds, cn_fds * sizeof(int));
rfds = t;
- rn_fds += cn_fds;
+ rn_socket_fds += cn_fds;
}
r = strv_extend_n(&rfd_names, socket_fdname(sock), cn_fds);
@@ -1139,40 +1146,45 @@ static int service_collect_fds(Service *s, int **fds, char ***fd_names) {
if (s->n_fd_store > 0) {
ServiceFDStore *fs;
+ unsigned n_fds;
char **nl;
int *t;
- t = realloc(rfds, (rn_fds + s->n_fd_store) * sizeof(int));
+ t = realloc(rfds, (rn_socket_fds + s->n_fd_store) * sizeof(int));
if (!t)
return -ENOMEM;
rfds = t;
- nl = realloc(rfd_names, (rn_fds + s->n_fd_store + 1) * sizeof(char*));
+ nl = realloc(rfd_names, (rn_socket_fds + s->n_fd_store + 1) * sizeof(char*));
if (!nl)
return -ENOMEM;
rfd_names = nl;
+ n_fds = rn_socket_fds;
LIST_FOREACH(fd_store, fs, s->fd_store) {
- rfds[rn_fds] = fs->fd;
- rfd_names[rn_fds] = strdup(strempty(fs->fdname));
- if (!rfd_names[rn_fds])
+ rfds[n_fds] = fs->fd;
+ rfd_names[n_fds] = strdup(strempty(fs->fdname));
+ if (!rfd_names[n_fds])
return -ENOMEM;
- rn_fds++;
+ rn_storage_fds++;
+ n_fds++;
}
- rfd_names[rn_fds] = NULL;
+ rfd_names[n_fds] = NULL;
}
*fds = rfds;
*fd_names = rfd_names;
+ *n_socket_fds = rn_socket_fds;
+ *n_storage_fds = rn_storage_fds;
rfds = NULL;
rfd_names = NULL;
- return rn_fds;
+ return 0;
}
static bool service_exec_needs_notify_socket(Service *s, ExecFlags flags) {
@@ -1203,7 +1215,7 @@ static int service_spawn(
_cleanup_strv_free_ char **final_env = NULL, **our_env = NULL, **fd_names = NULL;
_cleanup_free_ int *fds = NULL;
- unsigned n_fds = 0, n_env = 0;
+ unsigned n_storage_fds = 0, n_socket_fds = 0, n_env = 0;
const char *path;
pid_t pid;
@@ -1247,12 +1259,11 @@ static int service_spawn(
s->exec_context.std_output == EXEC_OUTPUT_SOCKET ||
s->exec_context.std_error == EXEC_OUTPUT_SOCKET) {
- r = service_collect_fds(s, &fds, &fd_names);
+ r = service_collect_fds(s, &fds, &fd_names, &n_storage_fds, &n_socket_fds);
if (r < 0)
return r;
- n_fds = r;
- log_unit_debug(UNIT(s), "Passing %i fds to service", n_fds);
+ log_unit_debug(UNIT(s), "Passing %i fds to service", n_storage_fds + n_socket_fds);
}
r = service_arm_timer(s, usec_add(now(CLOCK_MONOTONIC), timeout));
@@ -1272,7 +1283,7 @@ static int service_spawn(
return -ENOMEM;
if (MANAGER_IS_USER(UNIT(s)->manager))
- if (asprintf(our_env + n_env++, "MANAGERPID="PID_FMT, getpid()) < 0)
+ if (asprintf(our_env + n_env++, "MANAGERPID="PID_FMT, getpid_cached()) < 0)
return -ENOMEM;
if (s->socket_fd >= 0) {
@@ -1345,7 +1356,8 @@ static int service_spawn(
exec_params.environment = final_env;
exec_params.fds = fds;
exec_params.fd_names = fd_names;
- exec_params.n_fds = n_fds;
+ exec_params.n_storage_fds = n_storage_fds;
+ exec_params.n_socket_fds = n_socket_fds;
exec_params.confirm_spawn = manager_get_confirm_spawn(UNIT(s)->manager);
exec_params.cgroup_supported = UNIT(s)->manager->cgroup_supported;
exec_params.cgroup_path = path;
@@ -2139,6 +2151,79 @@ _pure_ static bool service_can_reload(Unit *u) {
return !!s->exec_command[SERVICE_EXEC_RELOAD];
}
+static unsigned service_exec_command_index(Unit *u, ServiceExecCommand id, ExecCommand *current) {
+ Service *s = SERVICE(u);
+ unsigned idx = 0;
+ ExecCommand *first, *c;
+
+ assert(s);
+
+ first = s->exec_command[id];
+
+ /* Figure out where we are in the list by walking back to the beginning */
+ for (c = current; c != first; c = c->command_prev)
+ idx++;
+
+ return idx;
+}
+
+static int service_serialize_exec_command(Unit *u, FILE *f, ExecCommand *command) {
+ Service *s = SERVICE(u);
+ ServiceExecCommand id;
+ unsigned idx;
+ const char *type;
+ char **arg;
+ _cleanup_free_ char *args = NULL, *p = NULL;
+ size_t allocated = 0, length = 0;
+
+ assert(s);
+ assert(f);
+
+ if (!command)
+ return 0;
+
+ if (command == s->control_command) {
+ type = "control";
+ id = s->control_command_id;
+ } else {
+ type = "main";
+ id = SERVICE_EXEC_START;
+ }
+
+ idx = service_exec_command_index(u, id, command);
+
+ STRV_FOREACH(arg, command->argv) {
+ size_t n;
+ _cleanup_free_ char *e = NULL;
+
+ e = xescape(*arg, WHITESPACE);
+ if (!e)
+ return -ENOMEM;
+
+ n = strlen(e);
+ if (!GREEDY_REALLOC(args, allocated, length + 1 + n + 1))
+ return -ENOMEM;
+
+ if (length > 0)
+ args[length++] = ' ';
+
+ memcpy(args + length, e, n);
+ length += n;
+ }
+
+ if (!GREEDY_REALLOC(args, allocated, length + 1))
+ return -ENOMEM;
+ args[length++] = 0;
+
+ p = xescape(command->path, WHITESPACE);
+ if (!p)
+ return -ENOMEM;
+
+ fprintf(f, "%s-command=%s %u %s %s\n", type, service_exec_command_to_string(id), idx, p, args);
+
+ return 0;
+}
+
static int service_serialize(Unit *u, FILE *f, FDSet *fds) {
Service *s = SERVICE(u);
ServiceFDStore *fs;
@@ -2166,11 +2251,8 @@ static int service_serialize(Unit *u, FILE *f, FDSet *fds) {
if (r < 0)
return r;
- /* FIXME: There's a minor uncleanliness here: if there are
- * multiple commands attached here, we will start from the
- * first one again */
- if (s->control_command_id >= 0)
- unit_serialize_item(u, f, "control-command", service_exec_command_to_string(s->control_command_id));
+ service_serialize_exec_command(u, f, s->control_command);
+ service_serialize_exec_command(u, f, s->main_command);
r = unit_serialize_item_fd(u, f, fds, "stdin-fd", s->stdin_fd);
if (r < 0)
@@ -2226,6 +2308,106 @@ static int service_serialize(Unit *u, FILE *f, FDSet *fds) {
return 0;
}
+static int service_deserialize_exec_command(Unit *u, const char *key, const char *value) {
+ Service *s = SERVICE(u);
+ int r;
+ unsigned idx = 0, i;
+ bool control, found = false;
+ ServiceExecCommand id = _SERVICE_EXEC_COMMAND_INVALID;
+ ExecCommand *command = NULL;
+ _cleanup_free_ char *path = NULL;
+ _cleanup_strv_free_ char **argv = NULL;
+
+ enum ExecCommandState {
+ STATE_EXEC_COMMAND_TYPE,
+ STATE_EXEC_COMMAND_INDEX,
+ STATE_EXEC_COMMAND_PATH,
+ STATE_EXEC_COMMAND_ARGS,
+ _STATE_EXEC_COMMAND_MAX,
+ _STATE_EXEC_COMMAND_INVALID = -1,
+ } state;
+
+ assert(s);
+ assert(key);
+ assert(value);
+
+ control = streq(key, "control-command");
+
+ state = STATE_EXEC_COMMAND_TYPE;
+
+ for (;;) {
+ _cleanup_free_ char *arg = NULL;
+
+ r = extract_first_word(&value, &arg, NULL, EXTRACT_CUNESCAPE);
+ if (r == 0)
+ break;
+ else if (r < 0)
+ return r;
+
+ switch (state) {
+ case STATE_EXEC_COMMAND_TYPE:
+ id = service_exec_command_from_string(arg);
+ if (id < 0)
+ return -EINVAL;
+
+ state = STATE_EXEC_COMMAND_INDEX;
+ break;
+ case STATE_EXEC_COMMAND_INDEX:
+ r = safe_atou(arg, &idx);
+ if (r < 0)
+ return -EINVAL;
+
+ state = STATE_EXEC_COMMAND_PATH;
+ break;
+ case STATE_EXEC_COMMAND_PATH:
+ path = arg;
+ arg = NULL;
+ state = STATE_EXEC_COMMAND_ARGS;
+
+ if (!path_is_absolute(path))
+ return -EINVAL;
+ break;
+ case STATE_EXEC_COMMAND_ARGS:
+ r = strv_extend(&argv, arg);
+ if (r < 0)
+ return -ENOMEM;
+ break;
+ default:
+ assert_not_reached("Unknown error at deserialization of exec command");
+ break;
+ }
+ }
+
+ if (state != STATE_EXEC_COMMAND_ARGS)
+ return -EINVAL;
+
+ /* Let's check whether exec command on given offset matches data that we just deserialized */
+ for (command = s->exec_command[id], i = 0; command; command = command->command_next, i++) {
+ if (i != idx)
+ continue;
+
+ found = strv_equal(argv, command->argv) && streq(command->path, path);
+ break;
+ }
+
+ if (!found) {
+ /* Command at the index we serialized is different, let's look for command that exactly
+ * matches but is on different index. If there is no such command we will not resume execution. */
+ for (command = s->exec_command[id]; command; command = command->command_next)
+ if (strv_equal(command->argv, argv) && streq(command->path, path))
+ break;
+ }
+
+ if (command && control)
+ s->control_command = command;
+ else if (command)
+ s->main_command = command;
+ else
+ log_unit_warning(u, "Current command vanished from the unit file, execution of the command list won't be resumed.");
+
+ return 0;
+}
+
static int service_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
Service *s = SERVICE(u);
int r;
@@ -2308,16 +2490,6 @@ static int service_deserialize_item(Unit *u, const char *key, const char *value,
s->status_text = t;
}
- } else if (streq(key, "control-command")) {
- ServiceExecCommand id;
-
- id = service_exec_command_from_string(value);
- if (id < 0)
- log_unit_debug(u, "Failed to parse exec-command value: %s", value);
- else {
- s->control_command_id = id;
- s->control_command = s->exec_command[id];
- }
} else if (streq(key, "accept-socket")) {
Unit *socket;
@@ -2436,6 +2608,10 @@ static int service_deserialize_item(Unit *u, const char *key, const char *value,
s->watchdog_override_enable = true;
s->watchdog_override_usec = watchdog_override_usec;
}
+ } else if (STR_IN_SET(key, "main-command", "control-command")) {
+ r = service_deserialize_exec_command(u, key, value);
+ if (r < 0)
+ log_unit_debug_errno(u, r, "Failed to parse serialized command \"%s\": %m", value);
} else
log_unit_debug(u, "Unknown serialization key: %s", key);
@@ -2692,7 +2868,6 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
log_struct(f == SERVICE_SUCCESS ? LOG_DEBUG :
(code == CLD_EXITED ? LOG_NOTICE : LOG_WARNING),
- LOG_UNIT_ID(u),
LOG_UNIT_MESSAGE(u, "Main process exited, code=%s, status=%i/%s",
sigchld_code_to_string(code), status,
strna(code == CLD_EXITED
@@ -2700,6 +2875,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
: signal_to_string(status))),
"EXIT_CODE=%s", sigchld_code_to_string(code),
"EXIT_STATUS=%i", status,
+ LOG_UNIT_ID(u),
NULL);
if (s->result == SERVICE_SUCCESS)
@@ -3092,7 +3268,7 @@ static void service_notify_message(Unit *u, pid_t pid, char **tags, FDSet *fds)
log_unit_warning(u, "Failed to parse MAINPID= field in notification message: %s", e);
else if (pid == s->control_pid)
log_unit_warning(u, "A control process cannot also be the main process");
- else if (pid == getpid() || pid == 1)
+ else if (pid == getpid_cached() || pid == 1)
log_unit_warning(u, "Service manager can't be main process, ignoring sd_notify() MAINPID= field");
else {
service_set_main_pid(s, pid);
@@ -3406,15 +3582,6 @@ static const char* const service_exec_command_table[_SERVICE_EXEC_COMMAND_MAX] =
DEFINE_STRING_TABLE_LOOKUP(service_exec_command, ServiceExecCommand);
-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);
-
static const char* const notify_state_table[_NOTIFY_STATE_MAX] = {
[NOTIFY_UNKNOWN] = "unknown",
[NOTIFY_READY] = "ready",
diff --git a/src/core/service.h b/src/core/service.h
index ff9cfaeb88..f4ba604f69 100644
--- a/src/core/service.h
+++ b/src/core/service.h
@@ -61,15 +61,6 @@ typedef enum ServiceExecCommand {
_SERVICE_EXEC_COMMAND_INVALID = -1
} ServiceExecCommand;
-typedef enum NotifyAccess {
- NOTIFY_NONE,
- NOTIFY_ALL,
- NOTIFY_MAIN,
- NOTIFY_EXEC,
- _NOTIFY_ACCESS_MAX,
- _NOTIFY_ACCESS_INVALID = -1
-} NotifyAccess;
-
typedef enum NotifyState {
NOTIFY_UNKNOWN,
NOTIFY_READY,
@@ -218,9 +209,6 @@ ServiceType service_type_from_string(const char *s) _pure_;
const char* service_exec_command_to_string(ServiceExecCommand i) _const_;
ServiceExecCommand service_exec_command_from_string(const char *s) _pure_;
-const char* notify_access_to_string(NotifyAccess i) _const_;
-NotifyAccess notify_access_from_string(const char *s) _pure_;
-
const char* notify_state_to_string(NotifyState i) _const_;
NotifyState notify_state_from_string(const char *s) _pure_;
diff --git a/src/core/shutdown.c b/src/core/shutdown.c
index a7d5e57936..6d1cc3120a 100644
--- a/src/core/shutdown.c
+++ b/src/core/shutdown.c
@@ -180,7 +180,7 @@ int main(int argc, char *argv[]) {
umask(0022);
- if (getpid() != 1) {
+ if (getpid_cached() != 1) {
log_error("Not executed by init (PID 1).");
r = -EPERM;
goto error;
diff --git a/src/core/smack-setup.c b/src/core/smack-setup.c
index 5a6d11cfa1..adf2293142 100644
--- a/src/core/smack-setup.c
+++ b/src/core/smack-setup.c
@@ -264,6 +264,54 @@ static int write_netlabel_rules(const char* srcdir) {
return r;
}
+static int write_onlycap_list(void) {
+ _cleanup_close_ int onlycap_fd = -1;
+ _cleanup_free_ char *list = NULL;
+ _cleanup_fclose_ FILE *f = NULL;
+ size_t len = 0, allocated = 0;
+ char buf[LINE_MAX];
+ int r;
+
+ f = fopen("/etc/smack/onlycap", "re");
+ if (!f) {
+ if (errno != ENOENT)
+ log_warning_errno(errno, "Failed to read '/etc/smack/onlycap'");
+ return errno == ENOENT ? ENOENT : -errno;
+ }
+
+ FOREACH_LINE(buf, f, return -errno) {
+ size_t l;
+
+ if (isempty(truncate_nl(buf)) || strchr(COMMENTS, *buf))
+ continue;
+
+ l = strlen(buf);
+ if (!GREEDY_REALLOC(list, allocated, len + l + 1))
+ return log_oom();
+
+ stpcpy(list + len, buf)[0] = ' ';
+ len += l + 1;
+ }
+
+ if (!len)
+ return 0;
+
+ list[len - 1] = 0;
+
+ onlycap_fd = open("/sys/fs/smackfs/onlycap", O_WRONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY);
+ if (onlycap_fd < 0) {
+ if (errno != ENOENT)
+ log_warning_errno(errno, "Failed to open '/sys/fs/smackfs/onlycap'");
+ return -errno; /* negative error */
+ }
+
+ r = write(onlycap_fd, list, len);
+ if (r < 0)
+ return log_error_errno(errno, "Failed to write onlycap list(%s) to '/sys/fs/smackfs/onlycap'", list);
+
+ return 0;
+}
+
#endif
int mac_smack_setup(bool *loaded_policy) {
@@ -338,6 +386,22 @@ int mac_smack_setup(bool *loaded_policy) {
break;
}
+ r = write_onlycap_list();
+ switch(r) {
+ case -ENOENT:
+ log_debug("Smack is not enabled in the kernel.");
+ break;
+ case ENOENT:
+ log_debug("Smack onlycap list file '/etc/smack/onlycap' not found");
+ break;
+ case 0:
+ log_info("Successfully wrote Smack onlycap list.");
+ break;
+ default:
+ log_emergency_errno(r, "Failed to write Smack onlycap list.");
+ return r;
+ }
+
*loaded_policy = true;
#endif
diff --git a/src/core/socket.c b/src/core/socket.c
index c4da227e09..8750643d92 100644
--- a/src/core/socket.c
+++ b/src/core/socket.c
@@ -2528,7 +2528,7 @@ static int socket_deserialize_item(Unit *u, const char *key, const char *value,
else
LIST_FOREACH(port, p, s->ports)
if (p->type == SOCKET_FIFO &&
- path_equal_or_files_same(p->path, value+skip)) {
+ path_equal_or_files_same(p->path, value+skip, 0)) {
socket_port_take_fd(p, fds, fd);
break;
}
@@ -2542,7 +2542,7 @@ static int socket_deserialize_item(Unit *u, const char *key, const char *value,
else
LIST_FOREACH(port, p, s->ports)
if (p->type == SOCKET_SPECIAL &&
- path_equal_or_files_same(p->path, value+skip)) {
+ path_equal_or_files_same(p->path, value+skip, 0)) {
socket_port_take_fd(p, fds, fd);
break;
}
@@ -2596,7 +2596,7 @@ static int socket_deserialize_item(Unit *u, const char *key, const char *value,
else
LIST_FOREACH(port, p, s->ports)
if (p->type == SOCKET_USB_FUNCTION &&
- path_equal_or_files_same(p->path, value+skip)) {
+ path_equal_or_files_same(p->path, value+skip, 0)) {
socket_port_take_fd(p, fds, fd);
break;
}
diff --git a/src/core/swap.c b/src/core/swap.c
index e9468e105c..4c3a74ce00 100644
--- a/src/core/swap.c
+++ b/src/core/swap.c
@@ -487,13 +487,14 @@ static void swap_set_state(Swap *s, SwapState state) {
old_state = s->state;
s->state = state;
- if (state != SWAP_ACTIVATING &&
- state != SWAP_ACTIVATING_SIGTERM &&
- state != SWAP_ACTIVATING_SIGKILL &&
- state != SWAP_ACTIVATING_DONE &&
- state != SWAP_DEACTIVATING &&
- state != SWAP_DEACTIVATING_SIGTERM &&
- state != SWAP_DEACTIVATING_SIGKILL) {
+ if (!IN_SET(state,
+ SWAP_ACTIVATING,
+ SWAP_ACTIVATING_SIGTERM,
+ SWAP_ACTIVATING_SIGKILL,
+ SWAP_ACTIVATING_DONE,
+ SWAP_DEACTIVATING,
+ SWAP_DEACTIVATING_SIGTERM,
+ SWAP_DEACTIVATING_SIGKILL)) {
s->timer_event_source = sd_event_source_unref(s->timer_event_source);
swap_unwatch_control_pid(s);
s->control_command = NULL;
@@ -695,20 +696,19 @@ static void swap_enter_active(Swap *s, SwapResult f) {
static void swap_enter_signal(Swap *s, SwapState state, SwapResult f) {
int r;
+ KillOperation kop;
assert(s);
if (s->result == SWAP_SUCCESS)
s->result = f;
- r = unit_kill_context(
- UNIT(s),
- &s->kill_context,
- (state != SWAP_ACTIVATING_SIGTERM && state != SWAP_DEACTIVATING_SIGTERM) ?
- KILL_KILL : KILL_TERMINATE,
- -1,
- s->control_pid,
- false);
+ if (IN_SET(state, SWAP_ACTIVATING_SIGTERM, SWAP_DEACTIVATING_SIGTERM))
+ kop = KILL_TERMINATE;
+ else
+ kop = KILL_KILL;
+
+ r = unit_kill_context(UNIT(s), &s->kill_context, kop, -1, s->control_pid, false);
if (r < 0)
goto fail;
@@ -829,17 +829,18 @@ static int swap_start(Unit *u) {
/* We cannot fulfill this request right now, try again later
* please! */
- if (s->state == SWAP_DEACTIVATING ||
- s->state == SWAP_DEACTIVATING_SIGTERM ||
- s->state == SWAP_DEACTIVATING_SIGKILL ||
- s->state == SWAP_ACTIVATING_SIGTERM ||
- s->state == SWAP_ACTIVATING_SIGKILL)
+ if (IN_SET(s->state,
+ SWAP_DEACTIVATING,
+ SWAP_DEACTIVATING_SIGTERM,
+ SWAP_DEACTIVATING_SIGKILL,
+ SWAP_ACTIVATING_SIGTERM,
+ SWAP_ACTIVATING_SIGKILL))
return -EAGAIN;
if (s->state == SWAP_ACTIVATING)
return 0;
- assert(s->state == SWAP_DEAD || s->state == SWAP_FAILED);
+ assert(IN_SET(s->state, SWAP_DEAD, SWAP_FAILED));
if (detect_container() > 0)
return -EPERM;
@@ -873,16 +874,15 @@ static int swap_stop(Unit *u) {
assert(s);
- if (s->state == SWAP_DEACTIVATING ||
- s->state == SWAP_DEACTIVATING_SIGTERM ||
- s->state == SWAP_DEACTIVATING_SIGKILL ||
- s->state == SWAP_ACTIVATING_SIGTERM ||
- s->state == SWAP_ACTIVATING_SIGKILL)
+ if (IN_SET(s->state,
+ SWAP_DEACTIVATING,
+ SWAP_DEACTIVATING_SIGTERM,
+ SWAP_DEACTIVATING_SIGKILL,
+ SWAP_ACTIVATING_SIGTERM,
+ SWAP_ACTIVATING_SIGKILL))
return 0;
- assert(s->state == SWAP_ACTIVATING ||
- s->state == SWAP_ACTIVATING_DONE ||
- s->state == SWAP_ACTIVE);
+ assert(IN_SET(s->state, SWAP_ACTIVATING, SWAP_ACTIVATING_DONE, SWAP_ACTIVE));
if (detect_container() > 0)
return -EPERM;
@@ -1340,7 +1340,7 @@ int swap_process_device_new(Manager *m, struct udev_device *dev) {
struct udev_list_entry *item = NULL, *first = NULL;
_cleanup_free_ char *e = NULL;
const char *dn;
- Swap *s;
+ Unit *u;
int r = 0;
assert(m);
@@ -1354,9 +1354,9 @@ int swap_process_device_new(Manager *m, struct udev_device *dev) {
if (r < 0)
return r;
- s = hashmap_get(m->units, e);
- if (s)
- r = swap_set_devnode(s, dn);
+ u = manager_get_unit(m, e);
+ if (u)
+ r = swap_set_devnode(SWAP(u), dn);
first = udev_device_get_devlinks_list_entry(dev);
udev_list_entry_foreach(item, first) {
@@ -1367,9 +1367,9 @@ int swap_process_device_new(Manager *m, struct udev_device *dev) {
if (q < 0)
return q;
- s = hashmap_get(m->units, n);
- if (s) {
- q = swap_set_devnode(s, dn);
+ u = manager_get_unit(m, n);
+ if (u) {
+ q = swap_set_devnode(SWAP(u), dn);
if (q < 0)
r = q;
}
diff --git a/src/core/target.c b/src/core/target.c
index ff0d764fb5..2a58dd394d 100644
--- a/src/core/target.c
+++ b/src/core/target.c
@@ -63,6 +63,9 @@ static int target_add_default_dependencies(Target *t) {
assert(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
@@ -93,7 +96,7 @@ static int target_load(Unit *u) {
return r;
/* This is a new unit? Then let's add in some extras */
- if (u->load_state == UNIT_LOADED && u->default_dependencies) {
+ if (u->load_state == UNIT_LOADED) {
r = target_add_default_dependencies(t);
if (r < 0)
return r;
diff --git a/src/core/timer.c b/src/core/timer.c
index af67b7591a..701949fd60 100644
--- a/src/core/timer.c
+++ b/src/core/timer.c
@@ -316,21 +316,6 @@ static void timer_enter_elapsed(Timer *t, bool leave_around) {
timer_enter_dead(t, TIMER_SUCCESS);
}
-static usec_t monotonic_to_boottime(usec_t t) {
- usec_t a, b;
-
- if (t <= 0)
- return 0;
-
- a = now(clock_boottime_or_monotonic());
- b = now(CLOCK_MONOTONIC);
-
- if (t + a > b)
- return t + a - b;
- else
- return 0;
-}
-
static void add_random(Timer *t, usec_t *v) {
char s[FORMAT_TIMESPAN_MAX];
usec_t add;
@@ -355,9 +340,9 @@ static void add_random(Timer *t, usec_t *v) {
static void timer_enter_waiting(Timer *t, bool initial) {
bool found_monotonic = false, found_realtime = false;
- usec_t ts_realtime, ts_monotonic;
- usec_t base = 0;
bool leave_around = false;
+ triple_timestamp ts;
+ usec_t base = 0;
TimerValue *v;
Unit *trigger;
int r;
@@ -371,11 +356,7 @@ static void timer_enter_waiting(Timer *t, bool initial) {
return;
}
- /* If we shall wake the system we use the boottime clock
- * rather than the monotonic clock. */
-
- ts_realtime = now(CLOCK_REALTIME);
- ts_monotonic = now(t->wake_system ? clock_boottime_or_monotonic() : CLOCK_MONOTONIC);
+ triple_timestamp_get(&ts);
t->next_elapse_monotonic_or_boottime = t->next_elapse_realtime = 0;
LIST_FOREACH(value, v, t->values) {
@@ -391,7 +372,7 @@ static void timer_enter_waiting(Timer *t, bool initial) {
* to that. If we don't just start from
* now. */
- b = t->last_trigger.realtime > 0 ? t->last_trigger.realtime : ts_realtime;
+ b = t->last_trigger.realtime > 0 ? t->last_trigger.realtime : ts.realtime;
r = calendar_spec_next_usec(v->calendar_spec, b, &v->next_elapse);
if (r < 0)
@@ -405,13 +386,14 @@ static void timer_enter_waiting(Timer *t, bool initial) {
found_realtime = true;
} else {
+
switch (v->base) {
case TIMER_ACTIVE:
if (state_translation_table[t->state] == UNIT_ACTIVE)
base = UNIT(t)->inactive_exit_timestamp.monotonic;
else
- base = ts_monotonic;
+ base = ts.monotonic;
break;
case TIMER_BOOT:
@@ -456,12 +438,11 @@ static void timer_enter_waiting(Timer *t, bool initial) {
assert_not_reached("Unknown timer base");
}
- if (t->wake_system)
- base = monotonic_to_boottime(base);
-
- v->next_elapse = base + v->value;
+ v->next_elapse = usec_add(usec_shift_clock(base, CLOCK_MONOTONIC, TIMER_MONOTONIC_CLOCK(t)), v->value);
- if (!initial && v->next_elapse < ts_monotonic && IN_SET(v->base, TIMER_ACTIVE, TIMER_BOOT, TIMER_STARTUP)) {
+ if (!initial &&
+ v->next_elapse < triple_timestamp_by_clock(&ts, TIMER_MONOTONIC_CLOCK(t)) &&
+ IN_SET(v->base, TIMER_ACTIVE, TIMER_BOOT, TIMER_STARTUP)) {
/* This is a one time trigger, disable it now */
v->disabled = true;
continue;
@@ -488,7 +469,7 @@ static void timer_enter_waiting(Timer *t, bool initial) {
add_random(t, &t->next_elapse_monotonic_or_boottime);
- left = t->next_elapse_monotonic_or_boottime > ts_monotonic ? t->next_elapse_monotonic_or_boottime - ts_monotonic : 0;
+ left = usec_sub_unsigned(t->next_elapse_monotonic_or_boottime, triple_timestamp_by_clock(&ts, TIMER_MONOTONIC_CLOCK(t)));
log_unit_debug(UNIT(t), "Monotonic timer elapses in %s.", format_timespan(buf, sizeof(buf), left, 0));
if (t->monotonic_event_source) {
diff --git a/src/core/timer.h b/src/core/timer.h
index 9c4b64f898..546c60d750 100644
--- a/src/core/timer.h
+++ b/src/core/timer.h
@@ -78,6 +78,8 @@ struct Timer {
char *stamp_path;
};
+#define TIMER_MONOTONIC_CLOCK(t) ((t)->wake_system && clock_boottime_supported() ? CLOCK_BOOTTIME_ALARM : CLOCK_MONOTONIC)
+
void timer_free_values(Timer *t);
extern const UnitVTable timer_vtable;
diff --git a/src/core/transaction.c b/src/core/transaction.c
index b6d1062414..a2dfd8ae90 100644
--- a/src/core/transaction.c
+++ b/src/core/transaction.c
@@ -632,7 +632,7 @@ static int transaction_apply(Transaction *tr, Manager *m, JobMode mode) {
job_add_to_run_queue(j);
job_add_to_dbus_queue(j);
- job_start_timer(j);
+ job_start_timer(j, false);
job_shutdown_magic(j);
}
diff --git a/src/core/umount.c b/src/core/umount.c
index 77b5bd9556..591dac71f0 100644
--- a/src/core/umount.c
+++ b/src/core/umount.c
@@ -19,7 +19,6 @@
#include <errno.h>
#include <fcntl.h>
-#include <linux/dm-ioctl.h>
#include <linux/loop.h>
#include <string.h>
#include <sys/mount.h>
@@ -31,6 +30,7 @@
#include "escape.h"
#include "fd-util.h"
#include "fstab-util.h"
+#include "linux-3.13/dm-ioctl.h"
#include "list.h"
#include "mount-setup.h"
#include "path-util.h"
diff --git a/src/core/unit.c b/src/core/unit.c
index f76b6c30a8..b28eeb2262 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -99,6 +99,7 @@ Unit *unit_new(Manager *m, size_t size) {
u->on_failure_job_mode = JOB_REPLACE;
u->cgroup_inotify_wd = -1;
u->job_timeout = USEC_INFINITY;
+ u->job_running_timeout = USEC_INFINITY;
u->ref_uid = UID_INVALID;
u->ref_gid = GID_INVALID;
u->cpu_usage_last = NSEC_INFINITY;
@@ -955,9 +956,7 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) {
"%s\tPerpetual: %s\n"
"%s\tSlice: %s\n"
"%s\tCGroup: %s\n"
- "%s\tCGroup realized: %s\n"
- "%s\tCGroup mask: 0x%x\n"
- "%s\tCGroup members mask: 0x%x\n",
+ "%s\tCGroup realized: %s\n",
prefix, u->id,
prefix, unit_description(u),
prefix, strna(u->instance),
@@ -974,9 +973,18 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) {
prefix, yes_no(u->perpetual),
prefix, strna(unit_slice_name(u)),
prefix, strna(u->cgroup_path),
- prefix, yes_no(u->cgroup_realized),
- prefix, u->cgroup_realized_mask,
- prefix, u->cgroup_members_mask);
+ prefix, yes_no(u->cgroup_realized));
+
+ 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));
+ }
+ if (u->cgroup_members_mask != 0) {
+ _cleanup_free_ char *s = NULL;
+ (void) cg_mask_to_string(u->cgroup_members_mask, &s);
+ fprintf(f, "%s\tCGroup members mask: %s\n", prefix, strnull(s));
+ }
SET_FOREACH(t, u->names, i)
fprintf(f, "%s\tName: %s\n", prefix, t);
@@ -1336,6 +1344,9 @@ int unit_load(Unit *u) {
goto fail;
}
+ if (u->job_running_timeout != USEC_INFINITY && u->job_running_timeout > u->job_timeout)
+ log_unit_warning(u, "JobRunningTimeoutSec= is greater than JobTimeoutSec=, it has no effect.");
+
unit_update_cgroup_members_masks(u);
}
@@ -1497,9 +1508,9 @@ static void unit_status_log_starting_stopping_reloading(Unit *u, JobType t) {
* possible, which means we should avoid the low-level unit
* name. */
log_struct(LOG_INFO,
- mid,
- LOG_UNIT_ID(u),
LOG_MESSAGE("%s", buf),
+ LOG_UNIT_ID(u),
+ mid,
NULL);
}
@@ -1821,6 +1832,10 @@ static void unit_check_binds_to(Unit *u) {
if (other->job)
continue;
+ if (!other->coldplugged)
+ /* We might yet create a job for the other unit… */
+ continue;
+
if (!UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other)))
continue;
@@ -2627,6 +2642,9 @@ 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;
+
if (UNIT_VTABLE(u)->bus_name_owner_change)
UNIT_VTABLE(u)->bus_name_owner_change(u, name, old_owner, new_owner);
@@ -2693,6 +2711,25 @@ bool unit_can_serialize(Unit *u) {
return UNIT_VTABLE(u)->serialize && UNIT_VTABLE(u)->deserialize_item;
}
+static int unit_serialize_cgroup_mask(FILE *f, const char *key, CGroupMask mask) {
+ _cleanup_free_ char *s = NULL;
+ int r = 0;
+
+ assert(f);
+ assert(key);
+
+ if (mask != 0) {
+ r = cg_mask_to_string(mask, &s);
+ if (r >= 0) {
+ fputs(key, f);
+ fputc('=', f);
+ fputs(s, f);
+ fputc('\n', f);
+ }
+ }
+ return r;
+}
+
int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool serialize_jobs) {
int r;
@@ -2740,6 +2777,8 @@ int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool serialize_jobs) {
if (u->cgroup_path)
unit_serialize_item(u, f, "cgroup", u->cgroup_path);
unit_serialize_item(u, f, "cgroup-realized", yes_no(u->cgroup_realized));
+ (void) unit_serialize_cgroup_mask(f, "cgroup-realized-mask", u->cgroup_realized_mask);
+ (void) unit_serialize_cgroup_mask(f, "cgroup-enabled-mask", u->cgroup_enabled_mask);
if (uid_is_valid(u->ref_uid))
unit_serialize_item_format(u, f, "ref-uid", UID_FMT, u->ref_uid);
@@ -2997,6 +3036,20 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds) {
continue;
+ } else if (streq(l, "cgroup-realized-mask")) {
+
+ r = cg_mask_from_string(v, &u->cgroup_realized_mask);
+ if (r < 0)
+ log_unit_debug(u, "Failed to parse cgroup-realized-mask %s, ignoring.", v);
+ continue;
+
+ } else if (streq(l, "cgroup-enabled-mask")) {
+
+ r = cg_mask_from_string(v, &u->cgroup_enabled_mask);
+ if (r < 0)
+ log_unit_debug(u, "Failed to parse cgroup-enabled-mask %s, ignoring.", v);
+ continue;
+
} else if (streq(l, "ref-uid")) {
uid_t uid;
diff --git a/src/core/unit.h b/src/core/unit.h
index 8052c234fd..cf21b37e22 100644
--- a/src/core/unit.h
+++ b/src/core/unit.h
@@ -114,6 +114,7 @@ struct Unit {
/* Job timeout and action to take */
usec_t job_timeout;
+ usec_t job_running_timeout;
EmergencyAction job_timeout_action;
char *job_timeout_reboot_arg;
diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c
index 5828e949e3..a2c62e55a5 100644
--- a/src/coredump/coredump.c
+++ b/src/coredump/coredump.c
@@ -144,10 +144,10 @@ static int parse_config(void) {
};
return config_parse_many_nulstr(PKGSYSCONFDIR "/coredump.conf",
- CONF_PATHS_NULSTR("systemd/coredump.conf.d"),
- "Coredump\0",
- config_item_table_lookup, items,
- false, NULL);
+ CONF_PATHS_NULSTR("systemd/coredump.conf.d"),
+ "Coredump\0",
+ config_item_table_lookup, items,
+ false, NULL);
}
static inline uint64_t storage_size_max(void) {
@@ -800,12 +800,11 @@ log:
if (journald_crash) {
/* We cannot log to the journal, so just print the MESSAGE.
* The target was set previously to something safe. */
- log_struct(LOG_ERR, core_message, NULL);
+ log_dispatch(LOG_ERR, 0, core_message);
return 0;
}
- if (core_message)
- IOVEC_SET_STRING(iovec[n_iovec++], core_message);
+ IOVEC_SET_STRING(iovec[n_iovec++], core_message);
if (truncated)
IOVEC_SET_STRING(iovec[n_iovec++], "COREDUMP_TRUNCATED=1");
diff --git a/src/coredump/meson.build b/src/coredump/meson.build
new file mode 100644
index 0000000000..8f7d898b62
--- /dev/null
+++ b/src/coredump/meson.build
@@ -0,0 +1,24 @@
+systemd_coredump_sources = files('''
+ coredump.c
+ coredump-vacuum.c
+ coredump-vacuum.h
+'''.split())
+
+if conf.get('HAVE_ELFUTILS', false)
+ systemd_coredump_sources += files(['stacktrace.c',
+ 'stacktrace.h'])
+endif
+
+coredumpctl_sources = files('coredumpctl.c')
+
+install_data('coredump.conf',
+ install_dir : pkgsysconfdir)
+
+tests += [
+ [['src/coredump/test-coredump-vacuum.c',
+ 'src/coredump/coredump-vacuum.c',
+ 'src/coredump/coredump-vacuum.h'],
+ [],
+ [],
+ 'ENABLE_COREDUMP', 'manual'],
+]
diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c
index 91c653312a..08ed7e53ba 100644
--- a/src/cryptsetup/cryptsetup.c
+++ b/src/cryptsetup/cryptsetup.c
@@ -56,7 +56,7 @@ static bool arg_tcrypt_veracrypt = false;
static char **arg_tcrypt_keyfiles = NULL;
static uint64_t arg_offset = 0;
static uint64_t arg_skip = 0;
-static usec_t arg_timeout = 0;
+static usec_t arg_timeout = USEC_INFINITY;
/* Options Debian's crypttab knows we don't:
@@ -190,7 +190,7 @@ static int parse_one_option(const char *option) {
arg_type = CRYPT_PLAIN;
else if ((val = startswith(option, "timeout="))) {
- r = parse_sec(val, &arg_timeout);
+ r = parse_sec_fix_0(val, &arg_timeout);
if (r < 0) {
log_error_errno(r, "Failed to parse %s, ignoring: %m", option);
return 0;
@@ -670,10 +670,10 @@ int main(int argc, char *argv[]) {
if (arg_discards)
flags |= CRYPT_ACTIVATE_ALLOW_DISCARDS;
- if (arg_timeout > 0)
- until = now(CLOCK_MONOTONIC) + arg_timeout;
- else
+ if (arg_timeout == USEC_INFINITY)
until = 0;
+ else
+ until = now(CLOCK_MONOTONIC) + arg_timeout;
arg_key_size = (arg_key_size > 0 ? arg_key_size : (256 / 8));
diff --git a/src/delta/delta.c b/src/delta/delta.c
index 9a44b15da7..b0689ffff7 100644
--- a/src/delta/delta.c
+++ b/src/delta/delta.c
@@ -205,7 +205,12 @@ static int found_override(const char *top, const char *bottom) {
return k;
}
-static int enumerate_dir_d(Hashmap *top, Hashmap *bottom, Hashmap *drops, const char *toppath, const char *drop) {
+static int enumerate_dir_d(
+ OrderedHashmap *top,
+ OrderedHashmap *bottom,
+ OrderedHashmap *drops,
+ const char *toppath, const char *drop) {
+
_cleanup_free_ char *unit = NULL;
_cleanup_free_ char *path = NULL;
_cleanup_strv_free_ char **list = NULL;
@@ -234,8 +239,10 @@ static int enumerate_dir_d(Hashmap *top, Hashmap *bottom, Hashmap *drops, const
if (r < 0)
return log_error_errno(r, "Failed to enumerate %s: %m", path);
+ strv_sort(list);
+
STRV_FOREACH(file, list) {
- Hashmap *h;
+ OrderedHashmap *h;
int k;
char *p;
char *d;
@@ -249,7 +256,7 @@ static int enumerate_dir_d(Hashmap *top, Hashmap *bottom, Hashmap *drops, const
d = p + strlen(toppath) + 1;
log_debug("Adding at top: %s %s %s", d, special_glyph(ARROW), p);
- k = hashmap_put(top, d, p);
+ k = ordered_hashmap_put(top, d, p);
if (k >= 0) {
p = strdup(p);
if (!p)
@@ -261,19 +268,19 @@ static int enumerate_dir_d(Hashmap *top, Hashmap *bottom, Hashmap *drops, const
}
log_debug("Adding at bottom: %s %s %s", d, special_glyph(ARROW), p);
- free(hashmap_remove(bottom, d));
- k = hashmap_put(bottom, d, p);
+ free(ordered_hashmap_remove(bottom, d));
+ k = ordered_hashmap_put(bottom, d, p);
if (k < 0) {
free(p);
return k;
}
- h = hashmap_get(drops, unit);
+ h = ordered_hashmap_get(drops, unit);
if (!h) {
- h = hashmap_new(&string_hash_ops);
+ h = ordered_hashmap_new(&string_hash_ops);
if (!h)
return -ENOMEM;
- hashmap_put(drops, unit, h);
+ ordered_hashmap_put(drops, unit, h);
unit = strdup(unit);
if (!unit)
return -ENOMEM;
@@ -285,7 +292,7 @@ static int enumerate_dir_d(Hashmap *top, Hashmap *bottom, Hashmap *drops, const
log_debug("Adding to drops: %s %s %s %s %s",
unit, special_glyph(ARROW), basename(p), special_glyph(ARROW), p);
- k = hashmap_put(h, basename(p), p);
+ k = ordered_hashmap_put(h, basename(p), p);
if (k < 0) {
free(p);
if (k != -EEXIST)
@@ -295,9 +302,18 @@ static int enumerate_dir_d(Hashmap *top, Hashmap *bottom, Hashmap *drops, const
return 0;
}
-static int enumerate_dir(Hashmap *top, Hashmap *bottom, Hashmap *drops, const char *path, bool dropins) {
- _cleanup_closedir_ DIR *d;
+static int enumerate_dir(
+ OrderedHashmap *top,
+ OrderedHashmap *bottom,
+ OrderedHashmap *drops,
+ const char *path, bool dropins) {
+
+ _cleanup_closedir_ DIR *d = NULL;
struct dirent *de;
+ _cleanup_strv_free_ char **files = NULL, **dirs = NULL;
+ size_t n_files = 0, allocated_files = 0, n_dirs = 0, allocated_dirs = 0;
+ char **t;
+ int r;
assert(top);
assert(bottom);
@@ -315,40 +331,63 @@ static int enumerate_dir(Hashmap *top, Hashmap *bottom, Hashmap *drops, const ch
}
FOREACH_DIRENT_ALL(de, d, return -errno) {
- int k;
- char *p;
-
dirent_ensure_type(d, de);
- if (dropins && de->d_type == DT_DIR && endswith(de->d_name, ".d"))
- enumerate_dir_d(top, bottom, drops, path, de->d_name);
+ if (dropins && de->d_type == DT_DIR && endswith(de->d_name, ".d")) {
+ if (!GREEDY_REALLOC0(dirs, allocated_dirs, n_dirs + 2))
+ return -ENOMEM;
+
+ dirs[n_dirs] = strdup(de->d_name);
+ if (!dirs[n_dirs])
+ return -ENOMEM;
+ n_dirs ++;
+ }
if (!dirent_is_file(de))
continue;
- p = strjoin(path, "/", de->d_name);
+ if (!GREEDY_REALLOC0(files, allocated_files, n_files + 2))
+ return -ENOMEM;
+
+ files[n_files] = strdup(de->d_name);
+ if (!files[n_files])
+ return -ENOMEM;
+ n_files ++;
+ }
+
+ strv_sort(dirs);
+ strv_sort(files);
+
+ STRV_FOREACH(t, dirs) {
+ r = enumerate_dir_d(top, bottom, drops, path, *t);
+ if (r < 0)
+ return r;
+ }
+
+ STRV_FOREACH(t, files) {
+ _cleanup_free_ char *p = NULL;
+
+ p = strjoin(path, "/", *t);
if (!p)
return -ENOMEM;
log_debug("Adding at top: %s %s %s", basename(p), special_glyph(ARROW), p);
- k = hashmap_put(top, basename(p), p);
- if (k >= 0) {
+ r = ordered_hashmap_put(top, basename(p), p);
+ if (r >= 0) {
p = strdup(p);
if (!p)
return -ENOMEM;
- } else if (k != -EEXIST) {
- free(p);
- return k;
- }
+ } else if (r != -EEXIST)
+ return r;
log_debug("Adding at bottom: %s %s %s", basename(p), special_glyph(ARROW), p);
- free(hashmap_remove(bottom, basename(p)));
- k = hashmap_put(bottom, basename(p), p);
- if (k < 0) {
- free(p);
- return k;
- }
+ free(ordered_hashmap_remove(bottom, basename(p)));
+ r = ordered_hashmap_put(bottom, basename(p), p);
+ if (r < 0)
+ return r;
+ p = NULL;
}
+
return 0;
}
@@ -370,8 +409,8 @@ static int should_skip_prefix(const char* p) {
static int process_suffix(const char *suffix, const char *onlyprefix) {
const char *p;
char *f;
- Hashmap *top, *bottom, *drops;
- Hashmap *h;
+ OrderedHashmap *top, *bottom, *drops;
+ OrderedHashmap *h;
char *key;
int r = 0, k;
Iterator i, j;
@@ -384,9 +423,9 @@ static int process_suffix(const char *suffix, const char *onlyprefix) {
dropins = nulstr_contains(have_dropins, suffix);
- top = hashmap_new(&string_hash_ops);
- bottom = hashmap_new(&string_hash_ops);
- drops = hashmap_new(&string_hash_ops);
+ top = ordered_hashmap_new(&string_hash_ops);
+ bottom = ordered_hashmap_new(&string_hash_ops);
+ drops = ordered_hashmap_new(&string_hash_ops);
if (!top || !bottom || !drops) {
r = -ENOMEM;
goto finish;
@@ -415,10 +454,10 @@ static int process_suffix(const char *suffix, const char *onlyprefix) {
r = k;
}
- HASHMAP_FOREACH_KEY(f, key, top, i) {
+ ORDERED_HASHMAP_FOREACH_KEY(f, key, top, i) {
char *o;
- o = hashmap_get(bottom, key);
+ o = ordered_hashmap_get(bottom, key);
assert(o);
if (!onlyprefix || startswith(o, onlyprefix)) {
@@ -433,23 +472,23 @@ static int process_suffix(const char *suffix, const char *onlyprefix) {
}
}
- h = hashmap_get(drops, key);
+ h = ordered_hashmap_get(drops, key);
if (h)
- HASHMAP_FOREACH(o, h, j)
+ ORDERED_HASHMAP_FOREACH(o, h, j)
if (!onlyprefix || startswith(o, onlyprefix))
n_found += notify_override_extended(f, o);
}
finish:
- hashmap_free_free(top);
- hashmap_free_free(bottom);
+ ordered_hashmap_free_free(top);
+ ordered_hashmap_free_free(bottom);
- HASHMAP_FOREACH_KEY(h, key, drops, i) {
- hashmap_free_free(hashmap_remove(drops, key));
- hashmap_remove(drops, key);
+ ORDERED_HASHMAP_FOREACH_KEY(h, key, drops, i) {
+ ordered_hashmap_free_free(ordered_hashmap_remove(drops, key));
+ ordered_hashmap_remove(drops, key);
free(key);
}
- hashmap_free(drops);
+ ordered_hashmap_free(drops);
return r < 0 ? r : n_found;
}
diff --git a/src/environment-d-generator/environment-d-generator.c b/src/environment-d-generator/environment-d-generator.c
index 2d4c4235e4..9c72502373 100644
--- a/src/environment-d-generator/environment-d-generator.c
+++ b/src/environment-d-generator/environment-d-generator.c
@@ -78,7 +78,7 @@ static int load_and_print(void) {
t = strchr(*i, '=');
assert(t);
- q = shell_maybe_quote(t + 1);
+ q = shell_maybe_quote(t + 1, ESCAPE_BACKSLASH);
if (!q)
return log_oom();
diff --git a/src/escape/escape.c b/src/escape/escape.c
index af98c98e40..89e885d47c 100644
--- a/src/escape/escape.c
+++ b/src/escape/escape.c
@@ -38,7 +38,7 @@ static bool arg_path = false;
static void help(void) {
printf("%s [OPTIONS...] [NAME...]\n\n"
- "Show system and user paths.\n\n"
+ "Escape strings for usage in system unit names.\n\n"
" -h --help Show this help\n"
" --version Show package version\n"
" --suffix=SUFFIX Unit suffix to append to escaped strings\n"
diff --git a/src/firstboot/firstboot.c b/src/firstboot/firstboot.c
index f7574223ae..6b76a78692 100644
--- a/src/firstboot/firstboot.c
+++ b/src/firstboot/firstboot.c
@@ -572,7 +572,7 @@ static int process_root_password(void) {
if (!arg_root_password)
return 0;
- r = dev_urandom(raw, 16);
+ r = acquire_random_bytes(raw, 16, true);
if (r < 0)
return log_error_errno(r, "Failed to get salt: %m");
diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c
index 50d350fce8..f172e9c07b 100644
--- a/src/fstab-generator/fstab-generator.c
+++ b/src/fstab-generator/fstab-generator.c
@@ -25,6 +25,7 @@
#include "alloc-util.h"
#include "fd-util.h"
+#include "fs-util.h"
#include "fileio.h"
#include "fstab-util.h"
#include "generator.h"
@@ -176,7 +177,7 @@ static bool mount_in_initrd(struct mntent *me) {
}
static int write_timeout(FILE *f, const char *where, const char *opts,
- const char *filter, const char *variable) {
+ const char *filter, const char *variable) {
_cleanup_free_ char *timeout = NULL;
char timespan[FORMAT_TIMESPAN_MAX];
usec_t u;
@@ -188,7 +189,7 @@ static int write_timeout(FILE *f, const char *where, const char *opts,
if (r == 0)
return 0;
- r = parse_sec(timeout, &u);
+ r = parse_sec_fix_0(timeout, &u);
if (r < 0) {
log_warning("Failed to parse timeout for %s, ignoring: %s", where, timeout);
return 0;
@@ -290,6 +291,7 @@ static int add_mount(
const char *dest,
const char *what,
const char *where,
+ const char *original_where,
const char *fstype,
const char *opts,
int passno,
@@ -358,6 +360,20 @@ static int add_mount(
"Documentation=man:fstab(5) man:systemd-fstab-generator(8)\n",
source);
+ if (STRPTR_IN_SET(fstype, "nfs", "nfs4") && !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.
+ * As we are making 'bg' mounts look like an 'fg' mount to
+ * mount.nfs (so systemd can manage the job-control aspects of 'bg'),
+ * we need to explicitly preserve that default, and also ensure
+ * the systemd mount-timeout doesn't interfere.
+ * 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;
+ }
+
if (!nofail && !automount)
fprintf(f, "Before=%s\n", post);
@@ -382,11 +398,10 @@ static int add_mount(
return r;
}
- fprintf(f,
- "\n"
- "[Mount]\n"
- "Where=%s\n",
- where);
+ fprintf(f, "\n[Mount]\n");
+ if (original_where)
+ fprintf(f, "# Canonicalized from %s\n", original_where);
+ fprintf(f, "Where=%s\n", where);
r = write_what(f, what);
if (r < 0)
@@ -399,6 +414,10 @@ static int add_mount(
if (r < 0)
return r;
+ r = generator_write_device_deps(dest, what, where, opts);
+ if (r < 0)
+ return r;
+
r = write_mount_timeout(f, where, opts);
if (r < 0)
return r;
@@ -502,7 +521,7 @@ static int parse_fstab(bool initrd) {
}
while ((me = getmntent(f))) {
- _cleanup_free_ char *where = NULL, *what = NULL;
+ _cleanup_free_ char *where = NULL, *what = NULL, *canonical_where = NULL;
bool noauto, nofail;
int k;
@@ -518,12 +537,32 @@ static int parse_fstab(bool initrd) {
continue;
}
- where = initrd ? strappend("/sysroot/", me->mnt_dir) : strdup(me->mnt_dir);
+ where = strdup(me->mnt_dir);
if (!where)
return log_oom();
- if (is_path(where))
+ if (is_path(where)) {
path_kill_slashes(where);
+ /* Follow symlinks here; see 5261ba901845c084de5a8fd06500ed09bfb0bd80 which makes sense for
+ * mount units, but causes problems since it historically worked to have symlinks in e.g.
+ * /etc/fstab. So we canonicalize here. Note that we use CHASE_NONEXISTENT to handle the case
+ * where a symlink refers to another mount target; this works assuming the sub-mountpoint
+ * target is the final directory.
+ */
+ r = chase_symlinks(where, initrd ? "/sysroot" : NULL,
+ CHASE_PREFIX_ROOT | CHASE_NONEXISTENT,
+ &canonical_where);
+ if (r < 0)
+ /* In this case for now we continue on as if it wasn't a symlink */
+ log_warning_errno(r, "Failed to read symlink target for %s: %m", where);
+ else {
+ if (streq(canonical_where, where))
+ canonical_where = mfree(canonical_where);
+ else
+ log_debug("Canonicalized what=%s where=%s to %s",
+ what, where, canonical_where);
+ }
+ }
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");
@@ -549,7 +588,8 @@ static int parse_fstab(bool initrd) {
k = add_mount(arg_dest,
what,
- where,
+ canonical_where ?: where,
+ canonical_where ? where: NULL,
me->mnt_type,
me->mnt_opts,
me->mnt_passno,
@@ -612,6 +652,7 @@ static int add_sysroot_mount(void) {
return add_mount(arg_dest,
what,
"/sysroot",
+ NULL,
arg_root_fstype,
opts,
is_device_path(what) ? 1 : 0, /* passno */
@@ -666,6 +707,7 @@ static int add_sysroot_usr_mount(void) {
return add_mount(arg_dest,
what,
"/sysroot/usr",
+ NULL,
arg_usr_fstype,
opts,
is_device_path(what) ? 1 : 0, /* passno */
@@ -706,6 +748,7 @@ static int add_volatile_var(void) {
return add_mount(arg_dest_late,
"tmpfs",
"/var",
+ NULL,
"tmpfs",
"mode=0755",
0,
diff --git a/src/gpt-auto-generator/gpt-auto-generator.c b/src/gpt-auto-generator/gpt-auto-generator.c
index 80f676e477..a072242430 100644
--- a/src/gpt-auto-generator/gpt-auto-generator.c
+++ b/src/gpt-auto-generator/gpt-auto-generator.c
@@ -17,7 +17,7 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <blkid/blkid.h>
+#include <blkid.h>
#include <stdlib.h>
#include <sys/statfs.h>
#include <unistd.h>
@@ -305,6 +305,15 @@ static int add_swap(const char *path) {
assert(path);
+ /* Disable the swap auto logic if at least one swap is defined in /etc/fstab, see #6192. */
+ r = fstab_has_fstype("swap");
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse fstab: %m");
+ if (r > 0) {
+ log_debug("swap specified in fstab, ignoring.");
+ return 0;
+ }
+
log_debug("Adding swap: %s", path);
r = unit_name_from_path(path, ".swap", &name);
@@ -435,7 +444,10 @@ static int add_esp(DissectedPartition *p) {
esp = access("/efi/", F_OK) >= 0 ? "/efi" : "/boot";
/* We create an .automount which is not overridden by the .mount from the fstab generator. */
- if (fstab_is_mount_point(esp)) {
+ r = fstab_is_mount_point(esp);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse fstab: %m");
+ if (r > 0) {
log_debug("%s specified in fstab, ignoring.", esp);
return 0;
}
diff --git a/src/hostname/meson.build b/src/hostname/meson.build
new file mode 100644
index 0000000000..d58caa6787
--- /dev/null
+++ b/src/hostname/meson.build
@@ -0,0 +1,14 @@
+if conf.get('ENABLE_HOSTNAMED', false)
+ install_data('org.freedesktop.hostname1.conf',
+ install_dir : dbuspolicydir)
+ install_data('org.freedesktop.hostname1.service',
+ install_dir : dbussystemservicedir)
+
+ custom_target(
+ 'org.freedesktop.hostname1.policy',
+ input : 'org.freedesktop.hostname1.policy.in',
+ output : 'org.freedesktop.hostname1.policy',
+ command : intltool_command,
+ install : install_polkit,
+ install_dir : polkitpolicydir)
+endif
diff --git a/src/hwdb/hwdb.c b/src/hwdb/hwdb.c
index df79fbc275..793398ca68 100644
--- a/src/hwdb/hwdb.c
+++ b/src/hwdb/hwdb.c
@@ -391,7 +391,7 @@ static int trie_store(struct trie *trie, const char *filename) {
int64_t size;
struct trie_header_f h = {
.signature = HWDB_SIG,
- .tool_version = htole64(atoi(VERSION)),
+ .tool_version = htole64(atoi(PACKAGE_VERSION)),
.header_size = htole64(sizeof(struct trie_header_f)),
.node_size = htole64(sizeof(struct trie_node_f)),
.child_entry_size = htole64(sizeof(struct trie_child_entry_f)),
diff --git a/src/import/meson.build b/src/import/meson.build
new file mode 100644
index 0000000000..3fd58cc2c8
--- /dev/null
+++ b/src/import/meson.build
@@ -0,0 +1,77 @@
+systemd_importd_sources = files('''
+ importd.c
+'''.split())
+
+systemd_pull_sources = files('''
+ pull.c
+ pull-raw.c
+ pull-raw.h
+ pull-tar.c
+ pull-tar.h
+ pull-job.c
+ pull-job.h
+ pull-common.c
+ pull-common.h
+ import-common.c
+ import-common.h
+ import-compress.c
+ import-compress.h
+ curl-util.c
+ curl-util.h
+ qcow2-util.c
+ qcow2-util.h
+'''.split())
+
+systemd_import_sources = files('''
+ import.c
+ import-raw.c
+ import-raw.h
+ import-tar.c
+ import-tar.h
+ import-common.c
+ import-common.h
+ import-compress.c
+ import-compress.h
+ qcow2-util.c
+ qcow2-util.h
+'''.split())
+
+systemd_export_sources = files('''
+ export.c
+ export-tar.c
+ export-tar.h
+ export-raw.c
+ export-raw.h
+ import-common.c
+ import-common.h
+ import-compress.c
+ import-compress.h
+'''.split())
+
+if conf.get('ENABLE_IMPORTD', false)
+ install_data('org.freedesktop.import1.conf',
+ install_dir : dbuspolicydir)
+ install_data('org.freedesktop.import1.service',
+ install_dir : dbussystemservicedir)
+
+ custom_target(
+ 'org.freedesktop.import1.policy',
+ input : 'org.freedesktop.import1.policy.in',
+ output : 'org.freedesktop.import1.policy',
+ command : intltool_command,
+ install : install_polkit,
+ install_dir : polkitpolicydir)
+
+ install_data('import-pubring.gpg',
+ install_dir : rootlibexecdir)
+ # TODO: shouldn't this be in pkgdatadir?
+endif
+
+tests += [
+ [['src/import/test-qcow2.c',
+ 'src/import/qcow2-util.c',
+ 'src/import/qcow2-util.h'],
+ [libshared],
+ [libz],
+ 'HAVE_ZLIB', 'manual'],
+]
diff --git a/src/import/pull-common.c b/src/import/pull-common.c
index 62a9195cc4..78840dd882 100644
--- a/src/import/pull-common.c
+++ b/src/import/pull-common.c
@@ -275,6 +275,7 @@ int pull_make_verification_jobs(
_cleanup_(pull_job_unrefp) PullJob *checksum_job = NULL, *signature_job = NULL;
int r;
+ const char *chksums = NULL;
assert(ret_checksum_job);
assert(ret_signature_job);
@@ -284,10 +285,16 @@ int pull_make_verification_jobs(
assert(glue);
if (verify != IMPORT_VERIFY_NO) {
- _cleanup_free_ char *checksum_url = NULL;
+ _cleanup_free_ char *checksum_url = NULL, *fn = NULL;
- /* Queue job for the SHA256SUMS file for the image */
- r = import_url_change_last_component(url, "SHA256SUMS", &checksum_url);
+ /* Queue jobs for the checksum file for the image. */
+ r = import_url_last_component(url, &fn);
+ if (r < 0)
+ return r;
+
+ chksums = strjoina(fn, ".sha256");
+
+ r = import_url_change_last_component(url, chksums, &checksum_url);
if (r < 0)
return r;
@@ -362,6 +369,15 @@ static int verify_one(PullJob *checksum_job, PullJob *job) {
line,
strlen(line));
+ if (!p) {
+ line = strjoina(job->checksum, " ", fn, "\n");
+
+ p = memmem(checksum_job->payload,
+ checksum_job->payload_size,
+ line,
+ strlen(line));
+ }
+
if (!p || (p != (char*) checksum_job->payload && p[-1] != '\n')) {
log_error("DOWNLOAD INVALID: Checksum of %s file did not checkout, file has been tampered with.", fn);
return -EBADMSG;
@@ -378,7 +394,6 @@ int pull_verify(PullJob *main_job,
PullJob *signature_job) {
_cleanup_close_pair_ int gpg_pipe[2] = { -1, -1 };
- _cleanup_free_ char *fn = NULL;
_cleanup_close_ int sig_file = -1;
char sig_file_path[] = "/tmp/sigXXXXXX", gpg_home[] = "/tmp/gpghomeXXXXXX";
_cleanup_(sigkill_waitp) pid_t pid = 0;
@@ -416,6 +431,9 @@ int pull_verify(PullJob *main_job,
if (!signature_job)
return 0;
+ if (checksum_job->style == VERIFICATION_PER_FILE)
+ signature_job = checksum_job;
+
assert(signature_job->state == PULL_JOB_DONE);
if (!signature_job->payload || signature_job->payload_size <= 0) {
@@ -507,9 +525,11 @@ int pull_verify(PullJob *main_job,
cmd[k++] = "--keyring=" VENDOR_KEYRING_PATH;
cmd[k++] = "--verify";
- cmd[k++] = sig_file_path;
- cmd[k++] = "-";
- cmd[k++] = NULL;
+ if (checksum_job->style == VERIFICATION_PER_DIRECTORY) {
+ cmd[k++] = sig_file_path;
+ cmd[k++] = "-";
+ cmd[k++] = NULL;
+ }
stdio_unset_cloexec();
diff --git a/src/import/pull-job.c b/src/import/pull-job.c
index 70aaa5c291..320c21305a 100644
--- a/src/import/pull-job.c
+++ b/src/import/pull-job.c
@@ -22,9 +22,11 @@
#include "alloc-util.h"
#include "fd-util.h"
#include "hexdecoct.h"
+#include "import-util.h"
#include "io-util.h"
#include "machine-pool.h"
#include "parse-util.h"
+#include "pull-common.h"
#include "pull-job.h"
#include "string-util.h"
#include "strv.h"
@@ -73,6 +75,31 @@ static void pull_job_finish(PullJob *j, int ret) {
j->on_finished(j);
}
+static int pull_job_restart(PullJob *j) {
+ int r;
+ char *chksum_url = NULL;
+
+ r = import_url_change_last_component(j->url, "SHA256SUMS", &chksum_url);
+ if (r < 0)
+ return r;
+
+ free(j->url);
+ j->url = chksum_url;
+ j->state = PULL_JOB_INIT;
+ j->payload = mfree(j->payload);
+ j->payload_size = 0;
+ j->payload_allocated = 0;
+ j->written_compressed = 0;
+ j->written_uncompressed = 0;
+ j->written_since_last_grow = 0;
+
+ r = pull_job_begin(j);
+ if (r < 0)
+ return r;
+
+ return 0;
+}
+
void pull_job_curl_on_finished(CurlGlue *g, CURL *curl, CURLcode result) {
PullJob *j = NULL;
CURLcode code;
@@ -102,6 +129,26 @@ void pull_job_curl_on_finished(CurlGlue *g, CURL *curl, CURLcode result) {
r = 0;
goto finish;
} else if (status >= 300) {
+ if (status == 404 && j->style == VERIFICATION_PER_FILE) {
+
+ /* retry pull job with SHA256SUMS file */
+ r = pull_job_restart(j);
+ if (r < 0)
+ goto finish;
+
+ code = curl_easy_getinfo(j->curl, CURLINFO_RESPONSE_CODE, &status);
+ if (code != CURLE_OK) {
+ log_error("Failed to retrieve response code: %s", curl_easy_strerror(code));
+ r = -EIO;
+ goto finish;
+ }
+
+ if (status == 0) {
+ j->style = VERIFICATION_PER_DIRECTORY;
+ return;
+ }
+ }
+
log_error("HTTP request to %s failed with code %li.", j->url, status);
r = -EIO;
goto finish;
@@ -528,6 +575,7 @@ int pull_job_new(PullJob **ret, const char *url, CurlGlue *glue, void *userdata)
j->content_length = (uint64_t) -1;
j->start_usec = now(CLOCK_MONOTONIC);
j->compressed_max = j->uncompressed_max = 64LLU * 1024LLU * 1024LLU * 1024LLU; /* 64GB safety limit */
+ j->style = VERIFICATION_STYLE_UNSET;
j->url = strdup(url);
if (!j->url)
diff --git a/src/import/pull-job.h b/src/import/pull-job.h
index 3a152a50e3..412b66cf22 100644
--- a/src/import/pull-job.h
+++ b/src/import/pull-job.h
@@ -42,6 +42,12 @@ typedef enum PullJobState {
_PULL_JOB_STATE_INVALID = -1,
} PullJobState;
+typedef enum VerificationStyle {
+ VERIFICATION_STYLE_UNSET,
+ VERIFICATION_PER_FILE, /* SuSE-style ".sha256" files with inline signature */
+ VERIFICATION_PER_DIRECTORY, /* Ubuntu-style SHA256SUM files with detach SHA256SUM.gpg signatures */
+} VerificationStyle;
+
#define PULL_JOB_IS_COMPLETE(j) (IN_SET((j)->state, PULL_JOB_DONE, PULL_JOB_FAILED))
struct PullJob {
@@ -94,6 +100,8 @@ struct PullJob {
bool grow_machine_directory;
uint64_t written_since_last_grow;
+
+ VerificationStyle style;
};
int pull_job_new(PullJob **job, const char *url, CurlGlue *glue, void *userdata);
diff --git a/src/import/pull-raw.c b/src/import/pull-raw.c
index 60a769e944..b45ac814a9 100644
--- a/src/import/pull-raw.c
+++ b/src/import/pull-raw.c
@@ -444,7 +444,7 @@ static int raw_pull_rename_auxiliary_file(
assert(suffix);
assert(path);
- /* Regenerate final name for this auxiliary file, we might know the etag of the raw file now, and we shoud
+ /* Regenerate final name for this auxiliary file, we might know the etag of the file now, and we should
* incorporate it in the file name if we can */
*path = mfree(*path);
r = raw_pull_determine_path(i, suffix, path);
@@ -478,11 +478,9 @@ static void raw_pull_job_on_finished(PullJob *j) {
} else if (j == i->settings_job) {
if (j->error != 0)
log_info_errno(j->error, "Settings file could not be retrieved, proceeding without.");
- } else if (j->error != 0) {
+ } else if (j->error != 0 && j != i->signature_job) {
if (j == i->checksum_job)
log_error_errno(j->error, "Failed to retrieve SHA256 checksum, cannot verify. (Try --verify=no?)");
- else if (j == i->signature_job)
- log_error_errno(j->error, "Failed to retrieve signature file, cannot verify. (Try --verify=no?)");
else
log_error_errno(j->error, "Failed to retrieve image file. (Wrong URL?)");
@@ -500,6 +498,13 @@ static void raw_pull_job_on_finished(PullJob *j) {
if (!raw_pull_is_done(i))
return;
+ if (i->signature_job && i->checksum_job->style == VERIFICATION_PER_DIRECTORY && i->signature_job->error != 0) {
+ log_error_errno(j->error, "Failed to retrieve signature file, cannot verify. (Try --verify=no?)");
+
+ r = i->signature_job->error;
+ goto finish;
+ }
+
if (i->roothash_job)
i->roothash_job->disk_fd = safe_close(i->roothash_job->disk_fd);
if (i->settings_job)
@@ -533,7 +538,7 @@ static void raw_pull_job_on_finished(PullJob *j) {
r = rename_noreplace(AT_FDCWD, i->temp_path, AT_FDCWD, i->final_path);
if (r < 0) {
- log_error_errno(r, "Failed to move RAW file into place: %m");
+ log_error_errno(r, "Failed to rename raw file to %s: %m", i->final_path);
goto finish;
}
@@ -575,7 +580,6 @@ static int raw_pull_job_on_open_disk_generic(
const char *extra,
char **temp_path) {
- _cleanup_free_ char *p = NULL;
int r;
assert(i);
@@ -744,6 +748,7 @@ int raw_pull_start(
if (i->checksum_job) {
i->checksum_job->on_progress = raw_pull_job_on_progress;
+ i->checksum_job->style = VERIFICATION_PER_FILE;
r = pull_job_begin(i->checksum_job);
if (r < 0)
diff --git a/src/import/pull-tar.c b/src/import/pull-tar.c
index 91833d6174..12211a6fc6 100644
--- a/src/import/pull-tar.c
+++ b/src/import/pull-tar.c
@@ -114,6 +114,7 @@ TarPull* tar_pull_unref(TarPull *i) {
free(i->settings_path);
free(i->image_root);
free(i->local);
+
return mfree(i);
}
@@ -298,11 +299,9 @@ static void tar_pull_job_on_finished(PullJob *j) {
if (j == i->settings_job) {
if (j->error != 0)
log_info_errno(j->error, "Settings file could not be retrieved, proceeding without.");
- } else if (j->error != 0) {
+ } else if (j->error != 0 && j != i->signature_job) {
if (j == i->checksum_job)
log_error_errno(j->error, "Failed to retrieve SHA256 checksum, cannot verify. (Try --verify=no?)");
- else if (j == i->signature_job)
- log_error_errno(j->error, "Failed to retrieve signature file, cannot verify. (Try --verify=no?)");
else
log_error_errno(j->error, "Failed to retrieve image file. (Wrong URL?)");
@@ -317,6 +316,13 @@ static void tar_pull_job_on_finished(PullJob *j) {
if (!tar_pull_is_done(i))
return;
+ if (i->signature_job && i->checksum_job->style == VERIFICATION_PER_DIRECTORY && i->signature_job->error != 0) {
+ log_error_errno(j->error, "Failed to retrieve signature file, cannot verify. (Try --verify=no?)");
+
+ r = i->signature_job->error;
+ goto finish;
+ }
+
i->tar_job->disk_fd = safe_close(i->tar_job->disk_fd);
if (i->settings_job)
i->settings_job->disk_fd = safe_close(i->settings_job->disk_fd);
@@ -353,7 +359,7 @@ static void tar_pull_job_on_finished(PullJob *j) {
r = rename_noreplace(AT_FDCWD, i->temp_path, AT_FDCWD, i->final_path);
if (r < 0) {
- log_error_errno(r, "Failed to rename to final image name: %m");
+ log_error_errno(r, "Failed to rename to final image name to %s: %m", i->final_path);
goto finish;
}
@@ -362,13 +368,14 @@ static void tar_pull_job_on_finished(PullJob *j) {
if (i->settings_job &&
i->settings_job->error == 0) {
- assert(i->settings_temp_path);
- assert(i->settings_path);
-
- /* Also move the settings file into place, if it exist. Note that we do so only if we also
+ /* Also move the settings file into place, if it exists. Note that we do so only if we also
* moved the tar file in place, to keep things strictly in sync. */
+ assert(i->settings_temp_path);
+ /* Regenerate final name for this auxiliary file, we might know the etag of the file now, and
+ * we should incorporate it in the file name if we can */
i->settings_path = mfree(i->settings_path);
+
r = tar_pull_determine_path(i, ".nspawn", &i->settings_path);
if (r < 0)
goto finish;
@@ -379,7 +386,7 @@ static void tar_pull_job_on_finished(PullJob *j) {
r = rename_noreplace(AT_FDCWD, i->settings_temp_path, AT_FDCWD, i->settings_path);
if (r < 0) {
- log_error_errno(r, "Failed to rename settings file: %m");
+ log_error_errno(r, "Failed to rename settings file to %s: %m", i->settings_path);
goto finish;
}
@@ -547,6 +554,7 @@ int tar_pull_start(
if (i->checksum_job) {
i->checksum_job->on_progress = tar_pull_job_on_progress;
+ i->checksum_job->style = VERIFICATION_PER_FILE;
r = pull_job_begin(i->checksum_job);
if (r < 0)
diff --git a/src/initctl/initctl.c b/src/initctl/initctl.c
index 6aeb5ad614..deb3f1b2a8 100644
--- a/src/initctl/initctl.c
+++ b/src/initctl/initctl.c
@@ -388,7 +388,7 @@ int main(int argc, char *argv[]) {
if (server_init(&server, (unsigned) n) < 0)
return EXIT_FAILURE;
- log_debug("systemd-initctl running as pid "PID_FMT, getpid());
+ log_debug("systemd-initctl running as pid "PID_FMT, getpid_cached());
sd_notify(false,
"READY=1\n"
@@ -415,7 +415,7 @@ int main(int argc, char *argv[]) {
r = EXIT_SUCCESS;
- log_debug("systemd-initctl stopped as pid "PID_FMT, getpid());
+ log_debug("systemd-initctl stopped as pid "PID_FMT, getpid_cached());
fail:
sd_notify(false,
diff --git a/src/journal-remote/journal-remote.c b/src/journal-remote/journal-remote.c
index 202a5a3f97..810206c621 100644
--- a/src/journal-remote/journal-remote.c
+++ b/src/journal-remote/journal-remote.c
@@ -86,7 +86,7 @@ static int spawn_child(const char* child, char** argv) {
if (pipe(fd) < 0)
return log_error_errno(errno, "Failed to create pager pipe: %m");
- parent_pid = getpid();
+ parent_pid = getpid_cached();
child_pid = fork();
if (child_pid < 0) {
@@ -529,7 +529,7 @@ static int process_http_upload(
log_warning("Failed to process data for connection %p", connection);
if (r == -E2BIG)
return mhd_respondf(connection,
- r, MHD_HTTP_REQUEST_ENTITY_TOO_LARGE,
+ r, MHD_HTTP_PAYLOAD_TOO_LARGE,
"Entry is too large, maximum is " STRINGIFY(DATA_SIZE_MAX) " bytes.");
else
return mhd_respondf(connection,
@@ -1200,9 +1200,9 @@ 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);
+ CONF_PATHS_NULSTR("systemd/journal-remote.conf.d"),
+ "Remote\0", config_item_table_lookup, items,
+ false, NULL);
}
static void help(void) {
@@ -1564,7 +1564,7 @@ int main(int argc, char **argv) {
log_debug("Watchdog is %sd.", enable_disable(r > 0));
log_debug("%s running as pid "PID_FMT,
- program_invocation_short_name, getpid());
+ program_invocation_short_name, getpid_cached());
sd_notify(false,
"READY=1\n"
"STATUS=Processing requests...");
diff --git a/src/journal-remote/journal-upload-journal.c b/src/journal-remote/journal-upload-journal.c
index 8ce8e1895e..3a36e46ae0 100644
--- a/src/journal-remote/journal-upload-journal.c
+++ b/src/journal-remote/journal-upload-journal.c
@@ -251,7 +251,7 @@ static inline void check_update_watchdog(Uploader *u) {
return;
after = now(CLOCK_MONOTONIC);
- elapsed_time = usec_sub(after, u->watchdog_timestamp);
+ elapsed_time = usec_sub_unsigned(after, u->watchdog_timestamp);
if (elapsed_time > u->watchdog_usec / 2) {
log_debug("Update watchdog timer");
sd_notify(false, "WATCHDOG=1");
diff --git a/src/journal-remote/journal-upload.c b/src/journal-remote/journal-upload.c
index 371b6acc64..ea264989ab 100644
--- a/src/journal-remote/journal-upload.c
+++ b/src/journal-remote/journal-upload.c
@@ -541,9 +541,9 @@ 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);
+ CONF_PATHS_NULSTR("systemd/journal-upload.conf.d"),
+ "Upload\0", config_item_table_lookup, items,
+ false, NULL);
}
static void help(void) {
@@ -811,7 +811,7 @@ int main(int argc, char **argv) {
goto cleanup;
log_debug("%s running as pid "PID_FMT,
- program_invocation_short_name, getpid());
+ program_invocation_short_name, getpid_cached());
use_journal = optind >= argc;
if (use_journal) {
diff --git a/src/journal-remote/log-generator.py b/src/journal-remote/log-generator.py
index 7b434b334e..c2f945bb47 100755
--- a/src/journal-remote/log-generator.py
+++ b/src/journal-remote/log-generator.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python3
+#!/usr/bin/env python3
import sys
import argparse
diff --git a/src/journal-remote/meson.build b/src/journal-remote/meson.build
new file mode 100644
index 0000000000..d266b34e65
--- /dev/null
+++ b/src/journal-remote/meson.build
@@ -0,0 +1,49 @@
+systemd_journal_upload_sources = files('''
+ journal-upload.h
+ journal-upload.c
+ journal-upload-journal.c
+'''.split())
+
+systemd_journal_remote_sources = files('''
+ journal-remote-parse.h
+ journal-remote-parse.c
+ journal-remote-write.h
+ journal-remote-write.c
+ journal-remote.h
+ journal-remote.c
+ microhttpd-util.h
+ microhttpd-util.c
+'''.split())
+
+systemd_journal_gatewayd_sources = files('''
+ journal-gatewayd.c
+ microhttpd-util.h
+ microhttpd-util.c
+'''.split())
+
+if conf.get('ENABLE_REMOTE', false) and conf.get('HAVE_LIBCURL', false)
+ journal_upload_conf = configure_file(
+ input : 'journal-upload.conf.in',
+ output : 'journal-upload.conf',
+ configuration : substs)
+ install_data(journal_upload_conf,
+ install_dir : pkgsysconfdir)
+endif
+
+if conf.get('ENABLE_REMOTE', false) and conf.get('HAVE_MICROHTTPD', false)
+ journal_remote_conf = configure_file(
+ input : 'journal-remote.conf.in',
+ output : 'journal-remote.conf',
+ configuration : substs)
+ install_data(journal_remote_conf,
+ install_dir : pkgsysconfdir)
+
+ install_data('browse.html',
+ install_dir : join_paths(pkgdatadir, 'gatewayd'))
+
+ meson.add_install_script('sh', '-c',
+ mkdir_p.format('/var/log/journal/remote'))
+ meson.add_install_script('sh', '-c',
+ 'chown 0:0 $DESTDIR/var/log/journal/remote &&
+ chmod 755 $DESTDIR/var/log/journal/remote || :')
+endif
diff --git a/src/journal-remote/microhttpd-util.c b/src/journal-remote/microhttpd-util.c
index cae10203c6..f5d2d7967a 100644
--- a/src/journal-remote/microhttpd-util.c
+++ b/src/journal-remote/microhttpd-util.c
@@ -103,7 +103,10 @@ int mhd_respondf(struct MHD_Connection *connection,
errno = -error;
fmt = strjoina(format, "\n");
va_start(ap, format);
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat-nonliteral"
r = vasprintf(&m, fmt, ap);
+#pragma GCC diagnostic pop
va_end(ap);
if (r < 0)
diff --git a/src/journal-remote/microhttpd-util.h b/src/journal-remote/microhttpd-util.h
index 49def4f630..7f88c2cb7d 100644
--- a/src/journal-remote/microhttpd-util.h
+++ b/src/journal-remote/microhttpd-util.h
@@ -31,14 +31,21 @@
# define MHD_HTTP_NOT_ACCEPTABLE MHD_HTTP_METHOD_NOT_ACCEPTABLE
#endif
+/* Renamed in µhttpd 0.9.51 */
+#ifndef MHD_USE_PIPE_FOR_SHUTDOWN
+# define MHD_USE_ITC MHD_USE_PIPE_FOR_SHUTDOWN
+#endif
+
/* Renamed in µhttpd 0.9.52 */
#ifndef MHD_USE_EPOLL_LINUX_ONLY
# define MHD_USE_EPOLL MHD_USE_EPOLL_LINUX_ONLY
#endif
-/* Renamed in µhttpd 0.9.51 */
-#ifndef MHD_USE_PIPE_FOR_SHUTDOWN
-# define MHD_USE_ITC MHD_USE_PIPE_FOR_SHUTDOWN
+/* Both the old and new names are defines, check for the new one. */
+
+/* Renamed in µhttpd 0.9.53 */
+#ifndef MHD_HTTP_PAYLOAD_TOO_LARGE
+# define MHD_HTTP_PAYLOAD_TOO_LARGE MHD_HTTP_REQUEST_ENTITY_TOO_LARGE
#endif
#if MHD_VERSION < 0x00094203
diff --git a/src/journal/audit_type-to-name.awk b/src/journal/audit_type-to-name.awk
new file mode 100644
index 0000000000..44fc702eb3
--- /dev/null
+++ b/src/journal/audit_type-to-name.awk
@@ -0,0 +1,9 @@
+BEGIN{
+ print "const char *audit_type_to_string(int type) {\n\tswitch(type) {"
+}
+{
+ printf " case AUDIT_%s: return \"%s\";\n", $1, $1
+}
+END{
+ print " default: return NULL;\n\t}\n}\n"
+}
diff --git a/src/journal/fsprg.c b/src/journal/fsprg.c
index 612b10f3a9..e7c22880be 100644
--- a/src/journal/fsprg.c
+++ b/src/journal/fsprg.c
@@ -40,6 +40,9 @@
#define RND_GEN_Q 0x02
#define RND_GEN_X 0x03
+#pragma GCC diagnostic ignored "-Wpointer-arith"
+/* TODO: remove void* arithmetic and this work-around */
+
/******************************************************************************/
static void mpi_export(void *buf, size_t buflen, const gcry_mpi_t x) {
diff --git a/src/journal/generate-audit_type-list.sh b/src/journal/generate-audit_type-list.sh
new file mode 100755
index 0000000000..18cbe0599c
--- /dev/null
+++ b/src/journal/generate-audit_type-list.sh
@@ -0,0 +1,14 @@
+#!/bin/sh -eu
+
+cpp="$1"
+shift
+
+includes=""
+for i in "$@"; do
+ includes="$includes -include $i"
+done
+
+$cpp -dM $includes - </dev/null | \
+ grep -vE 'AUDIT_.*(FIRST|LAST)_' | \
+ sed -r -n 's/^#define\s+AUDIT_(\w+)\s+([0-9]{4})\s*$$/\1\t\2/p' | \
+ sort -k2
diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c
index 243d5198d9..4ff38de2e6 100644
--- a/src/journal/journal-file.c
+++ b/src/journal/journal-file.c
@@ -162,7 +162,7 @@ static int journal_file_set_offline_thread_join(JournalFile *f) {
f->offline_state = OFFLINE_JOINED;
- if (mmap_cache_got_sigbus(f->mmap, f->fd))
+ if (mmap_cache_got_sigbus(f->mmap, f->cache_fd))
return -EIO;
return 0;
@@ -300,7 +300,7 @@ static int journal_file_set_online(JournalFile *f) {
}
}
- if (mmap_cache_got_sigbus(f->mmap, f->fd))
+ if (mmap_cache_got_sigbus(f->mmap, f->cache_fd))
return -EIO;
switch (f->header->state) {
@@ -356,8 +356,8 @@ JournalFile* journal_file_close(JournalFile *f) {
journal_file_set_offline(f, true);
- if (f->mmap && f->fd >= 0)
- mmap_cache_close_fd(f->mmap, f->fd);
+ if (f->mmap && f->cache_fd)
+ mmap_cache_free_fd(f->mmap, f->cache_fd);
if (f->fd >= 0 && f->defrag_on_close) {
@@ -660,7 +660,7 @@ static int journal_file_allocate(JournalFile *f, uint64_t offset, uint64_t size)
* for sure, since we always call posix_fallocate()
* ourselves */
- if (mmap_cache_got_sigbus(f->mmap, f->fd))
+ if (mmap_cache_got_sigbus(f->mmap, f->cache_fd))
return -EIO;
old_size =
@@ -749,7 +749,7 @@ static int journal_file_move_to(JournalFile *f, ObjectType type, bool keep_alway
return -EADDRNOTAVAIL;
}
- return mmap_cache_get(f->mmap, f->fd, f->prot, type_to_context(type), keep_always, offset, size, &f->last_stat, ret);
+ return mmap_cache_get(f->mmap, f->cache_fd, f->prot, type_to_context(type), keep_always, offset, size, &f->last_stat, ret);
}
static uint64_t minimum_header_size(Object *o) {
@@ -1857,7 +1857,7 @@ int journal_file_append_entry(JournalFile *f, const dual_timestamp *ts, const st
* it is very likely just an effect of a nullified replacement
* mapping page */
- if (mmap_cache_got_sigbus(f->mmap, f->fd))
+ if (mmap_cache_got_sigbus(f->mmap, f->cache_fd))
r = -EIO;
if (f->post_change_timer)
@@ -3144,6 +3144,12 @@ int journal_file_open(
f->close_fd = true;
}
+ f->cache_fd = mmap_cache_add_fd(f->mmap, f->fd);
+ if (!f->cache_fd) {
+ r = -ENOMEM;
+ goto fail;
+ }
+
r = journal_file_fstat(f);
if (r < 0)
goto fail;
@@ -3190,7 +3196,7 @@ int journal_file_open(
goto fail;
}
- r = mmap_cache_get(f->mmap, f->fd, f->prot, CONTEXT_HEADER, true, 0, PAGE_ALIGN(sizeof(Header)), &f->last_stat, &h);
+ r = mmap_cache_get(f->mmap, f->cache_fd, f->prot, CONTEXT_HEADER, true, 0, PAGE_ALIGN(sizeof(Header)), &f->last_stat, &h);
if (r < 0)
goto fail;
@@ -3247,7 +3253,7 @@ int journal_file_open(
#endif
}
- if (mmap_cache_got_sigbus(f->mmap, f->fd)) {
+ if (mmap_cache_got_sigbus(f->mmap, f->cache_fd)) {
r = -EIO;
goto fail;
}
@@ -3269,7 +3275,7 @@ int journal_file_open(
return 0;
fail:
- if (f->fd >= 0 && mmap_cache_got_sigbus(f->mmap, f->fd))
+ if (f->cache_fd && mmap_cache_got_sigbus(f->mmap, f->cache_fd))
r = -EIO;
(void) journal_file_close(f);
@@ -3482,7 +3488,7 @@ int journal_file_copy_entry(JournalFile *from, JournalFile *to, Object *o, uint6
r = journal_file_append_entry_internal(to, &ts, xor_hash, items, n, seqnum, ret, offset);
- if (mmap_cache_got_sigbus(to->mmap, to->fd))
+ if (mmap_cache_got_sigbus(to->mmap, to->cache_fd))
return -EIO;
return r;
diff --git a/src/journal/journal-file.h b/src/journal/journal-file.h
index 564e1a8179..df457c9a81 100644
--- a/src/journal/journal-file.h
+++ b/src/journal/journal-file.h
@@ -75,6 +75,7 @@ typedef enum OfflineState {
typedef struct JournalFile {
int fd;
+ MMapFileDescriptor *cache_fd;
mode_t mode;
diff --git a/src/journal/journal-qrcode.c b/src/journal/journal-qrcode.c
index e38730d65c..5ee10498d1 100644
--- a/src/journal/journal-qrcode.c
+++ b/src/journal/journal-qrcode.c
@@ -17,7 +17,6 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <assert.h>
#include <errno.h>
#include <qrencode.h>
#include <stdbool.h>
@@ -25,6 +24,7 @@
#include <stdlib.h>
#include "journal-qrcode.h"
+#include "macro.h"
#define WHITE_ON_BLACK "\033[40;37;1m"
#define NORMAL "\033[0m"
diff --git a/src/journal/journal-verify.c b/src/journal/journal-verify.c
index 9e4d8a28a5..9feb5b5ae6 100644
--- a/src/journal/journal-verify.c
+++ b/src/journal/journal-verify.c
@@ -377,12 +377,12 @@ static int write_uint64(int fd, uint64_t p) {
return 0;
}
-static int contains_uint64(MMapCache *m, int fd, uint64_t n, uint64_t p) {
+static int contains_uint64(MMapCache *m, MMapFileDescriptor *f, uint64_t n, uint64_t p) {
uint64_t a, b;
int r;
assert(m);
- assert(fd >= 0);
+ assert(f);
/* Bisection ... */
@@ -392,7 +392,7 @@ static int contains_uint64(MMapCache *m, int fd, uint64_t n, uint64_t p) {
c = (a + b) / 2;
- r = mmap_cache_get(m, fd, PROT_READ|PROT_WRITE, 0, false, c * sizeof(uint64_t), sizeof(uint64_t), NULL, (void **) &z);
+ r = mmap_cache_get(m, f, PROT_READ|PROT_WRITE, 0, false, c * sizeof(uint64_t), sizeof(uint64_t), NULL, (void **) &z);
if (r < 0)
return r;
@@ -413,7 +413,7 @@ static int contains_uint64(MMapCache *m, int fd, uint64_t n, uint64_t p) {
static int entry_points_to_data(
JournalFile *f,
- int entry_fd,
+ MMapFileDescriptor *cache_entry_fd,
uint64_t n_entries,
uint64_t entry_p,
uint64_t data_p) {
@@ -424,9 +424,9 @@ static int entry_points_to_data(
bool found = false;
assert(f);
- assert(entry_fd >= 0);
+ assert(cache_entry_fd);
- if (!contains_uint64(f->mmap, entry_fd, n_entries, entry_p)) {
+ if (!contains_uint64(f->mmap, cache_entry_fd, n_entries, entry_p)) {
error(data_p, "Data object references invalid entry at "OFSfmt, entry_p);
return -EBADMSG;
}
@@ -500,16 +500,16 @@ static int entry_points_to_data(
static int verify_data(
JournalFile *f,
Object *o, uint64_t p,
- int entry_fd, uint64_t n_entries,
- int entry_array_fd, uint64_t n_entry_arrays) {
+ MMapFileDescriptor *cache_entry_fd, uint64_t n_entries,
+ MMapFileDescriptor *cache_entry_array_fd, uint64_t n_entry_arrays) {
uint64_t i, n, a, last, q;
int r;
assert(f);
assert(o);
- assert(entry_fd >= 0);
- assert(entry_array_fd >= 0);
+ assert(cache_entry_fd);
+ assert(cache_entry_array_fd);
n = le64toh(o->data.n_entries);
a = le64toh(o->data.entry_array_offset);
@@ -527,7 +527,7 @@ static int verify_data(
assert(o->data.entry_offset);
last = q = le64toh(o->data.entry_offset);
- r = entry_points_to_data(f, entry_fd, n_entries, q, p);
+ r = entry_points_to_data(f, cache_entry_fd, n_entries, q, p);
if (r < 0)
return r;
@@ -540,7 +540,7 @@ static int verify_data(
return -EBADMSG;
}
- if (!contains_uint64(f->mmap, entry_array_fd, n_entry_arrays, a)) {
+ if (!contains_uint64(f->mmap, cache_entry_array_fd, n_entry_arrays, a)) {
error(p, "Invalid array offset "OFSfmt, a);
return -EBADMSG;
}
@@ -565,7 +565,7 @@ static int verify_data(
}
last = q;
- r = entry_points_to_data(f, entry_fd, n_entries, q, p);
+ r = entry_points_to_data(f, cache_entry_fd, n_entries, q, p);
if (r < 0)
return r;
@@ -583,9 +583,9 @@ static int verify_data(
static int verify_hash_table(
JournalFile *f,
- int data_fd, uint64_t n_data,
- int entry_fd, uint64_t n_entries,
- int entry_array_fd, uint64_t n_entry_arrays,
+ MMapFileDescriptor *cache_data_fd, uint64_t n_data,
+ MMapFileDescriptor *cache_entry_fd, uint64_t n_entries,
+ MMapFileDescriptor *cache_entry_array_fd, uint64_t n_entry_arrays,
usec_t *last_usec,
bool show_progress) {
@@ -593,9 +593,9 @@ static int verify_hash_table(
int r;
assert(f);
- assert(data_fd >= 0);
- assert(entry_fd >= 0);
- assert(entry_array_fd >= 0);
+ assert(cache_data_fd);
+ assert(cache_entry_fd);
+ assert(cache_entry_array_fd);
assert(last_usec);
n = le64toh(f->header->data_hash_table_size) / sizeof(HashItem);
@@ -617,7 +617,7 @@ static int verify_hash_table(
Object *o;
uint64_t next;
- if (!contains_uint64(f->mmap, data_fd, n_data, p)) {
+ if (!contains_uint64(f->mmap, cache_data_fd, n_data, p)) {
error(p, "Invalid data object at hash entry %"PRIu64" of %"PRIu64, i, n);
return -EBADMSG;
}
@@ -637,7 +637,7 @@ static int verify_hash_table(
return -EBADMSG;
}
- r = verify_data(f, o, p, entry_fd, n_entries, entry_array_fd, n_entry_arrays);
+ r = verify_data(f, o, p, cache_entry_fd, n_entries, cache_entry_array_fd, n_entry_arrays);
if (r < 0)
return r;
@@ -689,14 +689,14 @@ static int data_object_in_hash_table(JournalFile *f, uint64_t hash, uint64_t p)
static int verify_entry(
JournalFile *f,
Object *o, uint64_t p,
- int data_fd, uint64_t n_data) {
+ MMapFileDescriptor *cache_data_fd, uint64_t n_data) {
uint64_t i, n;
int r;
assert(f);
assert(o);
- assert(data_fd >= 0);
+ assert(cache_data_fd);
n = journal_file_entry_n_items(o);
for (i = 0; i < n; i++) {
@@ -706,7 +706,7 @@ static int verify_entry(
q = le64toh(o->entry.items[i].object_offset);
h = le64toh(o->entry.items[i].hash);
- if (!contains_uint64(f->mmap, data_fd, n_data, q)) {
+ if (!contains_uint64(f->mmap, cache_data_fd, n_data, q)) {
error(p, "Invalid data object of entry");
return -EBADMSG;
}
@@ -734,9 +734,9 @@ static int verify_entry(
static int verify_entry_array(
JournalFile *f,
- int data_fd, uint64_t n_data,
- int entry_fd, uint64_t n_entries,
- int entry_array_fd, uint64_t n_entry_arrays,
+ MMapFileDescriptor *cache_data_fd, uint64_t n_data,
+ MMapFileDescriptor *cache_entry_fd, uint64_t n_entries,
+ MMapFileDescriptor *cache_entry_array_fd, uint64_t n_entry_arrays,
usec_t *last_usec,
bool show_progress) {
@@ -744,9 +744,9 @@ static int verify_entry_array(
int r;
assert(f);
- assert(data_fd >= 0);
- assert(entry_fd >= 0);
- assert(entry_array_fd >= 0);
+ assert(cache_data_fd);
+ assert(cache_entry_fd);
+ assert(cache_entry_array_fd);
assert(last_usec);
n = le64toh(f->header->n_entries);
@@ -763,7 +763,7 @@ static int verify_entry_array(
return -EBADMSG;
}
- if (!contains_uint64(f->mmap, entry_array_fd, n_entry_arrays, a)) {
+ if (!contains_uint64(f->mmap, cache_entry_array_fd, n_entry_arrays, a)) {
error(a, "Invalid array %"PRIu64" of %"PRIu64, i, n);
return -EBADMSG;
}
@@ -789,7 +789,7 @@ static int verify_entry_array(
}
last = p;
- if (!contains_uint64(f->mmap, entry_fd, n_entries, p)) {
+ if (!contains_uint64(f->mmap, cache_entry_fd, n_entries, p)) {
error(a, "Invalid array entry at %"PRIu64" of %"PRIu64, i, n);
return -EBADMSG;
}
@@ -798,7 +798,7 @@ static int verify_entry_array(
if (r < 0)
return r;
- r = verify_entry(f, o, p, data_fd, n_data);
+ r = verify_entry(f, o, p, cache_data_fd, n_data);
if (r < 0)
return r;
@@ -829,6 +829,7 @@ int journal_file_verify(
uint64_t n_weird = 0, n_objects = 0, n_entries = 0, n_data = 0, n_fields = 0, n_data_hash_tables = 0, n_field_hash_tables = 0, n_entry_arrays = 0, n_tags = 0;
usec_t last_usec = 0;
int data_fd = -1, entry_fd = -1, entry_array_fd = -1;
+ MMapFileDescriptor *cache_data_fd = NULL, *cache_entry_fd = NULL, *cache_entry_array_fd = NULL;
unsigned i;
bool found_last = false;
const char *tmp_dir = NULL;
@@ -876,6 +877,24 @@ int journal_file_verify(
goto fail;
}
+ cache_data_fd = mmap_cache_add_fd(f->mmap, data_fd);
+ if (!cache_data_fd) {
+ r = log_oom();
+ goto fail;
+ }
+
+ cache_entry_fd = mmap_cache_add_fd(f->mmap, entry_fd);
+ if (!cache_entry_fd) {
+ r = log_oom();
+ goto fail;
+ }
+
+ cache_entry_array_fd = mmap_cache_add_fd(f->mmap, entry_array_fd);
+ if (!cache_entry_array_fd) {
+ r = log_oom();
+ goto fail;
+ }
+
if (le32toh(f->header->compatible_flags) & ~HEADER_COMPATIBLE_SUPPORTED) {
log_error("Cannot verify file with unknown extensions.");
r = -EOPNOTSUPP;
@@ -1247,18 +1266,18 @@ int journal_file_verify(
* referenced is consistent. */
r = verify_entry_array(f,
- data_fd, n_data,
- entry_fd, n_entries,
- entry_array_fd, n_entry_arrays,
+ cache_data_fd, n_data,
+ cache_entry_fd, n_entries,
+ cache_entry_array_fd, n_entry_arrays,
&last_usec,
show_progress);
if (r < 0)
goto fail;
r = verify_hash_table(f,
- data_fd, n_data,
- entry_fd, n_entries,
- entry_array_fd, n_entry_arrays,
+ cache_data_fd, n_data,
+ cache_entry_fd, n_entries,
+ cache_entry_array_fd, n_entry_arrays,
&last_usec,
show_progress);
if (r < 0)
@@ -1267,9 +1286,9 @@ int journal_file_verify(
if (show_progress)
flush_progress();
- mmap_cache_close_fd(f->mmap, data_fd);
- mmap_cache_close_fd(f->mmap, entry_fd);
- mmap_cache_close_fd(f->mmap, entry_array_fd);
+ mmap_cache_free_fd(f->mmap, cache_data_fd);
+ mmap_cache_free_fd(f->mmap, cache_entry_fd);
+ mmap_cache_free_fd(f->mmap, cache_entry_array_fd);
safe_close(data_fd);
safe_close(entry_fd);
@@ -1294,20 +1313,23 @@ fail:
(unsigned long long) f->last_stat.st_size,
100 * p / f->last_stat.st_size);
- if (data_fd >= 0) {
- mmap_cache_close_fd(f->mmap, data_fd);
+ if (data_fd >= 0)
safe_close(data_fd);
- }
- if (entry_fd >= 0) {
- mmap_cache_close_fd(f->mmap, entry_fd);
+ if (entry_fd >= 0)
safe_close(entry_fd);
- }
- if (entry_array_fd >= 0) {
- mmap_cache_close_fd(f->mmap, entry_array_fd);
+ if (entry_array_fd >= 0)
safe_close(entry_array_fd);
- }
+
+ if (cache_data_fd)
+ mmap_cache_free_fd(f->mmap, cache_data_fd);
+
+ if (cache_entry_fd)
+ mmap_cache_free_fd(f->mmap, cache_entry_fd);
+
+ if (cache_entry_array_fd)
+ mmap_cache_free_fd(f->mmap, cache_entry_array_fd);
return r;
}
diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c
index ad11fb314d..2313c8c678 100644
--- a/src/journal/journalctl.c
+++ b/src/journal/journalctl.c
@@ -299,8 +299,9 @@ static void help(void) {
" --no-tail Show all lines, even in follow mode\n"
" -r --reverse Show the newest entries first\n"
" -o --output=STRING Change journal output mode (short, short-precise,\n"
- " short-iso, short-full, short-monotonic, short-unix,\n"
- " verbose, export, json, json-pretty, json-sse, cat)\n"
+ " short-iso, short-iso-precise, short-full,\n"
+ " short-monotonic, short-unix, verbose, export,\n"
+ " json, json-pretty, json-sse, cat)\n"
" --utc Express time in Coordinated Universal Time (UTC)\n"
" -x --catalog Add message explanations where available\n"
" --no-full Ellipsize fields\n"
@@ -2364,20 +2365,13 @@ int main(int argc, char *argv[]) {
log_error_errno(r, "Failed to iterate through journal: %m");
goto finish;
}
- if (r == 0) {
- if (arg_follow)
- need_seek = true;
- else {
- if (!arg_quiet)
- printf("-- No entries --\n");
- goto finish;
- }
- }
+ if (r == 0)
+ need_seek = true;
if (!arg_follow)
pager_open(arg_no_pager, arg_pager_end);
- if (!arg_quiet) {
+ if (!arg_quiet && (arg_lines != 0 || arg_follow)) {
usec_t start, end;
char start_buf[FORMAT_TIMESTAMP_MAX], end_buf[FORMAT_TIMESTAMP_MAX];
@@ -2473,6 +2467,9 @@ int main(int argc, char *argv[]) {
}
if (!arg_follow) {
+ if (n_shown == 0 && !arg_quiet)
+ printf("-- No entries --\n");
+
if (arg_show_cursor) {
_cleanup_free_ char *cursor = NULL;
@@ -2486,6 +2483,7 @@ int main(int argc, char *argv[]) {
break;
}
+ fflush(stdout);
r = sd_journal_wait(j, (uint64_t) -1);
if (r < 0) {
log_error_errno(r, "Couldn't wait for journal event: %m");
@@ -2496,6 +2494,7 @@ int main(int argc, char *argv[]) {
}
finish:
+ fflush(stdout);
pager_close();
strv_free(arg_file);
diff --git a/src/journal/journald-kmsg.c b/src/journal/journald-kmsg.c
index 8afaec0ced..415c7efdfc 100644
--- a/src/journal/journald-kmsg.c
+++ b/src/journal/journald-kmsg.c
@@ -106,7 +106,7 @@ static bool is_us(const char *pid) {
if (parse_pid(pid, &t) < 0)
return false;
- return t == getpid();
+ return t == getpid_cached();
}
static void dev_kmsg_record(Server *s, const char *p, size_t l) {
diff --git a/src/journal/journald-native.c b/src/journal/journald-native.c
index db3fdcf1df..abd06b1adc 100644
--- a/src/journal/journald-native.c
+++ b/src/journal/journald-native.c
@@ -513,7 +513,7 @@ int server_open_native_socket(Server*s) {
return log_error_errno(errno, "SO_PASSCRED failed: %m");
#ifdef HAVE_SELINUX
- if (mac_selinux_have()) {
+ if (mac_selinux_use()) {
r = setsockopt(s->native_fd, SOL_SOCKET, SO_PASSSEC, &one, sizeof(one));
if (r < 0)
log_warning_errno(errno, "SO_PASSSEC failed: %m");
diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
index da85260ccd..c736332d49 100644
--- a/src/journal/journald-server.c
+++ b/src/journal/journald-server.c
@@ -918,7 +918,7 @@ static void dispatch_message_real(
}
#ifdef HAVE_SELINUX
- if (mac_selinux_have()) {
+ if (mac_selinux_use()) {
if (label) {
x = alloca(strlen("_SELINUX_CONTEXT=") + label_len + 1);
@@ -1095,7 +1095,7 @@ void server_driver_message(Server *s, const char *message_id, const char *format
/* Error handling below */
va_end(ap);
- ucred.pid = getpid();
+ ucred.pid = getpid_cached();
ucred.uid = getuid();
ucred.gid = getgid();
@@ -1637,10 +1637,10 @@ static int server_parse_config_file(Server *s) {
assert(s);
return config_parse_many_nulstr(PKGSYSCONFDIR "/journald.conf",
- CONF_PATHS_NULSTR("systemd/journald.conf.d"),
- "Journal\0",
- config_item_perf_lookup, journald_gperf_lookup,
- false, s);
+ CONF_PATHS_NULSTR("systemd/journald.conf.d"),
+ "Journal\0",
+ config_item_perf_lookup, journald_gperf_lookup,
+ false, s);
}
static int server_dispatch_sync(sd_event_source *es, usec_t t, void *userdata) {
diff --git a/src/journal/journald-stream.c b/src/journal/journald-stream.c
index bc092f3c12..77551dc14b 100644
--- a/src/journal/journald-stream.c
+++ b/src/journal/journald-stream.c
@@ -494,7 +494,7 @@ static int stdout_stream_install(Server *s, int fd, StdoutStream **ret) {
if (r < 0)
return log_error_errno(r, "Failed to determine peer credentials: %m");
- if (mac_selinux_have()) {
+ if (mac_selinux_use()) {
r = getpeersec(fd, &stream->label);
if (r < 0 && r != -EOPNOTSUPP)
(void) log_warning_errno(r, "Failed to determine peer security context: %m");
diff --git a/src/journal/journald-syslog.c b/src/journal/journald-syslog.c
index 474369039a..17f855e967 100644
--- a/src/journal/journald-syslog.c
+++ b/src/journal/journald-syslog.c
@@ -99,7 +99,7 @@ static void forward_syslog_iovec(Server *s, const struct iovec *iovec, unsigned
* let's fix it as good as we can, and retry */
u = *ucred;
- u.pid = getpid();
+ u.pid = getpid_cached();
memcpy(CMSG_DATA(cmsg), &u, sizeof(struct ucred));
if (sendmsg(s->syslog_fd, &msghdr, MSG_NOSIGNAL) >= 0)
@@ -410,7 +410,7 @@ int server_open_syslog_socket(Server *s) {
return log_error_errno(errno, "SO_PASSCRED failed: %m");
#ifdef HAVE_SELINUX
- if (mac_selinux_have()) {
+ if (mac_selinux_use()) {
r = setsockopt(s->syslog_fd, SOL_SOCKET, SO_PASSSEC, &one, sizeof(one));
if (r < 0)
log_warning_errno(errno, "SO_PASSSEC failed: %m");
diff --git a/src/journal/journald.c b/src/journal/journald.c
index 1aaef387b4..4dee764fdd 100644
--- a/src/journal/journald.c
+++ b/src/journal/journald.c
@@ -55,7 +55,7 @@ int main(int argc, char *argv[]) {
server_flush_to_var(&server, true);
server_flush_dev_kmsg(&server);
- log_debug("systemd-journald running as pid "PID_FMT, getpid());
+ log_debug("systemd-journald running as pid "PID_FMT, getpid_cached());
server_driver_message(&server,
"MESSAGE_ID=" SD_MESSAGE_JOURNAL_START_STR,
LOG_MESSAGE("Journal started"),
@@ -114,7 +114,7 @@ int main(int argc, char *argv[]) {
server_maybe_warn_forward_syslog_missed(&server);
}
- log_debug("systemd-journald stopped as pid "PID_FMT, getpid());
+ log_debug("systemd-journald stopped as pid "PID_FMT, getpid_cached());
server_driver_message(&server,
"MESSAGE_ID=" SD_MESSAGE_JOURNAL_STOP_STR,
LOG_MESSAGE("Journal stopped"),
diff --git a/src/journal/meson.build b/src/journal/meson.build
new file mode 100644
index 0000000000..582f83afb9
--- /dev/null
+++ b/src/journal/meson.build
@@ -0,0 +1,122 @@
+journal_internal_sources = files('''
+ audit-type.c
+ audit-type.h
+ catalog.c
+ catalog.h
+ compress.c
+ compress.h
+ journal-def.h
+ journal-file.c
+ journal-file.h
+ journal-send.c
+ journal-vacuum.c
+ journal-vacuum.h
+ journal-verify.c
+ journal-verify.h
+ lookup3.c
+ lookup3.h
+ mmap-cache.c
+ mmap-cache.h
+ sd-journal.c
+'''.split())
+
+if conf.get('HAVE_GCRYPT', false)
+ journal_internal_sources += files('''
+ journal-authenticate.c
+ journal-authenticate.h
+ fsprg.c
+ fsprg.h
+ '''.split())
+
+ journal_internal_sources += gcrypt_util_sources
+endif
+
+############################################################
+
+audit_type_includes = [config_h,
+ missing_h,
+ 'linux/audit.h']
+if conf.get('HAVE_AUDIT', false)
+ audit_type_includes += 'libaudit.h'
+endif
+
+generate_audit_type_list = find_program('generate-audit_type-list.sh')
+audit_type_list_txt = custom_target(
+ 'audit_type-list.txt',
+ output : 'audit_type-list.txt',
+ command : [generate_audit_type_list, cpp] + audit_type_includes,
+ capture : true)
+
+audit_type_to_name = custom_target(
+ 'audit_type-to-name.h',
+ input : ['audit_type-to-name.awk', audit_type_list_txt],
+ output : 'audit_type-to-name.h',
+ command : [awk, '-f', '@INPUT0@', '@INPUT1@'],
+ capture : true)
+
+journal_internal_sources += [audit_type_to_name]
+
+############################################################
+
+libjournal_core_sources = files('''
+ journald-kmsg.c
+ journald-kmsg.h
+ journald-syslog.c
+ journald-syslog.h
+ journald-stream.c
+ journald-stream.h
+ journald-server.c
+ journald-server.h
+ journald-console.c
+ journald-console.h
+ journald-wall.c
+ journald-wall.h
+ journald-native.c
+ journald-native.h
+ journald-audit.c
+ journald-audit.h
+ journald-rate-limit.c
+ journald-rate-limit.h
+ journal-internal.h
+'''.split())
+
+systemd_journald_sources = files('''
+ journald.c
+ journald-server.h
+'''.split())
+
+journald_gperf_c = custom_target(
+ 'journald-gperf.c',
+ input : 'journald-gperf.gperf',
+ output : 'journald-gperf.c',
+ command : [gperf, '@INPUT@', '--output-file', '@OUTPUT@'])
+
+systemd_cat_sources = files('cat.c')
+
+journalctl_sources = files('journalctl.c')
+
+if conf.get('HAVE_QRENCODE', false)
+ journalctl_sources += files('journal-qrcode.c',
+ 'journal-qrcode.h')
+endif
+
+install_data('journald.conf',
+ install_dir : pkgsysconfdir)
+
+meson.add_install_script(
+ 'sh', '-c',
+ mkdir_p.format('/var/log/journal'))
+meson.add_install_script(
+ 'sh', '-c',
+ 'chown 0:0 $DESTDIR/var/log/journal &&
+ chmod 755 $DESTDIR/var/log/journal || :')
+if get_option('adm-group')
+ meson.add_install_script(
+ 'sh', '-c',
+ 'setfacl -nm g:adm:rx,d:g:adm:rx $DESTDIR/var/log/journal || :')
+endif
+if get_option('wheel-group')
+ meson.add_install_script(
+ 'sh', '-c',
+ 'setfacl -nm g:wheel:rx,d:g:wheel:rx $DESTDIR/var/log/journal || :')
+endif
diff --git a/src/journal/mmap-cache.c b/src/journal/mmap-cache.c
index d91247b524..5dfda73c56 100644
--- a/src/journal/mmap-cache.c
+++ b/src/journal/mmap-cache.c
@@ -33,7 +33,6 @@
typedef struct Window Window;
typedef struct Context Context;
-typedef struct FileDescriptor FileDescriptor;
struct Window {
MMapCache *cache;
@@ -47,7 +46,7 @@ struct Window {
uint64_t offset;
size_t size;
- FileDescriptor *fd;
+ MMapFileDescriptor *fd;
LIST_FIELDS(Window, by_fd);
LIST_FIELDS(Window, unused);
@@ -63,7 +62,7 @@ struct Context {
LIST_FIELDS(Context, by_window);
};
-struct FileDescriptor {
+struct MMapFileDescriptor {
MMapCache *cache;
int fd;
bool sigbus;
@@ -158,24 +157,24 @@ static void window_free(Window *w) {
free(w);
}
-_pure_ static bool window_matches(Window *w, int fd, int prot, uint64_t offset, size_t size) {
+_pure_ static bool window_matches(Window *w, MMapFileDescriptor *f, int prot, uint64_t offset, size_t size) {
assert(w);
- assert(fd >= 0);
+ assert(f);
assert(size > 0);
return
w->fd &&
- fd == w->fd->fd &&
+ f->fd == w->fd->fd &&
prot == w->prot &&
offset >= w->offset &&
offset + size <= w->offset + w->size;
}
-static Window *window_add(MMapCache *m, FileDescriptor *fd, int prot, bool keep_always, uint64_t offset, size_t size, void *ptr) {
+static Window *window_add(MMapCache *m, MMapFileDescriptor *f, int prot, bool keep_always, uint64_t offset, size_t size, void *ptr) {
Window *w;
assert(m);
- assert(fd);
+ assert(f);
if (!m->last_unused || m->n_windows <= WINDOWS_MIN) {
@@ -193,14 +192,14 @@ static Window *window_add(MMapCache *m, FileDescriptor *fd, int prot, bool keep_
}
w->cache = m;
- w->fd = fd;
+ w->fd = f;
w->prot = prot;
w->keep_always = keep_always;
w->offset = offset;
w->size = size;
w->ptr = ptr;
- LIST_PREPEND(by_fd, fd->windows, w);
+ LIST_PREPEND(by_fd, f->windows, w);
return w;
}
@@ -290,49 +289,7 @@ static void context_free(Context *c) {
free(c);
}
-static void fd_free(FileDescriptor *f) {
- assert(f);
-
- while (f->windows)
- window_free(f->windows);
-
- if (f->cache)
- assert_se(hashmap_remove(f->cache->fds, FD_TO_PTR(f->fd)));
-
- free(f);
-}
-
-static FileDescriptor* fd_add(MMapCache *m, int fd) {
- FileDescriptor *f;
- int r;
-
- assert(m);
- assert(fd >= 0);
-
- f = hashmap_get(m->fds, FD_TO_PTR(fd));
- if (f)
- return f;
-
- r = hashmap_ensure_allocated(&m->fds, NULL);
- if (r < 0)
- return NULL;
-
- f = new0(FileDescriptor, 1);
- if (!f)
- return NULL;
-
- f->cache = m;
- f->fd = fd;
-
- r = hashmap_put(m->fds, FD_TO_PTR(fd), f);
- if (r < 0)
- return mfree(f);
-
- return f;
-}
-
static void mmap_cache_free(MMapCache *m) {
- FileDescriptor *f;
int i;
assert(m);
@@ -341,9 +298,6 @@ static void mmap_cache_free(MMapCache *m) {
if (m->contexts[i])
context_free(m->contexts[i]);
- while ((f = hashmap_first(m->fds)))
- fd_free(f);
-
hashmap_free(m->fds);
while (m->unused)
@@ -378,7 +332,7 @@ static int make_room(MMapCache *m) {
static int try_context(
MMapCache *m,
- int fd,
+ MMapFileDescriptor *f,
int prot,
unsigned context,
bool keep_always,
@@ -390,7 +344,7 @@ static int try_context(
assert(m);
assert(m->n_ref > 0);
- assert(fd >= 0);
+ assert(f);
assert(size > 0);
assert(ret);
@@ -403,7 +357,7 @@ static int try_context(
if (!c->window)
return 0;
- if (!window_matches(c->window, fd, prot, offset, size)) {
+ if (!window_matches(c->window, f, prot, offset, size)) {
/* Drop the reference to the window, since it's unnecessary now */
context_detach_window(c);
@@ -421,7 +375,7 @@ static int try_context(
static int find_mmap(
MMapCache *m,
- int fd,
+ MMapFileDescriptor *f,
int prot,
unsigned context,
bool keep_always,
@@ -429,26 +383,19 @@ static int find_mmap(
size_t size,
void **ret) {
- FileDescriptor *f;
Window *w;
Context *c;
assert(m);
assert(m->n_ref > 0);
- assert(fd >= 0);
+ assert(f);
assert(size > 0);
- f = hashmap_get(m->fds, FD_TO_PTR(fd));
- if (!f)
- return 0;
-
- assert(f->fd == fd);
-
if (f->sigbus)
return -EIO;
LIST_FOREACH(by_fd, w, f->windows)
- if (window_matches(w, fd, prot, offset, size))
+ if (window_matches(w, f, prot, offset, size))
break;
if (!w)
@@ -465,17 +412,17 @@ static int find_mmap(
return 1;
}
-static int mmap_try_harder(MMapCache *m, void *addr, int fd, int prot, int flags, uint64_t offset, size_t size, void **res) {
+static int mmap_try_harder(MMapCache *m, void *addr, MMapFileDescriptor *f, int prot, int flags, uint64_t offset, size_t size, void **res) {
void *ptr;
assert(m);
- assert(fd >= 0);
+ assert(f);
assert(res);
for (;;) {
int r;
- ptr = mmap(addr, size, prot, flags, fd, offset);
+ ptr = mmap(addr, size, prot, flags, f->fd, offset);
if (ptr != MAP_FAILED)
break;
if (errno != ENOMEM)
@@ -494,7 +441,7 @@ static int mmap_try_harder(MMapCache *m, void *addr, int fd, int prot, int flags
static int add_mmap(
MMapCache *m,
- int fd,
+ MMapFileDescriptor *f,
int prot,
unsigned context,
bool keep_always,
@@ -505,14 +452,13 @@ static int add_mmap(
uint64_t woffset, wsize;
Context *c;
- FileDescriptor *f;
Window *w;
void *d;
int r;
assert(m);
assert(m->n_ref > 0);
- assert(fd >= 0);
+ assert(f);
assert(size > 0);
assert(ret);
@@ -545,7 +491,7 @@ static int add_mmap(
wsize = PAGE_ALIGN(st->st_size - woffset);
}
- r = mmap_try_harder(m, NULL, fd, prot, MAP_SHARED, woffset, wsize, &d);
+ r = mmap_try_harder(m, NULL, f, prot, MAP_SHARED, woffset, wsize, &d);
if (r < 0)
return r;
@@ -553,10 +499,6 @@ static int add_mmap(
if (!c)
goto outofmem;
- f = fd_add(m, fd);
- if (!f)
- goto outofmem;
-
w = window_add(m, f, prot, keep_always, woffset, wsize, d);
if (!w)
goto outofmem;
@@ -575,7 +517,7 @@ outofmem:
int mmap_cache_get(
MMapCache *m,
- int fd,
+ MMapFileDescriptor *f,
int prot,
unsigned context,
bool keep_always,
@@ -588,20 +530,20 @@ int mmap_cache_get(
assert(m);
assert(m->n_ref > 0);
- assert(fd >= 0);
+ assert(f);
assert(size > 0);
assert(ret);
assert(context < MMAP_CACHE_MAX_CONTEXTS);
/* Check whether the current context is the right one already */
- r = try_context(m, fd, prot, context, keep_always, offset, size, ret);
+ r = try_context(m, f, prot, context, keep_always, offset, size, ret);
if (r != 0) {
m->n_hit++;
return r;
}
/* Search for a matching mmap */
- r = find_mmap(m, fd, prot, context, keep_always, offset, size, ret);
+ r = find_mmap(m, f, prot, context, keep_always, offset, size, ret);
if (r != 0) {
m->n_hit++;
return r;
@@ -610,7 +552,7 @@ int mmap_cache_get(
m->n_missed++;
/* Create a new mmap */
- return add_mmap(m, fd, prot, context, keep_always, offset, size, st, ret);
+ return add_mmap(m, f, prot, context, keep_always, offset, size, st, ret);
}
unsigned mmap_cache_get_hit(MMapCache *m) {
@@ -627,7 +569,7 @@ unsigned mmap_cache_get_missed(MMapCache *m) {
static void mmap_cache_process_sigbus(MMapCache *m) {
bool found = false;
- FileDescriptor *f;
+ MMapFileDescriptor *f;
Iterator i;
int r;
@@ -688,36 +630,59 @@ static void mmap_cache_process_sigbus(MMapCache *m) {
}
}
-bool mmap_cache_got_sigbus(MMapCache *m, int fd) {
- FileDescriptor *f;
-
+bool mmap_cache_got_sigbus(MMapCache *m, MMapFileDescriptor *f) {
assert(m);
- assert(fd >= 0);
+ assert(f);
mmap_cache_process_sigbus(m);
- f = hashmap_get(m->fds, FD_TO_PTR(fd));
- if (!f)
- return false;
-
return f->sigbus;
}
-void mmap_cache_close_fd(MMapCache *m, int fd) {
- FileDescriptor *f;
+MMapFileDescriptor* mmap_cache_add_fd(MMapCache *m, int fd) {
+ MMapFileDescriptor *f;
+ int r;
assert(m);
assert(fd >= 0);
+ f = hashmap_get(m->fds, FD_TO_PTR(fd));
+ if (f)
+ return f;
+
+ r = hashmap_ensure_allocated(&m->fds, NULL);
+ if (r < 0)
+ return NULL;
+
+ f = new0(MMapFileDescriptor, 1);
+ if (!f)
+ return NULL;
+
+ f->cache = m;
+ f->fd = fd;
+
+ r = hashmap_put(m->fds, FD_TO_PTR(fd), f);
+ if (r < 0)
+ return mfree(f);
+
+ return f;
+}
+
+void mmap_cache_free_fd(MMapCache *m, MMapFileDescriptor *f) {
+ assert(m);
+ assert(f);
+
/* Make sure that any queued SIGBUS are first dispatched, so
* that we don't end up with a SIGBUS entry we cannot relate
* to any existing memory map */
mmap_cache_process_sigbus(m);
- f = hashmap_get(m->fds, FD_TO_PTR(fd));
- if (!f)
- return;
+ while (f->windows)
+ window_free(f->windows);
+
+ if (f->cache)
+ assert_se(hashmap_remove(f->cache->fds, FD_TO_PTR(f->fd)));
- fd_free(f);
+ free(f);
}
diff --git a/src/journal/mmap-cache.h b/src/journal/mmap-cache.h
index 199d944647..7b33218563 100644
--- a/src/journal/mmap-cache.h
+++ b/src/journal/mmap-cache.h
@@ -26,6 +26,7 @@
#define MMAP_CACHE_MAX_CONTEXTS 9
typedef struct MMapCache MMapCache;
+typedef struct MMapFileDescriptor MMapFileDescriptor;
MMapCache* mmap_cache_new(void);
MMapCache* mmap_cache_ref(MMapCache *m);
@@ -33,7 +34,7 @@ MMapCache* mmap_cache_unref(MMapCache *m);
int mmap_cache_get(
MMapCache *m,
- int fd,
+ MMapFileDescriptor *f,
int prot,
unsigned context,
bool keep_always,
@@ -41,9 +42,10 @@ int mmap_cache_get(
size_t size,
struct stat *st,
void **ret);
-void mmap_cache_close_fd(MMapCache *m, int fd);
+MMapFileDescriptor * mmap_cache_add_fd(MMapCache *m, int fd);
+void mmap_cache_free_fd(MMapCache *m, MMapFileDescriptor *f);
unsigned mmap_cache_get_hit(MMapCache *m);
unsigned mmap_cache_get_missed(MMapCache *m);
-bool mmap_cache_got_sigbus(MMapCache *m, int fd);
+bool mmap_cache_got_sigbus(MMapCache *m, MMapFileDescriptor *f);
diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c
index 86afb4985d..22054835ba 100644
--- a/src/journal/sd-journal.c
+++ b/src/journal/sd-journal.c
@@ -69,7 +69,7 @@ static bool journal_pid_changed(sd_journal *j) {
/* We don't support people creating a journal object and
* keeping it around over a fork(). Let's complain. */
- return j->original_pid != getpid();
+ return j->original_pid != getpid_cached();
}
static int journal_put_error(sd_journal *j, int r, const char *path) {
@@ -882,8 +882,11 @@ static int real_journal_next_skip(sd_journal *j, direction_t direction, uint64_t
if (skip == 0) {
/* If this is not a discrete skip, then at least
* resolve the current location */
- if (j->current_location.type != LOCATION_DISCRETE)
- return real_journal_next(j, direction);
+ if (j->current_location.type != LOCATION_DISCRETE) {
+ r = real_journal_next(j, direction);
+ if (r < 0)
+ return r;
+ }
return 0;
}
@@ -1712,7 +1715,7 @@ static sd_journal *journal_new(int flags, const char *path) {
if (!j)
return NULL;
- j->original_pid = getpid();
+ j->original_pid = getpid_cached();
j->toplevel_fd = -1;
j->inotify_fd = -1;
j->flags = flags;
diff --git a/src/journal/test-compress-benchmark.c b/src/journal/test-compress-benchmark.c
index 6f6d71435d..200b7928f2 100644
--- a/src/journal/test-compress-benchmark.c
+++ b/src/journal/test-compress-benchmark.c
@@ -30,6 +30,8 @@ typedef int (compress_t)(const void *src, uint64_t src_size, void *dst,
typedef int (decompress_t)(const void *src, uint64_t src_size,
void **dst, size_t *dst_alloc_size, size_t* dst_size, size_t dst_max);
+#if defined(HAVE_XZ) || defined(HAVE_LZ4)
+
static usec_t arg_duration = 2 * USEC_PER_SEC;
static size_t arg_start;
@@ -151,8 +153,10 @@ static void test_compress_decompress(const char* label, const char* type,
100 - compressed * 100. / total,
skipped);
}
+#endif
int main(int argc, char *argv[]) {
+#if defined(HAVE_XZ) || defined(HAVE_LZ4)
const char *i;
log_set_max_level(LOG_INFO);
@@ -166,7 +170,7 @@ int main(int argc, char *argv[]) {
if (argc == 3)
(void) safe_atozu(argv[2], &arg_start);
else
- arg_start = getpid();
+ arg_start = getpid_cached();
NULSTR_FOREACH(i, "zeros\0simple\0random\0") {
#ifdef HAVE_XZ
@@ -177,4 +181,7 @@ int main(int argc, char *argv[]) {
#endif
}
return 0;
+#else
+ return EXIT_TEST_SKIP;
+#endif
}
diff --git a/src/journal/test-compress.c b/src/journal/test-compress.c
index 44a2cf5217..92108a84b3 100644
--- a/src/journal/test-compress.c
+++ b/src/journal/test-compress.c
@@ -54,6 +54,7 @@ typedef int (decompress_sw_t)(const void *src, uint64_t src_size,
typedef int (compress_stream_t)(int fdf, int fdt, uint64_t max_bytes);
typedef int (decompress_stream_t)(int fdf, int fdt, uint64_t max_size);
+#if defined(HAVE_XZ) || defined(HAVE_LZ4)
static void test_compress_decompress(int compression,
compress_blob_t compress,
decompress_blob_t decompress,
@@ -203,6 +204,7 @@ static void test_compress_stream(int compression,
assert_se(unlink(pattern) == 0);
assert_se(unlink(pattern2) == 0);
}
+#endif
#ifdef HAVE_LZ4
static void test_lz4_decompress_partial(void) {
@@ -247,6 +249,7 @@ static void test_lz4_decompress_partial(void) {
#endif
int main(int argc, char *argv[]) {
+#if defined(HAVE_XZ) || defined(HAVE_LZ4)
const char text[] =
"text\0foofoofoofoo AAAA aaaaaaaaa ghost busters barbarbar FFF"
"foofoofoofoo AAAA aaaaaaaaa ghost busters barbarbar FFF";
@@ -312,4 +315,7 @@ int main(int argc, char *argv[]) {
#endif
return 0;
+#else
+ return EXIT_TEST_SKIP;
+#endif
}
diff --git a/src/journal/test-mmap-cache.c b/src/journal/test-mmap-cache.c
index 0ad49aeb5f..c51b069f8b 100644
--- a/src/journal/test-mmap-cache.c
+++ b/src/journal/test-mmap-cache.c
@@ -29,6 +29,7 @@
#include "util.h"
int main(int argc, char *argv[]) {
+ MMapFileDescriptor *fx;
int x, y, z, r;
char px[] = "/tmp/testmmapXXXXXXX", py[] = "/tmp/testmmapYXXXXXX", pz[] = "/tmp/testmmapZXXXXXX";
MMapCache *m;
@@ -40,6 +41,8 @@ int main(int argc, char *argv[]) {
assert_se(x >= 0);
unlink(px);
+ assert_se(fx = mmap_cache_add_fd(m, x));
+
y = mkostemp_safe(py);
assert_se(y >= 0);
unlink(py);
@@ -48,27 +51,28 @@ int main(int argc, char *argv[]) {
assert_se(z >= 0);
unlink(pz);
- r = mmap_cache_get(m, x, PROT_READ, 0, false, 1, 2, NULL, &p);
+ r = mmap_cache_get(m, fx, PROT_READ, 0, false, 1, 2, NULL, &p);
assert_se(r >= 0);
- r = mmap_cache_get(m, x, PROT_READ, 0, false, 2, 2, NULL, &q);
+ r = mmap_cache_get(m, fx, PROT_READ, 0, false, 2, 2, NULL, &q);
assert_se(r >= 0);
assert_se((uint8_t*) p + 1 == (uint8_t*) q);
- r = mmap_cache_get(m, x, PROT_READ, 1, false, 3, 2, NULL, &q);
+ r = mmap_cache_get(m, fx, PROT_READ, 1, false, 3, 2, NULL, &q);
assert_se(r >= 0);
assert_se((uint8_t*) p + 2 == (uint8_t*) q);
- r = mmap_cache_get(m, x, PROT_READ, 0, false, 16ULL*1024ULL*1024ULL, 2, NULL, &p);
+ r = mmap_cache_get(m, fx, PROT_READ, 0, false, 16ULL*1024ULL*1024ULL, 2, NULL, &p);
assert_se(r >= 0);
- r = mmap_cache_get(m, x, PROT_READ, 1, false, 16ULL*1024ULL*1024ULL+1, 2, NULL, &q);
+ r = mmap_cache_get(m, fx, PROT_READ, 1, false, 16ULL*1024ULL*1024ULL+1, 2, NULL, &q);
assert_se(r >= 0);
assert_se((uint8_t*) p + 1 == (uint8_t*) q);
+ mmap_cache_free_fd(m, fx);
mmap_cache_unref(m);
safe_close(x);
diff --git a/src/kernel-install/50-depmod.install b/src/kernel-install/50-depmod.install
index 68c24bed7a..56925c8a5d 100644
--- a/src/kernel-install/50-depmod.install
+++ b/src/kernel-install/50-depmod.install
@@ -2,7 +2,15 @@
# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
# ex: ts=8 sw=4 sts=4 et filetype=sh
-[[ $1 == "add" ]] || exit 0
[[ $2 ]] || exit 1
-exec depmod -a "$2"
+case "$1" in
+ add)
+ exec depmod -a "$2"
+ ;;
+ remove)
+ exec rm -f /lib/modules/"$2"/modules.{alias{,.bin},builtin.bin,dep{,.bin},devname,softdep,symbols{,.bin}}
+ ;;
+ *)
+ exit 0
+esac
diff --git a/src/kernel-install/90-loaderentry.install b/src/kernel-install/90-loaderentry.install
index af9f0f9ccd..ae46dcc34d 100644
--- a/src/kernel-install/90-loaderentry.install
+++ b/src/kernel-install/90-loaderentry.install
@@ -7,13 +7,11 @@ KERNEL_VERSION="$2"
BOOT_DIR_ABS="$3"
KERNEL_IMAGE="$4"
-if [[ -f /etc/machine-id ]]; then
- read MACHINE_ID < /etc/machine-id
+if ! [[ $KERNEL_INSTALL_MACHINE_ID ]]; then
+ exit 0
fi
-if ! [[ $MACHINE_ID ]]; then
- exit 1
-fi
+MACHINE_ID=$KERNEL_INSTALL_MACHINE_ID
BOOT_DIR="/$MACHINE_ID/$KERNEL_VERSION"
BOOT_ROOT=${BOOT_DIR_ABS%$BOOT_DIR}
diff --git a/src/kernel-install/kernel-install b/src/kernel-install/kernel-install
index c7d9f4eea9..66bc4a6e8e 100644
--- a/src/kernel-install/kernel-install
+++ b/src/kernel-install/kernel-install
@@ -77,18 +77,15 @@ if [[ -f /etc/machine-id ]]; then
read MACHINE_ID < /etc/machine-id
fi
-if ! [[ $MACHINE_ID ]]; then
- echo "Could not determine your machine ID from /etc/machine-id." >&2
- echo "Please run 'systemd-machine-id-setup' as root. See man:machine-id(5)" >&2
- exit 1
-fi
-
if [[ ! $COMMAND ]] || [[ ! $KERNEL_VERSION ]]; then
echo "Not enough arguments" >&2
exit 1
fi
-if [[ -d /efi/loader/entries ]] || [[ -d /efi/$MACHINE_ID ]]; then
+if ! [[ $MACHINE_ID ]]; then
+ BOOT_DIR_ABS=$(mktemp -d /tmp/kernel-install.XXXXX) || exit 1
+ trap "rm -rf '$BOOT_DIR_ABS'" EXIT INT QUIT PIPE
+elif [[ -d /efi/loader/entries ]] || [[ -d /efi/$MACHINE_ID ]]; then
BOOT_DIR_ABS="/efi/$MACHINE_ID/$KERNEL_VERSION"
elif [[ -d /boot/loader/entries ]] || [[ -d /boot/$MACHINE_ID ]]; then
BOOT_DIR_ABS="/boot/$MACHINE_ID/$KERNEL_VERSION"
@@ -102,6 +99,8 @@ else
BOOT_DIR_ABS="/boot/$MACHINE_ID/$KERNEL_VERSION"
fi
+export KERNEL_INSTALL_MACHINE_ID=$MACHINE_ID
+
ret=0
readarray -t PLUGINS <<<"$(
@@ -127,11 +126,20 @@ case $COMMAND in
"$f" add "$KERNEL_VERSION" "$BOOT_DIR_ABS" "$KERNEL_IMAGE"
x=$?
if [[ $x == $SKIP_REMAINING ]]; then
- exit 0
+ ret=0
+ break
fi
((ret+=$x))
fi
done
+
+ if ! [[ $MACHINE_ID ]] && ! rmdir "$BOOT_DIR_ABS"; then
+ echo "Warning: In kernel-install plugins, requiring BOOT_DIR_ABS to be preset is deprecated." >&2
+ echo " All plugins should not put anything in BOOT_DIR_ABS if the environment" >&2
+ echo " variable KERNEL_INSTALL_MACHINE_ID is empty." >&2
+ rm -rf "$BOOT_DIR_ABS"
+ ((ret+=$?))
+ fi
;;
remove)
@@ -140,7 +148,8 @@ case $COMMAND in
"$f" remove "$KERNEL_VERSION" "$BOOT_DIR_ABS"
x=$?
if [[ $x == $SKIP_REMAINING ]]; then
- exit 0
+ ret=0
+ break
fi
((ret+=$x))
fi
diff --git a/src/kernel-install/meson.build b/src/kernel-install/meson.build
new file mode 100644
index 0000000000..ede3323bab
--- /dev/null
+++ b/src/kernel-install/meson.build
@@ -0,0 +1,11 @@
+install_data('kernel-install',
+ install_mode : 'rwxr-xr-x',
+ install_dir : bindir)
+
+install_data('50-depmod.install',
+ '90-loaderentry.install',
+ install_mode : 'rwxr-xr-x',
+ install_dir : kernelinstalldir)
+
+meson.add_install_script('sh', '-c',
+ mkdir_p.format(join_paths(sysconfdir, 'kernel/install.d')))
diff --git a/src/libsystemd-network/dhcp-lease-internal.h b/src/libsystemd-network/dhcp-lease-internal.h
index 82cae2300a..7847ce0709 100644
--- a/src/libsystemd-network/dhcp-lease-internal.h
+++ b/src/libsystemd-network/dhcp-lease-internal.h
@@ -75,6 +75,7 @@ struct sd_dhcp_lease {
uint16_t mtu; /* 0 if unset */
char *domainname;
+ char **search_domains;
char *hostname;
char *root_path;
@@ -92,6 +93,7 @@ struct sd_dhcp_lease {
int dhcp_lease_new(sd_dhcp_lease **ret);
int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void *userdata);
+int dhcp_lease_parse_search_domains(const uint8_t *option, size_t len, char ***domains);
int dhcp_lease_insert_private_option(sd_dhcp_lease *lease, uint8_t tag, const void *data, uint8_t len);
int dhcp_lease_set_default_subnet_mask(sd_dhcp_lease *lease);
diff --git a/src/libsystemd-network/icmp6-util.c b/src/libsystemd-network/icmp6-util.c
index c2e4b0e9e3..7fbebd6f27 100644
--- a/src/libsystemd-network/icmp6-util.c
+++ b/src/libsystemd-network/icmp6-util.c
@@ -32,6 +32,7 @@
#include "fd-util.h"
#include "icmp6-util.h"
#include "socket-util.h"
+#include "in-addr-util.h"
#define IN6ADDR_ALL_ROUTERS_MULTICAST_INIT \
{ { { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
@@ -41,12 +42,9 @@
{ { { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } } }
-int icmp6_bind_router_solicitation(int index) {
- struct icmp6_filter filter = { };
- struct ipv6_mreq mreq = {
- .ipv6mr_multiaddr = IN6ADDR_ALL_NODES_MULTICAST_INIT,
- .ipv6mr_interface = index,
- };
+static int icmp6_bind_router_message(const struct icmp6_filter *filter,
+ const struct ipv6_mreq *mreq) {
+ int index = mreq->ipv6mr_interface;
_cleanup_close_ int s = -1;
char ifname[IF_NAMESIZE] = "";
static const int zero = 0, one = 1, hops = 255;
@@ -56,9 +54,11 @@ int icmp6_bind_router_solicitation(int index) {
if (s < 0)
return -errno;
- ICMP6_FILTER_SETBLOCKALL(&filter);
- ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filter);
- r = setsockopt(s, IPPROTO_ICMPV6, ICMP6_FILTER, &filter, sizeof(filter));
+ r = setsockopt(s, IPPROTO_ICMPV6, ICMP6_FILTER, filter, sizeof(*filter));
+ if (r < 0)
+ return -errno;
+
+ r = setsockopt(s, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, mreq, sizeof(*mreq));
if (r < 0)
return -errno;
@@ -78,7 +78,7 @@ int icmp6_bind_router_solicitation(int index) {
if (r < 0)
return -errno;
- r = setsockopt(s, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
+ r = setsockopt(s, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &hops, sizeof(hops));
if (r < 0)
return -errno;
@@ -102,6 +102,32 @@ int icmp6_bind_router_solicitation(int index) {
return r;
}
+int icmp6_bind_router_solicitation(int index) {
+ struct icmp6_filter filter = {};
+ struct ipv6_mreq mreq = {
+ .ipv6mr_multiaddr = IN6ADDR_ALL_NODES_MULTICAST_INIT,
+ .ipv6mr_interface = index,
+ };
+
+ ICMP6_FILTER_SETBLOCKALL(&filter);
+ ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filter);
+
+ return icmp6_bind_router_message(&filter, &mreq);
+}
+
+int icmp6_bind_router_advertisement(int index) {
+ struct icmp6_filter filter = {};
+ struct ipv6_mreq mreq = {
+ .ipv6mr_multiaddr = IN6ADDR_ALL_ROUTERS_MULTICAST_INIT,
+ .ipv6mr_interface = index,
+ };
+
+ ICMP6_FILTER_SETBLOCKALL(&filter);
+ ICMP6_FILTER_SETPASS(ND_ROUTER_SOLICIT, &filter);
+
+ return icmp6_bind_router_message(&filter, &mreq);
+}
+
int icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr) {
struct sockaddr_in6 dst = {
.sin6_family = AF_INET6,
@@ -139,3 +165,74 @@ int icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr) {
return 0;
}
+
+int icmp6_receive(int fd, void *buffer, size_t size, struct in6_addr *dst,
+ triple_timestamp *timestamp) {
+ union {
+ struct cmsghdr cmsghdr;
+ uint8_t buf[CMSG_SPACE(sizeof(int)) + /* ttl */
+ CMSG_SPACE(sizeof(struct timeval))];
+ } control = {};
+ struct iovec iov = {};
+ union sockaddr_union sa = {};
+ struct msghdr msg = {
+ .msg_name = &sa.sa,
+ .msg_namelen = sizeof(sa),
+ .msg_iov = &iov,
+ .msg_iovlen = 1,
+ .msg_control = &control,
+ .msg_controllen = sizeof(control),
+ };
+ struct cmsghdr *cmsg;
+ ssize_t len;
+
+ iov.iov_base = buffer;
+ iov.iov_len = size;
+
+ len = recvmsg(fd, &msg, MSG_DONTWAIT);
+ if (len < 0) {
+ if (errno == EAGAIN || errno == EINTR)
+ return 0;
+
+ return -errno;
+ }
+
+ if ((size_t) len != size)
+ return -EINVAL;
+
+ if (msg.msg_namelen == sizeof(struct sockaddr_in6) &&
+ sa.in6.sin6_family == AF_INET6) {
+
+ *dst = sa.in6.sin6_addr;
+ if (in_addr_is_link_local(AF_INET6, (union in_addr_union*) dst) <= 0)
+ return -EADDRNOTAVAIL;
+
+ } else if (msg.msg_namelen > 0)
+ return -EPFNOSUPPORT;
+
+ /* namelen == 0 only happens when running the test-suite over a socketpair */
+
+ assert(!(msg.msg_flags & MSG_CTRUNC));
+ assert(!(msg.msg_flags & MSG_TRUNC));
+
+ CMSG_FOREACH(cmsg, &msg) {
+ if (cmsg->cmsg_level == SOL_IPV6 &&
+ cmsg->cmsg_type == IPV6_HOPLIMIT &&
+ cmsg->cmsg_len == CMSG_LEN(sizeof(int))) {
+ int hops = *(int*) CMSG_DATA(cmsg);
+
+ if (hops != 255)
+ return -EMULTIHOP;
+ }
+
+ if (cmsg->cmsg_level == SOL_SOCKET &&
+ cmsg->cmsg_type == SO_TIMESTAMP &&
+ cmsg->cmsg_len == CMSG_LEN(sizeof(struct timeval)))
+ triple_timestamp_from_realtime(timestamp, timeval_load((struct timeval*) CMSG_DATA(cmsg)));
+ }
+
+ if (!triple_timestamp_is_set(timestamp))
+ triple_timestamp_get(timestamp);
+
+ return 0;
+}
diff --git a/src/libsystemd-network/icmp6-util.h b/src/libsystemd-network/icmp6-util.h
index 2b4dbc76ce..16b8be8298 100644
--- a/src/libsystemd-network/icmp6-util.h
+++ b/src/libsystemd-network/icmp6-util.h
@@ -21,5 +21,18 @@
#include <net/ethernet.h>
+#include "time-util.h"
+
+#define IN6ADDR_ALL_ROUTERS_MULTICAST_INIT \
+ { { { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 } } }
+
+#define IN6ADDR_ALL_NODES_MULTICAST_INIT \
+ { { { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } } }
+
int icmp6_bind_router_solicitation(int index);
+int icmp6_bind_router_advertisement(int index);
int icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr);
+int icmp6_receive(int fd, void *buffer, size_t size, struct in6_addr *dst,
+ triple_timestamp *timestamp);
diff --git a/src/libsystemd-network/lldp-neighbor.c b/src/libsystemd-network/lldp-neighbor.c
index 53e29377b3..f1fecba6fa 100644
--- a/src/libsystemd-network/lldp-neighbor.c
+++ b/src/libsystemd-network/lldp-neighbor.c
@@ -249,10 +249,9 @@ int lldp_neighbor_parse(sd_lldp_neighbor *n) {
log_lldp("End marker TLV not zero-sized, ignoring datagram.");
return -EBADMSG;
}
- if (left != 0) {
- log_lldp("Trailing garbage in datagram, ignoring datagram.");
- return -EBADMSG;
- }
+
+ /* Note that after processing the SD_LLDP_TYPE_END left could still be > 0
+ * as the message may contain padding (see IEEE 802.1AB-2016, sec. 8.5.12) */
goto end_marker;
diff --git a/src/libsystemd-network/meson.build b/src/libsystemd-network/meson.build
new file mode 100644
index 0000000000..78c74560b8
--- /dev/null
+++ b/src/libsystemd-network/meson.build
@@ -0,0 +1,48 @@
+sources = files('''
+ sd-dhcp-client.c
+ sd-dhcp-server.c
+ dhcp-network.c
+ dhcp-option.c
+ dhcp-packet.c
+ dhcp-internal.h
+ dhcp-server-internal.h
+ dhcp-protocol.h
+ dhcp-lease-internal.h
+ sd-dhcp-lease.c
+ sd-ipv4ll.c
+ sd-ipv4acd.c
+ arp-util.h
+ arp-util.c
+ network-internal.c
+ sd-ndisc.c
+ ndisc-internal.h
+ ndisc-router.h
+ ndisc-router.c
+ sd-radv.c
+ radv-internal.h
+ icmp6-util.h
+ icmp6-util.c
+ sd-dhcp6-client.c
+ dhcp6-internal.h
+ dhcp6-protocol.h
+ dhcp6-network.c
+ dhcp6-option.c
+ dhcp6-lease-internal.h
+ sd-dhcp6-lease.c
+ dhcp-identifier.h
+ dhcp-identifier.c
+ lldp-internal.h
+ lldp-network.h
+ lldp-network.c
+ lldp-neighbor.h
+ lldp-neighbor.c
+ sd-lldp.c
+'''.split())
+
+network_internal_h = files('network-internal.h')
+
+libsystemd_network = static_library(
+ 'systemd-network',
+ sources,
+ network_internal_h,
+ include_directories : includes)
diff --git a/src/libsystemd-network/ndisc-internal.h b/src/libsystemd-network/ndisc-internal.h
index 60e183ff8c..82b896dba3 100644
--- a/src/libsystemd-network/ndisc-internal.h
+++ b/src/libsystemd-network/ndisc-internal.h
@@ -23,6 +23,10 @@
#include "sd-ndisc.h"
+#define NDISC_ROUTER_SOLICITATION_INTERVAL (4U * USEC_PER_SEC)
+#define NDISC_MAX_ROUTER_SOLICITATION_INTERVAL (3600U * USEC_PER_SEC)
+#define NDISC_MAX_ROUTER_SOLICITATIONS 3U
+
struct sd_ndisc {
unsigned n_ref;
@@ -38,8 +42,9 @@ struct sd_ndisc {
sd_event_source *recv_event_source;
sd_event_source *timeout_event_source;
+ sd_event_source *timeout_no_ra;
- unsigned nd_sent;
+ usec_t retransmit_time;
sd_ndisc_callback_t callback;
void *userdata;
diff --git a/src/libsystemd-network/network-internal.c b/src/libsystemd-network/network-internal.c
index 092a1eabb0..337241a815 100644
--- a/src/libsystemd-network/network-internal.c
+++ b/src/libsystemd-network/network-internal.c
@@ -349,6 +349,45 @@ int config_parse_iaid(const char *unit,
return 0;
}
+int config_parse_bridge_port_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) {
+
+ uint16_t i;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ r = safe_atou16(rvalue, &i);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "Failed to parse bridge port priority, ignoring: %s", rvalue);
+ return 0;
+ }
+
+ if (i > LINK_BRIDGE_PORT_PRIORITY_MAX) {
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "Bridge port priority is larger than maximum %u, ignoring: %s", LINK_BRIDGE_PORT_PRIORITY_MAX, rvalue);
+ return 0;
+ }
+
+ *((uint16_t *)data) = i;
+
+ return 0;
+}
+
+
void serialize_in_addrs(FILE *f, const struct in_addr *addresses, size_t size) {
unsigned i;
diff --git a/src/libsystemd-network/network-internal.h b/src/libsystemd-network/network-internal.h
index 5bcd577167..4666f174e9 100644
--- a/src/libsystemd-network/network-internal.h
+++ b/src/libsystemd-network/network-internal.h
@@ -26,6 +26,9 @@
#include "condition.h"
#include "udev.h"
+#define LINK_BRIDGE_PORT_PRIORITY_INVALID 128
+#define LINK_BRIDGE_PORT_PRIORITY_MAX 63
+
bool net_match_config(const struct ether_addr *match_mac,
char * const *match_path,
char * const *match_driver,
@@ -62,6 +65,10 @@ int config_parse_iaid(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_bridge_port_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 net_get_unique_predictable_data(struct udev_device *device, uint64_t *result);
const char *net_get_name(struct udev_device *device);
diff --git a/src/libsystemd-network/radv-internal.h b/src/libsystemd-network/radv-internal.h
new file mode 100644
index 0000000000..b21d4e54cb
--- /dev/null
+++ b/src/libsystemd-network/radv-internal.h
@@ -0,0 +1,88 @@
+#pragma once
+
+/***
+ This file is part of systemd.
+
+ Copyright (C) 2017 Intel Corporation. All rights reserved.
+
+ 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-radv.h"
+
+#include "log.h"
+#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)
+#define SD_RADV_MAX_INITIAL_RTR_ADVERTISEMENTS 3
+#define SD_RADV_MAX_FINAL_RTR_ADVERTISEMENTS 3
+#define SD_RADV_MIN_DELAY_BETWEEN_RAS 3
+#define SD_RADV_MAX_RA_DELAY_TIME_USEC (500*USEC_PER_MSEC)
+
+enum RAdvState {
+ SD_RADV_STATE_IDLE = 0,
+ SD_RADV_STATE_ADVERTISING = 1,
+};
+typedef enum RAdvState RAdvState;
+
+struct sd_radv {
+ unsigned n_ref;
+ RAdvState state;
+
+ int ifindex;
+
+ sd_event *event;
+ int event_priority;
+
+ struct ether_addr mac_addr;
+ uint8_t hop_limit;
+ uint8_t flags;
+ uint32_t mtu;
+ uint16_t lifetime;
+
+ int fd;
+ unsigned ra_sent;
+ sd_event_source *recv_event_source;
+ sd_event_source *timeout_event_source;
+
+ unsigned n_prefixes;
+ LIST_HEAD(sd_radv_prefix, prefixes);
+};
+
+struct sd_radv_prefix {
+ unsigned n_ref;
+
+ struct {
+ uint8_t type;
+ uint8_t length;
+ uint8_t prefixlen;
+ uint8_t flags;
+ be32_t valid_lifetime;
+ be32_t preferred_lifetime;
+ uint32_t reserved;
+ struct in6_addr in6_addr;
+ } _packed_ opt;
+
+ LIST_FIELDS(struct sd_radv_prefix, prefix);
+};
+
+#define log_radv_full(level, error, fmt, ...) log_internal(level, error, __FILE__, __LINE__, __func__, "RADV: " fmt, ##__VA_ARGS__)
+#define log_radv_errno(error, fmt, ...) log_radv_full(LOG_DEBUG, error, fmt, ##__VA_ARGS__)
+#define log_radv_warning_errno(error, fmt, ...) log_radv_full(LOG_WARNING, error, fmt, ##__VA_ARGS__)
+#define log_radv(fmt, ...) log_radv_errno(0, fmt, ##__VA_ARGS__)
diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c
index 7c0317640f..e20d339bd5 100644
--- a/src/libsystemd-network/sd-dhcp-client.c
+++ b/src/libsystemd-network/sd-dhcp-client.c
@@ -1655,7 +1655,8 @@ static int client_receive_message_udp(
if (errno == EAGAIN || errno == EINTR)
return 0;
- return log_dhcp_client_errno(client, errno, "Could not receive message from UDP socket: %m");
+ return log_dhcp_client_errno(client, errno,
+ "Could not receive message from UDP socket: %m");
}
if ((size_t) len < sizeof(DHCPMessage)) {
log_dhcp_client(client, "Too small to be a DHCP message: ignoring");
@@ -1748,9 +1749,8 @@ static int client_receive_message_raw(
if (errno == EAGAIN || errno == EINTR)
return 0;
- log_dhcp_client(client, "Could not receive message from raw socket: %m");
-
- return -errno;
+ return log_dhcp_client_errno(client, errno,
+ "Could not receive message from raw socket: %m");
} else if ((size_t)len < sizeof(DHCPPacket))
return 0;
diff --git a/src/libsystemd-network/sd-dhcp-lease.c b/src/libsystemd-network/sd-dhcp-lease.c
index 13dc6e4386..1661874a55 100644
--- a/src/libsystemd-network/sd-dhcp-lease.c
+++ b/src/libsystemd-network/sd-dhcp-lease.c
@@ -231,6 +231,21 @@ int sd_dhcp_lease_get_routes(sd_dhcp_lease *lease, sd_dhcp_route ***routes) {
return (int) lease->static_route_size;
}
+int sd_dhcp_lease_get_search_domains(sd_dhcp_lease *lease, char ***domains) {
+ unsigned r;
+
+ assert_return(lease, -EINVAL);
+ assert_return(domains, -EINVAL);
+
+ r = strv_length(lease->search_domains);
+ if (r > 0) {
+ *domains = lease->search_domains;
+ return (int) r;
+ }
+
+ return -ENODATA;
+}
+
int sd_dhcp_lease_get_vendor_specific(sd_dhcp_lease *lease, const void **data, size_t *data_len) {
assert_return(lease, -EINVAL);
assert_return(data, -EINVAL);
@@ -282,6 +297,7 @@ sd_dhcp_lease *sd_dhcp_lease_unref(sd_dhcp_lease *lease) {
free(lease->static_route);
free(lease->client_id);
free(lease->vendor_specific);
+ strv_free(lease->search_domains);
return mfree(lease);
}
@@ -610,6 +626,12 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void
break;
+ case SD_DHCP_OPTION_DOMAIN_SEARCH_LIST:
+ r = dhcp_lease_parse_search_domains(option, len, &lease->search_domains);
+ if (r < 0)
+ log_debug_errno(r, "Failed to parse Domain Search List, ignoring: %m");
+ break;
+
case SD_DHCP_OPTION_HOST_NAME:
r = lease_parse_domain(option, len, &lease->hostname);
if (r < 0) {
@@ -701,6 +723,96 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void
return 0;
}
+/* Parses compressed domain names. */
+int dhcp_lease_parse_search_domains(const uint8_t *option, size_t len, char ***domains) {
+ _cleanup_strv_free_ char **names = NULL;
+ size_t pos = 0, cnt = 0;
+ int r;
+
+ assert(domains);
+ assert_return(option && len > 0, -ENODATA);
+
+ while (pos < len) {
+ _cleanup_free_ char *name = NULL;
+ size_t n = 0, allocated = 0;
+ size_t jump_barrier = pos, next_chunk = 0;
+ bool first = true;
+
+ for (;;) {
+ uint8_t c;
+ c = option[pos++];
+
+ if (c == 0) {
+ /* End of name */
+ break;
+ } else if (c <= 63) {
+ const char *label;
+
+ /* Literal label */
+ label = (const char*) (option + pos);
+ pos += c;
+ if (pos >= len)
+ return -EBADMSG;
+
+ if (!GREEDY_REALLOC(name, allocated, n + !first + DNS_LABEL_ESCAPED_MAX))
+ return -ENOMEM;
+
+ if (first)
+ first = false;
+ else
+ name[n++] = '.';
+
+ r = dns_label_escape(label, c, name + n, DNS_LABEL_ESCAPED_MAX);
+ if (r < 0)
+ return r;
+
+ n += r;
+ } else if ((c & 0xc0) == 0xc0) {
+ /* Pointer */
+
+ uint8_t d;
+ uint16_t ptr;
+
+ if (pos >= len)
+ return -EBADMSG;
+
+ d = option[pos++];
+ ptr = (uint16_t) (c & ~0xc0) << 8 | (uint16_t) d;
+
+ /* Jumps are limited to a "prior occurrence" (RFC-1035 4.1.4) */
+ if (ptr >= jump_barrier)
+ return -EBADMSG;
+ jump_barrier = ptr;
+
+ /* Save current location so we don't end up re-parsing what's parsed so far. */
+ if (next_chunk == 0)
+ next_chunk = pos;
+
+ pos = ptr;
+ } else
+ return -EBADMSG;
+ }
+
+ if (!GREEDY_REALLOC(name, allocated, n + 1))
+ return -ENOMEM;
+ name[n] = 0;
+
+ r = strv_extend(&names, name);
+ if (r < 0)
+ return r;
+
+ cnt++;
+
+ if (next_chunk != 0)
+ pos = next_chunk;
+ }
+
+ *domains = names;
+ names = NULL;
+
+ return cnt;
+}
+
int dhcp_lease_insert_private_option(sd_dhcp_lease *lease, uint8_t tag, const void *data, uint8_t len) {
struct sd_dhcp_raw_option *cur, *option;
@@ -756,6 +868,7 @@ int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file) {
const char *string;
uint16_t mtu;
_cleanup_free_ sd_dhcp_route **routes = NULL;
+ char **search_domains = NULL;
uint32_t t1, t2, lifetime;
int r;
@@ -829,6 +942,13 @@ int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file) {
if (r >= 0)
fprintf(f, "DOMAINNAME=%s\n", string);
+ r = sd_dhcp_lease_get_search_domains(lease, &search_domains);
+ if (r > 0) {
+ fputs("DOMAIN_SEARCH_LIST=", f);
+ fputstrv(f, search_domains, NULL, NULL);
+ fputs("\n", f);
+ }
+
r = sd_dhcp_lease_get_hostname(lease, &string);
if (r >= 0)
fprintf(f, "HOSTNAME=%s\n", string);
@@ -910,6 +1030,7 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
*ntp = NULL,
*mtu = NULL,
*routes = NULL,
+ *domains = NULL,
*client_id_hex = NULL,
*vendor_specific_hex = NULL,
*lifetime = NULL,
@@ -938,6 +1059,7 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
"MTU", &mtu,
"DOMAINNAME", &lease->domainname,
"HOSTNAME", &lease->hostname,
+ "DOMAIN_SEARCH_LIST", &domains,
"ROOT_PATH", &lease->root_path,
"ROUTES", &routes,
"CLIENTID", &client_id_hex,
@@ -1043,6 +1165,18 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
log_debug_errno(r, "Failed to parse MTU %s, ignoring: %m", mtu);
}
+ if (domains) {
+ _cleanup_strv_free_ char **a = NULL;
+ a = strv_split(domains, " ");
+ if (!a)
+ return -ENOMEM;
+
+ if (!strv_isempty(a)) {
+ lease->search_domains = a;
+ a = NULL;
+ }
+ }
+
if (routes) {
r = deserialize_dhcp_routes(
&lease->static_route,
diff --git a/src/libsystemd-network/sd-dhcp-server.c b/src/libsystemd-network/sd-dhcp-server.c
index 315cbf1ac5..5a59c377f8 100644
--- a/src/libsystemd-network/sd-dhcp-server.c
+++ b/src/libsystemd-network/sd-dhcp-server.c
@@ -34,6 +34,14 @@
#define DHCP_DEFAULT_LEASE_TIME_USEC USEC_PER_HOUR
#define DHCP_MAX_LEASE_TIME_USEC (USEC_PER_HOUR*12)
+static void dhcp_lease_free(DHCPLease *lease) {
+ if (!lease)
+ return;
+
+ free(lease->client_id.data);
+ free(lease);
+}
+
/* configures the server's address and subnet, and optionally the pool's size and offset into the subnet
* the whole pool must fit into the subnet, and may not contain the first (any) nor last (broadcast) address
* moreover, the server's own address may be in the pool, and is in that case reserved in order not to
@@ -47,7 +55,6 @@ int sd_dhcp_server_configure_pool(sd_dhcp_server *server, struct in_addr *addres
assert_return(address, -EINVAL);
assert_return(address->s_addr != INADDR_ANY, -EINVAL);
assert_return(prefixlen <= 32, -ERANGE);
- assert_return(server->address == INADDR_ANY, -EBUSY);
assert_se(in_addr_prefixlen_to_netmask(&netmask_addr, prefixlen));
netmask = netmask_addr.s_addr;
@@ -78,19 +85,28 @@ int sd_dhcp_server_configure_pool(sd_dhcp_server *server, struct in_addr *addres
else
size = size_max;
- server->bound_leases = new0(DHCPLease*, size);
- if (!server->bound_leases)
- return -ENOMEM;
+ 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);
+ if (!server->bound_leases)
+ return -ENOMEM;
- server->pool_offset = offset;
- server->pool_size = size;
+ server->pool_offset = offset;
+ server->pool_size = size;
- server->address = address->s_addr;
- server->netmask = netmask;
- server->subnet = address->s_addr & netmask;
+ server->address = address->s_addr;
+ server->netmask = netmask;
+ server->subnet = address->s_addr & netmask;
- if (server_off >= offset && server_off - offset < size)
- server->bound_leases[server_off - offset] = &server->invalid_lease;
+ if (server_off >= offset && server_off - offset < size)
+ 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);
+ }
return 0;
}
@@ -143,14 +159,6 @@ static const struct hash_ops client_id_hash_ops = {
.compare = client_id_compare_func
};
-static void dhcp_lease_free(DHCPLease *lease) {
- if (!lease)
- return;
-
- free(lease->client_id.data);
- free(lease);
-}
-
sd_dhcp_server *sd_dhcp_server_unref(sd_dhcp_server *server) {
DHCPLease *lease;
diff --git a/src/libsystemd-network/sd-ipv4ll.c b/src/libsystemd-network/sd-ipv4ll.c
index 13209261f9..88a90e593b 100644
--- a/src/libsystemd-network/sd-ipv4ll.c
+++ b/src/libsystemd-network/sd-ipv4ll.c
@@ -248,6 +248,12 @@ static int ipv4ll_pick_address(sd_ipv4ll *ll) {
return sd_ipv4ll_set_address(ll, &(struct in_addr) { addr });
}
+int sd_ipv4ll_restart(sd_ipv4ll *ll) {
+ ll->address = 0;
+
+ return sd_ipv4ll_start(ll);
+}
+
#define MAC_HASH_KEY SD_ID128_MAKE(df,04,22,98,3f,ad,14,52,f9,87,2e,d1,9c,70,e2,f2)
int sd_ipv4ll_start(sd_ipv4ll *ll) {
diff --git a/src/libsystemd-network/sd-ndisc.c b/src/libsystemd-network/sd-ndisc.c
index 1d3be9b862..4bf558b12b 100644
--- a/src/libsystemd-network/sd-ndisc.c
+++ b/src/libsystemd-network/sd-ndisc.c
@@ -28,12 +28,12 @@
#include "in-addr-util.h"
#include "ndisc-internal.h"
#include "ndisc-router.h"
+#include "random-util.h"
#include "socket-util.h"
#include "string-util.h"
#include "util.h"
-#define NDISC_ROUTER_SOLICITATION_INTERVAL (4U * USEC_PER_SEC)
-#define NDISC_MAX_ROUTER_SOLICITATIONS 3U
+#define NDISC_TIMEOUT_NO_RA_USEC (NDISC_ROUTER_SOLICITATION_INTERVAL * NDISC_MAX_ROUTER_SOLICITATIONS)
static void ndisc_callback(sd_ndisc *ndisc, sd_ndisc_event event, sd_ndisc_router *rt) {
assert(ndisc);
@@ -129,6 +129,8 @@ static int ndisc_reset(sd_ndisc *nd) {
assert(nd);
nd->timeout_event_source = sd_event_source_unref(nd->timeout_event_source);
+ nd->timeout_no_ra = sd_event_source_unref(nd->timeout_no_ra);
+ nd->retransmit_time = 0;
nd->recv_event_source = sd_event_source_unref(nd->recv_event_source);
nd->fd = safe_close(nd->fd);
@@ -221,23 +223,9 @@ static int ndisc_handle_datagram(sd_ndisc *nd, sd_ndisc_router *rt) {
static int ndisc_recv(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
_cleanup_(sd_ndisc_router_unrefp) sd_ndisc_router *rt = NULL;
sd_ndisc *nd = userdata;
- union {
- struct cmsghdr cmsghdr;
- uint8_t buf[CMSG_SPACE(sizeof(int)) + /* ttl */
- CMSG_SPACE(sizeof(struct timeval))];
- } control = {};
- struct iovec iov = {};
- union sockaddr_union sa = {};
- struct msghdr msg = {
- .msg_name = &sa.sa,
- .msg_namelen = sizeof(sa),
- .msg_iov = &iov,
- .msg_iovlen = 1,
- .msg_control = &control,
- .msg_controllen = sizeof(control),
- };
- struct cmsghdr *cmsg;
- ssize_t len, buflen;
+ ssize_t buflen;
+ int r;
+ _cleanup_free_ char *addr = NULL;
assert(s);
assert(nd);
@@ -251,110 +239,90 @@ static int ndisc_recv(sd_event_source *s, int fd, uint32_t revents, void *userda
if (!rt)
return -ENOMEM;
- iov.iov_base = NDISC_ROUTER_RAW(rt);
- iov.iov_len = rt->raw_size;
-
- len = recvmsg(fd, &msg, MSG_DONTWAIT);
- if (len < 0) {
- if (errno == EAGAIN || errno == EINTR)
- return 0;
-
- return log_ndisc_errno(errno, "Could not receive message from ICMPv6 socket: %m");
- }
-
- if ((size_t) len != rt->raw_size) {
- log_ndisc("Packet size mismatch.");
- return -EINVAL;
- }
-
- if (msg.msg_namelen == sizeof(struct sockaddr_in6) &&
- sa.in6.sin6_family == AF_INET6) {
-
- if (in_addr_is_link_local(AF_INET6, (union in_addr_union*) &sa.in6.sin6_addr) <= 0) {
- _cleanup_free_ char *addr = NULL;
-
- (void) in_addr_to_string(AF_INET6, (union in_addr_union*) &sa.in6.sin6_addr, &addr);
- log_ndisc("Received RA from non-link-local address %s. Ignoring.", strna(addr));
- return 0;
- }
-
- rt->address = sa.in6.sin6_addr;
-
- } else if (msg.msg_namelen > 0) {
- log_ndisc("Received invalid source address size from ICMPv6 socket: %zu bytes", (size_t) msg.msg_namelen);
- return -EINVAL;
- }
-
- /* namelen == 0 only happens when running the test-suite over a socketpair */
-
- assert(!(msg.msg_flags & MSG_CTRUNC));
- assert(!(msg.msg_flags & MSG_TRUNC));
-
- CMSG_FOREACH(cmsg, &msg) {
- if (cmsg->cmsg_level == SOL_IPV6 &&
- cmsg->cmsg_type == IPV6_HOPLIMIT &&
- cmsg->cmsg_len == CMSG_LEN(sizeof(int))) {
- int hops = *(int*) CMSG_DATA(cmsg);
-
- if (hops != 255) {
- log_ndisc("Received RA with invalid hop limit %d. Ignoring.", hops);
- return 0;
- }
+ r = icmp6_receive(fd, NDISC_ROUTER_RAW(rt), rt->raw_size, &rt->address,
+ &rt->timestamp);
+ if (r < 0) {
+ switch (r) {
+ case -EADDRNOTAVAIL:
+ (void) in_addr_to_string(AF_INET6, (union in_addr_union*) &rt->address, &addr);
+ log_ndisc("Received RA from non-link-local address %s. Ignoring", addr);
+ break;
+
+ case -EMULTIHOP:
+ log_ndisc("Received RA with invalid hop limit. Ignoring.");
+ break;
+
+ case -EPFNOSUPPORT:
+ log_ndisc("Received invalid source address from ICMPv6 socket.");
+ break;
}
- if (cmsg->cmsg_level == SOL_SOCKET &&
- cmsg->cmsg_type == SO_TIMESTAMP &&
- cmsg->cmsg_len == CMSG_LEN(sizeof(struct timeval)))
- triple_timestamp_from_realtime(&rt->timestamp, timeval_load((struct timeval*) CMSG_DATA(cmsg)));
+ return 0;
}
- if (!triple_timestamp_is_set(&rt->timestamp))
- triple_timestamp_get(&rt->timestamp);
-
nd->timeout_event_source = sd_event_source_unref(nd->timeout_event_source);
return ndisc_handle_datagram(nd, rt);
}
+static usec_t ndisc_timeout_compute_random(usec_t val) {
+ /* compute a time that is random within ±10% of the given value */
+ return val - val / 10 +
+ (random_u64() % (2 * USEC_PER_SEC)) * val / 10 / USEC_PER_SEC;
+}
+
static int ndisc_timeout(sd_event_source *s, uint64_t usec, void *userdata) {
sd_ndisc *nd = userdata;
- usec_t time_now, next_timeout;
+ usec_t time_now;
int r;
+ char time_string[FORMAT_TIMESPAN_MAX];
assert(s);
assert(nd);
assert(nd->event);
- if (nd->nd_sent >= NDISC_MAX_ROUTER_SOLICITATIONS) {
- nd->timeout_event_source = sd_event_source_unref(nd->timeout_event_source);
- ndisc_callback(nd, SD_NDISC_EVENT_TIMEOUT, NULL);
- return 0;
+ assert_se(sd_event_now(nd->event, clock_boottime_or_monotonic(), &time_now) >= 0);
+
+ nd->timeout_event_source = sd_event_source_unref(nd->timeout_event_source);
+
+ if (!nd->retransmit_time)
+ nd->retransmit_time = ndisc_timeout_compute_random(NDISC_ROUTER_SOLICITATION_INTERVAL);
+ else {
+ if (nd->retransmit_time > NDISC_MAX_ROUTER_SOLICITATION_INTERVAL / 2)
+ nd->retransmit_time = ndisc_timeout_compute_random(NDISC_MAX_ROUTER_SOLICITATION_INTERVAL);
+ else
+ nd->retransmit_time += ndisc_timeout_compute_random(nd->retransmit_time);
}
- r = icmp6_send_router_solicitation(nd->fd, &nd->mac_addr);
- if (r < 0) {
- log_ndisc_errno(r, "Error sending Router Solicitation: %m");
+ r = sd_event_add_time(nd->event, &nd->timeout_event_source,
+ clock_boottime_or_monotonic(),
+ time_now + nd->retransmit_time,
+ 10 * USEC_PER_MSEC, ndisc_timeout, nd);
+ if (r < 0)
goto fail;
- }
- log_ndisc("Sent Router Solicitation");
- nd->nd_sent++;
+ r = sd_event_source_set_priority(nd->timeout_event_source, nd->event_priority);
+ if (r < 0)
+ goto fail;
- assert_se(sd_event_now(nd->event, clock_boottime_or_monotonic(), &time_now) >= 0);
- next_timeout = time_now + NDISC_ROUTER_SOLICITATION_INTERVAL;
+ (void) sd_event_source_set_description(nd->timeout_event_source, "ndisc-timeout-no-ra");
- r = sd_event_source_set_time(nd->timeout_event_source, next_timeout);
+ r = sd_event_source_set_enabled(nd->timeout_event_source, SD_EVENT_ONESHOT);
if (r < 0) {
- log_ndisc_errno(r, "Error updating timer: %m");
+ log_ndisc_errno(r, "Error reenabling timer: %m");
goto fail;
}
- r = sd_event_source_set_enabled(nd->timeout_event_source, SD_EVENT_ONESHOT);
+ r = icmp6_send_router_solicitation(nd->fd, &nd->mac_addr);
if (r < 0) {
- log_ndisc_errno(r, "Error reenabling timer: %m");
+ log_ndisc_errno(r, "Error sending Router Solicitation: %m");
goto fail;
}
+ log_ndisc("Sent Router Solicitation, next solicitation in %s",
+ format_timespan(time_string, FORMAT_TIMESPAN_MAX,
+ nd->retransmit_time, USEC_PER_SEC));
+
return 0;
fail:
@@ -362,6 +330,20 @@ fail:
return 0;
}
+static int ndisc_timeout_no_ra(sd_event_source *s, uint64_t usec, void *userdata) {
+ sd_ndisc *nd = userdata;
+
+ assert(s);
+ assert(nd);
+
+ log_ndisc("No RA received before link confirmation timeout");
+
+ nd->timeout_no_ra = sd_event_source_unref(nd->timeout_no_ra);
+ ndisc_callback(nd, SD_NDISC_EVENT_TIMEOUT, NULL);
+
+ return 0;
+}
+
_public_ int sd_ndisc_stop(sd_ndisc *nd) {
assert_return(nd, -EINVAL);
@@ -376,6 +358,7 @@ _public_ int sd_ndisc_stop(sd_ndisc *nd) {
_public_ int sd_ndisc_start(sd_ndisc *nd) {
int r;
+ usec_t time_now;
assert_return(nd, -EINVAL);
assert_return(nd->event, -EINVAL);
@@ -387,6 +370,10 @@ _public_ int sd_ndisc_start(sd_ndisc *nd) {
assert(!nd->recv_event_source);
assert(!nd->timeout_event_source);
+ r = sd_event_now(nd->event, clock_boottime_or_monotonic(), &time_now);
+ if (r < 0)
+ goto fail;
+
nd->fd = icmp6_bind_router_solicitation(nd->ifindex);
if (nd->fd < 0)
return nd->fd;
@@ -411,6 +398,19 @@ _public_ int sd_ndisc_start(sd_ndisc *nd) {
(void) sd_event_source_set_description(nd->timeout_event_source, "ndisc-timeout");
+ r = sd_event_add_time(nd->event, &nd->timeout_no_ra,
+ clock_boottime_or_monotonic(),
+ time_now + NDISC_TIMEOUT_NO_RA_USEC,
+ 10 * USEC_PER_MSEC, ndisc_timeout_no_ra, nd);
+ if (r < 0)
+ goto fail;
+
+ r = sd_event_source_set_priority(nd->timeout_no_ra, nd->event_priority);
+ if (r < 0)
+ goto fail;
+
+ (void) sd_event_source_set_description(nd->timeout_no_ra, "ndisc-timeout-no-ra");
+
log_ndisc("Started IPv6 Router Solicitation client");
return 1;
diff --git a/src/libsystemd-network/sd-radv.c b/src/libsystemd-network/sd-radv.c
new file mode 100644
index 0000000000..f23275a80c
--- /dev/null
+++ b/src/libsystemd-network/sd-radv.c
@@ -0,0 +1,653 @@
+/***
+ This file is part of systemd.
+
+ Copyright (C) 2017 Intel Corporation. All rights reserved.
+
+ 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 <netinet/icmp6.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <linux/in6.h>
+
+#include "sd-radv.h"
+
+#include "macro.h"
+#include "alloc-util.h"
+#include "fd-util.h"
+#include "icmp6-util.h"
+#include "in-addr-util.h"
+#include "radv-internal.h"
+#include "socket-util.h"
+#include "string-util.h"
+#include "util.h"
+#include "random-util.h"
+
+_public_ int sd_radv_new(sd_radv **ret) {
+ _cleanup_(sd_radv_unrefp) sd_radv *ra = NULL;
+
+ assert_return(ret, -EINVAL);
+
+ ra = new0(sd_radv, 1);
+ if (!ra)
+ return -ENOMEM;
+
+ ra->n_ref = 1;
+ ra->fd = -1;
+
+ LIST_HEAD_INIT(ra->prefixes);
+
+ *ret = ra;
+ ra = NULL;
+
+ return 0;
+}
+
+_public_ int sd_radv_attach_event(sd_radv *ra, sd_event *event, int64_t priority) {
+ int r;
+
+ assert_return(ra, -EINVAL);
+ assert_return(!ra->event, -EBUSY);
+
+ if (event)
+ ra->event = sd_event_ref(event);
+ else {
+ r = sd_event_default(&ra->event);
+ if (r < 0)
+ return 0;
+ }
+
+ ra->event_priority = priority;
+
+ return 0;
+}
+
+_public_ int sd_radv_detach_event(sd_radv *ra) {
+
+ assert_return(ra, -EINVAL);
+
+ ra->event = sd_event_unref(ra->event);
+ return 0;
+}
+
+_public_ sd_event *sd_radv_get_event(sd_radv *ra) {
+ assert_return(ra, NULL);
+
+ return ra->event;
+}
+
+static void radv_reset(sd_radv *ra) {
+
+ ra->timeout_event_source =
+ sd_event_source_unref(ra->timeout_event_source);
+
+ ra->recv_event_source =
+ sd_event_source_unref(ra->recv_event_source);
+
+ ra->ra_sent = 0;
+}
+
+_public_ sd_radv *sd_radv_ref(sd_radv *ra) {
+ if (!ra)
+ return NULL;
+
+ assert(ra->n_ref > 0);
+ ra->n_ref++;
+
+ return ra;
+}
+
+_public_ sd_radv *sd_radv_unref(sd_radv *ra) {
+ if (!ra)
+ return NULL;
+
+ assert(ra->n_ref > 0);
+ ra->n_ref--;
+
+ if (ra->n_ref > 0)
+ return NULL;
+
+ while (ra->prefixes) {
+ sd_radv_prefix *p = ra->prefixes;
+
+ LIST_REMOVE(prefix, ra->prefixes, p);
+ sd_radv_prefix_unref(p);
+ }
+
+ radv_reset(ra);
+
+ sd_radv_detach_event(ra);
+ return mfree(ra);
+}
+
+static int radv_send(sd_radv *ra, const struct in6_addr *dst,
+ const uint32_t router_lifetime) {
+ static const struct ether_addr mac_zero = {};
+ sd_radv_prefix *p;
+ struct sockaddr_in6 dst_addr = {
+ .sin6_family = AF_INET6,
+ .sin6_addr = IN6ADDR_ALL_NODES_MULTICAST_INIT,
+ };
+ struct nd_router_advert adv = {};
+ struct {
+ struct nd_opt_hdr opthdr;
+ struct ether_addr slladdr;
+ } _packed_ opt_mac = {
+ .opthdr = {
+ .nd_opt_type = ND_OPT_SOURCE_LINKADDR,
+ .nd_opt_len = (sizeof(struct nd_opt_hdr) +
+ sizeof(struct ether_addr) - 1) /8 + 1,
+ },
+ };
+ struct nd_opt_mtu opt_mtu = {
+ .nd_opt_mtu_type = ND_OPT_MTU,
+ .nd_opt_mtu_len = 1,
+ };
+ /* Reserve iov space for RA header, linkaddr, MTU + N prefixes */
+ struct iovec iov[3 + ra->n_prefixes];
+ struct msghdr msg = {
+ .msg_name = &dst_addr,
+ .msg_namelen = sizeof(dst_addr),
+ .msg_iov = iov,
+ };
+
+ if (dst && !in_addr_is_null(AF_INET6, (union in_addr_union*) dst))
+ dst_addr.sin6_addr = *dst;
+
+ adv.nd_ra_type = ND_ROUTER_ADVERT;
+ adv.nd_ra_curhoplimit = ra->hop_limit;
+ adv.nd_ra_flags_reserved = ra->flags;
+ adv.nd_ra_router_lifetime = htobe16(router_lifetime);
+ iov[msg.msg_iovlen].iov_base = &adv;
+ iov[msg.msg_iovlen].iov_len = sizeof(adv);
+ msg.msg_iovlen++;
+
+ /* MAC address is optional, either because the link does not use L2
+ addresses or load sharing is desired. See RFC 4861, Section 4.2 */
+ if (memcmp(&mac_zero, &ra->mac_addr, sizeof(mac_zero))) {
+ opt_mac.slladdr = ra->mac_addr;
+ iov[msg.msg_iovlen].iov_base = &opt_mac;
+ iov[msg.msg_iovlen].iov_len = sizeof(opt_mac);
+ msg.msg_iovlen++;
+ }
+
+ if (ra->mtu) {
+ opt_mtu.nd_opt_mtu_mtu = htobe32(ra->mtu);
+ iov[msg.msg_iovlen].iov_base = &opt_mtu;
+ iov[msg.msg_iovlen].iov_len = sizeof(opt_mtu);
+ msg.msg_iovlen++;
+ }
+
+ LIST_FOREACH(prefix, p, ra->prefixes) {
+ iov[msg.msg_iovlen].iov_base = &p->opt;
+ iov[msg.msg_iovlen].iov_len = sizeof(p->opt);
+ msg.msg_iovlen++;
+ }
+
+ if (sendmsg(ra->fd, &msg, 0) < 0)
+ return -errno;
+
+ return 0;
+}
+
+static int radv_recv(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
+ sd_radv *ra = userdata;
+ _cleanup_free_ char *addr = NULL;
+ struct in6_addr src;
+ triple_timestamp timestamp;
+ int r;
+ ssize_t buflen;
+ _cleanup_free_ char *buf = NULL;
+
+ assert(s);
+ assert(ra);
+ assert(ra->event);
+
+ buflen = next_datagram_size_fd(fd);
+
+ if ((unsigned) buflen < sizeof(struct nd_router_solicit))
+ return log_radv("Too short packet received");
+
+ buf = new0(char, buflen);
+ if (!buf)
+ return 0;
+
+ r = icmp6_receive(fd, buf, buflen, &src, &timestamp);
+ if (r < 0) {
+ switch (r) {
+ case -EADDRNOTAVAIL:
+ (void) in_addr_to_string(AF_INET6, (union in_addr_union*) &src, &addr);
+ log_radv("Received RS from non-link-local address %s. Ignoring", addr);
+ break;
+
+ case -EMULTIHOP:
+ log_radv("Received RS with invalid hop limit. Ignoring.");
+ break;
+
+ case -EPFNOSUPPORT:
+ log_radv("Received invalid source address from ICMPv6 socket. Ignoring.");
+ break;
+
+ default:
+ log_radv_warning_errno(r, "Error receiving from ICMPv6 socket: %m");
+ break;
+ }
+
+ return 0;
+ }
+
+ (void) in_addr_to_string(AF_INET6, (union in_addr_union*) &src, &addr);
+
+ r = radv_send(ra, &src, ra->lifetime);
+ if (r < 0)
+ log_radv_warning_errno(r, "Unable to send solicited Router Advertisment to %s: %m", addr);
+ else
+ log_radv("Sent solicited Router Advertisement to %s", addr);
+
+ return 0;
+}
+
+static usec_t radv_compute_timeout(usec_t min, usec_t max) {
+ assert_return(min <= max, SD_RADV_DEFAULT_MIN_TIMEOUT_USEC);
+
+ return min + (random_u32() % (max - min));
+}
+
+static int radv_timeout(sd_event_source *s, uint64_t usec, void *userdata) {
+ int r;
+ sd_radv *ra = userdata;
+ usec_t min_timeout = SD_RADV_DEFAULT_MIN_TIMEOUT_USEC;
+ usec_t max_timeout = SD_RADV_DEFAULT_MAX_TIMEOUT_USEC;
+ usec_t time_now, timeout;
+ char time_string[FORMAT_TIMESPAN_MAX];
+
+ assert(s);
+ assert(ra);
+ assert(ra->event);
+
+ ra->timeout_event_source = sd_event_source_unref(ra->timeout_event_source);
+
+ r = sd_event_now(ra->event, clock_boottime_or_monotonic(), &time_now);
+ if (r < 0)
+ goto fail;
+
+ r = radv_send(ra, NULL, ra->lifetime);
+ if (r < 0)
+ log_radv_warning_errno(r, "Unable to send Router Advertisement: %m");
+
+ /* RFC 4861, Section 6.2.4, sending initial Router Advertisements */
+ if (ra->ra_sent < SD_RADV_MAX_INITIAL_RTR_ADVERTISEMENTS) {
+ max_timeout = SD_RADV_MAX_INITIAL_RTR_ADVERT_INTERVAL_USEC;
+ min_timeout = SD_RADV_MAX_INITIAL_RTR_ADVERT_INTERVAL_USEC / 3;
+ }
+
+ timeout = radv_compute_timeout(min_timeout, max_timeout);
+
+ log_radv("Next Router Advertisement in %s",
+ format_timespan(time_string, FORMAT_TIMESPAN_MAX,
+ timeout, USEC_PER_SEC));
+
+ r = sd_event_add_time(ra->event, &ra->timeout_event_source,
+ clock_boottime_or_monotonic(),
+ time_now + timeout, MSEC_PER_SEC,
+ radv_timeout, ra);
+ if (r < 0)
+ goto fail;
+
+ r = sd_event_source_set_priority(ra->timeout_event_source,
+ ra->event_priority);
+ if (r < 0)
+ goto fail;
+
+ r = sd_event_source_set_description(ra->timeout_event_source,
+ "radv-timeout");
+ if (r < 0)
+ goto fail;
+
+ ra->ra_sent++;
+
+fail:
+ if (r < 0)
+ sd_radv_stop(ra);
+
+ return 0;
+}
+
+_public_ int sd_radv_stop(sd_radv *ra) {
+ int r;
+
+ assert_return(ra, -EINVAL);
+
+ log_radv("Stopping IPv6 Router Advertisement daemon");
+
+ /* RFC 4861, Section 6.2.5, send at least one Router Advertisement
+ with zero lifetime */
+ r = radv_send(ra, NULL, 0);
+ if (r < 0)
+ log_radv_warning_errno(r, "Unable to send last Router Advertisement with router lifetime set to zero: %m");
+
+ radv_reset(ra);
+ ra->fd = safe_close(ra->fd);
+ ra->state = SD_RADV_STATE_IDLE;
+
+ return 0;
+}
+
+_public_ int sd_radv_start(sd_radv *ra) {
+ int r = 0;
+
+ assert_return(ra, -EINVAL);
+ assert_return(ra->event, -EINVAL);
+ assert_return(ra->ifindex > 0, -EINVAL);
+
+ if (ra->state != SD_RADV_STATE_IDLE)
+ return 0;
+
+ r = sd_event_add_time(ra->event, &ra->timeout_event_source,
+ clock_boottime_or_monotonic(), 0, 0,
+ radv_timeout, ra);
+ if (r < 0)
+ goto fail;
+
+ r = sd_event_source_set_priority(ra->timeout_event_source,
+ ra->event_priority);
+ if (r < 0)
+ goto fail;
+
+ (void) sd_event_source_set_description(ra->timeout_event_source,
+ "radv-timeout");
+
+ r = icmp6_bind_router_advertisement(ra->ifindex);
+ if (r < 0)
+ goto fail;
+
+ ra->fd = r;
+
+ r = sd_event_add_io(ra->event, &ra->recv_event_source, ra->fd, EPOLLIN, radv_recv, ra);
+ if (r < 0)
+ goto fail;
+
+ r = sd_event_source_set_priority(ra->recv_event_source, ra->event_priority);
+ if (r < 0)
+ goto fail;
+
+ (void) sd_event_source_set_description(ra->recv_event_source, "radv-receive-message");
+
+ ra->state = SD_RADV_STATE_ADVERTISING;
+
+ log_radv("Started IPv6 Router Advertisement daemon");
+
+ return 0;
+
+ fail:
+ radv_reset(ra);
+
+ return r;
+}
+
+_public_ int sd_radv_set_ifindex(sd_radv *ra, int ifindex) {
+ assert_return(ra, -EINVAL);
+ assert_return(ifindex >= -1, -EINVAL);
+
+ if (ra->state != SD_RADV_STATE_IDLE)
+ return -EBUSY;
+
+ ra->ifindex = ifindex;
+
+ return 0;
+}
+
+_public_ int sd_radv_set_mac(sd_radv *ra, const struct ether_addr *mac_addr) {
+ assert_return(ra, -EINVAL);
+
+ if (ra->state != SD_RADV_STATE_IDLE)
+ return -EBUSY;
+
+ if (mac_addr)
+ ra->mac_addr = *mac_addr;
+ else
+ zero(ra->mac_addr);
+
+ return 0;
+}
+
+_public_ int sd_radv_set_mtu(sd_radv *ra, uint32_t mtu) {
+ assert_return(ra, -EINVAL);
+ assert_return(mtu >= 1280, -EINVAL);
+
+ if (ra->state != SD_RADV_STATE_IDLE)
+ return -EBUSY;
+
+ ra->mtu = mtu;
+
+ return 0;
+}
+
+_public_ int sd_radv_set_hop_limit(sd_radv *ra, uint8_t hop_limit) {
+ assert_return(ra, -EINVAL);
+
+ if (ra->state != SD_RADV_STATE_IDLE)
+ return -EBUSY;
+
+ ra->hop_limit = hop_limit;
+
+ return 0;
+}
+
+_public_ int sd_radv_set_router_lifetime(sd_radv *ra, uint32_t router_lifetime) {
+ assert_return(ra, -EINVAL);
+
+ if (ra->state != SD_RADV_STATE_IDLE)
+ return -EBUSY;
+
+ /* RFC 4191, Section 2.2, "...If the Router Lifetime is zero, the
+ preference value MUST be set to (00) by the sender..." */
+ if (router_lifetime == 0 &&
+ (ra->flags & (0x3 << 3)) != (SD_NDISC_PREFERENCE_MEDIUM << 3))
+ return -ETIME;
+
+ ra->lifetime = router_lifetime;
+
+ return 0;
+}
+
+_public_ int sd_radv_set_managed_information(sd_radv *ra, int managed) {
+ assert_return(ra, -EINVAL);
+
+ if (ra->state != SD_RADV_STATE_IDLE)
+ return -EBUSY;
+
+ SET_FLAG(ra->flags, ND_RA_FLAG_MANAGED, managed);
+
+ return 0;
+}
+
+_public_ int sd_radv_set_other_information(sd_radv *ra, int other) {
+ assert_return(ra, -EINVAL);
+
+ if (ra->state != SD_RADV_STATE_IDLE)
+ return -EBUSY;
+
+ SET_FLAG(ra->flags, ND_RA_FLAG_OTHER, other);
+
+ return 0;
+}
+
+_public_ int sd_radv_set_preference(sd_radv *ra, unsigned preference) {
+ int r = 0;
+
+ assert_return(ra, -EINVAL);
+ assert_return(IN_SET(preference,
+ SD_NDISC_PREFERENCE_LOW,
+ SD_NDISC_PREFERENCE_MEDIUM,
+ SD_NDISC_PREFERENCE_HIGH), -EINVAL);
+
+ ra->flags = (ra->flags & ~(0x3 << 3)) | (preference << 3);
+
+ return r;
+}
+
+_public_ int sd_radv_add_prefix(sd_radv *ra, sd_radv_prefix *p) {
+ sd_radv_prefix *cur;
+ _cleanup_free_ char *addr_p = NULL;
+
+ assert_return(ra, -EINVAL);
+
+ if (!p)
+ return -EINVAL;
+
+ LIST_FOREACH(prefix, cur, ra->prefixes) {
+ int r;
+
+ r = in_addr_prefix_intersect(AF_INET6,
+ (union in_addr_union*) &cur->opt.in6_addr,
+ cur->opt.prefixlen,
+ (union in_addr_union*) &p->opt.in6_addr,
+ p->opt.prefixlen);
+ if (r > 0) {
+ _cleanup_free_ char *addr_cur = NULL;
+
+ (void) in_addr_to_string(AF_INET6,
+ (union in_addr_union*) &cur->opt.in6_addr,
+ &addr_cur);
+ (void) in_addr_to_string(AF_INET6,
+ (union in_addr_union*) &p->opt.in6_addr,
+ &addr_p);
+
+ log_radv("IPv6 prefix %s/%u already configured, ignoring %s/%u",
+ addr_cur, cur->opt.prefixlen,
+ addr_p, p->opt.prefixlen);
+
+ return -EEXIST;
+ }
+ }
+
+ p = sd_radv_prefix_ref(p);
+
+ LIST_APPEND(prefix, ra->prefixes, p);
+
+ ra->n_prefixes++;
+
+ (void) in_addr_to_string(AF_INET6, (union in_addr_union*) &p->opt.in6_addr, &addr_p);
+ log_radv("Added prefix %s/%d", addr_p, p->opt.prefixlen);
+
+ return 0;
+}
+
+_public_ int sd_radv_prefix_new(sd_radv_prefix **ret) {
+ _cleanup_(sd_radv_prefix_unrefp) sd_radv_prefix *p = NULL;
+
+ assert_return(ret, -EINVAL);
+
+ p = new0(sd_radv_prefix, 1);
+ if (!p)
+ return -ENOMEM;
+
+ p->n_ref = 1;
+
+ p->opt.type = ND_OPT_PREFIX_INFORMATION;
+ p->opt.length = (sizeof(p->opt) - 1) /8 + 1;
+
+ p->opt.prefixlen = 64;
+
+ /* RFC 4861, Section 6.2.1 */
+ SET_FLAG(p->opt.flags, ND_OPT_PI_FLAG_ONLINK, true);
+ SET_FLAG(p->opt.flags, ND_OPT_PI_FLAG_AUTO, true);
+ p->opt.preferred_lifetime = htobe32(604800);
+ p->opt.valid_lifetime = htobe32(2592000);
+
+ LIST_INIT(prefix, p);
+
+ *ret = p;
+ p = NULL;
+
+ return 0;
+}
+
+_public_ sd_radv_prefix *sd_radv_prefix_ref(sd_radv_prefix *p) {
+ if (!p)
+ return NULL;
+
+ assert(p->n_ref > 0);
+ p->n_ref++;
+
+ return p;
+}
+
+_public_ sd_radv_prefix *sd_radv_prefix_unref(sd_radv_prefix *p) {
+ if (!p)
+ return NULL;
+
+ assert(p->n_ref > 0);
+ p->n_ref--;
+
+ if (p->n_ref > 0)
+ return NULL;
+
+ return mfree(p);
+}
+
+_public_ int sd_radv_prefix_set_prefix(sd_radv_prefix *p, struct in6_addr *in6_addr,
+ unsigned char prefixlen) {
+ assert_return(p, -EINVAL);
+ assert_return(in6_addr, -EINVAL);
+
+ if (prefixlen < 3 || prefixlen > 128)
+ return -EINVAL;
+
+ if (prefixlen > 64)
+ /* unusual but allowed, log it */
+ log_radv("Unusual prefix length %d greater than 64", prefixlen);
+
+ p->opt.in6_addr = *in6_addr;
+ p->opt.prefixlen = prefixlen;
+
+ return 0;
+}
+
+_public_ int sd_radv_prefix_set_onlink(sd_radv_prefix *p, int onlink) {
+ assert_return(p, -EINVAL);
+
+ SET_FLAG(p->opt.flags, ND_OPT_PI_FLAG_ONLINK, onlink);
+
+ return 0;
+}
+
+_public_ int sd_radv_prefix_set_address_autoconfiguration(sd_radv_prefix *p,
+ int address_autoconfiguration) {
+ assert_return(p, -EINVAL);
+
+ SET_FLAG(p->opt.flags, ND_OPT_PI_FLAG_AUTO, address_autoconfiguration);
+
+ return 0;
+}
+
+_public_ int sd_radv_prefix_set_valid_lifetime(sd_radv_prefix *p,
+ uint32_t valid_lifetime) {
+ assert_return(p, -EINVAL);
+
+ p->opt.valid_lifetime = htobe32(valid_lifetime);
+
+ return 0;
+}
+
+_public_ int sd_radv_prefix_set_preferred_lifetime(sd_radv_prefix *p,
+ uint32_t preferred_lifetime) {
+ assert_return(p, -EINVAL);
+
+ p->opt.preferred_lifetime = htobe32(preferred_lifetime);
+
+ return 0;
+}
diff --git a/src/libsystemd-network/test-dhcp-server.c b/src/libsystemd-network/test-dhcp-server.c
index e81c508c7f..26f217835f 100644
--- a/src/libsystemd-network/test-dhcp-server.c
+++ b/src/libsystemd-network/test-dhcp-server.c
@@ -63,7 +63,7 @@ static int test_basic(sd_event *event) {
assert_se(sd_dhcp_server_configure_pool(server, &address_any, 28, 0, 0) == -EINVAL);
assert_se(sd_dhcp_server_configure_pool(server, &address_lo, 38, 0, 0) == -ERANGE);
assert_se(sd_dhcp_server_configure_pool(server, &address_lo, 8, 0, 0) >= 0);
- assert_se(sd_dhcp_server_configure_pool(server, &address_lo, 8, 0, 0) == -EBUSY);
+ assert_se(sd_dhcp_server_configure_pool(server, &address_lo, 8, 0, 0) >= 0);
test_pool(&address_any, 1, -EINVAL);
test_pool(&address_lo, 1, 0);
diff --git a/src/libsystemd-network/test-ipv4ll.c b/src/libsystemd-network/test-ipv4ll.c
index fe70697075..89864fd39c 100644
--- a/src/libsystemd-network/test-ipv4ll.c
+++ b/src/libsystemd-network/test-ipv4ll.c
@@ -17,7 +17,6 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
@@ -72,10 +71,10 @@ int arp_send_probe(int fd, int ifindex,
be32_t pa, const struct ether_addr *ha) {
struct ether_arp ea = {};
- assert(fd >= 0);
- assert(ifindex > 0);
- assert(pa != 0);
- assert(ha);
+ assert_se(fd >= 0);
+ assert_se(ifindex > 0);
+ assert_se(pa != 0);
+ assert_se(ha);
return arp_network_send_raw_socket(fd, ifindex, &ea);
}
@@ -84,10 +83,10 @@ int arp_send_announcement(int fd, int ifindex,
be32_t pa, const struct ether_addr *ha) {
struct ether_arp ea = {};
- assert(fd >= 0);
- assert(ifindex > 0);
- assert(pa != 0);
- assert(ha);
+ assert_se(fd >= 0);
+ assert_se(ifindex > 0);
+ assert_se(pa != 0);
+ assert_se(ha);
return arp_network_send_raw_socket(fd, ifindex, &ea);
}
diff --git a/src/libsystemd-network/test-ndisc-ra.c b/src/libsystemd-network/test-ndisc-ra.c
new file mode 100644
index 0000000000..6e6d05642d
--- /dev/null
+++ b/src/libsystemd-network/test-ndisc-ra.c
@@ -0,0 +1,359 @@
+/***
+ This file is part of systemd.
+
+ Copyright (C) 2017 Intel Corporation. All rights reserved.
+
+ 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 <netinet/icmp6.h>
+#include <arpa/inet.h>
+
+#include "sd-radv.h"
+
+#include "alloc-util.h"
+#include "hexdecoct.h"
+#include "icmp6-util.h"
+#include "socket-util.h"
+#include "strv.h"
+
+static struct ether_addr mac_addr = {
+ .ether_addr_octet = { 0x78, 0x2b, 0xcb, 0xb3, 0x6d, 0x53 }
+};
+
+static uint8_t advertisement[] = {
+ /* ICMPv6 Router Advertisement, no checksum */
+ 0x86, 0x00, 0x00, 0x00, 0x40, 0xc0, 0x00, 0xb4,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* Source Link Layer Address Option */
+ 0x01, 0x01, 0x78, 0x2b, 0xcb, 0xb3, 0x6d, 0x53,
+ /* Prefix Information Option */
+ 0x03, 0x04, 0x40, 0xc0, 0x00, 0x00, 0x01, 0xf4,
+ 0x00, 0x00, 0x01, 0xb8, 0x00, 0x00, 0x00, 0x00,
+ 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* Prefix Information Option */
+ 0x03, 0x04, 0x40, 0xc0, 0x00, 0x27, 0x8d, 0x00,
+ 0x00, 0x09, 0x3a, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x20, 0x01, 0x0d, 0xb8, 0x0b, 0x16, 0xd0, 0x0d,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* Prefix Information Option */
+ 0x03, 0x04, 0x30, 0xc0, 0x00, 0x27, 0x8d, 0x00,
+ 0x00, 0x09, 0x3a, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x20, 0x01, 0x0d, 0xb8, 0xc0, 0x01, 0x0d, 0xad,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* Recursive DNS Server Option - not yet supported */
+ 0x19, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
+ 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ /* DNS Search List Option - not yet supported */
+ 0x1f, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
+ 0x03, 0x6c, 0x61, 0x62, 0x05, 0x69, 0x6e, 0x74,
+ 0x72, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+static sd_event_source *test_hangcheck;
+static bool test_stopped;
+static int test_fd[2];
+static sd_event_source *recv_router_advertisement;
+static struct {
+ struct in6_addr address;
+ unsigned char prefixlen;
+ uint32_t valid;
+ uint32_t preferred;
+ bool succesful;
+} prefix[] = {
+ { { { { 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, 64,
+ 500, 440, true },
+ { { { { 0x20, 0x01, 0x0d, 0xb8, 0x0b, 0x16, 0xd0, 0x0d,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, 64,
+ /* indicate default valid and preferred lifetimes for the test code */
+ 0, 0, true },
+ { { { { 0x20, 0x01, 0x0d, 0xb8, 0x0b, 0x16, 0xd0, 0x0d,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, 58,
+ 0, 0,
+ /* indicate that this prefix already exists */
+ false },
+ { { { { 0x20, 0x01, 0x0d, 0xb8, 0x0b, 0x16, 0xd0, 0x0d,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, 120,
+ 0, 0,
+ /* indicate that this prefix already exists */
+ false },
+ { { { { 0x20, 0x01, 0x0d, 0xb8, 0x0b, 0x16, 0xd0, 0x0d,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, 12,
+ 0, 0,
+ /* indicate that this prefix already exists */
+ false },
+ { { { { 0x20, 0x01, 0x0d, 0xb8, 0xc0, 0x01, 0x0d, 0xad,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, 48,
+ 0, 0, true },
+ { { { { 0x20, 0x01, 0x0d, 0xb8, 0xc0, 0x01, 0x0d, 0xad,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, 60,
+ 0, 0,
+ /* indicate that this prefix already exists */
+ false },
+};
+
+static int test_rs_hangcheck(sd_event_source *s, uint64_t usec,
+ void *userdata) {
+ assert_se(false);
+
+ return 0;
+}
+
+static void test_radv_prefix(void) {
+ sd_radv_prefix *p;
+
+ printf("* %s\n", __FUNCTION__);
+
+ assert_se(sd_radv_prefix_new(&p) >= 0);
+
+ assert_se(sd_radv_prefix_set_onlink(NULL, true) < 0);
+ assert_se(sd_radv_prefix_set_onlink(p, true) >= 0);
+ assert_se(sd_radv_prefix_set_onlink(p, false) >= 0);
+
+ assert_se(sd_radv_prefix_set_address_autoconfiguration(NULL, true) < 0);
+ assert_se(sd_radv_prefix_set_address_autoconfiguration(p, true) >= 0);
+ assert_se(sd_radv_prefix_set_address_autoconfiguration(p, false) >= 0);
+
+ assert_se(sd_radv_prefix_set_valid_lifetime(NULL, true) < 0);
+ assert_se(sd_radv_prefix_set_valid_lifetime(p, ~0) >= 0);
+ assert_se(sd_radv_prefix_set_valid_lifetime(p, 42) >= 0);
+ assert_se(sd_radv_prefix_set_valid_lifetime(p, 0) >= 0);
+
+ assert_se(sd_radv_prefix_set_preferred_lifetime(NULL, true) < 0);
+ assert_se(sd_radv_prefix_set_preferred_lifetime(p, ~0) >= 0);
+ assert_se(sd_radv_prefix_set_preferred_lifetime(p, 42) >= 0);
+ assert_se(sd_radv_prefix_set_preferred_lifetime(p, 0) >= 0);
+
+ assert_se(sd_radv_prefix_set_prefix(NULL, NULL, 0) < 0);
+ assert_se(sd_radv_prefix_set_prefix(p, NULL, 0) < 0);
+
+ assert_se(sd_radv_prefix_set_prefix(p, &prefix[0].address, 64) >= 0);
+ assert_se(sd_radv_prefix_set_prefix(p, &prefix[0].address, 0) < 0);
+ assert_se(sd_radv_prefix_set_prefix(p, &prefix[0].address, 1) < 0);
+ assert_se(sd_radv_prefix_set_prefix(p, &prefix[0].address, 2) < 0);
+ assert_se(sd_radv_prefix_set_prefix(p, &prefix[0].address, 3) >= 0);
+ assert_se(sd_radv_prefix_set_prefix(p, &prefix[0].address, 125) >= 0);
+ assert_se(sd_radv_prefix_set_prefix(p, &prefix[0].address, 128) >= 0);
+ assert_se(sd_radv_prefix_set_prefix(p, &prefix[0].address, 129) < 0);
+ assert_se(sd_radv_prefix_set_prefix(p, &prefix[0].address, 255) < 0);
+
+ p = sd_radv_prefix_unref(p);
+ assert_se(!p);
+}
+
+static void test_radv(void) {
+ sd_radv *ra;
+
+ printf("* %s\n", __FUNCTION__);
+
+ assert_se(sd_radv_new(&ra) >= 0);
+ assert_se(ra);
+
+ assert_se(sd_radv_set_ifindex(NULL, 0) < 0);
+ assert_se(sd_radv_set_ifindex(ra, 0) >= 0);
+ assert_se(sd_radv_set_ifindex(ra, -1) >= 0);
+ assert_se(sd_radv_set_ifindex(ra, -2) < 0);
+ assert_se(sd_radv_set_ifindex(ra, 42) >= 0);
+
+ assert_se(sd_radv_set_mac(NULL, NULL) < 0);
+ assert_se(sd_radv_set_mac(ra, NULL) >= 0);
+ assert_se(sd_radv_set_mac(ra, &mac_addr) >= 0);
+
+ assert_se(sd_radv_set_mtu(NULL, 0) < 0);
+ assert_se(sd_radv_set_mtu(ra, 0) < 0);
+ assert_se(sd_radv_set_mtu(ra, 1279) < 0);
+ assert_se(sd_radv_set_mtu(ra, 1280) >= 0);
+ assert_se(sd_radv_set_mtu(ra, ~0) >= 0);
+
+ assert_se(sd_radv_set_hop_limit(NULL, 0) < 0);
+ assert_se(sd_radv_set_hop_limit(ra, 0) >= 0);
+ assert_se(sd_radv_set_hop_limit(ra, ~0) >= 0);
+
+ assert_se(sd_radv_set_router_lifetime(NULL, 0) < 0);
+ assert_se(sd_radv_set_router_lifetime(ra, 0) >= 0);
+ assert_se(sd_radv_set_router_lifetime(ra, ~0) >= 0);
+
+ assert_se(sd_radv_set_preference(NULL, 0) < 0);
+ assert_se(sd_radv_set_preference(ra, SD_NDISC_PREFERENCE_LOW) >= 0);
+ assert_se(sd_radv_set_preference(ra, SD_NDISC_PREFERENCE_MEDIUM) >= 0);
+ assert_se(sd_radv_set_preference(ra, SD_NDISC_PREFERENCE_HIGH) >= 0);
+ assert_se(sd_radv_set_preference(ra, ~0) < 0);
+
+ assert_se(sd_radv_set_preference(ra, SD_NDISC_PREFERENCE_HIGH) >= 0);
+ assert_se(sd_radv_set_router_lifetime(ra, 42000) >= 0);
+ assert_se(sd_radv_set_router_lifetime(ra, 0) < 0);
+ assert_se(sd_radv_set_preference(ra, SD_NDISC_PREFERENCE_MEDIUM) >= 0);
+ assert_se(sd_radv_set_router_lifetime(ra, 0) >= 0);
+
+ assert_se(sd_radv_set_managed_information(NULL, true) < 0);
+ assert_se(sd_radv_set_managed_information(ra, true) >= 0);
+ assert_se(sd_radv_set_managed_information(ra, false) >= 0);
+
+ assert_se(sd_radv_set_other_information(NULL, true) < 0);
+ assert_se(sd_radv_set_other_information(ra, true) >= 0);
+ assert_se(sd_radv_set_other_information(ra, false) >= 0);
+
+ ra = sd_radv_unref(ra);
+ assert_se(!ra);
+}
+
+int icmp6_bind_router_solicitation(int index) {
+ return -ENOSYS;
+}
+
+int icmp6_bind_router_advertisement(int index) {
+ assert_se(index == 42);
+
+ return test_fd[1];
+}
+
+int icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr) {
+
+ return 0;
+}
+
+int icmp6_receive(int fd, void *iov_base, size_t iov_len,
+ struct in6_addr *dst, triple_timestamp *timestamp) {
+ assert_se(read (fd, iov_base, iov_len) == (ssize_t)iov_len);
+
+ if (timestamp)
+ triple_timestamp_get(timestamp);
+
+ return 0;
+}
+
+static int radv_recv(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
+ sd_radv *ra = userdata;
+ unsigned char buf[120];
+ size_t i;
+
+ read(test_fd[0], &buf, sizeof(buf));
+
+ /* router lifetime must be zero when test is stopped */
+ if (test_stopped) {
+ advertisement[6] = 0x00;
+ advertisement[7] = 0x00;
+ }
+
+ printf ("Received Router Advertisement with lifetime %u\n",
+ (advertisement[6] << 8) + advertisement[7]);
+
+ /* test only up to buf size, rest is not yet implemented */
+ for (i = 0; i < sizeof(buf); i++) {
+ printf("0x%02x", buf[i]);
+
+ assert_se(buf[i] == advertisement[i]);
+
+ if ((i + 1) % 8)
+ printf(", ");
+ else
+ printf("\n");
+ }
+
+ if (test_stopped) {
+ sd_event *e;
+
+ e = sd_radv_get_event(ra);
+ sd_event_exit(e, 0);
+
+ return 0;
+ }
+
+ assert_se(sd_radv_stop(ra) >= 0);
+ test_stopped = true;
+
+ return 0;
+}
+
+static void test_ra(void) {
+ sd_event *e;
+ sd_radv *ra;
+ usec_t time_now = now(clock_boottime_or_monotonic());
+ unsigned int i;
+
+ printf("* %s\n", __FUNCTION__);
+
+ assert_se(socketpair(AF_UNIX, SOCK_SEQPACKET, 0, test_fd) >= 0);
+
+ assert_se(sd_event_new(&e) >= 0);
+
+ assert_se(sd_radv_new(&ra) >= 0);
+ assert_se(ra);
+
+ assert_se(sd_radv_attach_event(ra, e, 0) >= 0);
+
+ assert_se(sd_radv_set_ifindex(ra, 42) >= 0);
+ assert_se(sd_radv_set_mac(ra, &mac_addr) >= 0);
+ assert_se(sd_radv_set_router_lifetime(ra, 180) >= 0);
+ assert_se(sd_radv_set_hop_limit(ra, 64) >= 0);
+ assert_se(sd_radv_set_managed_information(ra, true) >= 0);
+ assert_se(sd_radv_set_other_information(ra, true) >= 0);
+
+ for (i = 0; i < ELEMENTSOF(prefix); i++) {
+ sd_radv_prefix *p;
+
+ printf("Test prefix %u\n", i);
+ assert_se(sd_radv_prefix_new(&p) >= 0);
+
+ assert_se(sd_radv_prefix_set_prefix(p, &prefix[i].address,
+ prefix[i].prefixlen) >= 0);
+ if (prefix[i].valid)
+ assert_se(sd_radv_prefix_set_valid_lifetime(p, prefix[i].valid) >= 0);
+ if (prefix[i].preferred)
+ assert_se(sd_radv_prefix_set_preferred_lifetime(p, prefix[i].preferred) >= 0);
+
+ assert_se((sd_radv_add_prefix(ra, p) >= 0) == prefix[i].succesful);
+ assert_se(sd_radv_add_prefix(ra, p) < 0);
+
+ p = sd_radv_prefix_unref(p);
+ assert_se(!p);
+ }
+
+ assert_se(sd_event_add_io(e, &recv_router_advertisement, test_fd[0],
+ EPOLLIN, radv_recv, ra) >= 0);
+
+ assert_se(sd_event_add_time(e, &test_hangcheck, clock_boottime_or_monotonic(),
+ time_now + 2 *USEC_PER_SEC, 0,
+ test_rs_hangcheck, NULL) >= 0);
+
+ assert_se(sd_radv_start(ra) >= 0);
+
+ sd_event_loop(e);
+
+ test_hangcheck = sd_event_source_unref(test_hangcheck);
+
+ ra = sd_radv_unref(ra);
+ assert_se(!ra);
+
+ close(test_fd[0]);
+
+ sd_event_unref(e);
+}
+
+int main(int argc, char *argv[]) {
+
+ log_set_max_level(LOG_DEBUG);
+ log_parse_environment();
+ log_open();
+
+ test_radv_prefix();
+ test_radv();
+ test_ra();
+
+ printf("* done\n");
+ return 0;
+}
diff --git a/src/libsystemd-network/test-ndisc-rs.c b/src/libsystemd-network/test-ndisc-rs.c
index d9669488be..c3e1a8e340 100644
--- a/src/libsystemd-network/test-ndisc-rs.c
+++ b/src/libsystemd-network/test-ndisc-rs.c
@@ -27,6 +27,7 @@
#include "icmp6-util.h"
#include "socket-util.h"
#include "strv.h"
+#include "ndisc-internal.h"
static struct ether_addr mac_addr = {
.ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'}
@@ -35,6 +36,7 @@ static struct ether_addr mac_addr = {
static bool verbose = false;
static sd_event_source *test_hangcheck;
static int test_fd[2];
+static sd_ndisc *test_timeout_nd;
typedef int (*send_ra_t)(uint8_t flags);
static send_ra_t send_ra_function;
@@ -193,6 +195,21 @@ int icmp6_bind_router_solicitation(int index) {
return test_fd[0];
}
+int icmp6_bind_router_advertisement(int index) {
+
+ return -ENOSYS;
+}
+
+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);
+
+ if (timestamp)
+ triple_timestamp_get(timestamp);
+
+ return 0;
+}
+
static int send_ra(uint8_t flags) {
uint8_t advertisement[] = {
0x86, 0x00, 0xde, 0x83, 0x40, 0xc0, 0x00, 0xb4,
@@ -222,6 +239,9 @@ static int send_ra(uint8_t flags) {
}
int icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr) {
+ if (!send_ra_function)
+ return 0;
+
return send_ra_function(0);
}
@@ -305,6 +325,100 @@ static void test_rs(void) {
sd_event_unref(e);
}
+static int test_timeout_value(uint8_t flags) {
+ static int count = 0;
+ static usec_t last = 0;
+ sd_ndisc *nd = test_timeout_nd;
+ usec_t min, max;
+ char time_string_min[FORMAT_TIMESPAN_MAX];
+ char time_string_nd[FORMAT_TIMESPAN_MAX];
+ char time_string_max[FORMAT_TIMESPAN_MAX];
+
+ assert_se(nd);
+ assert_se(nd->event);
+
+ if (++count >= 20)
+ sd_event_exit(nd->event, 0);
+
+ if (last == 0) {
+ /* initial RT = IRT + RAND*IRT */
+ min = NDISC_ROUTER_SOLICITATION_INTERVAL -
+ NDISC_ROUTER_SOLICITATION_INTERVAL / 10;
+ max = NDISC_ROUTER_SOLICITATION_INTERVAL +
+ NDISC_ROUTER_SOLICITATION_INTERVAL / 10;
+ } else {
+ /* next RT = 2*RTprev + RAND*RTprev */
+ min = 2 * last - last / 10;
+ max = 2 * last + last / 10;
+ }
+
+ /* final RT > MRT */
+ if (last * 2 > NDISC_MAX_ROUTER_SOLICITATION_INTERVAL) {
+ min = NDISC_MAX_ROUTER_SOLICITATION_INTERVAL -
+ NDISC_MAX_ROUTER_SOLICITATION_INTERVAL / 10;
+ max = NDISC_MAX_ROUTER_SOLICITATION_INTERVAL +
+ NDISC_MAX_ROUTER_SOLICITATION_INTERVAL / 10;
+ }
+
+ format_timespan(time_string_min, FORMAT_TIMESPAN_MAX,
+ min, USEC_PER_MSEC);
+ format_timespan(time_string_nd, FORMAT_TIMESPAN_MAX,
+ nd->retransmit_time, USEC_PER_MSEC);
+ format_timespan(time_string_max, FORMAT_TIMESPAN_MAX,
+ max, USEC_PER_MSEC);
+
+ log_info("backoff timeout interval %2d %s%s <= %s <= %s",
+ count,
+ (last * 2 > NDISC_MAX_ROUTER_SOLICITATION_INTERVAL)? "(max) ": "",
+ time_string_min, time_string_nd, time_string_max);
+
+ assert_se(min <= nd->retransmit_time);
+ assert_se(max >= nd->retransmit_time);
+
+ last = nd->retransmit_time;
+
+ assert_se(sd_event_source_set_time(nd->timeout_event_source, 0) >= 0);
+
+ return 0;
+}
+
+static void test_timeout(void) {
+ sd_event *e;
+ sd_ndisc *nd;
+ usec_t time_now = now(clock_boottime_or_monotonic());
+
+ if (verbose)
+ printf("* %s\n", __FUNCTION__);
+
+ send_ra_function = test_timeout_value;
+
+ assert_se(sd_event_new(&e) >= 0);
+
+ assert_se(sd_ndisc_new(&nd) >= 0);
+ assert_se(nd);
+
+ test_timeout_nd = nd;
+
+ assert_se(sd_ndisc_attach_event(nd, e, 0) >= 0);
+
+ assert_se(sd_ndisc_set_ifindex(nd, 42) >= 0);
+ assert_se(sd_ndisc_set_mac(nd, &mac_addr) >= 0);
+
+ assert_se(sd_event_add_time(e, &test_hangcheck, clock_boottime_or_monotonic(),
+ time_now + 2U * USEC_PER_SEC, 0,
+ test_rs_hangcheck, NULL) >= 0);
+
+ assert_se(sd_ndisc_start(nd) >= 0);
+
+ sd_event_loop(e);
+
+ test_hangcheck = sd_event_source_unref(test_hangcheck);
+
+ nd = sd_ndisc_unref(nd);
+
+ sd_event_unref(e);
+}
+
int main(int argc, char *argv[]) {
log_set_max_level(LOG_DEBUG);
@@ -312,6 +426,7 @@ int main(int argc, char *argv[]) {
log_open();
test_rs();
+ test_timeout();
return 0;
}
diff --git a/src/libsystemd-network/test-sd-dhcp-lease.c b/src/libsystemd-network/test-sd-dhcp-lease.c
new file mode 100644
index 0000000000..0f881809ab
--- /dev/null
+++ b/src/libsystemd-network/test-sd-dhcp-lease.c
@@ -0,0 +1,90 @@
+#include <errno.h>
+
+#include "dhcp-lease-internal.h"
+#include "macro.h"
+#include "string-util.h"
+#include "strv.h"
+
+/* According to RFC1035 section 4.1.4, a domain name in a message can be either:
+ * - a sequence of labels ending in a zero octet
+ * - a pointer
+ * - a sequence of labels ending with a pointer
+ */
+static void test_dhcp_lease_parse_search_domains_basic(void) {
+ int r;
+ _cleanup_strv_free_ char **domains = NULL;
+ static const uint8_t optionbuf[] = {
+ 0x03, 'F', 'O', 'O', 0x03, 'B', 'A', 'R', 0x00,
+ 0x04, 'A', 'B', 'C', 'D', 0x03, 'E', 'F', 'G', 0x00,
+ };
+
+ r = dhcp_lease_parse_search_domains(optionbuf, sizeof(optionbuf), &domains);
+ assert_se(r == 2);
+ assert_se(streq(domains[0], "FOO.BAR"));
+ assert_se(streq(domains[1], "ABCD.EFG"));
+}
+
+static void test_dhcp_lease_parse_search_domains_ptr(void) {
+ int r;
+ _cleanup_strv_free_ char **domains = NULL;
+ static const uint8_t optionbuf[] = {
+ 0x03, 'F', 'O', 'O', 0x00, 0xC0, 0x00,
+ };
+
+ r = dhcp_lease_parse_search_domains(optionbuf, sizeof(optionbuf), &domains);
+ assert_se(r == 2);
+ assert_se(streq(domains[0], "FOO"));
+ assert_se(streq(domains[1], "FOO"));
+}
+
+static void test_dhcp_lease_parse_search_domains_labels_and_ptr(void) {
+ int r;
+ _cleanup_strv_free_ char **domains = NULL;
+ static const uint8_t optionbuf[] = {
+ 0x03, 'F', 'O', 'O', 0x03, 'B', 'A', 'R', 0x00,
+ 0x03, 'A', 'B', 'C', 0xC0, 0x04,
+ };
+
+ r = dhcp_lease_parse_search_domains(optionbuf, sizeof(optionbuf), &domains);
+ assert_se(r == 2);
+ assert_se(streq(domains[0], "FOO.BAR"));
+ assert_se(streq(domains[1], "ABC.BAR"));
+}
+
+/* Tests for exceptions. */
+
+static void test_dhcp_lease_parse_search_domains_no_data(void) {
+ _cleanup_strv_free_ char **domains = NULL;
+ static const uint8_t optionbuf[3] = {0, 0, 0};
+
+ assert_se(dhcp_lease_parse_search_domains(NULL, 0, &domains) == -ENODATA);
+ assert_se(dhcp_lease_parse_search_domains(optionbuf, 0, &domains) == -ENODATA);
+}
+
+static void test_dhcp_lease_parse_search_domains_loops(void) {
+ _cleanup_strv_free_ char **domains = NULL;
+ static const uint8_t optionbuf[] = {
+ 0x03, 'F', 'O', 'O', 0x00, 0x03, 'B', 'A', 'R', 0xC0, 0x06,
+ };
+
+ assert_se(dhcp_lease_parse_search_domains(optionbuf, sizeof(optionbuf), &domains) == -EBADMSG);
+}
+
+static void test_dhcp_lease_parse_search_domains_wrong_len(void) {
+ _cleanup_strv_free_ char **domains = NULL;
+ static const uint8_t optionbuf[] = {
+ 0x03, 'F', 'O', 'O', 0x03, 'B', 'A', 'R', 0x00,
+ 0x04, 'A', 'B', 'C', 'D', 0x03, 'E', 'F', 'G', 0x00,
+ };
+
+ assert_se(dhcp_lease_parse_search_domains(optionbuf, sizeof(optionbuf) - 5, &domains) == -EBADMSG);
+}
+
+int main(int argc, char *argv[]) {
+ test_dhcp_lease_parse_search_domains_basic();
+ test_dhcp_lease_parse_search_domains_ptr();
+ test_dhcp_lease_parse_search_domains_labels_and_ptr();
+ test_dhcp_lease_parse_search_domains_no_data();
+ test_dhcp_lease_parse_search_domains_loops();
+ test_dhcp_lease_parse_search_domains_wrong_len();
+}
diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym
index c1135ffa22..92cb790d49 100644
--- a/src/libsystemd/libsystemd.sym
+++ b/src/libsystemd/libsystemd.sym
@@ -517,3 +517,8 @@ global:
sd_id128_get_machine_app_specific;
sd_is_socket_sockaddr;
} LIBSYSTEMD_232;
+
+LIBSYSTEMD_234 {
+global:
+ sd_bus_message_appendv;
+} LIBSYSTEMD_233;
diff --git a/src/libsystemd/meson.build b/src/libsystemd/meson.build
new file mode 100644
index 0000000000..ab69afee42
--- /dev/null
+++ b/src/libsystemd/meson.build
@@ -0,0 +1,96 @@
+sd_login_c = files('sd-login/sd-login.c')
+
+libsystemd_internal_sources = files('''
+ sd-bus/bus-bloom.c
+ sd-bus/bus-bloom.h
+ sd-bus/bus-common-errors.c
+ sd-bus/bus-common-errors.h
+ sd-bus/bus-container.c
+ sd-bus/bus-container.h
+ sd-bus/bus-control.c
+ sd-bus/bus-control.h
+ sd-bus/bus-convenience.c
+ sd-bus/bus-creds.c
+ sd-bus/bus-creds.h
+ sd-bus/bus-dump.c
+ sd-bus/bus-dump.h
+ sd-bus/bus-error.c
+ sd-bus/bus-error.h
+ sd-bus/bus-gvariant.c
+ sd-bus/bus-gvariant.h
+ sd-bus/bus-internal.c
+ sd-bus/bus-internal.h
+ sd-bus/bus-introspect.c
+ sd-bus/bus-introspect.h
+ sd-bus/bus-kernel.c
+ sd-bus/bus-kernel.h
+ sd-bus/bus-match.c
+ sd-bus/bus-match.h
+ sd-bus/bus-message.c
+ sd-bus/bus-message.h
+ sd-bus/bus-objects.c
+ sd-bus/bus-objects.h
+ sd-bus/bus-protocol.h
+ sd-bus/bus-signature.c
+ sd-bus/bus-signature.h
+ sd-bus/bus-slot.c
+ sd-bus/bus-slot.h
+ sd-bus/bus-socket.c
+ sd-bus/bus-socket.h
+ sd-bus/bus-track.c
+ sd-bus/bus-track.h
+ sd-bus/bus-type.c
+ sd-bus/bus-type.h
+ sd-bus/kdbus.h
+ sd-bus/sd-bus.c
+ sd-daemon/sd-daemon.c
+ sd-device/device-enumerator-private.h
+ sd-device/device-enumerator.c
+ sd-device/device-internal.h
+ sd-device/device-private.c
+ sd-device/device-private.h
+ sd-device/device-util.h
+ sd-device/sd-device.c
+ sd-event/sd-event.c
+ sd-hwdb/hwdb-internal.h
+ sd-hwdb/hwdb-util.h
+ sd-hwdb/sd-hwdb.c
+ sd-id128/id128-util.c
+ sd-id128/id128-util.h
+ sd-id128/sd-id128.c
+ sd-netlink/local-addresses.c
+ sd-netlink/local-addresses.h
+ sd-netlink/netlink-internal.h
+ sd-netlink/netlink-message.c
+ sd-netlink/netlink-socket.c
+ sd-netlink/netlink-types.c
+ sd-netlink/netlink-types.h
+ sd-netlink/netlink-util.c
+ sd-netlink/netlink-util.h
+ sd-netlink/rtnl-message.c
+ sd-netlink/sd-netlink.c
+ sd-network/network-util.c
+ sd-network/network-util.h
+ sd-network/sd-network.c
+ sd-path/sd-path.c
+ sd-resolve/sd-resolve.c
+ sd-utf8/sd-utf8.c
+'''.split()) + sd_login_c
+
+libsystemd_internal = static_library(
+ 'systemd',
+ libsystemd_internal_sources,
+ install : false,
+ include_directories : includes,
+ link_with : libbasic,
+ dependencies : [threads,
+ librt])
+
+libsystemd_sym = 'src/libsystemd/libsystemd.sym'
+
+libsystemd_pc = configure_file(
+ input : 'libsystemd.pc.in',
+ output : 'libsystemd.pc',
+ configuration : substs)
+install_data(libsystemd_pc,
+ install_dir : pkgconfiglibdir)
diff --git a/src/libsystemd/sd-bus/DIFFERENCES b/src/libsystemd/sd-bus/DIFFERENCES
deleted file mode 100644
index db269675a7..0000000000
--- a/src/libsystemd/sd-bus/DIFFERENCES
+++ /dev/null
@@ -1,25 +0,0 @@
-Known differences between dbus1 and kdbus:
-
-- NameAcquired/NameLost is gone entirely on kdbus backends if
- libsystemd is used. It is still added in by systemd-bus-proxyd
- for old dbus1 clients, and it is available if libsystemd is used
- against the classic dbus1 daemon. If you want to write compatible
- code with libsystem-bus you need to explicitly subscribe to
- NameOwnerChanged signals and just ignore NameAcquired/NameLost
-
-- Applications have to deal with spurious signals they didn't expect,
- due to the probabilistic bloom filters. They need to handle this
- anyway, given that any client can send anything to arbitrary clients
- anyway, even in dbus1, so not much changes.
-
-- clients of the system bus when kdbus is used must roll their own
- security. Only legacy dbus1 clients get the old XML policy enforced,
- which is implemented by systemd-bus-proxyd.
-
-- Serial numbers of synthesized messages are always (uint32_t) -1.
-
-- NameOwnerChanged is a synthetic message, generated locally and not
- by the driver. On dbus1 only the Disconnected message was
- synthesized like this.
-
-- There's no standard per-session bus anymore. Only a per-user bus.
diff --git a/src/libsystemd/sd-bus/GVARIANT-SERIALIZATION b/src/libsystemd/sd-bus/GVARIANT-SERIALIZATION
index 6aeb11364a..3110d57913 100644
--- a/src/libsystemd/sd-bus/GVARIANT-SERIALIZATION
+++ b/src/libsystemd/sd-bus/GVARIANT-SERIALIZATION
@@ -73,10 +73,9 @@ the reply_cookie/reply_serial additional header field has been
increased from 32bit to 64bit, too!
The header field identifiers have been extended from 8bit to
-64bit. This has been done to simplify things (as kdbus otherwise uses
-exclusively 64bit types, unless there is a strong reason not to), and
-has no effect on the serialization size, as due to alignment for each
-8bit header field identifier 56 bits of padding had to be added.
+64bit. This has been done to simplify things, and has no effect
+on the serialization size, as due to alignment for each 8bit
+header field identifier 56 bits of padding had to be added.
Note that the header size changed, due to these changes. However,
consider that on dbus1 the beginning of the fields array contains the
@@ -94,16 +93,12 @@ array, the size of the header on dbus1 and dbus2 stays identical, at
And that's already it.
-Note: to simplify parsing, valid kdbus/dbus2 messages must include the
-entire fixed header and additional header fields in a single non-memfd
-message part. Also, the signature string of the body variant all the
-way to the end of the message must be in a single non-memfd part
-too. The parts for this extended header and footer can be the same
-one, and can also continue any amount of additional body bytes.
-
-Note: on kdbus only native endian messages marshalled in gvariant may
- be sent. If a client receives a message in non-native endianness
- or in dbus1 marshalling it shall ignore the message.
+Note: To simplify parsing, valid dbus2 messages must include the entire
+ fixed header and additional header fields in a single non-memfd
+ message part. Also, the signature string of the body variant all the
+ way to the end of the message must be in a single non-memfd part
+ too. The parts for this extended header and footer can be the same
+ one, and can also continue any amount of additional body bytes.
Note: The GVariant "MAYBE" type is not supported, so that messages can
be fully converted forth and back between dbus1 and gvariant
diff --git a/src/libsystemd/sd-bus/PORTING-DBUS1 b/src/libsystemd/sd-bus/PORTING-DBUS1
deleted file mode 100644
index 2dedb28bcf..0000000000
--- a/src/libsystemd/sd-bus/PORTING-DBUS1
+++ /dev/null
@@ -1,535 +0,0 @@
-A few hints on supporting kdbus as backend in your favorite D-Bus library.
-
-~~~
-
-Before you read this, have a look at the DIFFERENCES and
-GVARIANT_SERIALIZATION texts you find in the same directory where you
-found this.
-
-We invite you to port your favorite D-Bus protocol implementation
-over to kdbus. However, there are a couple of complexities
-involved. On kdbus we only speak GVariant marshaling, kdbus clients
-ignore traffic in dbus1 marshaling. Thus, you need to add a second,
-GVariant compatible marshaler to your library first.
-
-After you have done that: here's the basic principle how kdbus works:
-
-You connect to a bus by opening its bus node in /sys/fs/kdbus/. All
-buses have a device node there, it starts with a numeric UID of the
-owner of the bus, followed by a dash and a string identifying the
-bus. The system bus is thus called /sys/fs/kdbus/0-system, and for user
-buses the device node is /sys/fs/kdbus/1000-user (if 1000 is your user
-id).
-
-(Before we proceed, please always keep a copy of libsystemd next
-to you, ultimately that's where the details are, this document simply
-is a rough overview to help you grok things.)
-
-CONNECTING
-
-To connect to a bus, simply open() its device node and issue the
-KDBUS_CMD_HELLO call. That's it. Now you are connected. Do not send
-Hello messages or so (as you would on dbus1), that does not exist for
-kdbus.
-
-The structure you pass to the ioctl will contain a couple of
-parameters that you need to know, to operate on the bus.
-
-There are two flags fields, one indicating features of the kdbus
-kernel side ("conn_flags"), the other one ("bus_flags") indicating
-features of the bus owner (i.e. systemd). Both flags fields are 64bit
-in width.
-
-When calling into the ioctl, you need to place your own supported
-feature bits into these fields. This tells the kernel about the
-features you support. When the ioctl returns, it will contain the
-features the kernel supports.
-
-If any of the higher 32bit are set on the two flags fields and your
-client does not know what they mean, it must disconnect. The upper
-32bit are used to indicate "incompatible" feature additions on the bus
-system, the lower 32bit indicate "compatible" feature additions. A
-client that does not support a "compatible" feature addition can go on
-communicating with the bus, however a client that does not support an
-"incompatible" feature must not proceed with the connection. When a
-client encountes such an "incompatible" feature it should immediately
-try the next bus address configured in the bus address string.
-
-The hello structure also contains another flags field "attach_flags"
-which indicates metadata that is optionally attached to all incoming
-messages. You probably want to set KDBUS_ATTACH_NAMES unconditionally
-in it. This has the effect that all well-known names of a sender are
-attached to all incoming messages. You need this information to
-implement matches that match on a message sender name correctly. Of
-course, you should only request the attachment of as little metadata
-fields as you need.
-
-The kernel will return in the "id" field your unique id. This is a
-simple numeric value. For compatibility with classic dbus1 simply
-format this as string and prefix ":1.".
-
-The kernel will also return the bloom filter size and bloom filter
-hash function number used for the signal broadcast bloom filter (see
-below).
-
-The kernel will also return the bus ID of the bus in a 128bit field.
-
-The pool size field specifies the size of the memory mapped buffer.
-After the calling the hello ioctl, you should memory map the kdbus
-fd. In this memory mapped region, the kernel will place all your incoming
-messages.
-
-SENDING MESSAGES
-
-Use the MSG_SEND ioctl to send a message to another peer. The ioctl
-takes a structure that contains a variety of fields:
-
-The flags field corresponds closely to the old dbus1 message header
-flags field, though the DONT_EXPECT_REPLY field got inverted into
-EXPECT_REPLY.
-
-The dst_id/src_id field contains the unique id of the destination and
-the sender. The sender field is overridden by the kernel usually, hence
-you shouldn't fill it in. The destination field can also take the
-special value KDBUS_DST_ID_BROADCAST for broadcast messages. For
-messages intended to a well-known name set the field to
-KDBUS_DST_ID_NAME, and attach the name in a special "items" entry to
-the message (see below).
-
-The payload field indicates the payload. For all dbus traffic it
-should carry the value 0x4442757344427573ULL. (Which encodes
-'DBusDBus').
-
-The cookie field corresponds with the "serial" field of classic
-dbus1. We simply renamed it here (and extended it to 64bit) since we
-didn't want to imply the monotonicity of the assignment the way the
-word "serial" indicates it.
-
-When sending a message that expects a reply, you need to set the
-EXPECT_REPLY flag in the message flag field. In this case you should
-also fill out the "timeout_ns" value which indicates the timeout in
-nsec for this call. If the peer does not respond in this time you will
-get a notification of a timeout. Note that this is also used for
-security purposes: a single reply messages is only allowed through the
-bus as long as the timeout has not ended. With this timeout value you
-hence "open a time window" in which the peer might respond to your
-request and the policy allows the response to go through.
-
-When sending a message that is a reply, you need to fill in the
-cookie_reply field, which is similar to the reply_serial field of
-dbus1. Note that a message cannot have EXPECT_REPLY and a reply_serial
-at the same time!
-
-This pretty much explains the ioctl header. The actual payload of the
-data is now referenced in additional items that are attached to this
-ioctl header structure at the end. When sending a message, you attach
-items of the type PAYLOAD_VEC, PAYLOAD_MEMFD, FDS, BLOOM_FILTER,
-DST_NAME to it:
-
- KDBUS_ITEM_PAYLOAD_VEC: contains a pointer + length pair for
- referencing arbitrary user memory. This is how you reference most
- of your data. It's a lot like the good old iovec structure of glibc.
-
- KDBUS_ITEM_PAYLOAD_MEMFD: for large data blocks it is preferable
- to send prepared "memfds" (see below) over. This item contains an
- fd for a memfd plus a size.
-
- KDBUS_ITEM_FDS: for sending over fds attach an item of this type with
- an array of fds.
-
- KDBUS_ITEM_BLOOM_FILTER: the calculated bloom filter of this message,
- only for undirected (broadcast) message.
-
- KDBUS_ITEM_DST_NAME: for messages that are directed to a well-known
- name (instead of a unique name), this item contains the well-known
- name field.
-
-A single message may consists of no, one or more payload items of type
-PAYLOAD_VEC or PAYLOAD_MEMFD. D-Bus protocol implementations should
-treat them as a single block that just happens to be split up into
-multiple items. Some restrictions apply however:
-
- The message header in its entirety must be contained in a single
- PAYLOAD_VEC item.
-
- You may only split your message up right in front of each GVariant
- contained in the payload, as well is immediately before framing of a
- Gvariant, as well after as any padding bytes if there are any. The
- padding bytes must be wholly contained in the preceding
- PAYLOAD_VEC/PAYLOAD_MEMFD item. You may not split up basic types
- nor arrays of fixed types. The latter is necessary to allow APIs
- to return direct pointers to linear arrays of numeric
- values. Examples: The basic types "u", "s", "t" have to be in the
- same payload item. The array of fixed types "ay", "ai" have to be
- fully in contained in the same payload item. For an array "as" or
- "a(si)" the only restriction however is to keep each string
- individually in an uninterrupted item, to keep the framing of each
- element and the array in a single uninterrupted item, however the
- various strings might end up in different items.
-
-Note again, that splitting up messages into separate items is up to the
-implementation. Also note that the kdbus kernel side might merge
-separate items if it deems this to be useful. However, the order in
-which items are contained in the message is left untouched.
-
-PAYLOAD_MEMFD items allow zero-copy data transfer (see below regarding
-the memfd concept). Note however that the overhead of mapping these
-makes them relatively expensive, and only worth the trouble for memory
-blocks > 512K (this value appears to be quite universal across
-architectures, as we tested). Thus we recommend sending PAYLOAD_VEC
-items over for small messages and restore to PAYLOAD_MEMFD items for
-messages > 512K. Since while building up the message you might not
-know yet whether it will grow beyond this boundary a good approach is
-to simply build the message unconditionally in a memfd
-object. However, when the message is sealed to be sent away check for
-the size limit. If the size of the message is < 512K, then simply send
-the data as PAYLOAD_VEC and reuse the memfd. If it is >= 512K, seal
-the memfd and send it as PAYLOAD_MEMFD, and allocate a new memfd for
-the next message.
-
-RECEIVING MESSAGES
-
-Use the MSG_RECV ioctl to read a message from kdbus. This will return
-an offset into the pool memory map, relative to its beginning.
-
-The received message structure more or less follows the structure of
-the message originally sent. However, certain changes have been
-made. In the header the src_id field will be filled in.
-
-The payload items might have gotten merged and PAYLOAD_VEC items are
-not used. Instead, you will only find PAYLOAD_OFF and PAYLOAD_MEMFD
-items. The former contain an offset and size into your memory mapped
-pool where you find the payload.
-
-If during the HELLO ioctl you asked for getting metadata attached to
-your message, you will find additional KDBUS_ITEM_CREDS,
-KDBUS_ITEM_PID_COMM, KDBUS_ITEM_TID_COMM, KDBUS_ITEM_TIMESTAMP,
-KDBUS_ITEM_EXE, KDBUS_ITEM_CMDLINE, KDBUS_ITEM_CGROUP,
-KDBUS_ITEM_CAPS, KDBUS_ITEM_SECLABEL, KDBUS_ITEM_AUDIT items that
-contain this metadata. This metadata will be gathered from the sender
-at the point in time it sends the message. This information is
-uncached, and since it is appended by the kernel, trustable. The
-KDBUS_ITEM_SECLABEL item usually contains the SELinux security label,
-if it is used.
-
-After processing the message you need to call the KDBUS_CMD_FREE
-ioctl, which releases the message from the pool, and allows the kernel
-to store another message there. Note that the memory used by the pool
-is ordinary anonymous, swappable memory that is backed by tmpfs. Hence
-there is no need to copy the message out of it quickly, instead you
-can just leave it there as long as you need it and release it via the
-FREE ioctl only after that's done.
-
-BLOOM FILTERS
-
-The kernel does not understand dbus marshaling, it will not look into
-the message payload. To allow clients to subscribe to specific subsets
-of the broadcast matches we employ bloom filters.
-
-When broadcasting messages, a bloom filter needs to be attached to the
-message in a KDBUS_ITEM_BLOOM item (and only for broadcasting
-messages!). If you don't know what bloom filters are, read up now on
-Wikipedia. In short: they are a very efficient way how to
-probabilistically check whether a certain word is contained in a
-vocabulary. It knows no false negatives, but it does know false
-positives.
-
-The parameters for the bloom filters that need to be included in
-broadcast message is communicated to userspace as part of the hello
-response structure (see above). By default it has the parameters m=512
-(bits in the filter), k=8 (nr of hash functions). Note however, that
-this is subject to change in later versions, and userspace
-implementations must be capable of handling m values between at least
-m=8 and m=2^32, and k values between at least k=1 and k=32. The
-underlying hash function is SipHash-2-4. It is used with a number of
-constant (yet originally randomly generated) 128bit hash keys, more
-specifically:
-
- b9,66,0b,f0,46,70,47,c1,88,75,c4,9c,54,b9,bd,15,
- aa,a1,54,a2,e0,71,4b,39,bf,e1,dd,2e,9f,c5,4a,3b,
- 63,fd,ae,be,cd,82,48,12,a1,6e,41,26,cb,fa,a0,c8,
- 23,be,45,29,32,d2,46,2d,82,03,52,28,fe,37,17,f5,
- 56,3b,bf,ee,5a,4f,43,39,af,aa,94,08,df,f0,fc,10,
- 31,80,c8,73,c7,ea,46,d3,aa,25,75,0f,9e,4c,09,29,
- 7d,f7,18,4b,7b,a4,44,d5,85,3c,06,e0,65,53,96,6d,
- f2,77,e9,6f,93,b5,4e,71,9a,0c,34,88,39,25,bf,35
-
-When calculating the first bit index into the bloom filter, the
-SipHash-2-4 hash value is calculated for the input data and the first
-16 bytes of the array above as hash key. Of the resulting 8 bytes of
-output, as many full bytes are taken for the bit index as necessary,
-starting from the output's first byte. For the second bit index the
-same hash value is used, continuing with the next unused output byte,
-and so on. Each time the bytes returned by the hash function are
-depleted it is recalculated with the next 16 byte hash key from the
-array above and the same input data.
-
-For each message to send across the bus we populate the bloom filter
-with all possible matchable strings. If a client then wants to
-subscribe to messages of this type, it simply tells the kernel to test
-its own calculated bit mask against the bloom filter of each message.
-
-More specifically, the following strings are added to the bloom filter
-of each message that is broadcasted:
-
- The string "interface:" suffixed by the interface name
-
- The string "member:" suffixed by the member name
-
- The string "path:" suffixed by the path name
-
- The string "path-slash-prefix:" suffixed with the path name, and
- also all prefixes of the path name (cut off at "/"), also prefixed
- with "path-slash-prefix".
-
- The string "message-type:" suffixed with the strings "signal",
- "method_call", "error" or "method_return" for the respective message
- type of the message.
-
- If the first argument of the message is a string, "arg0:" suffixed
- with the first argument.
-
- If the first argument of the message is a string, "arg0-dot-prefix"
- suffixed with the first argument, and also all prefixes of the
- argument (cut off at "."), also prefixed with "arg0-dot-prefix".
-
- If the first argument of the message is a string,
- "arg0-slash-prefix" suffixed with the first argument, and also all
- prefixes of the argument (cut off at "/"), also prefixed with
- "arg0-slash-prefix".
-
- Similar for all further arguments that are strings up to 63, for the
- arguments and their "dot" and "slash" prefixes. On the first
- argument that is not a string, addition to the bloom filter should be
- stopped however.
-
-(Note that the bloom filter does not contain sender nor receiver
-names!)
-
-When a client wants to subscribe to messages matching a certain
-expression, it should calculate the bloom mask following the same
-algorithm. The kernel will then simply test the mask against the
-attached bloom filters.
-
-Note that bloom filters are probabilistic, which means that clients
-might get messages they did not expect. Your bus protocol
-implementation must be capable of dealing with these unexpected
-messages (which it needs to anyway, given that transfers are
-relatively unrestricted on kdbus and people can send you all kinds of
-non-sense).
-
-If a client connects to a bus whose bloom filter metrics (i.e. filter
-size and number of hash functions) are outside of the range the client
-supports it must immediately disconnect and continue connection with
-the next bus address of the bus connection string.
-
-INSTALLING MATCHES
-
-To install matches for broadcast messages, use the KDBUS_CMD_ADD_MATCH
-ioctl. It takes a structure that contains an encoded match expression,
-and that is followed by one or more items, which are combined in an
-AND way. (Meaning: a message is matched exactly when all items
-attached to the original ioctl struct match).
-
-To match against other user messages add a KDBUS_ITEM_BLOOM item in
-the match (see above). Note that the bloom filter does not include
-matches to the sender names. To additionally check against sender
-names, use the KDBUS_ITEM_ID (for unique id matches) and
-KDBUS_ITEM_NAME (for well-known name matches) item types.
-
-To match against kernel generated messages (see below) you should add
-items of the same type as the kernel messages include,
-i.e. KDBUS_ITEM_NAME_ADD, KDBUS_ITEM_NAME_REMOVE,
-KDBUS_ITEM_NAME_CHANGE, KDBUS_ITEM_ID_ADD, KDBUS_ITEM_ID_REMOVE and
-fill them out. Note however, that you have some wildcards in this
-case, for example the .id field of KDBUS_ITEM_ID_ADD/KDBUS_ITEM_ID_REMOVE
-structures may be set to 0 to match against any id addition/removal.
-
-Note that dbus match strings do no map 1:1 to these ioctl() calls. In
-many cases (where the match string is "underspecified") you might need
-to issue up to six different ioctl() calls for the same match. For
-example, the empty match (which matches against all messages), would
-translate into one KDBUS_ITEM_BLOOM ioctl, one KDBUS_ITEM_NAME_ADD,
-one KDBUS_ITEM_NAME_CHANGE, one KDBUS_ITEM_NAME_REMOVE, one
-KDBUS_ITEM_ID_ADD and one KDBUS_ITEM_ID_REMOVE.
-
-When creating a match, you may attach a "cookie" value to them, which
-is used for deleting this match again. The cookie can be selected freely
-by the client. When issuing KDBUS_CMD_REMOVE_MATCH, simply pass the
-same cookie as before and all matches matching the same "cookie" value
-will be removed. This is particularly handy for the case where multiple
-ioctl()s are added for a single match strings.
-
-MEMFDS
-
-memfds may be sent across kdbus via KDBUS_ITEM_PAYLOAD_MEMFD items
-attached to messages. If this is done, the data included in the memfd
-is considered part of the payload stream of a message, and are treated
-the same way as KDBUS_ITEM_PAYLOAD_VEC by the receiving side. It is
-possible to interleave KDBUS_ITEM_PAYLOAD_MEMFD and
-KDBUS_ITEM_PAYLOAD_VEC items freely, by the reader they will be
-considered a single stream of bytes in the order these items appear in
-the message, that just happens to be split up at various places
-(regarding rules how they may be split up, see above). The kernel will
-refuse taking KDBUS_ITEM_PAYLOAD_MEMFD items that refer to memfds that
-are not sealed.
-
-Note that sealed memfds may be unsealed again if they are not mapped
-you have the only fd reference to them.
-
-Alternatively to sending memfds as KDBUS_ITEM_PAYLOAD_MEMFD items
-(where they are just a part of the payload stream of a message) you can
-also simply attach any memfd to a message using
-KDBUS_ITEM_PAYLOAD_FDS. In this case, the memfd contents is not
-considered part of the payload stream of the message, but simply fds
-like any other, that happen to be attached to the message.
-
-MESSAGES FROM THE KERNEL
-
-A couple of messages previously generated by the dbus1 bus driver are
-now generated by the kernel. Since the kernel does not understand the
-payload marshaling, they are generated by the kernel in a different
-format. This is indicated with the "payload type" field of the
-messages set to 0. Library implementations should take these messages
-and synthesize traditional driver messages for them on reception.
-
-More specifically:
-
- Instead of the NameOwnerChanged, NameLost, NameAcquired signals
- there are kernel messages containing KDBUS_ITEM_NAME_ADD,
- KDBUS_ITEM_NAME_REMOVE, KDBUS_ITEM_NAME_CHANGE, KDBUS_ITEM_ID_ADD,
- KDBUS_ITEM_ID_REMOVE items are generated (each message will contain
- exactly one of these items). Note that in libsystemd we have
- obsoleted NameLost/NameAcquired messages, since they are entirely
- redundant to NameOwnerChanged. This library will hence only
- synthesize NameOwnerChanged messages from these kernel messages,
- and never generate NameLost/NameAcquired. If your library needs to
- stay compatible to the old dbus1 userspace, you possibly might need
- to synthesize both a NameOwnerChanged and NameLost/NameAcquired
- message from the same kernel message.
-
- When a method call times out, a KDBUS_ITEM_REPLY_TIMEOUT message is
- generated. This should be synthesized into a method error reply
- message to the original call.
-
- When a method call fails because the peer terminated the connection
- before responding, a KDBUS_ITEM_REPLY_DEAD message is
- generated. Similarly, it should be synthesized into a method error
- reply message.
-
-For synthesized messages we recommend setting the cookie field to
-(uint32_t) -1 (and not (uint64_t) -1!), so that the cookie is not 0
-(which the dbus1 spec does not allow), but clearly recognizable as
-synthetic.
-
-Note that the KDBUS_ITEM_NAME_XYZ messages will actually inform you
-about all kinds of names, including activatable ones. Classic dbus1
-NameOwnerChanged messages OTOH are only generated when a name is
-really acquired on the bus and not just simply activatable. This means
-you must explicitly check for the case where an activatable name
-becomes acquired or an acquired name is lost and returns to be
-activatable.
-
-NAME REGISTRY
-
-To acquire names on the bus, use the KDBUS_CMD_NAME_ACQUIRE ioctl(). It
-takes a flags field similar to dbus1's RequestName() bus driver call,
-however the NO_QUEUE flag got inverted into a QUEUE flag instead.
-
-To release a previously acquired name use the KDBUS_CMD_NAME_RELEASE
-ioctl().
-
-To list acquired names use the KDBUS_CMD_CONN_INFO ioctl. It may be
-used to list unique names, well known names as well as activatable
-names and clients currently queuing for ownership of a well-known
-name. The ioctl will return an offset into the memory pool. After
-reading all the data you need, you need to release this via the
-KDBUS_CMD_FREE ioctl(), similar how you release a received message.
-
-CREDENTIALS
-
-kdbus can optionally attach various kinds of metadata about the sender at
-the point of time of sending ("credentials") to messages, on request
-of the receiver. This is both supported on directed and undirected
-(broadcast) messages. The metadata to attach is selected at time of
-the HELLO ioctl of the receiver via a flags field (see above). Note
-that clients must be able to handle that messages contain more
-metadata than they asked for themselves, to simplify implementation of
-broadcasting in the kernel. The receiver should not rely on this data
-to be around though, even though it will be correct if it happens to
-be attached. In order to avoid programming errors in applications, we
-recommend though not passing this data on to clients that did not
-explicitly ask for it.
-
-Credentials may also be queried for a well-known or unique name. Use
-the KDBUS_CMD_CONN_INFO for this. It will return an offset to the pool
-area again, which will contain the same credential items as messages
-have attached. Note that when issuing the ioctl, you can select a
-different set of credentials to gather, than what was originally requested
-for being attached to incoming messages.
-
-Credentials are always specific to the sender's domain that was
-current at the time of sending, and of the process that opened the
-bus connection at the time of opening it. Note that this latter data
-is cached!
-
-POLICY
-
-The kernel enforces only very limited policy on names. It will not do
-access filtering by userspace payload, and thus not by interface or
-method name.
-
-This ultimately means that most fine-grained policy enforcement needs
-to be done by the receiving process. We recommend using PolicyKit for
-any more complex checks. However, libraries should make simple static
-policy decisions regarding privileged/unprivileged method calls
-easy. We recommend doing this by enabling KDBUS_ATTACH_CAPS and
-KDBUS_ATTACH_CREDS for incoming messages, and then discerning client
-access by some capability, or if sender and receiver UIDs match.
-
-BUS ADDRESSES
-
-When connecting to kdbus use the "kernel:" protocol prefix in DBus
-address strings. The device node path is encoded in its "path="
-parameter.
-
-Client libraries should use the following connection string when
-connecting to the system bus:
-
- kernel:path=/sys/fs/kdbus/0-system/bus;unix:path=/var/run/dbus/system_bus_socket
-
-This will ensure that kdbus is preferred over the legacy AF_UNIX
-socket, but compatibility is kept. For the user bus use:
-
- kernel:path=/sys/fs/kdbus/$UID-user/bus;unix:path=$XDG_RUNTIME_DIR/bus
-
-With $UID replaced by the callers numer user ID, and $XDG_RUNTIME_DIR
-following the XDG basedir spec.
-
-Of course the $DBUS_SYSTEM_BUS_ADDRESS and $DBUS_SESSION_BUS_ADDRESS
-variables should still take precedence.
-
-DBUS SERVICE FILES
-
-Activatable services for kdbus may not use classic dbus1 service
-activation files. Instead, programs should drop in native systemd
-.service and .busname unit files, so that they are treated uniformly
-with other types of units and activation of the system.
-
-Note that this results in a major difference to classic dbus1:
-activatable bus names can be established at any time in the boot process.
-This is unlike dbus1 where activatable names are unconditionally available
-as long as dbus-daemon is running. Being able to control when
-activatable names are established is essential to allow usage of kdbus
-during early boot and in initrds, without the risk of triggering
-services too early.
-
-DISCLAIMER
-
-This all is so far just the status quo. We are putting this together, because
-we are quite confident that further API changes will be smaller, but
-to make this very clear: this is all subject to change, still!
-
-We invite you to port over your favorite dbus library to this new
-scheme, but please be prepared to make minor changes when we still
-change these interfaces!
diff --git a/src/libsystemd/sd-bus/bus-control.c b/src/libsystemd/sd-bus/bus-control.c
index 9e58ffbd88..b56bb07713 100644
--- a/src/libsystemd/sd-bus/bus-control.c
+++ b/src/libsystemd/sd-bus/bus-control.c
@@ -264,10 +264,13 @@ static int kernel_get_list(sd_bus *bus, uint64_t flags, char ***x) {
if ((flags & KDBUS_LIST_UNIQUE) && name->id != previous_id && !(name->flags & KDBUS_HELLO_ACTIVATOR)) {
char *n;
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat"
if (asprintf(&n, ":1.%llu", name->id) < 0) {
r = -ENOMEM;
goto fail;
}
+#pragma GCC diagnostic pop
r = strv_consume(x, n);
if (r < 0)
@@ -711,10 +714,13 @@ int bus_get_name_creds_kdbus(
}
if (mask & SD_BUS_CREDS_UNIQUE_NAME) {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat"
if (asprintf(&c->unique_name, ":1.%llu", conn_info->id) < 0) {
r = -ENOMEM;
goto fail;
}
+#pragma GCC diagnostic pop
c->mask |= SD_BUS_CREDS_UNIQUE_NAME;
}
@@ -780,6 +786,8 @@ static int bus_get_name_creds_dbus1(
}
if (mask != 0) {
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ bool need_pid, need_uid, need_selinux, need_separate_calls;
c = bus_creds_new();
if (!c)
return -ENOMEM;
@@ -792,99 +800,216 @@ static int bus_get_name_creds_dbus1(
c->mask |= SD_BUS_CREDS_UNIQUE_NAME;
}
- if ((mask & SD_BUS_CREDS_PID) ||
- ((mask & SD_BUS_CREDS_AUGMENT) &&
- (mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID|
- SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID|
- SD_BUS_CREDS_SUPPLEMENTARY_GIDS|
- SD_BUS_CREDS_COMM|SD_BUS_CREDS_EXE|SD_BUS_CREDS_CMDLINE|
- SD_BUS_CREDS_CGROUP|SD_BUS_CREDS_UNIT|SD_BUS_CREDS_USER_UNIT|SD_BUS_CREDS_SLICE|SD_BUS_CREDS_SESSION|SD_BUS_CREDS_OWNER_UID|
- SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS|
- SD_BUS_CREDS_SELINUX_CONTEXT|
- SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID)))) {
+ need_pid = (mask & SD_BUS_CREDS_PID) ||
+ ((mask & SD_BUS_CREDS_AUGMENT) &&
+ (mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID|
+ SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID|
+ SD_BUS_CREDS_SUPPLEMENTARY_GIDS|
+ SD_BUS_CREDS_COMM|SD_BUS_CREDS_EXE|SD_BUS_CREDS_CMDLINE|
+ SD_BUS_CREDS_CGROUP|SD_BUS_CREDS_UNIT|SD_BUS_CREDS_USER_UNIT|SD_BUS_CREDS_SLICE|SD_BUS_CREDS_SESSION|SD_BUS_CREDS_OWNER_UID|
+ SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS|
+ SD_BUS_CREDS_SELINUX_CONTEXT|
+ SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID)));
+ need_uid = mask & SD_BUS_CREDS_EUID;
+ need_selinux = mask & SD_BUS_CREDS_SELINUX_CONTEXT;
- uint32_t u;
+ if (need_pid + need_uid + need_selinux > 1) {
+
+ /* If we need more than one of the credentials, then use GetConnectionCredentials() */
r = sd_bus_call_method(
bus,
"org.freedesktop.DBus",
"/org/freedesktop/DBus",
"org.freedesktop.DBus",
- "GetConnectionUnixProcessID",
- NULL,
+ "GetConnectionCredentials",
+ &error,
&reply,
"s",
- unique ? unique : name);
- if (r < 0)
- return r;
+ unique ?: name);
- r = sd_bus_message_read(reply, "u", &u);
- if (r < 0)
- return r;
+ if (r < 0) {
- pid = u;
- if (mask & SD_BUS_CREDS_PID) {
- c->pid = u;
- c->mask |= SD_BUS_CREDS_PID;
- }
+ if (!sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_METHOD))
+ return r;
- reply = sd_bus_message_unref(reply);
- }
+ /* If we got an unknown method error, fall back to the invidual calls... */
+ need_separate_calls = true;
+ sd_bus_error_free(&error);
- if (mask & SD_BUS_CREDS_EUID) {
- uint32_t u;
+ } else {
+ need_separate_calls = false;
- r = sd_bus_call_method(
- bus,
- "org.freedesktop.DBus",
- "/org/freedesktop/DBus",
- "org.freedesktop.DBus",
- "GetConnectionUnixUser",
- NULL,
- &reply,
- "s",
- unique ? unique : name);
- if (r < 0)
- return r;
+ r = sd_bus_message_enter_container(reply, 'a', "{sv}");
+ if (r < 0)
+ return r;
- r = sd_bus_message_read(reply, "u", &u);
- if (r < 0)
- return r;
+ for (;;) {
+ const char *m;
- c->euid = u;
- c->mask |= SD_BUS_CREDS_EUID;
+ r = sd_bus_message_enter_container(reply, 'e', "sv");
+ if (r < 0)
+ return r;
+ if (r == 0)
+ break;
- reply = sd_bus_message_unref(reply);
- }
+ r = sd_bus_message_read(reply, "s", &m);
+ if (r < 0)
+ return r;
- if (mask & SD_BUS_CREDS_SELINUX_CONTEXT) {
- _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
- const void *p = NULL;
- size_t sz = 0;
+ if (need_uid && streq(m, "UnixUserID")) {
+ uint32_t u;
- r = sd_bus_call_method(
- bus,
- "org.freedesktop.DBus",
- "/org/freedesktop/DBus",
- "org.freedesktop.DBus",
- "GetConnectionSELinuxSecurityContext",
- &error,
- &reply,
- "s",
- unique ? unique : name);
- if (r < 0) {
- if (!sd_bus_error_has_name(&error, "org.freedesktop.DBus.Error.SELinuxSecurityContextUnknown"))
+ r = sd_bus_message_read(reply, "v", "u", &u);
+ if (r < 0)
+ return r;
+
+ c->euid = u;
+ c->mask |= SD_BUS_CREDS_EUID;
+
+ } else if (need_pid && streq(m, "ProcessID")) {
+ uint32_t p;
+
+ r = sd_bus_message_read(reply, "v", "u", &p);
+ if (r < 0)
+ return r;
+
+ pid = p;
+ if (mask & SD_BUS_CREDS_PID) {
+ c->pid = p;
+ c->mask |= SD_BUS_CREDS_PID;
+ }
+
+ } else if (need_selinux && streq(m, "LinuxSecurityLabel")) {
+ const void *p = NULL;
+ size_t sz = 0;
+
+ r = sd_bus_message_enter_container(reply, 'v', "ay");
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_read_array(reply, 'y', &p, &sz);
+ if (r < 0)
+ return r;
+
+ free(c->label);
+ c->label = strndup(p, sz);
+ if (!c->label)
+ return -ENOMEM;
+
+ c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
+
+ r = sd_bus_message_exit_container(reply);
+ if (r < 0)
+ return r;
+ } else {
+ r = sd_bus_message_skip(reply, "v");
+ if (r < 0)
+ return r;
+ }
+
+ r = sd_bus_message_exit_container(reply);
+ if (r < 0)
+ return r;
+ }
+
+ r = sd_bus_message_exit_container(reply);
+ if (r < 0)
return r;
- } else {
- r = sd_bus_message_read_array(reply, 'y', &p, &sz);
+
+ if (need_pid && pid == 0)
+ return -EPROTO;
+ }
+
+ } else /* When we only need a single field, then let's use separate calls */
+ need_separate_calls = true;
+
+ if (need_separate_calls) {
+ if (need_pid) {
+ uint32_t u;
+
+ r = sd_bus_call_method(
+ bus,
+ "org.freedesktop.DBus",
+ "/org/freedesktop/DBus",
+ "org.freedesktop.DBus",
+ "GetConnectionUnixProcessID",
+ NULL,
+ &reply,
+ "s",
+ unique ?: name);
if (r < 0)
return r;
- c->label = strndup(p, sz);
- if (!c->label)
- return -ENOMEM;
+ r = sd_bus_message_read(reply, "u", &u);
+ if (r < 0)
+ return r;
- c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
+ pid = u;
+ if (mask & SD_BUS_CREDS_PID) {
+ c->pid = u;
+ c->mask |= SD_BUS_CREDS_PID;
+ }
+
+ reply = sd_bus_message_unref(reply);
+ }
+
+ if (need_uid) {
+ uint32_t u;
+
+ r = sd_bus_call_method(
+ bus,
+ "org.freedesktop.DBus",
+ "/org/freedesktop/DBus",
+ "org.freedesktop.DBus",
+ "GetConnectionUnixUser",
+ NULL,
+ &reply,
+ "s",
+ unique ? unique : name);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_read(reply, "u", &u);
+ if (r < 0)
+ return r;
+
+ c->euid = u;
+ c->mask |= SD_BUS_CREDS_EUID;
+
+ reply = sd_bus_message_unref(reply);
+ }
+
+ if (need_selinux) {
+ const void *p = NULL;
+ size_t sz = 0;
+
+ r = sd_bus_call_method(
+ bus,
+ "org.freedesktop.DBus",
+ "/org/freedesktop/DBus",
+ "org.freedesktop.DBus",
+ "GetConnectionSELinuxSecurityContext",
+ &error,
+ &reply,
+ "s",
+ unique ? unique : name);
+ if (r < 0) {
+ if (!sd_bus_error_has_name(&error, "org.freedesktop.DBus.Error.SELinuxSecurityContextUnknown"))
+ return r;
+
+ /* no data is fine */
+ } else {
+ r = sd_bus_message_read_array(reply, 'y', &p, &sz);
+ if (r < 0)
+ return r;
+
+ c->label = strndup(p, sz);
+ if (!c->label)
+ return -ENOMEM;
+
+ c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
+ }
}
}
@@ -917,9 +1042,17 @@ _public_ int sd_bus_get_name_creds(
if (!bus->bus_client)
return -EINVAL;
+ /* Turn off augmenting if this isn't a local connection. If the connection is not local, then /proc is not
+ * going to match. */
+ if (!bus->is_local)
+ mask &= ~SD_BUS_CREDS_AUGMENT;
+
if (streq(name, "org.freedesktop.DBus.Local"))
return -EINVAL;
+ if (streq(name, "org.freedesktop.DBus"))
+ return sd_bus_get_owner_creds(bus, mask, creds);
+
if (!BUS_IS_OPEN(bus->state))
return -ENOTCONN;
@@ -1040,6 +1173,9 @@ _public_ int sd_bus_get_owner_creds(sd_bus *bus, uint64_t mask, sd_bus_creds **r
if (!BUS_IS_OPEN(bus->state))
return -ENOTCONN;
+ if (!bus->is_local)
+ mask &= ~SD_BUS_CREDS_AUGMENT;
+
if (bus->is_kernel)
return bus_get_owner_creds_kdbus(bus, mask, ret);
else
diff --git a/src/libsystemd/sd-bus/bus-convenience.c b/src/libsystemd/sd-bus/bus-convenience.c
index 2d06bf541f..04158cae4d 100644
--- a/src/libsystemd/sd-bus/bus-convenience.c
+++ b/src/libsystemd/sd-bus/bus-convenience.c
@@ -48,7 +48,7 @@ _public_ int sd_bus_emit_signal(
va_list ap;
va_start(ap, types);
- r = bus_message_append_ap(m, types, ap);
+ r = sd_bus_message_appendv(m, types, ap);
va_end(ap);
if (r < 0)
return r;
@@ -85,7 +85,7 @@ _public_ int sd_bus_call_method_async(
va_list ap;
va_start(ap, types);
- r = bus_message_append_ap(m, types, ap);
+ r = sd_bus_message_appendv(m, types, ap);
va_end(ap);
if (r < 0)
return r;
@@ -123,7 +123,7 @@ _public_ int sd_bus_call_method(
va_list ap;
va_start(ap, types);
- r = bus_message_append_ap(m, types, ap);
+ r = sd_bus_message_appendv(m, types, ap);
va_end(ap);
if (r < 0)
goto fail;
@@ -162,7 +162,7 @@ _public_ int sd_bus_reply_method_return(
va_list ap;
va_start(ap, types);
- r = bus_message_append_ap(m, types, ap);
+ r = sd_bus_message_appendv(m, types, ap);
va_end(ap);
if (r < 0)
return r;
@@ -493,7 +493,7 @@ _public_ int sd_bus_set_property(
goto fail;
va_start(ap, type);
- r = bus_message_append_ap(m, type, ap);
+ r = sd_bus_message_appendv(m, type, ap);
va_end(ap);
if (r < 0)
goto fail;
diff --git a/src/libsystemd/sd-bus/bus-creds.c b/src/libsystemd/sd-bus/bus-creds.c
index 349fa57f2d..649fcdba44 100644
--- a/src/libsystemd/sd-bus/bus-creds.c
+++ b/src/libsystemd/sd-bus/bus-creds.c
@@ -165,7 +165,7 @@ _public_ int sd_bus_creds_new_from_pid(sd_bus_creds **ret, pid_t pid, uint64_t m
assert_return(ret, -EINVAL);
if (pid == 0)
- pid = getpid();
+ pid = getpid_cached();
c = bus_creds_new();
if (!c)
diff --git a/src/libsystemd/sd-bus/bus-internal.h b/src/libsystemd/sd-bus/bus-internal.h
index bb0414c4d6..3575ea8cde 100644
--- a/src/libsystemd/sd-bus/bus-internal.h
+++ b/src/libsystemd/sd-bus/bus-internal.h
@@ -212,6 +212,7 @@ struct sd_bus {
bool exit_on_disconnect:1;
bool exited:1;
bool exit_triggered:1;
+ bool is_local:1;
int use_memfd;
diff --git a/src/libsystemd/sd-bus/bus-kernel.c b/src/libsystemd/sd-bus/bus-kernel.c
index c82caeb3fc..ca6aee7c06 100644
--- a/src/libsystemd/sd-bus/bus-kernel.c
+++ b/src/libsystemd/sd-bus/bus-kernel.c
@@ -51,6 +51,8 @@
#include "user-util.h"
#include "util.h"
+#pragma GCC diagnostic ignored "-Wformat"
+
#define UNIQUE_NAME_MAX (3+DECIMAL_STR_MAX(uint64_t))
int bus_kernel_parse_unique_name(const char *s, uint64_t *id) {
diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c
index 5cec804e32..da6fd3b896 100644
--- a/src/libsystemd/sd-bus/bus-message.c
+++ b/src/libsystemd/sd-bus/bus-message.c
@@ -2341,7 +2341,7 @@ static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const cha
return 1;
}
-int bus_message_append_ap(
+_public_ int sd_bus_message_appendv(
sd_bus_message *m,
const char *types,
va_list ap) {
@@ -2351,10 +2351,10 @@ int bus_message_append_ap(
unsigned stack_ptr = 0;
int r;
- assert(m);
-
- if (!types)
- return 0;
+ assert_return(m, -EINVAL);
+ assert_return(types, -EINVAL);
+ assert_return(!m->sealed, -EPERM);
+ assert_return(!m->poisoned, -ESTALE);
n_array = (unsigned) -1;
n_struct = strlen(types);
@@ -2555,7 +2555,7 @@ _public_ int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
assert_return(!m->poisoned, -ESTALE);
va_start(ap, types);
- r = bus_message_append_ap(m, types, ap);
+ r = sd_bus_message_appendv(m, types, ap);
va_end(ap);
return r;
diff --git a/src/libsystemd/sd-bus/bus-message.h b/src/libsystemd/sd-bus/bus-message.h
index 4710c106b9..a59aa73833 100644
--- a/src/libsystemd/sd-bus/bus-message.h
+++ b/src/libsystemd/sd-bus/bus-message.h
@@ -220,8 +220,6 @@ int bus_message_from_malloc(
int bus_message_get_arg(sd_bus_message *m, unsigned i, const char **str);
int bus_message_get_arg_strv(sd_bus_message *m, unsigned i, char ***strv);
-int bus_message_append_ap(sd_bus_message *m, const char *types, va_list ap);
-
int bus_message_parse_fields(sd_bus_message *m);
struct bus_body_part *message_append_part(sd_bus_message *m);
diff --git a/src/libsystemd/sd-bus/bus-objects.c b/src/libsystemd/sd-bus/bus-objects.c
index 9bd07ffcab..98911d5203 100644
--- a/src/libsystemd/sd-bus/bus-objects.c
+++ b/src/libsystemd/sd-bus/bus-objects.c
@@ -974,8 +974,10 @@ static int process_introspect(
/* Nothing?, let's see if we exist at all, and if not
* refuse to do anything */
r = bus_node_exists(bus, n, m->path, require_fallback);
- if (r <= 0)
+ if (r <= 0) {
+ r = bus_maybe_reply_error(m, r, &error);
goto finish;
+ }
if (bus->nodes_modified) {
r = 0;
goto finish;
@@ -1057,6 +1059,22 @@ static int object_manager_serialize_path(
if (r < 0)
return r;
+ r = sd_bus_message_append(reply, "{sa{sv}}", "org.freedesktop.DBus.Peer", 0);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_append(reply, "{sa{sv}}", "org.freedesktop.DBus.Introspectable", 0);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_append(reply, "{sa{sv}}", "org.freedesktop.DBus.Properties", 0);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_append(reply, "{sa{sv}}", "org.freedesktop.DBus.ObjectManager", 0);
+ if (r < 0)
+ return r;
+
found_something = true;
}
@@ -1183,7 +1201,7 @@ static int process_get_managed_objects(
r = get_child_nodes(bus, m->path, n, CHILDREN_RECURSIVE, &s, &error);
if (r < 0)
- return r;
+ return bus_maybe_reply_error(m, r, &error);
if (bus->nodes_modified)
return 0;
@@ -1198,7 +1216,7 @@ static int process_get_managed_objects(
SET_FOREACH(path, s, i) {
r = object_manager_serialize_path_and_fallbacks(bus, reply, path, &error);
if (r < 0)
- return r;
+ return bus_maybe_reply_error(m, r, &error);
if (bus->nodes_modified)
return 0;
@@ -1328,7 +1346,7 @@ static int object_find_and_run(
if (!*found_object) {
r = bus_node_exists(bus, n, m->path, require_fallback);
if (r < 0)
- return r;
+ return bus_maybe_reply_error(m, r, NULL);
if (bus->nodes_modified)
return 0;
if (r > 0)
diff --git a/src/libsystemd/sd-bus/bus-socket.c b/src/libsystemd/sd-bus/bus-socket.c
index e6ed15eb71..8b25002f01 100644
--- a/src/libsystemd/sd-bus/bus-socket.c
+++ b/src/libsystemd/sd-bus/bus-socket.c
@@ -607,7 +607,7 @@ static void bus_get_peercred(sd_bus *b) {
b->ucred_valid = getpeercred(b->input_fd, &b->ucred) >= 0;
/* Get the SELinux context of the peer */
- if (mac_selinux_have()) {
+ if (mac_selinux_use()) {
r = getpeersec(b->input_fd, &b->label);
if (r < 0 && r != -EOPNOTSUPP)
log_debug_errno(r, "Failed to determine peer security context: %m");
diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c
index e809942278..7059578eb4 100644
--- a/src/libsystemd/sd-bus/sd-bus.c
+++ b/src/libsystemd/sd-bus/sd-bus.c
@@ -187,7 +187,7 @@ _public_ int sd_bus_new(sd_bus **ret) {
r->creds_mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES|SD_BUS_CREDS_UNIQUE_NAME;
r->hello_flags |= KDBUS_HELLO_ACCEPT_FD;
r->attach_flags |= KDBUS_ATTACH_NAMES;
- r->original_pid = getpid();
+ r->original_pid = getpid_cached();
assert_se(pthread_mutex_init(&r->memfd_cache_mutex, NULL) == 0);
@@ -588,6 +588,8 @@ static int parse_unix_address(sd_bus *b, const char **p, char **guid) {
b->sockaddr_size = offsetof(struct sockaddr_un, sun_path) + 1 + l;
}
+ b->is_local = true;
+
return 0;
}
@@ -655,6 +657,8 @@ static int parse_tcp_address(sd_bus *b, const char **p, char **guid) {
freeaddrinfo(result);
+ b->is_local = false;
+
return 0;
}
@@ -737,6 +741,9 @@ static int parse_exec_address(sd_bus *b, const char **p, char **guid) {
b->exec_path = path;
b->exec_argv = argv;
+
+ b->is_local = false;
+
return 0;
fail:
@@ -780,6 +787,8 @@ static int parse_kernel_address(sd_bus *b, const char **p, char **guid) {
b->kernel = path;
path = NULL;
+ b->is_local = true;
+
return 0;
}
@@ -838,6 +847,7 @@ static int parse_container_unix_address(sd_bus *b, const char **p, char **guid)
b->sockaddr.un.sun_family = AF_UNIX;
strncpy(b->sockaddr.un.sun_path, "/var/run/dbus/system_bus_socket", sizeof(b->sockaddr.un.sun_path));
b->sockaddr_size = SOCKADDR_UN_LEN(b->sockaddr.un);
+ b->is_local = false;
return 0;
}
@@ -898,6 +908,8 @@ static int parse_container_kernel_address(sd_bus *b, const char **p, char **guid
if (r < 0)
return r;
+ b->is_local = false;
+
return 0;
}
@@ -1179,6 +1191,7 @@ _public_ int sd_bus_open(sd_bus **ret) {
/* We don't know whether the bus is trusted or not, so better
* be safe, and authenticate everything */
b->trusted = false;
+ b->is_local = false;
b->attach_flags |= KDBUS_ATTACH_CAPS | KDBUS_ATTACH_CREDS;
b->creds_mask |= SD_BUS_CREDS_UID | SD_BUS_CREDS_EUID | SD_BUS_CREDS_EFFECTIVE_CAPS;
@@ -1227,6 +1240,7 @@ _public_ int sd_bus_open_system(sd_bus **ret) {
b->trusted = false;
b->attach_flags |= KDBUS_ATTACH_CAPS | KDBUS_ATTACH_CREDS;
b->creds_mask |= SD_BUS_CREDS_UID | SD_BUS_CREDS_EUID | SD_BUS_CREDS_EFFECTIVE_CAPS;
+ b->is_local = true;
r = sd_bus_start(b);
if (r < 0)
@@ -1293,6 +1307,7 @@ _public_ int sd_bus_open_user(sd_bus **ret) {
/* We don't do any per-method access control on the user
* bus. */
b->trusted = true;
+ b->is_local = true;
r = sd_bus_start(b);
if (r < 0)
@@ -1364,6 +1379,7 @@ _public_ int sd_bus_open_system_remote(sd_bus **ret, const char *host) {
bus->bus_client = true;
bus->trusted = false;
bus->is_system = true;
+ bus->is_local = false;
r = sd_bus_start(bus);
if (r < 0)
@@ -1413,6 +1429,7 @@ _public_ int sd_bus_open_system_machine(sd_bus **ret, const char *machine) {
bus->bus_client = true;
bus->trusted = false;
bus->is_system = true;
+ bus->is_local = false;
r = sd_bus_start(bus);
if (r < 0)
@@ -3114,7 +3131,7 @@ bool bus_pid_changed(sd_bus *bus) {
/* We don't support people creating a bus connection and
* keeping it around over a fork(). Let's complain. */
- return bus->original_pid != getpid();
+ return bus->original_pid != getpid_cached();
}
static int io_callback(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
diff --git a/src/libsystemd/sd-bus/test-bus-benchmark.c b/src/libsystemd/sd-bus/test-bus-benchmark.c
index 56ac2ab3dd..ef7abe4dd9 100644
--- a/src/libsystemd/sd-bus/test-bus-benchmark.c
+++ b/src/libsystemd/sd-bus/test-bus-benchmark.c
@@ -276,7 +276,7 @@ int main(int argc, char *argv[]) {
assert_se(arg_loop_usec > 0);
if (type == TYPE_KDBUS) {
- assert_se(asprintf(&name, "deine-mutter-%u", (unsigned) getpid()) >= 0);
+ assert_se(asprintf(&name, "deine-mutter-%u", (unsigned) getpid_cached()) >= 0);
bus_ref = bus_kernel_create_bus(name, false, &bus_name);
if (bus_ref == -ENOENT)
diff --git a/src/libsystemd/sd-bus/test-bus-kernel-bloom.c b/src/libsystemd/sd-bus/test-bus-kernel-bloom.c
index eb6179d7d2..03d6f27d55 100644
--- a/src/libsystemd/sd-bus/test-bus-kernel-bloom.c
+++ b/src/libsystemd/sd-bus/test-bus-kernel-bloom.c
@@ -49,7 +49,7 @@ static void test_one(
sd_bus *a, *b;
int r, found = 0;
- assert_se(asprintf(&name, "deine-mutter-%u", (unsigned) getpid()) >= 0);
+ assert_se(asprintf(&name, "deine-mutter-%u", (unsigned) getpid_cached()) >= 0);
bus_ref = bus_kernel_create_bus(name, false, &bus_name);
if (bus_ref == -ENOENT)
diff --git a/src/libsystemd/sd-bus/test-bus-kernel.c b/src/libsystemd/sd-bus/test-bus-kernel.c
index 2214817312..2fc22883e0 100644
--- a/src/libsystemd/sd-bus/test-bus-kernel.c
+++ b/src/libsystemd/sd-bus/test-bus-kernel.c
@@ -41,7 +41,7 @@ int main(int argc, char *argv[]) {
log_set_max_level(LOG_DEBUG);
- assert_se(asprintf(&name, "deine-mutter-%u", (unsigned) getpid()) >= 0);
+ assert_se(asprintf(&name, "deine-mutter-%u", (unsigned) getpid_cached()) >= 0);
bus_ref = bus_kernel_create_bus(name, false, &bus_name);
if (bus_ref == -ENOENT)
diff --git a/src/libsystemd/sd-bus/test-bus-track.c b/src/libsystemd/sd-bus/test-bus-track.c
index 4beb61f05a..06c6167511 100644
--- a/src/libsystemd/sd-bus/test-bus-track.c
+++ b/src/libsystemd/sd-bus/test-bus-track.c
@@ -17,7 +17,7 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <sd-bus.h>
+#include "sd-bus.h"
#include "macro.h"
diff --git a/src/libsystemd/sd-bus/test-bus-vtable-cc.cc b/src/libsystemd/sd-bus/test-bus-vtable-cc.cc
new file mode 120000
index 0000000000..abee398630
--- /dev/null
+++ b/src/libsystemd/sd-bus/test-bus-vtable-cc.cc
@@ -0,0 +1 @@
+test-bus-vtable.c \ No newline at end of file
diff --git a/src/libsystemd/sd-bus/test-bus-vtable.c b/src/libsystemd/sd-bus/test-bus-vtable.c
new file mode 100644
index 0000000000..fd9ad81217
--- /dev/null
+++ b/src/libsystemd/sd-bus/test-bus-vtable.c
@@ -0,0 +1,81 @@
+#include <stdbool.h>
+#include <stddef.h>
+
+/* We use system assert.h here, because we don't want to keep macro.h and log.h C++ compatible */
+#undef NDEBUG
+#include <assert.h>
+#include <errno.h>
+
+#include "sd-bus-vtable.h"
+
+#define DEFAULT_BUS_PATH "unix:path=/run/dbus/system_bus_socket"
+
+struct context {
+ bool quit;
+ char *something;
+ char *automatic_string_property;
+ uint32_t automatic_integer_property;
+};
+
+static int handler(sd_bus_message *m, void *userdata, sd_bus_error *error) {
+ return 1;
+}
+
+static int value_handler(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error) {
+ return 1;
+}
+
+static int get_handler(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error) {
+ return 1;
+}
+
+static int set_handler(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *value, void *userdata, sd_bus_error *error) {
+ return 1;
+}
+
+static const sd_bus_vtable vtable[] = {
+ SD_BUS_VTABLE_START(0),
+ SD_BUS_METHOD("AlterSomething", "s", "s", handler, 0),
+ SD_BUS_METHOD("Exit", "", "", handler, 0),
+ SD_BUS_METHOD_WITH_OFFSET("AlterSomething2", "s", "s", handler, 200, 0),
+ SD_BUS_METHOD_WITH_OFFSET("Exit2", "", "", handler, 200, 0),
+ SD_BUS_PROPERTY("Value", "s", value_handler, 10, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
+ SD_BUS_PROPERTY("Value2", "s", value_handler, 10, SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
+ SD_BUS_PROPERTY("Value3", "s", value_handler, 10, SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("Value4", "s", value_handler, 10, 0),
+ SD_BUS_PROPERTY("AnExplicitProperty", "s", NULL, offsetof(struct context, something),
+ SD_BUS_VTABLE_PROPERTY_EXPLICIT|SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
+ SD_BUS_WRITABLE_PROPERTY("Something", "s", get_handler, set_handler, 0, 0),
+ SD_BUS_WRITABLE_PROPERTY("AutomaticStringProperty", "s", NULL, NULL,
+ offsetof(struct context, automatic_string_property), 0),
+ SD_BUS_WRITABLE_PROPERTY("AutomaticIntegerProperty", "u", NULL, NULL,
+ offsetof(struct context, automatic_integer_property), 0),
+ SD_BUS_METHOD("NoOperation", NULL, NULL, NULL, 0),
+ SD_BUS_SIGNAL("DummySignal", "b", 0),
+ SD_BUS_SIGNAL("DummySignal2", "so", 0),
+ SD_BUS_VTABLE_END
+};
+
+static void test_vtable(void) {
+ sd_bus *bus = NULL;
+ struct context c = {};
+ int r;
+
+ assert(sd_bus_new(&bus) >= 0);
+
+ assert(sd_bus_add_object_vtable(bus, NULL, "/foo", "org.freedesktop.systemd.testVtable", vtable, &c) >= 0);
+ assert(sd_bus_add_object_vtable(bus, NULL, "/foo", "org.freedesktop.systemd.testVtable2", vtable, &c) >= 0);
+
+ assert(sd_bus_set_address(bus, DEFAULT_BUS_PATH) >= 0);
+ r = sd_bus_start(bus);
+ assert(r == 0 || /* success */
+ r == -ENOENT /* dbus is inactive */ );
+
+ sd_bus_unref(bus);
+}
+
+int main(int argc, char **argv) {
+ test_vtable();
+
+ return 0;
+}
diff --git a/src/libsystemd/sd-bus/test-bus-zero-copy.c b/src/libsystemd/sd-bus/test-bus-zero-copy.c
index 3380e8500a..e599427ce6 100644
--- a/src/libsystemd/sd-bus/test-bus-zero-copy.c
+++ b/src/libsystemd/sd-bus/test-bus-zero-copy.c
@@ -52,7 +52,7 @@ int main(int argc, char *argv[]) {
log_set_max_level(LOG_DEBUG);
- assert_se(asprintf(&name, "deine-mutter-%u", (unsigned) getpid()) >= 0);
+ assert_se(asprintf(&name, "deine-mutter-%u", (unsigned) getpid_cached()) >= 0);
bus_ref = bus_kernel_create_bus(name, false, &bus_name);
if (bus_ref == -ENOENT)
diff --git a/src/libsystemd/sd-daemon/sd-daemon.c b/src/libsystemd/sd-daemon/sd-daemon.c
index a9a32dd5a2..be1f01112e 100644
--- a/src/libsystemd/sd-daemon/sd-daemon.c
+++ b/src/libsystemd/sd-daemon/sd-daemon.c
@@ -70,7 +70,7 @@ _public_ int sd_listen_fds(int unset_environment) {
goto finish;
/* Is this for us? */
- if (getpid() != pid) {
+ if (getpid_cached() != pid) {
r = 0;
goto finish;
}
@@ -518,7 +518,7 @@ _public_ int sd_pid_notify_with_fds(pid_t pid, int unset_environment, const char
msghdr.msg_namelen = SOCKADDR_UN_LEN(sockaddr.un);
- have_pid = pid != 0 && pid != getpid();
+ have_pid = pid != 0 && pid != getpid_cached();
if (n_fds > 0 || have_pid) {
/* CMSG_SPACE(0) may return value different than zero, which results in miscalculated controllen. */
@@ -659,7 +659,7 @@ _public_ int sd_watchdog_enabled(int unset_environment, uint64_t *usec) {
goto finish;
/* Is this for us? */
- if (getpid() != pid) {
+ if (getpid_cached() != pid) {
r = 0;
goto finish;
}
diff --git a/src/libsystemd/sd-device/device-enumerator.c b/src/libsystemd/sd-device/device-enumerator.c
index 86f8935a14..ebb8b2d160 100644
--- a/src/libsystemd/sd-device/device-enumerator.c
+++ b/src/libsystemd/sd-device/device-enumerator.c
@@ -631,10 +631,8 @@ static int enumerator_scan_devices_tag(sd_device_enumerator *enumerator, const c
if (!dir) {
if (errno == ENOENT)
return 0;
- else {
- log_error("sd-device-enumerator: could not open tags directory %s: %m", path);
- return -errno;
- }
+ else
+ return log_error_errno(errno, "sd-device-enumerator: could not open tags directory %s: %m", path);
}
/* TODO: filter away subsystems? */
@@ -758,10 +756,8 @@ static int parent_crawl_children(sd_device_enumerator *enumerator, const char *p
int r = 0;
dir = opendir(path);
- if (!dir) {
- log_debug("sd-device-enumerate: could not open parent directory %s: %m", path);
- return -errno;
- }
+ if (!dir)
+ return log_debug_errno(errno, "sd-device-enumerate: could not open parent directory %s: %m", path);
FOREACH_DIRENT_ALL(dent, dir, return -errno) {
_cleanup_free_ char *child = NULL;
diff --git a/src/libsystemd/sd-device/device-private.c b/src/libsystemd/sd-device/device-private.c
index 9082d377f4..b4cd676c12 100644
--- a/src/libsystemd/sd-device/device-private.c
+++ b/src/libsystemd/sd-device/device-private.c
@@ -778,12 +778,12 @@ int device_rename(sd_device *device, const char *name) {
r = sd_device_get_property_value(device, "INTERFACE", &interface);
if (r >= 0) {
- r = device_add_property_internal(device, "INTERFACE", name);
+ /* like DEVPATH_OLD, INTERFACE_OLD is not saved to the db, but only stays around for the current event */
+ r = device_add_property_internal(device, "INTERFACE_OLD", interface);
if (r < 0)
return r;
- /* like DEVPATH_OLD, INTERFACE_OLD is not saved to the db, but only stays around for the current event */
- r = device_add_property_internal(device, "INTERFACE_OLD", interface);
+ r = device_add_property_internal(device, "INTERFACE", name);
if (r < 0)
return r;
} else if (r != -ENOENT)
diff --git a/src/libsystemd/sd-device/sd-device.c b/src/libsystemd/sd-device/sd-device.c
index 81d8d61ba9..ab36aa2e32 100644
--- a/src/libsystemd/sd-device/sd-device.c
+++ b/src/libsystemd/sd-device/sd-device.c
@@ -195,8 +195,7 @@ int device_set_syspath(sd_device *device, const char *_syspath, bool verify) {
/* this is not a valid device */
return -ENODEV;
- log_debug("sd-device: %s does not have an uevent file: %m", syspath);
- return -errno;
+ return log_debug_errno(errno, "sd-device: %s does not have an uevent file: %m", syspath);
}
} else {
/* everything else just needs to be a directory */
@@ -325,6 +324,10 @@ _public_ int sd_device_new_from_subsystem_sysname(sd_device **ret, const char *s
if (access(syspath, F_OK) >= 0)
return sd_device_new_from_syspath(ret, syspath);
+ syspath = strjoina("/sys/firmware/", subsystem, "/", sysname);
+ if (access(syspath, F_OK) >= 0)
+ return sd_device_new_from_syspath(ret, syspath);
+
return -ENODEV;
}
diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c
index b4686d0065..320a1ca5c0 100644
--- a/src/libsystemd/sd-event/sd-event.c
+++ b/src/libsystemd/sd-event/sd-event.c
@@ -436,7 +436,7 @@ _public_ int sd_event_new(sd_event** ret) {
e->watchdog_fd = e->epoll_fd = e->realtime.fd = e->boottime.fd = e->monotonic.fd = e->realtime_alarm.fd = e->boottime_alarm.fd = -1;
e->realtime.next = e->boottime.next = e->monotonic.next = e->realtime_alarm.next = e->boottime_alarm.next = USEC_INFINITY;
e->realtime.wakeup = e->boottime.wakeup = e->monotonic.wakeup = e->realtime_alarm.wakeup = e->boottime_alarm.wakeup = WAKEUP_CLOCK_DATA;
- e->original_pid = getpid();
+ e->original_pid = getpid_cached();
e->perturb = USEC_INFINITY;
r = prioq_ensure_allocated(&e->pending, pending_prioq_compare);
@@ -493,7 +493,7 @@ static bool event_pid_changed(sd_event *e) {
/* We don't support people creating an event loop and keeping
* it around over a fork(). Let's complain. */
- return e->original_pid != getpid();
+ return e->original_pid != getpid_cached();
}
static void source_io_unregister(sd_event_source *s) {
diff --git a/src/libsystemd/sd-event/test-event.c b/src/libsystemd/sd-event/test-event.c
index c0e5e06a18..1a581ae23e 100644
--- a/src/libsystemd/sd-event/test-event.c
+++ b/src/libsystemd/sd-event/test-event.c
@@ -17,6 +17,8 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include <sys/wait.h>
+
#include "sd-event.h"
#include "fd-util.h"
@@ -315,11 +317,11 @@ static void test_rtqueue(void) {
assert_se(sd_event_source_set_priority(v, -10) >= 0);
- assert(sigqueue(getpid(), SIGRTMIN+2, (union sigval) { .sival_int = 1 }) >= 0);
- assert(sigqueue(getpid(), SIGRTMIN+3, (union sigval) { .sival_int = 2 }) >= 0);
- assert(sigqueue(getpid(), SIGUSR2, (union sigval) { .sival_int = 3 }) >= 0);
- assert(sigqueue(getpid(), SIGRTMIN+3, (union sigval) { .sival_int = 4 }) >= 0);
- assert(sigqueue(getpid(), SIGUSR2, (union sigval) { .sival_int = 5 }) >= 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(n_rtqueue == 0);
assert_se(last_rtqueue_sigval == 0);
diff --git a/src/libsystemd/sd-id128/sd-id128.c b/src/libsystemd/sd-id128/sd-id128.c
index 0d673ba655..ea60a929b7 100644
--- a/src/libsystemd/sd-id128/sd-id128.c
+++ b/src/libsystemd/sd-id128/sd-id128.c
@@ -171,7 +171,7 @@ _public_ int sd_id128_randomize(sd_id128_t *ret) {
assert_return(ret, -EINVAL);
- r = dev_urandom(&t, sizeof(t));
+ r = acquire_random_bytes(&t, sizeof t, true);
if (r < 0)
return r;
diff --git a/src/libsystemd/sd-login/sd-login.c b/src/libsystemd/sd-login/sd-login.c
index cdbdc37856..5fb7fd99d5 100644
--- a/src/libsystemd/sd-login/sd-login.c
+++ b/src/libsystemd/sd-login/sd-login.c
@@ -56,59 +56,73 @@
*/
_public_ int sd_pid_get_session(pid_t pid, char **session) {
+ int r;
assert_return(pid >= 0, -EINVAL);
assert_return(session, -EINVAL);
- return cg_pid_get_session(pid, session);
+ r = cg_pid_get_session(pid, session);
+ return IN_SET(r, -ENXIO, -ENOMEDIUM) ? -ENODATA : r;
}
_public_ int sd_pid_get_unit(pid_t pid, char **unit) {
+ int r;
assert_return(pid >= 0, -EINVAL);
assert_return(unit, -EINVAL);
- return cg_pid_get_unit(pid, unit);
+ r = cg_pid_get_unit(pid, unit);
+ return IN_SET(r, -ENXIO, -ENOMEDIUM) ? -ENODATA : r;
}
_public_ int sd_pid_get_user_unit(pid_t pid, char **unit) {
+ int r;
assert_return(pid >= 0, -EINVAL);
assert_return(unit, -EINVAL);
- return cg_pid_get_user_unit(pid, unit);
+ r = cg_pid_get_user_unit(pid, unit);
+ return IN_SET(r, -ENXIO, -ENOMEDIUM) ? -ENODATA : r;
}
_public_ int sd_pid_get_machine_name(pid_t pid, char **name) {
+ int r;
assert_return(pid >= 0, -EINVAL);
assert_return(name, -EINVAL);
- return cg_pid_get_machine_name(pid, name);
+ r = cg_pid_get_machine_name(pid, name);
+ return IN_SET(r, -ENXIO, -ENOMEDIUM) ? -ENODATA : r;
}
_public_ int sd_pid_get_slice(pid_t pid, char **slice) {
+ int r;
assert_return(pid >= 0, -EINVAL);
assert_return(slice, -EINVAL);
- return cg_pid_get_slice(pid, slice);
+ r = cg_pid_get_slice(pid, slice);
+ return IN_SET(r, -ENXIO, -ENOMEDIUM) ? -ENODATA : r;
}
_public_ int sd_pid_get_user_slice(pid_t pid, char **slice) {
+ int r;
assert_return(pid >= 0, -EINVAL);
assert_return(slice, -EINVAL);
- return cg_pid_get_user_slice(pid, slice);
+ r = cg_pid_get_user_slice(pid, slice);
+ return IN_SET(r, -ENXIO, -ENOMEDIUM) ? -ENODATA : r;
}
_public_ int sd_pid_get_owner_uid(pid_t pid, uid_t *uid) {
+ int r;
assert_return(pid >= 0, -EINVAL);
assert_return(uid, -EINVAL);
- return cg_pid_get_owner_uid(pid, uid);
+ r = cg_pid_get_owner_uid(pid, uid);
+ return IN_SET(r, -ENXIO, -ENOMEDIUM) ? -ENODATA : r;
}
_public_ int sd_pid_get_cgroup(pid_t pid, char **cgroup) {
@@ -279,7 +293,7 @@ _public_ int sd_uid_get_state(uid_t uid, char**state) {
return -ENOMEM;
}
- if (r < 0) {
+ else if (r < 0) {
free(s);
return r;
}
@@ -723,7 +737,7 @@ _public_ int sd_seat_get_sessions(const char *seat, char ***sessions, uid_t **ui
r = parse_uid(k, b + i);
if (r < 0)
- continue;
+ return r;
i++;
}
@@ -784,11 +798,27 @@ _public_ int sd_seat_can_graphical(const char *seat) {
}
_public_ int sd_get_seats(char ***seats) {
- return get_files_in_directory("/run/systemd/seats/", seats);
+ int r;
+
+ r = get_files_in_directory("/run/systemd/seats/", seats);
+ if (r == -ENOENT) {
+ if (seats)
+ *seats = NULL;
+ return 0;
+ }
+ return r;
}
_public_ int sd_get_sessions(char ***sessions) {
- return get_files_in_directory("/run/systemd/sessions/", sessions);
+ int r;
+
+ r = get_files_in_directory("/run/systemd/sessions/", sessions);
+ if (r == -ENOENT) {
+ if (sessions)
+ *sessions = NULL;
+ return 0;
+ }
+ return r;
}
_public_ int sd_get_uids(uid_t **users) {
@@ -799,8 +829,14 @@ _public_ int sd_get_uids(uid_t **users) {
_cleanup_free_ uid_t *l = NULL;
d = opendir("/run/systemd/users/");
- if (!d)
+ if (!d) {
+ if (errno == ENOENT) {
+ if (users)
+ *users = NULL;
+ return 0;
+ }
return -errno;
+ }
FOREACH_DIRENT_ALL(de, d, return -errno) {
int k;
@@ -842,12 +878,16 @@ _public_ int sd_get_uids(uid_t **users) {
}
_public_ int sd_get_machine_names(char ***machines) {
- char **l = NULL, **a, **b;
+ _cleanup_strv_free_ char **l = NULL;
+ char **a, **b;
int r;
- assert_return(machines, -EINVAL);
-
r = get_files_in_directory("/run/systemd/machines/", &l);
+ if (r == -ENOENT) {
+ if (machines)
+ *machines = NULL;
+ return 0;
+ }
if (r < 0)
return r;
@@ -855,7 +895,7 @@ _public_ int sd_get_machine_names(char ***machines) {
r = 0;
/* Filter out the unit: symlinks */
- for (a = l, b = l; *a; a++) {
+ for (a = b = l; *a; a++) {
if (startswith(*a, "unit:") || !machine_name_is_valid(*a))
free(*a);
else {
@@ -868,7 +908,10 @@ _public_ int sd_get_machine_names(char ***machines) {
*b = NULL;
}
- *machines = l;
+ if (machines) {
+ *machines = l;
+ l = NULL;
+ }
return r;
}
diff --git a/src/libsystemd/sd-login/test-login.c b/src/libsystemd/sd-login/test-login.c
index 9de33d85db..b618b79b28 100644
--- a/src/libsystemd/sd-login/test-login.c
+++ b/src/libsystemd/sd-login/test-login.c
@@ -25,173 +25,199 @@
#include "alloc-util.h"
#include "fd-util.h"
#include "format-util.h"
+#include "log.h"
#include "string-util.h"
#include "strv.h"
#include "util.h"
+static char* format_uids(char **buf, uid_t* uids, int count) {
+ int pos = 0, k, inc;
+ size_t size = (DECIMAL_STR_MAX(uid_t) + 1) * count + 1;
+
+ assert_se(*buf = malloc(size));
+
+ for (k = 0; k < count; k++) {
+ sprintf(*buf + pos, "%s"UID_FMT"%n", k > 0 ? " " : "", uids[k], &inc);
+ pos += inc;
+ }
+
+ assert_se(pos < (ssize_t)size);
+ (*buf)[pos] = '\0';
+
+ return *buf;
+}
+
static void test_login(void) {
_cleanup_close_pair_ int pair[2] = { -1, -1 };
- _cleanup_free_ char *pp = NULL, *qq = NULL;
+ _cleanup_free_ char *pp = NULL, *qq = NULL,
+ *display_session = NULL, *cgroup = NULL,
+ *display = NULL, *remote_user = NULL, *remote_host = NULL,
+ *type = NULL, *class = NULL, *state = NULL, *state2 = NULL,
+ *seat = NULL, *session = NULL,
+ *unit = NULL, *user_unit = NULL, *slice = NULL;
int r, k;
uid_t u, u2;
- char *seat, *type, *class, *display, *remote_user, *remote_host, *display_session, *cgroup;
- char *session;
- char *state;
- char *session2;
- char *t;
- char **seats, **sessions, **machines;
- uid_t *uids;
- unsigned n;
- struct pollfd pollfd;
- sd_login_monitor *m = NULL;
+ char *t, **seats, **sessions;
- assert_se(sd_pid_get_session(0, &session) == 0);
- printf("session = %s\n", session);
-
- assert_se(sd_pid_get_owner_uid(0, &u2) == 0);
- printf("user = "UID_FMT"\n", u2);
+ r = sd_pid_get_unit(0, &unit);
+ assert_se(r >= 0 || r == -ENODATA);
+ log_info("sd_pid_get_unit(0, …) → \"%s\"", strna(unit));
- assert_se(sd_pid_get_cgroup(0, &cgroup) == 0);
- printf("cgroup = %s\n", cgroup);
- free(cgroup);
+ r = sd_pid_get_user_unit(0, &user_unit);
+ assert_se(r >= 0 || r == -ENODATA);
+ log_info("sd_pid_get_user_unit(0, …) → \"%s\"", strna(user_unit));
- display_session = NULL;
- r = sd_uid_get_display(u2, &display_session);
+ r = sd_pid_get_slice(0, &slice);
assert_se(r >= 0 || r == -ENODATA);
- printf("user's display session = %s\n", strna(display_session));
- free(display_session);
+ log_info("sd_pid_get_slice(0, …) → \"%s\"", strna(slice));
- assert_se(socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == 0);
- sd_peer_get_session(pair[0], &pp);
- sd_peer_get_session(pair[1], &qq);
- assert_se(streq_ptr(pp, qq));
+ r = sd_pid_get_session(0, &session);
+ if (r < 0) {
+ log_warning_errno(r, "sd_pid_get_session(0, …): %m");
+ if (r == -ENODATA)
+ log_info("Seems we are not running in a session, skipping some tests.");
+ } else {
+ log_info("sd_pid_get_session(0, …) → \"%s\"", session);
- r = sd_uid_get_sessions(u2, false, &sessions);
- assert_se(r >= 0);
- assert_se(r == (int) strv_length(sessions));
- assert_se(t = strv_join(sessions, ", "));
- strv_free(sessions);
- printf("sessions = %s\n", t);
- free(t);
+ assert_se(sd_pid_get_owner_uid(0, &u2) == 0);
+ log_info("sd_pid_get_owner_uid(0, …) → "UID_FMT, u2);
- assert_se(r == sd_uid_get_sessions(u2, false, NULL));
+ assert_se(sd_pid_get_cgroup(0, &cgroup) == 0);
+ log_info("sd_pid_get_cgroup(0, …) → \"%s\"", cgroup);
- r = sd_uid_get_seats(u2, false, &seats);
- assert_se(r >= 0);
- assert_se(r == (int) strv_length(seats));
- assert_se(t = strv_join(seats, ", "));
- strv_free(seats);
- printf("seats = %s\n", t);
- free(t);
+ r = sd_uid_get_display(u2, &display_session);
+ assert_se(r >= 0 || r == -ENODATA);
+ log_info("sd_uid_get_display("UID_FMT", …) → \"%s\"",
+ u2, strnull(display_session));
- assert_se(r == sd_uid_get_seats(u2, false, NULL));
+ assert_se(socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == 0);
+ sd_peer_get_session(pair[0], &pp);
+ sd_peer_get_session(pair[1], &qq);
+ assert_se(streq_ptr(pp, qq));
- r = sd_session_is_active(session);
- assert_se(r >= 0);
- printf("active = %s\n", yes_no(r));
+ r = sd_uid_get_sessions(u2, false, &sessions);
+ assert_se(r >= 0);
+ assert_se(r == (int) strv_length(sessions));
+ assert_se(t = strv_join(sessions, " "));
+ strv_free(sessions);
+ log_info("sd_uid_get_sessions("UID_FMT", …) → [%i] \"%s\"", u2, r, t);
+ free(t);
- r = sd_session_is_remote(session);
- assert_se(r >= 0);
- printf("remote = %s\n", yes_no(r));
+ assert_se(r == sd_uid_get_sessions(u2, false, NULL));
- r = sd_session_get_state(session, &state);
- assert_se(r >= 0);
- printf("state = %s\n", state);
- free(state);
+ r = sd_uid_get_seats(u2, false, &seats);
+ assert_se(r >= 0);
+ assert_se(r == (int) strv_length(seats));
+ assert_se(t = strv_join(seats, " "));
+ strv_free(seats);
+ log_info("sd_uid_get_seats("UID_FMT", …) → [%i] \"%s\"", u2, r, t);
+ free(t);
- assert_se(sd_session_get_uid(session, &u) >= 0);
- printf("uid = "UID_FMT"\n", u);
- assert_se(u == u2);
+ assert_se(r == sd_uid_get_seats(u2, false, NULL));
+ }
- assert_se(sd_session_get_type(session, &type) >= 0);
- printf("type = %s\n", type);
- free(type);
+ if (session) {
+ r = sd_session_is_active(session);
+ assert_se(r >= 0);
+ log_info("sd_session_is_active(\"%s\") → %s", session, yes_no(r));
- assert_se(sd_session_get_class(session, &class) >= 0);
- printf("class = %s\n", class);
- free(class);
+ r = sd_session_is_remote(session);
+ assert_se(r >= 0);
+ log_info("sd_session_is_remote(\"%s\") → %s", session, yes_no(r));
- display = NULL;
- r = sd_session_get_display(session, &display);
- assert_se(r >= 0 || r == -ENODATA);
- printf("display = %s\n", strna(display));
- free(display);
+ r = sd_session_get_state(session, &state);
+ assert_se(r >= 0);
+ log_info("sd_session_get_state(\"%s\") → \"%s\"", session, state);
- remote_user = NULL;
- r = sd_session_get_remote_user(session, &remote_user);
- assert_se(r >= 0 || r == -ENODATA);
- printf("remote_user = %s\n", strna(remote_user));
- free(remote_user);
+ assert_se(sd_session_get_uid(session, &u) >= 0);
+ log_info("sd_session_get_uid(\"%s\") → "UID_FMT, session, u);
+ assert_se(u == u2);
- remote_host = NULL;
- r = sd_session_get_remote_host(session, &remote_host);
- assert_se(r >= 0 || r == -ENODATA);
- printf("remote_host = %s\n", strna(remote_host));
- free(remote_host);
+ assert_se(sd_session_get_type(session, &type) >= 0);
+ log_info("sd_session_get_type(\"%s\") → \"%s\"", session, type);
- assert_se(sd_session_get_seat(session, &seat) >= 0);
- printf("seat = %s\n", seat);
+ assert_se(sd_session_get_class(session, &class) >= 0);
+ log_info("sd_session_get_class(\"%s\") → \"%s\"", session, class);
- r = sd_seat_can_multi_session(seat);
- assert_se(r >= 0);
- printf("can do multi session = %s\n", yes_no(r));
+ r = sd_session_get_display(session, &display);
+ assert_se(r >= 0 || r == -ENODATA);
+ log_info("sd_session_get_display(\"%s\") → \"%s\"", session, strna(display));
- r = sd_seat_can_tty(seat);
- assert_se(r >= 0);
- printf("can do tty = %s\n", yes_no(r));
+ r = sd_session_get_remote_user(session, &remote_user);
+ assert_se(r >= 0 || r == -ENODATA);
+ log_info("sd_session_get_remote_user(\"%s\") → \"%s\"",
+ session, strna(remote_user));
- r = sd_seat_can_graphical(seat);
- assert_se(r >= 0);
- printf("can do graphical = %s\n", yes_no(r));
+ r = sd_session_get_remote_host(session, &remote_host);
+ assert_se(r >= 0 || r == -ENODATA);
+ log_info("sd_session_get_remote_host(\"%s\") → \"%s\"",
+ session, strna(remote_host));
- assert_se(sd_uid_get_state(u, &state) >= 0);
- printf("state = %s\n", state);
+ r = sd_session_get_seat(session, &seat);
+ if (r >= 0) {
+ assert_se(seat);
- assert_se(sd_uid_is_on_seat(u, 0, seat) > 0);
+ log_info("sd_session_get_display(\"%s\") → \"%s\"", session, seat);
- k = sd_uid_is_on_seat(u, 1, seat);
- assert_se(k >= 0);
- assert_se(!!r == !!r);
+ r = sd_seat_can_multi_session(seat);
+ assert_se(r >= 0);
+ log_info("sd_session_can_multi_seat(\"%s\") → %s", seat, yes_no(r));
- assert_se(sd_seat_get_active(seat, &session2, &u2) >= 0);
- printf("session2 = %s\n", session2);
- printf("uid2 = "UID_FMT"\n", u2);
+ r = sd_seat_can_tty(seat);
+ assert_se(r >= 0);
+ log_info("sd_session_can_tty(\"%s\") → %s", seat, yes_no(r));
- r = sd_seat_get_sessions(seat, &sessions, &uids, &n);
- assert_se(r >= 0);
- printf("n_sessions = %i\n", r);
- assert_se(r == (int) strv_length(sessions));
- assert_se(t = strv_join(sessions, ", "));
- strv_free(sessions);
- printf("sessions = %s\n", t);
- free(t);
- printf("uids =");
- for (k = 0; k < (int) n; k++)
- printf(" "UID_FMT, uids[k]);
- printf("\n");
- free(uids);
+ r = sd_seat_can_graphical(seat);
+ assert_se(r >= 0);
+ log_info("sd_session_can_graphical(\"%s\") → %s", seat, yes_no(r));
+ } else {
+ log_info_errno(r, "sd_session_get_display(\"%s\"): %m", session);
+ assert_se(r == -ENODATA);
+ }
- assert_se(sd_seat_get_sessions(seat, NULL, NULL, NULL) == r);
+ assert_se(sd_uid_get_state(u, &state2) >= 0);
+ log_info("sd_uid_get_state("UID_FMT", …) → %s", u, state2);
+ }
+
+ if (seat) {
+ _cleanup_free_ char *session2 = NULL, *buf = NULL;
+ _cleanup_free_ uid_t *uids = NULL;
+ unsigned n;
+
+ assert_se(sd_uid_is_on_seat(u, 0, seat) > 0);
+
+ k = sd_uid_is_on_seat(u, 1, seat);
+ assert_se(k >= 0);
+ assert_se(!!k == !!r);
- free(session);
- free(state);
- free(session2);
- free(seat);
+ assert_se(sd_seat_get_active(seat, &session2, &u2) >= 0);
+ log_info("sd_seat_get_active(\"%s\", …) → \"%s\", "UID_FMT, seat, session2, u2);
+
+ r = sd_seat_get_sessions(seat, &sessions, &uids, &n);
+ assert_se(r >= 0);
+ assert_se(r == (int) strv_length(sessions));
+ assert_se(t = strv_join(sessions, " "));
+ strv_free(sessions);
+ log_info("sd_seat_get_sessions(\"%s\", …) → %i, \"%s\", [%i] {%s}",
+ seat, r, t, n, format_uids(&buf, uids, n));
+ free(t);
+
+ assert_se(sd_seat_get_sessions(seat, NULL, NULL, NULL) == r);
+ }
r = sd_get_seats(&seats);
assert_se(r >= 0);
assert_se(r == (int) strv_length(seats));
assert_se(t = strv_join(seats, ", "));
strv_free(seats);
- printf("n_seats = %i\n", r);
- printf("seats = %s\n", t);
- free(t);
+ log_info("sd_get_seats(…) → [%i] \"%s\"", r, t);
+ t = mfree(t);
assert_se(sd_get_seats(NULL) == r);
r = sd_seat_get_active(NULL, &t, NULL);
- assert_se(r >= 0);
- printf("active session on current seat = %s\n", t);
+ assert_se(IN_SET(r, 0, -ENODATA));
+ log_info("sd_seat_get_active(NULL, …) (active session on current seat) → %s", strnull(t));
free(t);
r = sd_get_sessions(&sessions);
@@ -199,40 +225,48 @@ static void test_login(void) {
assert_se(r == (int) strv_length(sessions));
assert_se(t = strv_join(sessions, ", "));
strv_free(sessions);
- printf("n_sessions = %i\n", r);
- printf("sessions = %s\n", t);
+ log_info("sd_get_sessions(…) → [%i] \"%s\"", r, t);
free(t);
assert_se(sd_get_sessions(NULL) == r);
- r = sd_get_uids(&uids);
- assert_se(r >= 0);
+ {
+ _cleanup_free_ uid_t *uids = NULL;
+ _cleanup_free_ char *buf = NULL;
+
+ r = sd_get_uids(&uids);
+ assert_se(r >= 0);
+ log_info("sd_get_uids(…) → [%i] {%s}", r, format_uids(&buf, uids, r));
- printf("uids =");
- for (k = 0; k < r; k++)
- printf(" "UID_FMT, uids[k]);
- printf("\n");
- free(uids);
+ assert_se(sd_get_uids(NULL) == r);
+ }
- printf("n_uids = %i\n", r);
- assert_se(sd_get_uids(NULL) == r);
+ {
+ _cleanup_strv_free_ char **machines = NULL;
+ _cleanup_free_ char *buf = NULL;
- r = sd_get_machine_names(&machines);
- assert_se(r >= 0);
- assert_se(r == (int) strv_length(machines));
- assert_se(t = strv_join(machines, ", "));
- strv_free(machines);
- printf("n_machines = %i\n", r);
- printf("machines = %s\n", t);
- free(t);
+ r = sd_get_machine_names(&machines);
+ assert_se(r >= 0);
+ assert_se(r == (int) strv_length(machines));
+ assert_se(buf = strv_join(machines, " "));
+ log_info("sd_get_machines(…) → [%i] \"%s\"", r, buf);
+
+ assert_se(sd_get_machine_names(NULL) == r);
+ }
+}
+
+static void test_monitor(void) {
+ sd_login_monitor *m = NULL;
+ unsigned n;
+ int r;
r = sd_login_monitor_new("session", &m);
assert_se(r >= 0);
for (n = 0; n < 5; n++) {
+ struct pollfd pollfd = {};
usec_t timeout, nw;
- zero(pollfd);
assert_se((pollfd.fd = sd_login_monitor_get_fd(m)) >= 0);
assert_se((pollfd.events = sd_login_monitor_get_events(m)) >= 0);
@@ -258,7 +292,12 @@ int main(int argc, char* argv[]) {
log_parse_environment();
log_open();
+ log_info("/* Information printed is from the live system */");
+
test_login();
+ if (streq_ptr(argv[1], "-m"))
+ test_monitor();
+
return 0;
}
diff --git a/src/libsystemd/sd-netlink/netlink-message.c b/src/libsystemd/sd-netlink/netlink-message.c
index 654a22fe3b..e8c8abac2a 100644
--- a/src/libsystemd/sd-netlink/netlink-message.c
+++ b/src/libsystemd/sd-netlink/netlink-message.c
@@ -104,7 +104,8 @@ int sd_netlink_message_request_dump(sd_netlink_message *m, int dump) {
assert_return(m->hdr->nlmsg_type == RTM_GETLINK ||
m->hdr->nlmsg_type == RTM_GETADDR ||
m->hdr->nlmsg_type == RTM_GETROUTE ||
- m->hdr->nlmsg_type == RTM_GETNEIGH,
+ m->hdr->nlmsg_type == RTM_GETNEIGH ||
+ m->hdr->nlmsg_type == RTM_GETADDRLABEL ,
-EINVAL);
SET_FLAG(m->hdr->nlmsg_flags, NLM_F_DUMP, dump);
diff --git a/src/libsystemd/sd-netlink/netlink-types.c b/src/libsystemd/sd-netlink/netlink-types.c
index ff0e99558e..923f7dd10c 100644
--- a/src/libsystemd/sd-netlink/netlink-types.c
+++ b/src/libsystemd/sd-netlink/netlink-types.c
@@ -26,6 +26,7 @@
#include <linux/veth.h>
#include <linux/if_bridge.h>
#include <linux/if_addr.h>
+#include <linux/if_addrlabel.h>
#include <linux/if.h>
#include <linux/ip.h>
#include <linux/if_link.h>
@@ -170,6 +171,9 @@ static const NLType rtnl_link_info_data_vxlan_types[] = {
[IFLA_VXLAN_REMCSUM_RX] = { .type = NETLINK_TYPE_U8 },
[IFLA_VXLAN_GBP] = { .type = NETLINK_TYPE_FLAG },
[IFLA_VXLAN_REMCSUM_NOPARTIAL] = { .type = NETLINK_TYPE_FLAG },
+ [IFLA_VXLAN_COLLECT_METADATA] = { .type = NETLINK_TYPE_U8 },
+ [IFLA_VXLAN_LABEL] = { .type = NETLINK_TYPE_U32 },
+ [IFLA_VXLAN_GPE] = { .type = NETLINK_TYPE_FLAG },
};
static const NLType rtnl_bond_arp_target_types[] = {
@@ -283,6 +287,19 @@ static const NLType rtnl_link_info_data_vrf_types[] = {
[IFLA_VRF_TABLE] = { .type = NETLINK_TYPE_U32 },
};
+static const NLType rtnl_link_info_data_geneve_types[] = {
+ [IFLA_GENEVE_ID] = { .type = NETLINK_TYPE_U32 },
+ [IFLA_GENEVE_TTL] = { .type = NETLINK_TYPE_U8 },
+ [IFLA_GENEVE_TOS] = { .type = NETLINK_TYPE_U8 },
+ [IFLA_GENEVE_PORT] = { .type = NETLINK_TYPE_U16 },
+ [IFLA_GENEVE_REMOTE] = { .type = NETLINK_TYPE_IN_ADDR },
+ [IFLA_GENEVE_REMOTE6] = { .type = NETLINK_TYPE_IN_ADDR },
+ [IFLA_GENEVE_UDP_CSUM] = { .type = NETLINK_TYPE_U8 },
+ [IFLA_GENEVE_UDP_ZERO_CSUM6_TX] = { .type = NETLINK_TYPE_U8 },
+ [IFLA_GENEVE_UDP_ZERO_CSUM6_RX] = { .type = NETLINK_TYPE_U8 },
+ [IFLA_GENEVE_LABEL] = { .type = NETLINK_TYPE_U32 },
+};
+
/* these strings must match the .kind entries in the kernel */
static const char* const nl_union_link_info_data_table[] = {
[NL_UNION_LINK_INFO_DATA_BOND] = "bond",
@@ -305,6 +322,7 @@ static const char* const nl_union_link_info_data_table[] = {
[NL_UNION_LINK_INFO_DATA_IP6TNL_TUNNEL] = "ip6tnl",
[NL_UNION_LINK_INFO_DATA_VRF] = "vrf",
[NL_UNION_LINK_INFO_DATA_VCAN] = "vcan",
+ [NL_UNION_LINK_INFO_DATA_GENEVE] = "geneve",
};
DEFINE_STRING_TABLE_LOOKUP(nl_union_link_info_data, NLUnionLinkInfoData);
@@ -346,6 +364,8 @@ static const NLTypeSystem rtnl_link_info_data_type_systems[] = {
.types = rtnl_link_info_data_ip6tnl_types },
[NL_UNION_LINK_INFO_DATA_VRF] = { .count = ELEMENTSOF(rtnl_link_info_data_vrf_types),
.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 },
};
static const NLTypeSystemUnion rtnl_link_info_data_type_system_union = {
@@ -567,22 +587,35 @@ static const NLTypeSystem rtnl_neigh_type_system = {
.types = rtnl_neigh_types,
};
+static const NLType rtnl_addrlabel_types[] = {
+ [IFAL_ADDRESS] = { .type = NETLINK_TYPE_IN_ADDR, .size = sizeof(struct in6_addr) },
+ [IFAL_LABEL] = { .type = NETLINK_TYPE_U32 },
+};
+
+static const NLTypeSystem rtnl_addrlabel_type_system = {
+ .count = ELEMENTSOF(rtnl_addrlabel_types),
+ .types = rtnl_addrlabel_types,
+};
+
static const NLType rtnl_types[] = {
- [NLMSG_DONE] = { .type = NETLINK_TYPE_NESTED, .type_system = &empty_type_system, .size = 0 },
- [NLMSG_ERROR] = { .type = NETLINK_TYPE_NESTED, .type_system = &empty_type_system, .size = sizeof(struct nlmsgerr) },
- [RTM_NEWLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
- [RTM_DELLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
- [RTM_GETLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
- [RTM_SETLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
- [RTM_NEWADDR] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) },
- [RTM_DELADDR] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) },
- [RTM_GETADDR] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) },
- [RTM_NEWROUTE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) },
- [RTM_DELROUTE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) },
- [RTM_GETROUTE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) },
- [RTM_NEWNEIGH] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) },
- [RTM_DELNEIGH] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) },
- [RTM_GETNEIGH] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) },
+ [NLMSG_DONE] = { .type = NETLINK_TYPE_NESTED, .type_system = &empty_type_system, .size = 0 },
+ [NLMSG_ERROR] = { .type = NETLINK_TYPE_NESTED, .type_system = &empty_type_system, .size = sizeof(struct nlmsgerr) },
+ [RTM_NEWLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
+ [RTM_DELLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
+ [RTM_GETLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
+ [RTM_SETLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
+ [RTM_NEWADDR] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) },
+ [RTM_DELADDR] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) },
+ [RTM_GETADDR] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) },
+ [RTM_NEWROUTE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) },
+ [RTM_DELROUTE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) },
+ [RTM_GETROUTE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) },
+ [RTM_NEWNEIGH] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) },
+ [RTM_DELNEIGH] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) },
+ [RTM_GETNEIGH] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) },
+ [RTM_NEWADDRLABEL] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_addrlabel_type_system, .size = sizeof(struct ifaddrlblmsg) },
+ [RTM_DELADDRLABEL] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_addrlabel_type_system, .size = sizeof(struct ifaddrlblmsg) },
+ [RTM_GETADDRLABEL] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_addrlabel_type_system, .size = sizeof(struct ifaddrlblmsg) },
};
const NLTypeSystem type_system_root = {
diff --git a/src/libsystemd/sd-netlink/netlink-types.h b/src/libsystemd/sd-netlink/netlink-types.h
index 42e96173de..ae65c1d8e4 100644
--- a/src/libsystemd/sd-netlink/netlink-types.h
+++ b/src/libsystemd/sd-netlink/netlink-types.h
@@ -88,6 +88,7 @@ typedef enum NLUnionLinkInfoData {
NL_UNION_LINK_INFO_DATA_IP6TNL_TUNNEL,
NL_UNION_LINK_INFO_DATA_VRF,
NL_UNION_LINK_INFO_DATA_VCAN,
+ NL_UNION_LINK_INFO_DATA_GENEVE,
_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 73b9ac0258..6b660b7dbf 100644
--- a/src/libsystemd/sd-netlink/netlink-util.c
+++ b/src/libsystemd/sd-netlink/netlink-util.c
@@ -116,51 +116,6 @@ int rtnl_message_new_synthetic_error(int error, uint32_t serial, sd_netlink_mess
return 0;
}
-bool rtnl_message_type_is_neigh(uint16_t type) {
- switch (type) {
- case RTM_NEWNEIGH:
- case RTM_GETNEIGH:
- case RTM_DELNEIGH:
- return true;
- default:
- return false;
- }
-}
-
-bool rtnl_message_type_is_route(uint16_t type) {
- switch (type) {
- case RTM_NEWROUTE:
- case RTM_GETROUTE:
- case RTM_DELROUTE:
- return true;
- default:
- return false;
- }
-}
-
-bool rtnl_message_type_is_link(uint16_t type) {
- switch (type) {
- case RTM_NEWLINK:
- case RTM_SETLINK:
- case RTM_GETLINK:
- case RTM_DELLINK:
- return true;
- default:
- return false;
- }
-}
-
-bool rtnl_message_type_is_addr(uint16_t type) {
- switch (type) {
- case RTM_NEWADDR:
- case RTM_GETADDR:
- case RTM_DELADDR:
- return true;
- default:
- return false;
- }
-}
-
int rtnl_log_parse_error(int r) {
return log_error_errno(r, "Failed to parse netlink message: %m");
}
diff --git a/src/libsystemd/sd-netlink/netlink-util.h b/src/libsystemd/sd-netlink/netlink-util.h
index f49bf4eaa6..215af12406 100644
--- a/src/libsystemd/sd-netlink/netlink-util.h
+++ b/src/libsystemd/sd-netlink/netlink-util.h
@@ -27,10 +27,25 @@ int rtnl_message_new_synthetic_error(int error, uint32_t serial, sd_netlink_mess
uint32_t rtnl_message_get_serial(sd_netlink_message *m);
void rtnl_message_seal(sd_netlink_message *m);
-bool rtnl_message_type_is_link(uint16_t type);
-bool rtnl_message_type_is_addr(uint16_t type);
-bool rtnl_message_type_is_route(uint16_t type);
-bool rtnl_message_type_is_neigh(uint16_t type);
+static inline bool rtnl_message_type_is_neigh(uint16_t type) {
+ return IN_SET(type, RTM_NEWNEIGH, RTM_GETNEIGH, RTM_DELNEIGH);
+}
+
+static inline bool rtnl_message_type_is_route(uint16_t type) {
+ return IN_SET(type, RTM_NEWROUTE, RTM_GETROUTE, RTM_DELROUTE);
+}
+
+static inline bool rtnl_message_type_is_link(uint16_t type) {
+ return IN_SET(type, RTM_NEWLINK, RTM_SETLINK, RTM_GETLINK, RTM_DELLINK);
+}
+
+static inline bool rtnl_message_type_is_addr(uint16_t type) {
+ return IN_SET(type, RTM_NEWADDR, RTM_GETADDR, RTM_DELADDR);
+}
+
+static inline bool rtnl_message_type_is_addrlabel(uint16_t type) {
+ return IN_SET(type, RTM_NEWADDRLABEL, RTM_DELADDRLABEL, RTM_GETADDRLABEL);
+}
int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name);
int rtnl_set_link_properties(sd_netlink **rtnl, int ifindex, const char *alias, const struct ether_addr *mac, unsigned mtu);
diff --git a/src/libsystemd/sd-netlink/rtnl-message.c b/src/libsystemd/sd-netlink/rtnl-message.c
index b543b5f20c..12c51ffe2e 100644
--- a/src/libsystemd/sd-netlink/rtnl-message.c
+++ b/src/libsystemd/sd-netlink/rtnl-message.c
@@ -18,6 +18,7 @@
***/
#include <netinet/in.h>
+#include <linux/if_addrlabel.h>
#include <stdbool.h>
#include <unistd.h>
@@ -700,3 +701,56 @@ int sd_rtnl_message_get_family(sd_netlink_message *m, int *family) {
return -EOPNOTSUPP;
}
+
+int sd_rtnl_message_new_addrlabel(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t nlmsg_type, int ifindex, int ifal_family) {
+ struct ifaddrlblmsg *addrlabel;
+ int r;
+
+ assert_return(rtnl_message_type_is_addrlabel(nlmsg_type), -EINVAL);
+ assert_return(ret, -EINVAL);
+
+ r = message_new(rtnl, ret, nlmsg_type);
+ if (r < 0)
+ return r;
+
+ if (nlmsg_type == RTM_NEWADDRLABEL)
+ (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL;
+
+ addrlabel = NLMSG_DATA((*ret)->hdr);
+
+ addrlabel->ifal_family = ifal_family;
+ addrlabel->ifal_index = ifindex;
+
+ return 0;
+}
+
+int sd_rtnl_message_addrlabel_set_prefixlen(sd_netlink_message *m, unsigned char prefixlen) {
+ struct ifaddrlblmsg *addrlabel;
+
+ assert_return(m, -EINVAL);
+ assert_return(m->hdr, -EINVAL);
+ assert_return(rtnl_message_type_is_addrlabel(m->hdr->nlmsg_type), -EINVAL);
+
+ addrlabel = NLMSG_DATA(m->hdr);
+
+ if (prefixlen > 128)
+ return -ERANGE;
+
+ addrlabel->ifal_prefixlen = prefixlen;
+
+ return 0;
+}
+
+int sd_rtnl_message_addrlabel_get_prefixlen(sd_netlink_message *m, unsigned char *prefixlen) {
+ struct ifaddrlblmsg *addrlabel;
+
+ assert_return(m, -EINVAL);
+ assert_return(m->hdr, -EINVAL);
+ assert_return(rtnl_message_type_is_addrlabel(m->hdr->nlmsg_type), -EINVAL);
+
+ addrlabel = NLMSG_DATA(m->hdr);
+
+ *prefixlen = addrlabel->ifal_prefixlen;
+
+ return 0;
+}
diff --git a/src/libsystemd/sd-netlink/sd-netlink.c b/src/libsystemd/sd-netlink/sd-netlink.c
index 68435564de..d67244676c 100644
--- a/src/libsystemd/sd-netlink/sd-netlink.c
+++ b/src/libsystemd/sd-netlink/sd-netlink.c
@@ -44,7 +44,7 @@ static int sd_netlink_new(sd_netlink **ret) {
rtnl->n_ref = REFCNT_INIT;
rtnl->fd = -1;
rtnl->sockaddr.nl.nl_family = AF_NETLINK;
- rtnl->original_pid = getpid();
+ rtnl->original_pid = getpid_cached();
LIST_HEAD_INIT(rtnl->match_callbacks);
@@ -99,7 +99,7 @@ static bool rtnl_pid_changed(sd_netlink *rtnl) {
/* We don't support people creating an rtnl connection and
* keeping it around over a fork(). Let's complain. */
- return rtnl->original_pid != getpid();
+ return rtnl->original_pid != getpid_cached();
}
int sd_netlink_open_fd(sd_netlink **ret, int fd) {
diff --git a/src/libsystemd/sd-resolve/sd-resolve.c b/src/libsystemd/sd-resolve/sd-resolve.c
index 60aa55de3b..12fae65e6b 100644
--- a/src/libsystemd/sd-resolve/sd-resolve.c
+++ b/src/libsystemd/sd-resolve/sd-resolve.c
@@ -459,7 +459,7 @@ static bool resolve_pid_changed(sd_resolve *r) {
/* We don't support people creating a resolver and keeping it
* around after fork(). Let's complain. */
- return r->original_pid != getpid();
+ return r->original_pid != getpid_cached();
}
_public_ int sd_resolve_new(sd_resolve **ret) {
@@ -473,7 +473,7 @@ _public_ int sd_resolve_new(sd_resolve **ret) {
return -ENOMEM;
resolve->n_ref = 1;
- resolve->original_pid = getpid();
+ resolve->original_pid = getpid_cached();
for (i = 0; i < _FD_MAX; i++)
resolve->fds[i] = -1;
diff --git a/src/libudev/libudev-monitor.c b/src/libudev/libudev-monitor.c
index a40329d732..8287694c49 100644
--- a/src/libudev/libudev-monitor.c
+++ b/src/libudev/libudev-monitor.c
@@ -681,7 +681,7 @@ retry:
udev_device = udev_device_new_from_nulstr(udev_monitor->udev, &buf.raw[bufpos], buflen - bufpos);
if (!udev_device) {
- log_debug("could not create device: %m");
+ log_debug_errno(errno, "could not create device: %m");
return NULL;
}
diff --git a/src/libudev/libudev.c b/src/libudev/libudev.c
index d8e13288b0..5f2225f402 100644
--- a/src/libudev/libudev.c
+++ b/src/libudev/libudev.c
@@ -103,82 +103,6 @@ _public_ struct udev *udev_new(void) {
}
udev->refcount = 1;
- f = fopen("/etc/udev/udev.conf", "re");
- if (f != NULL) {
- char line[UTIL_LINE_SIZE];
- unsigned line_nr = 0;
-
- while (fgets(line, sizeof(line), f)) {
- size_t len;
- char *key;
- char *val;
-
- line_nr++;
-
- /* find key */
- key = line;
- while (isspace(key[0]))
- key++;
-
- /* comment or empty line */
- if (key[0] == '#' || key[0] == '\0')
- continue;
-
- /* split key/value */
- val = strchr(key, '=');
- if (val == NULL) {
- log_debug("/etc/udev/udev.conf:%u: missing assignment, skipping line.", line_nr);
- continue;
- }
- val[0] = '\0';
- val++;
-
- /* find value */
- while (isspace(val[0]))
- val++;
-
- /* terminate key */
- len = strlen(key);
- if (len == 0)
- continue;
- while (isspace(key[len-1]))
- len--;
- key[len] = '\0';
-
- /* terminate value */
- len = strlen(val);
- if (len == 0)
- continue;
- while (isspace(val[len-1]))
- len--;
- val[len] = '\0';
-
- if (len == 0)
- continue;
-
- /* unquote */
- if (val[0] == '"' || val[0] == '\'') {
- if (len == 1 || val[len-1] != val[0]) {
- log_debug("/etc/udev/udev.conf:%u: inconsistent quoting, skipping line.", line_nr);
- continue;
- }
- val[len-1] = '\0';
- val++;
- }
-
- if (streq(key, "udev_log")) {
- int prio;
-
- prio = util_log_priority(val);
- if (prio < 0)
- log_debug("/etc/udev/udev.conf:%u: invalid log level '%s', ignoring.", line_nr, val);
- else
- log_set_max_level(prio);
- continue;
- }
- }
- }
-
return udev;
}
diff --git a/src/libudev/libudev.pc.in b/src/libudev/libudev.pc.in
index 770c92209e..1becae45fd 100644
--- a/src/libudev/libudev.pc.in
+++ b/src/libudev/libudev.pc.in
@@ -12,6 +12,6 @@ includedir=@includedir@
Name: libudev
Description: Library to access udev device information
-Version: @VERSION@
+Version: @PACKAGE_VERSION@
Libs: -L${libdir} -ludev
Cflags: -I${includedir}
diff --git a/src/libudev/meson.build b/src/libudev/meson.build
new file mode 100644
index 0000000000..1378f9a251
--- /dev/null
+++ b/src/libudev/meson.build
@@ -0,0 +1,41 @@
+libudev_sources = files('''
+ libudev-private.h
+ libudev-device-internal.h
+ libudev.c
+ libudev-list.c
+ libudev-util.c
+ libudev-device.c
+ libudev-device-private.c
+ libudev-enumerate.c
+ libudev-monitor.c
+ libudev-queue.c
+ libudev-hwdb.c
+'''.split())
+
+############################################################
+
+libudev_sym = 'libudev.sym'
+libudev_sym_path = '@0@/@1@'.format(meson.current_source_dir(), libudev_sym)
+libudev = shared_library(
+ 'udev',
+ libudev_sources,
+ version : '1.6.6',
+ include_directories : includes,
+ link_args : ['-shared',
+ '-Wl,--version-script=' + libudev_sym_path],
+ link_with : [libbasic,
+ libsystemd_internal],
+ dependencies : [threads],
+ link_depends : libudev_sym,
+ install : true,
+ install_dir : rootlibdir)
+
+install_headers('libudev.h')
+libudev_h_path = '@0@/libudev.h'.format(meson.current_source_dir())
+
+libudev_pc = configure_file(
+ input : 'libudev.pc.in',
+ output : 'libudev.pc',
+ configuration : substs)
+install_data(libudev_pc,
+ install_dir : pkgconfiglibdir)
diff --git a/src/locale/keymap-util.c b/src/locale/keymap-util.c
index da72bee4a9..105d9b0ee4 100644
--- a/src/locale/keymap-util.c
+++ b/src/locale/keymap-util.c
@@ -361,8 +361,9 @@ int x11_write_data(Context *c) {
fchmod(fileno(f), 0644);
- fputs("# Read and parsed by systemd-localed. It's probably wise not to edit this file\n"
- "# manually too freely.\n"
+ 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);
diff --git a/src/locale/localed.c b/src/locale/localed.c
index 1cb049e74a..b4798d674c 100644
--- a/src/locale/localed.c
+++ b/src/locale/localed.c
@@ -436,7 +436,10 @@ static void log_xkb(struct xkb_context *ctx, enum xkb_log_level lvl, const char
const char *fmt;
fmt = strjoina("libxkbcommon: ", format);
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat-nonliteral"
log_internalv(LOG_DEBUG, 0, __FILE__, __LINE__, __func__, fmt, args);
+#pragma GCC diagnostic pop
}
#define LOAD_SYMBOL(symbol, dl, name) \
diff --git a/src/locale/meson.build b/src/locale/meson.build
new file mode 100644
index 0000000000..d7dd113c8d
--- /dev/null
+++ b/src/locale/meson.build
@@ -0,0 +1,42 @@
+systemd_localed_sources = files('''
+ localed.c
+ keymap-util.c
+ keymap-util.h
+'''.split())
+
+localectl_sources = files('localectl.c')
+
+if conf.get('ENABLE_LOCALED', false)
+ install_data('org.freedesktop.locale1.conf',
+ install_dir : dbuspolicydir)
+ install_data('org.freedesktop.locale1.service',
+ install_dir : dbussystemservicedir)
+
+ custom_target(
+ 'org.freedesktop.locale1.policy',
+ input : 'org.freedesktop.locale1.policy.in',
+ output : 'org.freedesktop.locale1.policy',
+ command : intltool_command,
+ install : install_polkit,
+ install_dir : polkitpolicydir)
+endif
+
+# If you know a way that allows the same variables to be used
+# in sources list and concatenated to a string for test_env,
+# let me know.
+kbd_model_map = join_paths(meson.current_source_dir(), 'kbd-model-map')
+language_fallback_map = join_paths(meson.current_source_dir(), 'language-fallback-map')
+
+if conf.get('ENABLE_LOCALED', false)
+ install_data('kbd-model-map',
+ 'language-fallback-map',
+ install_dir : pkgdatadir)
+endif
+
+tests += [
+ [['src/locale/test-keymap-util.c',
+ 'src/locale/keymap-util.c',
+ 'src/locale/keymap-util.h'],
+ [libshared],
+ [libdl]],
+]
diff --git a/src/login/70-power-switch.rules b/src/login/70-power-switch.rules
index e2855b50f7..394a80f1f8 100644
--- a/src/login/70-power-switch.rules
+++ b/src/login/70-power-switch.rules
@@ -7,12 +7,7 @@
ACTION=="remove", GOTO="power_switch_end"
-SUBSYSTEM=="input", KERNEL=="event*", SUBSYSTEMS=="acpi", TAG+="power-switch"
-SUBSYSTEM=="input", KERNEL=="event*", KERNELS=="thinkpad_acpi", TAG+="power-switch"
-SUBSYSTEM=="input", KERNEL=="event*", ATTRS{name}=="twl4030_pwrbutton", TAG+="power-switch"
-SUBSYSTEM=="input", KERNEL=="event*", ATTRS{name}=="tps65217_pwr_but", TAG+="power-switch"
-SUBSYSTEM=="input", KERNEL=="event*", ATTRS{name}=="* WMI hotkeys", TAG+="power-switch"
-SUBSYSTEM=="input", KERNEL=="event*", \
- SUBSYSTEMS=="platform", DRIVERS=="gpio-keys", ATTRS{keys}=="*,116|116,*|116|*,116,*", TAG+="power-switch"
+SUBSYSTEM=="input", KERNEL=="event*", ENV{ID_INPUT_SWITCH}=="1", TAG+="power-switch"
+SUBSYSTEM=="input", KERNEL=="event*", ENV{ID_INPUT_KEY}=="1", TAG+="power-switch"
LABEL="power_switch_end"
diff --git a/src/login/loginctl.c b/src/login/loginctl.c
index 68cac4cb08..1862e8983c 100644
--- a/src/login/loginctl.c
+++ b/src/login/loginctl.c
@@ -907,6 +907,8 @@ static int show_session(int argc, char *argv[], void *userdata) {
bool properties, new_line = false;
sd_bus *bus = userdata;
int r, i;
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ _cleanup_free_ char *path = NULL;
assert(bus);
assert(argv);
@@ -916,19 +918,27 @@ static int show_session(int argc, char *argv[], void *userdata) {
pager_open(arg_no_pager, false);
if (argc <= 1) {
- /* If not argument is specified inspect the manager
- * itself */
+ const char *session, *p = "/org/freedesktop/login1/session/self";
+
if (properties)
+ /* If no argument is specified inspect the manager itself */
return show_properties(bus, "/org/freedesktop/login1", &new_line);
/* And in the pretty case, show data of the calling session */
- return print_session_status_info(bus, "/org/freedesktop/login1/session/self", &new_line);
+ session = getenv("XDG_SESSION_ID");
+ if (session) {
+ r = get_session_path(bus, session, &error, &path);
+ if (r < 0) {
+ log_error("Failed to get session path: %s", bus_error_message(&error, r));
+ return r;
+ }
+ p = path;
+ }
+
+ return print_session_status_info(bus, p, &new_line);
}
for (i = 1; i < argc; i++) {
- _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
- _cleanup_free_ char *path = NULL;
-
r = get_session_path(bus, argv[i], &error, &path);
if (r < 0) {
log_error("Failed to get session path: %s", bus_error_message(&error, r));
@@ -1074,12 +1084,11 @@ static int activate(int argc, char *argv[], void *userdata) {
polkit_agent_open_if_enabled();
if (argc < 2) {
- /* No argument? Let's convert this into the empty
- * session name, which the calls will then resolve to
- * the caller's session. */
+ /* 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. */
short_argv[0] = argv[0];
- short_argv[1] = (char*) "";
+ short_argv[1] = getenv("XDG_SESSION_ID") ?: (char*) "";
short_argv[2] = NULL;
argv = short_argv;
@@ -1155,8 +1164,11 @@ static int enable_linger(int argc, char *argv[], void *userdata) {
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. */
+
short_argv[0] = argv[0];
- short_argv[1] = (char*) "";
+ short_argv[1] = getenv("XDG_SESSION_ID") ?: (char*) "";
short_argv[2] = NULL;
argv = short_argv;
argc = 2;
@@ -1386,8 +1398,10 @@ static int help(int argc, char *argv[], void *userdata) {
" --kill-who=WHO Who to send signal to\n"
" -s --signal=SIGNAL Which signal to send\n"
" -n --lines=INTEGER Number of journal entries to show\n"
- " -o --output=STRING Change journal output mode (short, short-monotonic,\n"
- " verbose, export, json, json-pretty, json-sse, cat)\n\n"
+ " -o --output=STRING Change journal output mode (short, short-precise,\n"
+ " short-iso, short-iso-precise, short-full,\n"
+ " short-monotonic, short-unix, verbose, export,\n"
+ " json, json-pretty, json-sse, cat)\n"
"Session Commands:\n"
" list-sessions List sessions\n"
" session-status [ID...] Show session status\n"
diff --git a/src/login/logind-button.c b/src/login/logind-button.c
index d739af8ea2..e53dd63c29 100644
--- a/src/login/logind-button.c
+++ b/src/login/logind-button.c
@@ -32,6 +32,18 @@
#include "string-util.h"
#include "util.h"
+#define CONST_MAX4(a, b, c, d) CONST_MAX(CONST_MAX(a, b), CONST_MAX(c, d))
+
+#define ULONG_BITS (sizeof(unsigned long)*8)
+
+static bool bitset_get(const unsigned long *bits, unsigned i) {
+ return (bits[i / ULONG_BITS] >> (i % ULONG_BITS)) & 1UL;
+}
+
+static void bitset_put(unsigned long *bits, unsigned i) {
+ bits[i / ULONG_BITS] |= (unsigned long) 1 << (i % ULONG_BITS);
+}
+
Button* button_new(Manager *m, const char *name) {
Button *b;
@@ -231,6 +243,95 @@ static int button_dispatch(sd_event_source *s, int fd, uint32_t revents, void *u
return 0;
}
+static int button_suitable(Button *b) {
+ unsigned long types[CONST_MAX(EV_KEY, EV_SW)/ULONG_BITS+1];
+
+ assert(b);
+ assert(b->fd);
+
+ if (ioctl(b->fd, EVIOCGBIT(EV_SYN, sizeof(types)), types) < 0)
+ return -errno;
+
+ if (bitset_get(types, EV_KEY)) {
+ unsigned long keys[CONST_MAX4(KEY_POWER, KEY_POWER2, KEY_SLEEP, KEY_SUSPEND)/ULONG_BITS+1];
+
+ if (ioctl(b->fd, EVIOCGBIT(EV_KEY, sizeof(keys)), keys) < 0)
+ return -errno;
+
+ if (bitset_get(keys, KEY_POWER) ||
+ bitset_get(keys, KEY_POWER2) ||
+ bitset_get(keys, KEY_SLEEP) ||
+ bitset_get(keys, KEY_SUSPEND))
+ return true;
+ }
+
+ if (bitset_get(types, EV_SW)) {
+ unsigned long switches[CONST_MAX(SW_LID, SW_DOCK)/ULONG_BITS+1];
+
+ if (ioctl(b->fd, EVIOCGBIT(EV_SW, sizeof(switches)), switches) < 0)
+ return -errno;
+
+ if (bitset_get(switches, SW_LID) ||
+ bitset_get(switches, SW_DOCK))
+ return true;
+ }
+
+ return false;
+}
+
+static int button_set_mask(Button *b) {
+ unsigned long
+ types[CONST_MAX(EV_KEY, EV_SW)/ULONG_BITS+1] = {},
+ keys[CONST_MAX4(KEY_POWER, KEY_POWER2, KEY_SLEEP, KEY_SUSPEND)/ULONG_BITS+1] = {},
+ switches[CONST_MAX(SW_LID, SW_DOCK)/ULONG_BITS+1] = {};
+ struct input_mask mask;
+
+ assert(b);
+ assert(b->fd >= 0);
+
+ bitset_put(types, EV_KEY);
+ bitset_put(types, EV_SW);
+
+ mask = (struct input_mask) {
+ .type = EV_SYN,
+ .codes_size = sizeof(types),
+ .codes_ptr = PTR_TO_UINT64(types),
+ };
+
+ if (ioctl(b->fd, EVIOCSMASK, &mask) < 0)
+ /* Log only at debug level if the kernel doesn't do EVIOCSMASK yet */
+ return log_full_errno(IN_SET(errno, ENOTTY, EOPNOTSUPP, EINVAL) ? LOG_DEBUG : LOG_WARNING,
+ errno, "Failed to set EV_SYN event mask on /dev/input/%s: %m", b->name);
+
+ bitset_put(keys, KEY_POWER);
+ bitset_put(keys, KEY_POWER2);
+ bitset_put(keys, KEY_SLEEP);
+ bitset_put(keys, KEY_SUSPEND);
+
+ mask = (struct input_mask) {
+ .type = EV_KEY,
+ .codes_size = sizeof(keys),
+ .codes_ptr = PTR_TO_UINT64(keys),
+ };
+
+ if (ioctl(b->fd, EVIOCSMASK, &mask) < 0)
+ return log_warning_errno(errno, "Failed to set EV_KEY event mask on /dev/input/%s: %m", b->name);
+
+ bitset_put(switches, SW_LID);
+ bitset_put(switches, SW_DOCK);
+
+ mask = (struct input_mask) {
+ .type = EV_SW,
+ .codes_size = sizeof(switches),
+ .codes_ptr = PTR_TO_UINT64(switches),
+ };
+
+ if (ioctl(b->fd, EVIOCSMASK, &mask) < 0)
+ return log_warning_errno(errno, "Failed to set EV_SW event mask on /dev/input/%s: %m", b->name);
+
+ return 0;
+}
+
int button_open(Button *b) {
char *p, name[256];
int r;
@@ -243,13 +344,23 @@ int button_open(Button *b) {
b->fd = open(p, O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK);
if (b->fd < 0)
- return log_warning_errno(errno, "Failed to open %s: %m", b->name);
+ return log_warning_errno(errno, "Failed to open %s: %m", p);
+
+ r = button_suitable(b);
+ if (r < 0)
+ return log_warning_errno(r, "Failed to determine whether input device is relevant to us: %m");
+ if (r == 0) {
+ log_debug("Device %s does not expose keys or switches relevant to us, ignoring.", p);
+ return -EADDRNOTAVAIL;
+ }
if (ioctl(b->fd, EVIOCGNAME(sizeof(name)), name) < 0) {
r = log_error_errno(errno, "Failed to get input name: %m");
goto fail;
}
+ (void) button_set_mask(b);
+
r = sd_event_add_io(b->manager->event, &b->io_event_source, b->fd, EPOLLIN, button_dispatch, b);
if (r < 0) {
log_error_errno(r, "Failed to add button event: %m");
@@ -266,7 +377,7 @@ fail:
}
int button_check_switches(Button *b) {
- uint8_t switches[SW_MAX/8+1] = {};
+ unsigned long switches[CONST_MAX(SW_LID, SW_DOCK)/ULONG_BITS+1] = {};
assert(b);
if (b->fd < 0)
@@ -275,8 +386,8 @@ int button_check_switches(Button *b) {
if (ioctl(b->fd, EVIOCGSW(sizeof(switches)), switches) < 0)
return -errno;
- b->lid_closed = (switches[SW_LID/8] >> (SW_LID % 8)) & 1;
- b->docked = (switches[SW_DOCK/8] >> (SW_DOCK % 8)) & 1;
+ b->lid_closed = bitset_get(switches, SW_LID);
+ b->docked = bitset_get(switches, SW_DOCK);
if (b->lid_closed)
button_install_check_event_source(b);
diff --git a/src/login/logind-core.c b/src/login/logind-core.c
index eff5a4a36f..ebe1d68634 100644
--- a/src/login/logind-core.c
+++ b/src/login/logind-core.c
@@ -269,7 +269,11 @@ int manager_process_button_device(Manager *m, struct udev_device *d) {
sn = "seat0";
button_set_seat(b, sn);
- button_open(b);
+
+ r = button_open(b);
+ if (r < 0) /* event device doesn't have any keys or switches relevant to us? (or any other error
+ * opening the device?) let's close the button again. */
+ button_free(b);
}
return 0;
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
index c6be596af3..c9b7d99818 100644
--- a/src/login/logind-dbus.c
+++ b/src/login/logind-dbus.c
@@ -65,6 +65,9 @@ int manager_get_session_from_creds(Manager *m, sd_bus_message *message, const ch
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;
}
diff --git a/src/login/logind-session-dbus.c b/src/login/logind-session-dbus.c
index 22dea5db1f..22e5349a67 100644
--- a/src/login/logind-session-dbus.c
+++ b/src/login/logind-session-dbus.c
@@ -396,7 +396,7 @@ static int method_take_control(sd_bus_message *message, void *userdata, sd_bus_e
if (uid != 0 && (force || uid != s->user->uid))
return sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "Only owner of session may take control");
- r = session_set_controller(s, sd_bus_message_get_sender(message), force);
+ r = session_set_controller(s, sd_bus_message_get_sender(message), force, true);
if (r < 0)
return r;
@@ -444,14 +444,23 @@ static int method_take_device(sd_bus_message *message, void *userdata, sd_bus_er
* equivalent). */
return sd_bus_error_setf(error, BUS_ERROR_DEVICE_IS_TAKEN, "Device already taken");
- r = session_device_new(s, dev, &sd);
+ r = session_device_new(s, dev, true, &sd);
if (r < 0)
return r;
+ r = session_device_save(sd);
+ if (r < 0)
+ goto error;
+
r = sd_bus_reply_method_return(message, "hb", sd->fd, !sd->active);
if (r < 0)
- session_device_free(sd);
+ goto error;
+
+ session_save(s);
+ return 0;
+error:
+ session_device_free(sd);
return r;
}
@@ -478,6 +487,8 @@ static int method_release_device(sd_bus_message *message, void *userdata, sd_bus
return sd_bus_error_setf(error, BUS_ERROR_DEVICE_NOT_TAKEN, "Device not taken");
session_device_free(sd);
+ session_save(s);
+
return sd_bus_reply_method_return(message, NULL);
}
diff --git a/src/login/logind-session-device.c b/src/login/logind-session-device.c
index 4055a23277..05af2045d2 100644
--- a/src/login/logind-session-device.c
+++ b/src/login/logind-session-device.c
@@ -30,6 +30,8 @@
#include "fd-util.h"
#include "logind-session-device.h"
#include "missing.h"
+#include "parse-util.h"
+#include "sd-daemon.h"
#include "util.h"
enum SessionDeviceNotifications {
@@ -206,7 +208,10 @@ static int session_device_start(SessionDevice *sd) {
r = session_device_open(sd, true);
if (r < 0)
return r;
- close_nointr(sd->fd);
+ /* For evdev devices, the file descriptor might be left
+ * uninitialized. This might happen while resuming into a
+ * session and logind has been restarted right before. */
+ safe_close(sd->fd);
sd->fd = r;
break;
case DEVICE_TYPE_UNKNOWN:
@@ -341,7 +346,7 @@ err_dev:
return r;
}
-int session_device_new(Session *s, dev_t dev, SessionDevice **out) {
+int session_device_new(Session *s, dev_t dev, bool open_device, SessionDevice **out) {
SessionDevice *sd;
int r;
@@ -370,22 +375,24 @@ int session_device_new(Session *s, dev_t dev, SessionDevice **out) {
goto error;
}
- /* Open the device for the first time. We need a valid fd to pass back
- * to the caller. If the session is not active, this _might_ immediately
- * revoke access and thus invalidate the fd. But this is still needed
- * to pass a valid fd back. */
- sd->active = session_is_active(s);
- r = session_device_open(sd, sd->active);
- if (r < 0) {
- /* EINVAL _may_ mean a master is active; retry inactive */
- if (sd->active && r == -EINVAL) {
- sd->active = false;
- r = session_device_open(sd, false);
+ if (open_device) {
+ /* Open the device for the first time. We need a valid fd to pass back
+ * to the caller. If the session is not active, this _might_ immediately
+ * revoke access and thus invalidate the fd. But this is still needed
+ * to pass a valid fd back. */
+ sd->active = session_is_active(s);
+ r = session_device_open(sd, sd->active);
+ if (r < 0) {
+ /* EINVAL _may_ mean a master is active; retry inactive */
+ if (sd->active && r == -EINVAL) {
+ sd->active = false;
+ r = session_device_open(sd, false);
+ }
+ if (r < 0)
+ goto error;
}
- if (r < 0)
- goto error;
+ sd->fd = r;
}
- sd->fd = r;
LIST_PREPEND(sd_by_device, sd->device->session_devices, sd);
@@ -435,15 +442,16 @@ void session_device_complete_pause(SessionDevice *sd) {
void session_device_resume_all(Session *s) {
SessionDevice *sd;
Iterator i;
- int r;
assert(s);
HASHMAP_FOREACH(sd, s->devices, i) {
if (!sd->active) {
- r = session_device_start(sd);
- if (!r)
- session_device_notify(sd, SESSION_DEVICE_RESUME);
+ if (session_device_start(sd) < 0)
+ continue;
+ if (session_device_save(sd) < 0)
+ continue;
+ session_device_notify(sd, SESSION_DEVICE_RESUME);
}
}
}
@@ -478,3 +486,36 @@ unsigned int session_device_try_pause_all(Session *s) {
return num_pending;
}
+
+int session_device_save(SessionDevice *sd) {
+ _cleanup_free_ char *state = NULL;
+ 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.
+ *
+ * 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);
+ if (r < 0)
+ return -ENOMEM;
+
+ return sd_pid_notify_with_fds(0, false, state, &sd->fd, 1);
+}
+
+void session_device_attach_fd(SessionDevice *sd, int fd, bool active) {
+ assert(fd > 0);
+ assert(sd);
+ assert(sd->fd < 0);
+ assert(!sd->active);
+
+ sd->fd = fd;
+ sd->active = active;
+}
diff --git a/src/login/logind-session-device.h b/src/login/logind-session-device.h
index 7c8503583f..83aef1e18c 100644
--- a/src/login/logind-session-device.h
+++ b/src/login/logind-session-device.h
@@ -44,10 +44,13 @@ struct SessionDevice {
LIST_FIELDS(struct SessionDevice, sd_by_device);
};
-int session_device_new(Session *s, dev_t dev, SessionDevice **out);
+int session_device_new(Session *s, dev_t dev, bool open_device, SessionDevice **out);
void session_device_free(SessionDevice *sd);
void session_device_complete_pause(SessionDevice *sd);
void session_device_resume_all(Session *s);
void session_device_pause_all(Session *s);
unsigned int session_device_try_pause_all(Session *s);
+
+int session_device_save(SessionDevice *sd);
+void session_device_attach_fd(SessionDevice *sd, int fd, bool active);
diff --git a/src/login/logind-session.c b/src/login/logind-session.c
index 4a168906d6..42dfecaffb 100644
--- a/src/login/logind-session.c
+++ b/src/login/logind-session.c
@@ -152,6 +152,18 @@ void session_set_user(Session *s, User *u) {
LIST_PREPEND(sessions_by_user, u->sessions, s);
}
+static void session_save_devices(Session *s, FILE *f) {
+ SessionDevice *sd;
+ Iterator i;
+
+ if (!hashmap_isempty(s->devices)) {
+ fprintf(f, "DEVICES=");
+ HASHMAP_FOREACH(sd, s->devices, i)
+ fprintf(f, "%u:%u ", major(sd->dev), minor(sd->dev));
+ fprintf(f, "\n");
+ }
+}
+
int session_save(Session *s) {
_cleanup_free_ char *temp_path = NULL;
_cleanup_fclose_ FILE *f = NULL;
@@ -281,8 +293,10 @@ int session_save(Session *s) {
s->timestamp.realtime,
s->timestamp.monotonic);
- if (s->controller)
+ if (s->controller) {
fprintf(f, "CONTROLLER=%s\n", s->controller);
+ session_save_devices(s, f);
+ }
r = fflush_and_check(f);
if (r < 0)
@@ -304,6 +318,43 @@ fail:
return log_error_errno(r, "Failed to save session data %s: %m", s->state_file);
}
+static int session_load_devices(Session *s, const char *devices) {
+ const char *p;
+ int r = 0;
+
+ assert(s);
+
+ for (p = devices;;) {
+ _cleanup_free_ char *word = NULL;
+ SessionDevice *sd;
+ dev_t dev;
+ int k;
+
+ k = extract_first_word(&p, &word, NULL, 0);
+ if (k == 0)
+ break;
+ if (k < 0) {
+ r = k;
+ break;
+ }
+
+ k = parse_dev(word, &dev);
+ if (k < 0) {
+ r = k;
+ continue;
+ }
+
+ /* The file descriptors for loaded devices will be reattached later. */
+ k = session_device_new(s, dev, false, &sd);
+ if (k < 0)
+ r = k;
+ }
+
+ if (r < 0)
+ log_error_errno(r, "Loading session devices for session %s failed: %m", s->id);
+
+ return r;
+}
int session_load(Session *s) {
_cleanup_free_ char *remote = NULL,
@@ -317,7 +368,9 @@ int session_load(Session *s) {
*uid = NULL,
*realtime = NULL,
*monotonic = NULL,
- *controller = NULL;
+ *controller = NULL,
+ *active = NULL,
+ *devices = NULL;
int k, r;
@@ -345,6 +398,8 @@ int session_load(Session *s) {
"REALTIME", &realtime,
"MONOTONIC", &monotonic,
"CONTROLLER", &controller,
+ "ACTIVE", &active,
+ "DEVICES", &devices,
NULL);
if (r < 0)
@@ -447,10 +502,17 @@ int session_load(Session *s) {
if (monotonic)
timestamp_deserialize(monotonic, &s->timestamp.monotonic);
+ if (active) {
+ k = parse_boolean(active);
+ if (k >= 0)
+ s->was_active = k;
+ }
+
if (controller) {
- if (bus_name_has_owner(s->manager->bus, controller, NULL) > 0)
- session_set_controller(s, controller, false);
- else
+ if (bus_name_has_owner(s->manager->bus, controller, NULL) > 0) {
+ session_set_controller(s, controller, false, false);
+ session_load_devices(s, devices);
+ } else
session_restore_vt(s);
}
@@ -1170,7 +1232,7 @@ static int on_bus_track(sd_bus_track *track, void *userdata) {
return 0;
}
-int session_set_controller(Session *s, const char *sender, bool force) {
+int session_set_controller(Session *s, const char *sender, bool force, bool prepare) {
_cleanup_free_ char *name = NULL;
int r;
@@ -1202,11 +1264,14 @@ int session_set_controller(Session *s, const char *sender, bool force) {
* Note that we reset the VT on ReleaseControl() and if the controller
* exits.
* If logind crashes/restarts, we restore the controller during restart
- * or reset the VT in case it crashed/exited, too. */
- r = session_prepare_vt(s);
- if (r < 0) {
- s->track = sd_bus_track_unref(s->track);
- return r;
+ * (without preparing the VT since the controller has probably overridden
+ * VT state by now) or reset the VT in case it crashed/exited, too. */
+ if (prepare) {
+ r = session_prepare_vt(s);
+ if (r < 0) {
+ s->track = sd_bus_track_unref(s->track);
+ return r;
+ }
}
session_release_controller(s, true);
diff --git a/src/login/logind-session.h b/src/login/logind-session.h
index ffb7cd2d41..12b9d86f55 100644
--- a/src/login/logind-session.h
+++ b/src/login/logind-session.h
@@ -111,6 +111,8 @@ struct Session {
bool started:1;
bool stopping:1;
+ bool was_active:1;
+
sd_bus_message *create_message;
sd_event_source *timer_event_source;
@@ -176,7 +178,7 @@ void session_restore_vt(Session *s);
void session_leave_vt(Session *s);
bool session_is_controller(Session *s, const char *sender);
-int session_set_controller(Session *s, const char *sender, bool force);
+int session_set_controller(Session *s, const char *sender, bool force, bool prepare);
void session_drop_controller(Session *s);
int bus_session_method_activate(sd_bus_message *message, void *userdata, sd_bus_error *error);
diff --git a/src/login/logind.c b/src/login/logind.c
index 19bae294a4..6046596684 100644
--- a/src/login/logind.c
+++ b/src/login/logind.c
@@ -409,10 +409,71 @@ static int manager_enumerate_users(Manager *m) {
return r;
}
+static int manager_attach_fds(Manager *m) {
+ _cleanup_strv_free_ char **fdnames = NULL;
+ int n, i, fd;
+
+ /* Upon restart, PID1 will send us back all fds of session devices
+ * that we previously opened. Each file descriptor is associated
+ * with a given session. The session ids are passed through FDNAMES. */
+
+ n = sd_listen_fds_with_names(true, &fdnames);
+ if (n <= 0)
+ return n;
+
+ for (i = 0; i < n; i++) {
+ struct stat st;
+ SessionDevice *sd;
+ Session *s;
+ char *id;
+
+ fd = SD_LISTEN_FDS_START + i;
+
+ id = startswith(fdnames[i], "session-");
+ if (!id)
+ continue;
+
+ s = hashmap_get(m->sessions, id);
+ if (!s) {
+ /* If the session doesn't exist anymore, the associated session
+ * device attached to this fd doesn't either. Let's simply close
+ * this fd. */
+ log_debug("Failed to attach fd for unknown session: %s", id);
+ close_nointr(fd);
+ continue;
+ }
+
+ if (fstat(fd, &st) < 0) {
+ /* The device is allowed to go away at a random point, in which
+ * case fstat failing is expected. */
+ log_debug_errno(errno, "Failed to stat device fd for session %s: %m", id);
+ close_nointr(fd);
+ continue;
+ }
+
+ sd = hashmap_get(s->devices, &st.st_rdev);
+ if (!sd) {
+ /* Weird we got an fd for a session device which wasn't
+ * recorded in the session state file... */
+ log_warning("Got fd for missing session device [%u:%u] in session %s",
+ major(st.st_rdev), minor(st.st_rdev), s->id);
+ close_nointr(fd);
+ continue;
+ }
+
+ log_debug("Attaching fd to session device [%u:%u] for session %s",
+ major(st.st_rdev), minor(st.st_rdev), s->id);
+
+ session_device_attach_fd(sd, fd, s->was_active);
+ }
+
+ return 0;
+}
+
static int manager_enumerate_sessions(Manager *m) {
_cleanup_closedir_ DIR *d = NULL;
struct dirent *de;
- int r = 0;
+ int r = 0, k;
assert(m);
@@ -427,7 +488,6 @@ static int manager_enumerate_sessions(Manager *m) {
FOREACH_DIRENT(de, d, return -errno) {
struct Session *s;
- int k;
if (!dirent_is_file(de))
continue;
@@ -441,7 +501,6 @@ static int manager_enumerate_sessions(Manager *m) {
k = manager_add_session(m, de->d_name, &s);
if (k < 0) {
log_error_errno(k, "Failed to add session by file name %s: %m", de->d_name);
-
r = k;
continue;
}
@@ -453,6 +512,12 @@ static int manager_enumerate_sessions(Manager *m) {
r = k;
}
+ /* We might be restarted and PID1 could have sent us back the
+ * session device fds we previously saved. */
+ k = manager_attach_fds(m);
+ if (k < 0)
+ log_warning_errno(k, "Failed to reattach session device fds: %m");
+
return r;
}
@@ -1004,10 +1069,10 @@ static int manager_parse_config_file(Manager *m) {
assert(m);
return config_parse_many_nulstr(PKGSYSCONFDIR "/logind.conf",
- CONF_PATHS_NULSTR("systemd/logind.conf.d"),
- "Login\0",
- config_item_perf_lookup, logind_gperf_lookup,
- false, m);
+ CONF_PATHS_NULSTR("systemd/logind.conf.d"),
+ "Login\0",
+ config_item_perf_lookup, logind_gperf_lookup,
+ false, m);
}
static int manager_dispatch_reload_signal(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
@@ -1189,7 +1254,7 @@ int main(int argc, char *argv[]) {
goto finish;
}
- log_debug("systemd-logind running as pid "PID_FMT, getpid());
+ log_debug("systemd-logind running as pid "PID_FMT, getpid_cached());
sd_notify(false,
"READY=1\n"
@@ -1197,7 +1262,7 @@ int main(int argc, char *argv[]) {
r = manager_run(m);
- log_debug("systemd-logind stopped as pid "PID_FMT, getpid());
+ log_debug("systemd-logind stopped as pid "PID_FMT, getpid_cached());
finish:
sd_notify(false,
diff --git a/src/login/meson.build b/src/login/meson.build
new file mode 100644
index 0000000000..26bdbec424
--- /dev/null
+++ b/src/login/meson.build
@@ -0,0 +1,104 @@
+systemd_logind_sources = files('''
+ logind.c
+ logind.h
+'''.split())
+
+logind_gperf_c = custom_target(
+ 'logind_gperf.c',
+ input : 'logind-gperf.gperf',
+ output : 'logind-gperf.c',
+ command : [gperf, '@INPUT@', '--output-file', '@OUTPUT@'])
+
+systemd_logind_sources += [logind_gperf_c]
+
+
+liblogind_core_sources = files('''
+ logind-core.c
+ logind-device.c
+ logind-device.h
+ logind-button.c
+ logind-button.h
+ logind-action.c
+ logind-action.h
+ logind-seat.c
+ logind-seat.h
+ logind-session.c
+ logind-session.h
+ logind-session-device.c
+ logind-session-device.h
+ logind-user.c
+ logind-user.h
+ logind-inhibit.c
+ logind-inhibit.h
+ logind-dbus.c
+ logind-session-dbus.c
+ logind-seat-dbus.c
+ logind-user-dbus.c
+ logind-utmp.c
+ logind-acl.h
+'''.split())
+
+logind_acl_c = files('logind-acl.c')
+if conf.get('HAVE_ACL', false)
+ liblogind_core_sources += logind_acl_c
+endif
+
+liblogind_core = static_library(
+ 'logind-core',
+ liblogind_core_sources,
+ include_directories : includes,
+ dependencies : [libacl])
+
+loginctl_sources = files('''
+ loginctl.c
+ sysfs-show.h
+ sysfs-show.c
+'''.split())
+
+if conf.get('ENABLE_LOGIND', false)
+ logind_conf = configure_file(
+ input : 'logind.conf.in',
+ output : 'logind.conf',
+ configuration : substs)
+ install_data(logind_conf,
+ install_dir : pkgsysconfdir)
+
+ pam_systemd_sym = 'src/login/pam_systemd.sym'
+ pam_systemd_c = files('pam_systemd.c')
+
+ install_data('org.freedesktop.login1.conf',
+ install_dir : dbuspolicydir)
+ install_data('org.freedesktop.login1.service',
+ install_dir : dbussystemservicedir)
+
+ custom_target(
+ 'org.freedesktop.login1.policy',
+ input : 'org.freedesktop.login1.policy.in',
+ output : 'org.freedesktop.login1.policy',
+ command : intltool_command,
+ install : install_polkit,
+ install_dir : polkitpolicydir)
+
+ install_data('70-power-switch.rules',
+ '70-uaccess.rules',
+ install_dir : udevrulesdir)
+
+ foreach file : ['71-seat.rules',
+ '73-seat-late.rules']
+ gen = configure_file(
+ input : file + '.in',
+ output : file,
+ configuration : substs)
+ install_data(gen,
+ install_dir : udevrulesdir)
+ endforeach
+
+ custom_target(
+ 'systemd-user',
+ input : 'systemd-user.m4',
+ output: 'systemd-user',
+ command : [m4, '-P'] + m4_defines + ['@INPUT@'],
+ capture : true,
+ install : pamconfdir != 'no',
+ install_dir : pamconfdir)
+endif
diff --git a/src/login/pam_systemd.c b/src/login/pam_systemd.c
index dab082a26e..df16907ed2 100644
--- a/src/login/pam_systemd.c
+++ b/src/login/pam_systemd.c
@@ -41,6 +41,7 @@
#include "login-util.h"
#include "macro.h"
#include "parse-util.h"
+#include "process-util.h"
#include "socket-util.h"
#include "strv.h"
#include "terminal-util.h"
@@ -372,7 +373,7 @@ _public_ PAM_EXTERN int pam_sm_open_session(
if (debug)
pam_syslog(handle, LOG_DEBUG, "Asking logind to create session: "
"uid="UID_FMT" pid="PID_FMT" service=%s type=%s class=%s desktop=%s seat=%s vtnr=%"PRIu32" tty=%s display=%s remote=%s remote_user=%s remote_host=%s",
- pw->pw_uid, getpid(),
+ pw->pw_uid, getpid_cached(),
strempty(service),
type, class, strempty(desktop),
strempty(seat), vtnr, strempty(tty), strempty(display),
@@ -387,7 +388,7 @@ _public_ PAM_EXTERN int pam_sm_open_session(
&reply,
"uusssssussbssa(sv)",
(uint32_t) pw->pw_uid,
- (uint32_t) getpid(),
+ (uint32_t) getpid_cached(),
service,
type,
class,
diff --git a/src/machine/image-dbus.c b/src/machine/image-dbus.c
index 2f69e2c7b7..18e0e34896 100644
--- a/src/machine/image-dbus.c
+++ b/src/machine/image-dbus.c
@@ -17,6 +17,7 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include <sys/file.h>
#include <sys/mount.h>
#include "alloc-util.h"
diff --git a/src/machine/machinectl.c b/src/machine/machinectl.c
index 3031ed5def..a385e6819b 100644
--- a/src/machine/machinectl.c
+++ b/src/machine/machinectl.c
@@ -2694,9 +2694,10 @@ static int help(int argc, char *argv[], void *userdata) {
" --mkdir Create directory before bind mounting, if missing\n"
" -n --lines=INTEGER Number of journal entries to show\n"
" --max-addresses=INTEGER Number of internet addresses to show at most\n"
- " -o --output=STRING Change journal output mode (short,\n"
- " short-monotonic, verbose, export, json,\n"
- " json-pretty, json-sse, cat)\n"
+ " -o --output=STRING Change journal output mode (short, short-precise,\n"
+ " short-iso, short-iso-precise, short-full,\n"
+ " short-monotonic, short-unix, verbose, export,\n"
+ " json, json-pretty, json-sse, cat)\n"
" --verify=MODE Verification mode for downloaded images (no,\n"
" checksum, signature)\n"
" --force Download image even if already exists\n\n"
diff --git a/src/machine/machined.c b/src/machine/machined.c
index 8719e01de9..d8ddbec8b9 100644
--- a/src/machine/machined.c
+++ b/src/machine/machined.c
@@ -34,6 +34,7 @@
#include "label.h"
#include "machine-image.h"
#include "machined.h"
+#include "process-util.h"
#include "signal-util.h"
Manager *manager_new(void) {
@@ -398,7 +399,7 @@ int main(int argc, char *argv[]) {
goto finish;
}
- log_debug("systemd-machined running as pid "PID_FMT, getpid());
+ log_debug("systemd-machined running as pid "PID_FMT, getpid_cached());
sd_notify(false,
"READY=1\n"
@@ -406,7 +407,7 @@ int main(int argc, char *argv[]) {
r = manager_run(m);
- log_debug("systemd-machined stopped as pid "PID_FMT, getpid());
+ log_debug("systemd-machined stopped as pid "PID_FMT, getpid_cached());
finish:
manager_free(m);
diff --git a/src/machine/meson.build b/src/machine/meson.build
new file mode 100644
index 0000000000..1a0813323c
--- /dev/null
+++ b/src/machine/meson.build
@@ -0,0 +1,45 @@
+systemd_machined_sources = files('''
+ machined.c
+ machined.h
+'''.split())
+
+libmachine_core_sources = files('''
+ machine.c
+ machine.h
+ machined-dbus.c
+ machine-dbus.c
+ machine-dbus.h
+ image-dbus.c
+ image-dbus.h
+ operation.c
+ operation.h
+'''.split())
+
+libmachine_core = static_library(
+ 'machine-core',
+ libmachine_core_sources,
+ include_directories : includes,
+ dependencies : [threads])
+
+if conf.get('ENABLE_MACHINED', false)
+ install_data('org.freedesktop.machine1.conf',
+ install_dir : dbuspolicydir)
+ install_data('org.freedesktop.machine1.service',
+ install_dir : dbussystemservicedir)
+
+ custom_target(
+ 'org.freedesktop.machine1.policy',
+ input : 'org.freedesktop.machine1.policy.in',
+ output : 'org.freedesktop.machine1.policy',
+ command : intltool_command,
+ install : install_polkit,
+ install_dir : polkitpolicydir)
+endif
+
+tests += [
+ [['src/machine/test-machine-tables.c'],
+ [libmachine_core,
+ libshared],
+ [threads],
+ 'ENABLE_MACHINED'],
+]
diff --git a/src/machine/operation.c b/src/machine/operation.c
index f7d5310f44..9b2d13dde1 100644
--- a/src/machine/operation.c
+++ b/src/machine/operation.c
@@ -17,6 +17,8 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include <sys/wait.h>
+
#include "alloc-util.h"
#include "fd-util.h"
#include "operation.h"
diff --git a/src/mount/mount-tool.c b/src/mount/mount-tool.c
index b709166aa9..ed6578d540 100644
--- a/src/mount/mount-tool.c
+++ b/src/mount/mount-tool.c
@@ -25,12 +25,16 @@
#include "bus-error.h"
#include "bus-unit-util.h"
#include "bus-util.h"
+#include "dirent-util.h"
#include "escape.h"
+#include "fd-util.h"
+#include "fileio.h"
#include "fstab-util.h"
#include "pager.h"
#include "parse-util.h"
#include "path-util.h"
#include "spawn-polkit-agent.h"
+#include "stat-util.h"
#include "strv.h"
#include "udev-util.h"
#include "unit-name.h"
@@ -77,7 +81,9 @@ static void polkit_agent_open_if_enabled(void) {
}
static void help(void) {
- printf("%s [OPTIONS...] WHAT [WHERE]\n\n"
+ printf("systemd-mount [OPTIONS...] WHAT [WHERE]\n"
+ "systemd-mount [OPTIONS...] --list\n"
+ "%s [OPTIONS...] %sWHAT|WHERE...\n\n"
"Establish a mount or auto-mount point transiently.\n\n"
" -h --help Show this help\n"
" --version Show package version\n"
@@ -100,8 +106,9 @@ 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"
- , program_invocation_short_name);
+ " -u --umount Unmount mount points\n",
+ program_invocation_short_name,
+ streq(program_invocation_short_name, "systemd-umount") ? "" : "--umount ");
}
static int parse_argv(int argc, char *argv[]) {
@@ -297,6 +304,21 @@ static int parse_argv(int argc, char *argv[]) {
log_error("Listing devices only supported locally.");
return -EOPNOTSUPP;
}
+ } else if (arg_action == ACTION_UMOUNT) {
+ if (optind >= argc) {
+ log_error("At least one argument required.");
+ return -EINVAL;
+ }
+
+ if (arg_transport != BUS_TRANSPORT_LOCAL) {
+ int i;
+
+ for (i = optind; i < argc; i++)
+ if (!path_is_absolute(argv[i]) ) {
+ log_error("Only absolute path is supported: %s", argv[i]);
+ return -EINVAL;
+ }
+ }
} else {
if (optind >= argc) {
log_error("At least one argument required.");
@@ -308,14 +330,58 @@ static int parse_argv(int argc, char *argv[]) {
return -EINVAL;
}
- arg_mount_what = fstab_node_to_udev_node(argv[optind]);
- if (!arg_mount_what)
- return log_oom();
+ if (arg_transport == BUS_TRANSPORT_LOCAL) {
+ _cleanup_free_ char *u = NULL, *p = NULL;
- if (argc > optind+1) {
- r = path_make_absolute_cwd(argv[optind+1], &arg_mount_where);
+ u = fstab_node_to_udev_node(argv[optind]);
+ if (!u)
+ return log_oom();
+
+ r = path_make_absolute_cwd(u, &p);
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");
+
+ } else {
+ arg_mount_what = strdup(argv[optind+1]);
+ if (!arg_mount_what)
+ return log_oom();
+
+ path_kill_slashes(arg_mount_what);
+
+ if (!path_is_absolute(arg_mount_what)) {
+ log_error("Only absolute path is supported: %s", arg_mount_what);
+ return -EINVAL;
+ }
+ }
+
+ if (argc > optind+1) {
+ if (arg_transport == BUS_TRANSPORT_LOCAL) {
+ _cleanup_free_ char *p = NULL;
+
+ r = path_make_absolute_cwd(argv[optind+1], &p);
+ 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");
+
+ } else {
+ arg_mount_where = strdup(argv[optind+1]);
+ if (!arg_mount_where)
+ return log_oom();
+
+ path_kill_slashes(arg_mount_where);
+
+ if (!path_is_absolute(arg_mount_where)) {
+ log_error("Only absolute path is supported: %s", arg_mount_where);
+ return -EINVAL;
+ }
+ }
} else
arg_discover = true;
@@ -619,9 +685,127 @@ static int start_transient_automount(
return 0;
}
+static int find_mount_points(const char *what, char ***list) {
+ _cleanup_fclose_ FILE *proc_self_mountinfo = NULL;
+ _cleanup_strv_free_ char **l = NULL;
+ size_t bufsize = 0, n = 0;
+
+ assert(what);
+ assert(list);
+
+ /* Returns all mount points obtained from /proc/self/mountinfo in *list,
+ * and the number of mount points as return value. */
+
+ proc_self_mountinfo = fopen("/proc/self/mountinfo", "re");
+ if (!proc_self_mountinfo)
+ return log_error_errno(errno, "Can't open /proc/self/mountinfo: %m");
+
+ for (;;) {
+ _cleanup_free_ char *path = NULL, *where = NULL, *dev = NULL;
+ int r;
+
+ r = fscanf(proc_self_mountinfo,
+ "%*s " /* (1) mount id */
+ "%*s " /* (2) parent id */
+ "%*s " /* (3) major:minor */
+ "%*s " /* (4) root */
+ "%ms " /* (5) mount point */
+ "%*s" /* (6) mount options */
+ "%*[^-]" /* (7) optional fields */
+ "- " /* (8) separator */
+ "%*s " /* (9) file system type */
+ "%ms" /* (10) mount source */
+ "%*s" /* (11) mount options 2 */
+ "%*[^\n]", /* some rubbish at the end */
+ &path, &dev);
+ if (r != 2) {
+ if (r == EOF)
+ break;
+
+ continue;
+ }
+
+ if (!streq(what, dev))
+ continue;
+
+ r = cunescape(path, UNESCAPE_RELAX, &where);
+ if (r < 0)
+ continue;
+
+ /* one extra slot is needed for the terminating NULL */
+ if (!GREEDY_REALLOC(l, bufsize, n + 2))
+ return log_oom();
+
+ l[n++] = where;
+ where = NULL;
+ }
+
+ if (!GREEDY_REALLOC(l, bufsize, n + 1))
+ return log_oom();
+
+ l[n] = NULL;
+ *list = l;
+ l = NULL; /* avoid freeing */
+
+ return n;
+}
+
+static int find_loop_device(const char *backing_file, char **loop_dev) {
+ _cleanup_closedir_ DIR *d = NULL;
+ struct dirent *de;
+ _cleanup_free_ char *l = NULL;
+
+ assert(backing_file);
+ assert(loop_dev);
+
+ d = opendir("/sys/devices/virtual/block");
+ if (!d)
+ return -errno;
+
+ FOREACH_DIRENT(de, d, return -errno) {
+ _cleanup_free_ char *sys = NULL, *fname = NULL;
+ int r;
+
+ dirent_ensure_type(d, de);
+
+ if (de->d_type != DT_DIR)
+ continue;
+
+ if (!startswith(de->d_name, "loop"))
+ continue;
+
+ sys = strjoin("/sys/devices/virtual/block/", de->d_name, "/loop/backing_file");
+ if (!sys)
+ return -ENOMEM;
+
+ r = read_one_line_file(sys, &fname);
+ if (r < 0) {
+ log_debug_errno(r, "Failed to read %s, ignoring: %m", sys);
+ continue;
+ }
+
+ if (files_same(fname, backing_file, 0) <= 0)
+ continue;
+
+ l = strjoin("/dev/", de->d_name);
+ if (!l)
+ return -ENOMEM;
+
+ break;
+ }
+
+ if (!l)
+ return -ENXIO;
+
+ *loop_dev = l;
+ l = NULL; /* avoid freeing */
+
+ return 0;
+}
+
static int stop_mount(
sd_bus *bus,
- char **argv,
+ const char *where,
const char *suffix) {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL;
@@ -636,9 +820,9 @@ static int stop_mount(
return log_error_errno(r, "Could not watch jobs: %m");
}
- r = unit_name_from_path(arg_mount_where, suffix, &mount_unit);
+ r = unit_name_from_path(where, suffix, &mount_unit);
if (r < 0)
- return log_error_errno(r, "Failed to make mount unit name: %m");
+ return log_error_errno(r, "Failed to make mount unit name from path %s: %m", where);
r = sd_bus_message_new_method_call(
bus,
@@ -680,28 +864,162 @@ static int stop_mount(
if (!arg_quiet)
log_info("Stopped unit %s%s%s for mount point: %s%s%s",
ansi_highlight(), mount_unit, ansi_normal(),
- ansi_highlight(), arg_mount_where, ansi_normal());
+ ansi_highlight(), where, ansi_normal());
return 0;
}
static int stop_mounts(
sd_bus *bus,
- char **argv) {
+ const char *where) {
int r;
- r = stop_mount(bus, argv + optind, ".mount");
+ if (path_equal(where, "/")) {
+ log_error("Refusing to operate on root directory: %s", where);
+ return -EINVAL;
+ }
+
+ if (!path_is_safe(where)) {
+ log_error("Path contains unsafe components: %s", where);
+ return -EINVAL;
+ }
+
+ r = stop_mount(bus, where, ".mount");
if (r < 0)
return r;
- r = stop_mount(bus, argv + optind, ".automount");
+ r = stop_mount(bus, where, ".automount");
if (r < 0)
return r;
return 0;
}
+static int umount_by_device(sd_bus *bus, const char *what) {
+ _cleanup_udev_device_unref_ struct udev_device *d = NULL;
+ _cleanup_udev_unref_ struct udev *udev = NULL;
+ _cleanup_strv_free_ char **list = NULL;
+ struct stat st;
+ const char *v;
+ char **l;
+ int r, r2 = 0;
+
+ assert(what);
+
+ if (stat(what, &st) < 0)
+ return log_error_errno(errno, "Can't stat %s: %m", what);
+
+ if (!S_ISBLK(st.st_mode)) {
+ log_error("Not a block device: %s", what);
+ return -ENOTBLK;
+ }
+
+ udev = udev_new();
+ if (!udev)
+ return log_oom();
+
+ d = udev_device_new_from_devnum(udev, 'b', st.st_rdev);
+ if (!d)
+ return log_oom();
+
+ v = udev_device_get_property_value(d, "ID_FS_USAGE");
+ if (!streq_ptr(v, "filesystem")) {
+ log_error("%s does not contain a known file system.", what);
+ return -EINVAL;
+ }
+
+ v = udev_device_get_property_value(d, "SYSTEMD_MOUNT_WHERE");
+ if (!isempty(v))
+ r2 = stop_mounts(bus, v);
+
+ r = find_mount_points(what, &list);
+ if (r < 0)
+ return r;
+
+ for (l = list; *l; l++) {
+ r = stop_mounts(bus, *l);
+ if (r < 0)
+ r2 = r;
+ }
+
+ return r2;
+}
+
+static int umount_loop(sd_bus *bus, const char *backing_file) {
+ _cleanup_free_ char *loop_dev = NULL;
+ int r;
+
+ assert(backing_file);
+
+ r = find_loop_device(backing_file, &loop_dev);
+ if (r < 0)
+ return log_error_errno(r, r == -ENXIO ? "File %s is not mounted." : "Can't get loop device for %s: %m", backing_file);
+
+ return umount_by_device(bus, loop_dev);
+}
+
+static int action_umount(
+ sd_bus *bus,
+ int argc,
+ char **argv) {
+
+ int i, r, r2 = 0;
+
+ if (arg_transport != BUS_TRANSPORT_LOCAL) {
+ for (i = optind; i < argc; i++) {
+ _cleanup_free_ char *p = NULL;
+
+ p = strdup(argv[i]);
+ if (!p)
+ return log_oom();
+
+ path_kill_slashes(p);
+
+ r = stop_mounts(bus, p);
+ if (r < 0)
+ r2 = r;
+ }
+ return r2;
+ }
+
+ for (i = optind; i < argc; i++) {
+ _cleanup_free_ char *u = NULL, *a = 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);
+ if (r < 0) {
+ r2 = log_error_errno(r, "Failed to make path absolute: %m");
+ continue;
+ }
+
+ p = canonicalize_file_name(a);
+
+ if (stat(p, &st) < 0)
+ return log_error_errno(errno, "Can't stat %s: %m", p);
+
+ if (S_ISBLK(st.st_mode))
+ r = umount_by_device(bus, p);
+ else if (S_ISREG(st.st_mode))
+ r = umount_loop(bus, p);
+ else if (S_ISDIR(st.st_mode))
+ r = stop_mounts(bus, p);
+ else {
+ log_error("Invalid file type: %s", p);
+ r = -EINVAL;
+ }
+
+ if (r < 0)
+ r2 = r;
+ }
+
+ return r2;
+}
+
static int acquire_mount_type(struct udev_device *d) {
const char *v;
@@ -789,6 +1107,8 @@ static int acquire_mount_where(struct udev_device *d) {
}
escaped = xescape(name, "\\");
+ if (!escaped)
+ return log_oom();
if (!filename_is_valid(escaped))
return 0;
@@ -803,6 +1123,32 @@ static int acquire_mount_where(struct udev_device *d) {
return 1;
}
+static int acquire_mount_where_for_loop_dev(const char *loop_dev) {
+ _cleanup_strv_free_ char **list = NULL;
+ int r;
+
+ if (arg_mount_where)
+ return 0;
+
+ r = find_mount_points(loop_dev, &list);
+ if (r < 0)
+ return r;
+ else if (r == 0) {
+ log_error("Can't find mount point of %s. It is expected that %s is already mounted on a place.", loop_dev, loop_dev);
+ return -EINVAL;
+ } else if (r >= 2) {
+ log_error("%s is mounted on %d places. It is expected that %s is mounted on a place.", loop_dev, r, loop_dev);
+ return -EINVAL;
+ }
+
+ arg_mount_where = strdup(list[0]);
+ if (!arg_mount_where)
+ return log_oom();
+
+ log_debug("Discovered where=%s", arg_mount_where);
+ return 1;
+}
+
static int acquire_description(struct udev_device *d) {
const char *model, *label;
@@ -874,27 +1220,97 @@ static int acquire_removable(struct udev_device *d) {
return 1;
}
-static int discover_device(void) {
+static int discover_loop_backing_file(void) {
_cleanup_udev_device_unref_ struct udev_device *d = NULL;
_cleanup_udev_unref_ struct udev *udev = NULL;
+ _cleanup_free_ char *loop_dev = NULL;
struct stat st;
const char *v;
int r;
- if (!arg_discover)
+ r = find_loop_device(arg_mount_what, &loop_dev);
+ if (r < 0 && r != -ENXIO)
+ return log_error_errno(errno, "Can't get loop device for %s: %m", arg_mount_what);
+
+ if (r == -ENXIO) {
+ _cleanup_free_ char *escaped = NULL;
+
+ if (arg_mount_where)
+ return 0;
+
+ escaped = xescape(basename(arg_mount_what), "\\");
+ if (!escaped)
+ return log_oom();
+ if (!filename_is_valid(escaped)) {
+ log_error("Escaped name %s is not a valid filename.", escaped);
+ return -EINVAL;
+ }
+
+ arg_mount_where = strjoin("/run/media/system/", escaped);
+ if (!arg_mount_where)
+ return log_oom();
+
+ log_debug("Discovered where=%s", arg_mount_where);
return 0;
+ }
+
+ if (stat(loop_dev, &st) < 0)
+ return log_error_errno(errno, "Can't stat %s: %m", loop_dev);
- if (!is_device_path(arg_mount_what)) {
- log_error("Discovery only supported for block devices, don't know what to do.");
+ if (!S_ISBLK(st.st_mode)) {
+ log_error("Invalid file type: %s", loop_dev);
return -EINVAL;
}
+ udev = udev_new();
+ if (!udev)
+ return log_oom();
+
+ d = udev_device_new_from_devnum(udev, 'b', st.st_rdev);
+ if (!d)
+ return log_oom();
+
+ v = udev_device_get_property_value(d, "ID_FS_USAGE");
+ if (!streq_ptr(v, "filesystem")) {
+ log_error("%s does not contain a known file system.", arg_mount_what);
+ return -EINVAL;
+ }
+
+ r = acquire_mount_type(d);
+ if (r < 0)
+ return r;
+
+ r = acquire_mount_options(d);
+ if (r < 0)
+ return r;
+
+ r = acquire_mount_where_for_loop_dev(loop_dev);
+ if (r < 0)
+ return r;
+
+ r = acquire_description(d);
+ if (r < 0)
+ return r;
+
+ return 0;
+}
+
+static int discover_device(void) {
+ _cleanup_udev_device_unref_ struct udev_device *d = NULL;
+ _cleanup_udev_unref_ struct udev *udev = NULL;
+ struct stat st;
+ const char *v;
+ int r;
+
if (stat(arg_mount_what, &st) < 0)
return log_error_errno(errno, "Can't stat %s: %m", arg_mount_what);
+ if (S_ISREG(st.st_mode))
+ return discover_loop_backing_file();
+
if (!S_ISBLK(st.st_mode)) {
- log_error("Path %s is not a block device, don't know what to do.", arg_mount_what);
- return -ENOTBLK;
+ log_error("Invalid file type: %s", arg_mount_what);
+ return -EINVAL;
}
udev = udev_new();
@@ -907,7 +1323,7 @@ static int discover_device(void) {
v = udev_device_get_property_value(d, "ID_FS_USAGE");
if (!streq_ptr(v, "filesystem")) {
- log_error("%s does not contain a file system.", arg_mount_what);
+ log_error("%s does not contain a known file system.", arg_mount_what);
return -EINVAL;
}
@@ -1130,17 +1546,35 @@ int main(int argc, char* argv[]) {
goto finish;
}
- r = discover_device();
- if (r < 0)
+ r = bus_connect_transport_systemd(arg_transport, arg_host, arg_user, &bus);
+ if (r < 0) {
+ log_error_errno(r, "Failed to create bus connection: %m");
+ goto finish;
+ }
+
+ if (arg_action == ACTION_UMOUNT) {
+ r = action_umount(bus, argc, argv);
+ goto finish;
+ }
+
+ if (!path_is_safe(arg_mount_what)) {
+ log_error("Path contains unsafe components: %s", arg_mount_what);
+ r = -EINVAL;
goto finish;
+ }
+
+ if (arg_discover) {
+ r = discover_device();
+ if (r < 0)
+ goto finish;
+ }
+
if (!arg_mount_where) {
log_error("Can't figure out where to mount %s.", arg_mount_what);
r = -EINVAL;
goto finish;
}
- path_kill_slashes(arg_mount_where);
-
if (path_equal(arg_mount_where, "/")) {
log_error("Refusing to operate on root directory.");
r = -EINVAL;
@@ -1148,7 +1582,7 @@ int main(int argc, char* argv[]) {
}
if (!path_is_safe(arg_mount_where)) {
- log_error("Path is contains unsafe components.");
+ log_error("Path contains unsafe components: %s", arg_mount_where);
r = -EINVAL;
goto finish;
}
@@ -1171,12 +1605,6 @@ int main(int argc, char* argv[]) {
}
}
- r = bus_connect_transport_systemd(arg_transport, arg_host, arg_user, &bus);
- if (r < 0) {
- log_error_errno(r, "Failed to create bus connection: %m");
- goto finish;
- }
-
switch (arg_action) {
case ACTION_MOUNT:
@@ -1188,10 +1616,6 @@ int main(int argc, char* argv[]) {
r = start_transient_automount(bus, argv + optind);
break;
- case ACTION_UMOUNT:
- r = stop_mounts(bus, argv + optind);
- break;
-
default:
assert_not_reached("Unexpected action.");
}
diff --git a/src/network/meson.build b/src/network/meson.build
new file mode 100644
index 0000000000..35ecd86379
--- /dev/null
+++ b/src/network/meson.build
@@ -0,0 +1,150 @@
+sources = files('''
+ netdev/bond.c
+ netdev/bond.h
+ netdev/bridge.c
+ netdev/bridge.h
+ netdev/dummy.c
+ netdev/dummy.h
+ netdev/ipvlan.c
+ netdev/ipvlan.h
+ netdev/macvlan.c
+ netdev/macvlan.h
+ netdev/netdev.c
+ netdev/netdev.h
+ netdev/tunnel.c
+ netdev/tunnel.h
+ netdev/tuntap.c
+ netdev/tuntap.h
+ netdev/vcan.c
+ netdev/vcan.h
+ netdev/veth.c
+ netdev/veth.h
+ netdev/vlan.c
+ netdev/vlan.h
+ netdev/vrf.c
+ netdev/vrf.h
+ netdev/vxlan.c
+ netdev/vxlan.h
+ netdev/geneve.c
+ netdev/geneve.h
+ networkd-address-label.c
+ networkd-address-label.h
+ networkd-address-pool.c
+ networkd-address-pool.h
+ networkd-address.c
+ networkd-address.h
+ networkd-brvlan.c
+ networkd-brvlan.h
+ networkd-conf.c
+ networkd-conf.h
+ networkd-dhcp4.c
+ networkd-dhcp6.c
+ networkd-fdb.c
+ networkd-fdb.h
+ networkd-ipv4ll.c
+ networkd-ipv6-proxy-ndp.c
+ networkd-ipv6-proxy-ndp.h
+ networkd-link-bus.c
+ networkd-link.c
+ networkd-link.h
+ networkd-lldp-tx.c
+ networkd-lldp-tx.h
+ networkd-manager-bus.c
+ networkd-manager.c
+ networkd-manager.h
+ networkd-ndisc.c
+ networkd-ndisc.h
+ networkd-radv.c
+ networkd-radv.h
+ networkd-network-bus.c
+ networkd-network.c
+ networkd-network.h
+ networkd-route.c
+ networkd-route.h
+ networkd-util.c
+ networkd-util.h
+'''.split())
+
+systemd_networkd_sources = files('networkd.c')
+
+systemd_networkd_wait_online_sources = files('''
+ wait-online/link.c
+ wait-online/link.h
+ wait-online/manager.c
+ wait-online/manager.h
+ wait-online/wait-online.c
+'''.split()) + network_internal_h
+
+networkctl_sources = files('networkctl.c')
+
+network_include_dir = include_directories('.')
+
+if conf.get('ENABLE_NETWORKD', false)
+ networkd_gperf_c = custom_target(
+ 'networkd-gperf.c',
+ input : 'networkd-gperf.gperf',
+ output : 'networkd-gperf.c',
+ command : [gperf, '@INPUT@', '--output-file', '@OUTPUT@'])
+
+ networkd_network_gperf_c = custom_target(
+ 'networkd-network-gperf.c',
+ input : 'networkd-network-gperf.gperf',
+ output : 'networkd-network-gperf.c',
+ command : [gperf, '@INPUT@', '--output-file', '@OUTPUT@'])
+
+ netdev_gperf_c = custom_target(
+ 'netdev-gperf.c',
+ input : 'netdev/netdev-gperf.gperf',
+ output : 'netdev-gperf.c',
+ command : [gperf, '@INPUT@', '--output-file', '@OUTPUT@'])
+
+ libnetworkd_core = static_library(
+ 'networkd-core',
+ sources,
+ network_internal_h,
+ networkd_gperf_c,
+ networkd_network_gperf_c,
+ netdev_gperf_c,
+ include_directories : includes,
+ link_with : [libshared])
+
+ install_data('org.freedesktop.network1.conf',
+ install_dir : dbuspolicydir)
+ install_data('org.freedesktop.network1.service',
+ install_dir : dbussystemservicedir)
+ if install_polkit
+ install_data('systemd-networkd.rules',
+ install_dir : polkitrulesdir)
+ endif
+ if install_polkit_pkla
+ install_data('systemd-networkd.pkla',
+ install_dir : polkitpkladir)
+ endif
+
+ tests += [
+ [['src/network/test-networkd-conf.c'],
+ [libnetworkd_core,
+ libsystemd_network,
+ libudev],
+ []],
+
+ [['src/network/test-network.c'],
+ [libnetworkd_core,
+ libudev_internal,
+ libsystemd_network,
+ libshared],
+ [threads]],
+
+ [['src/network/test-network-tables.c',
+ 'src/network/test-network-tables.c',
+ test_tables_h],
+ [libnetworkd_core,
+ libudev_internal,
+ libudev_core,
+ libsystemd_network,
+ libshared],
+ [threads],
+ '', '', [],
+ [network_include_dir] + libudev_core_includes],
+ ]
+endif
diff --git a/src/network/netdev/bridge.c b/src/network/netdev/bridge.c
index 9fdcb55376..cf6c591f8b 100644
--- a/src/network/netdev/bridge.c
+++ b/src/network/netdev/bridge.c
@@ -24,6 +24,7 @@
#include "netlink-util.h"
#include "netdev/bridge.h"
#include "networkd-manager.h"
+#include "vlan-util.h"
/* callback for brige netdev's parameter set */
static int netdev_bridge_set_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
@@ -102,7 +103,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_PRIORITY attribute: %m");
}
- if (b->default_pvid > 0) {
+ if (b->default_pvid != VLANID_INVALID) {
r = sd_netlink_message_append_u16(req, IFLA_BR_VLAN_DEFAULT_PVID, b->default_pvid);
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not append IFLA_BR_VLAN_DEFAULT_PVID attribute: %m");
@@ -160,6 +161,7 @@ static void bridge_init(NetDev *n) {
b->mcast_snooping = -1;
b->vlan_filtering = -1;
b->stp = -1;
+ b->default_pvid = VLANID_INVALID;
b->forward_delay = USEC_INFINITY;
}
diff --git a/src/network/netdev/geneve.c b/src/network/netdev/geneve.c
new file mode 100644
index 0000000000..e71ea58a10
--- /dev/null
+++ b/src/network/netdev/geneve.c
@@ -0,0 +1,315 @@
+/***
+ 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 <net/if.h>
+
+#include "alloc-util.h"
+#include "conf-parser.h"
+#include "extract-word.h"
+#include "geneve.h"
+#include "parse-util.h"
+#include "sd-netlink.h"
+#include "string-util.h"
+#include "strv.h"
+#include "missing.h"
+#include "networkd-manager.h"
+
+#define GENEVE_FLOW_LABEL_MAX_MASK 0xFFFFFU
+#define DEFAULT_GENEVE_DESTINATION_PORT 6081
+
+/* callback for geneve netdev's created without a backing Link */
+static int geneve_netdev_create_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
+ _cleanup_netdev_unref_ NetDev *netdev = userdata;
+ int r;
+
+ assert(netdev->state != _NETDEV_STATE_INVALID);
+
+ r = sd_netlink_message_get_errno(m);
+ if (r == -EEXIST)
+ log_netdev_info(netdev, "Geneve netdev exists, using existing without changing its parameters");
+ else if (r < 0) {
+ log_netdev_warning_errno(netdev, r, "Geneve netdev could not be created: %m");
+ netdev_drop(netdev);
+
+ return 1;
+ }
+
+ log_netdev_debug(netdev, "Geneve created");
+
+ return 1;
+}
+
+static int netdev_geneve_create(NetDev *netdev) {
+ _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
+ Geneve *v;
+ int r;
+
+ assert(netdev);
+
+ v = GENEVE(netdev);
+
+ r = sd_rtnl_message_new_link(netdev->manager->rtnl, &m, RTM_NEWLINK, 0);
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not allocate RTM_NEWLINK message: %m");
+
+ r = sd_netlink_message_append_string(m, IFLA_IFNAME, netdev->ifname);
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_IFNAME, attribute: %m");
+
+ if (netdev->mac) {
+ r = sd_netlink_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac);
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_ADDRESS attribute: %m");
+ }
+
+ if (netdev->mtu) {
+ r = sd_netlink_message_append_u32(m, IFLA_MTU, netdev->mtu);
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_MTU attribute: %m");
+ }
+
+ r = sd_netlink_message_open_container(m, IFLA_LINKINFO);
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_LINKINFO attribute: %m");
+
+ r = sd_netlink_message_open_container_union(m, IFLA_INFO_DATA, netdev_kind_to_string(netdev->kind));
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_INFO_DATA attribute: %m");
+
+ if (v->id <= GENEVE_VID_MAX) {
+ r = sd_netlink_message_append_u32(m, IFLA_GENEVE_ID, v->id);
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_GENEVE_ID attribute: %m");
+ }
+
+ if (!in_addr_is_null(v->remote_family, &v->remote)) {
+
+ if (v->remote_family == AF_INET)
+ r = sd_netlink_message_append_in_addr(m, IFLA_GENEVE_REMOTE, &v->remote.in);
+ else
+ r = sd_netlink_message_append_in6_addr(m, IFLA_GENEVE_REMOTE6, &v->remote.in6);
+
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_GENEVE_GROUP attribute: %m");
+
+ }
+
+ if (v->ttl) {
+ r = sd_netlink_message_append_u8(m, IFLA_GENEVE_TTL, v->ttl);
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_GENEVE_TTL attribute: %m");
+ }
+
+ r = sd_netlink_message_append_u8(m, IFLA_GENEVE_TOS, v->tos);
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_GENEVE_TOS attribute: %m");
+
+ r = sd_netlink_message_append_u8(m, IFLA_GENEVE_UDP_CSUM, v->udpcsum);
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_GENEVE_UDP_CSUM attribute: %m");
+
+ r = sd_netlink_message_append_u8(m, IFLA_GENEVE_UDP_ZERO_CSUM6_TX, v->udp6zerocsumtx);
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_GENEVE_UDP_ZERO_CSUM6_TX attribute: %m");
+
+ r = sd_netlink_message_append_u8(m, IFLA_GENEVE_UDP_ZERO_CSUM6_RX, v->udp6zerocsumrx);
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_GENEVE_UDP_ZERO_CSUM6_RX attribute: %m");
+
+ if (v->dest_port != DEFAULT_GENEVE_DESTINATION_PORT) {
+ r = sd_netlink_message_append_u16(m, IFLA_GENEVE_PORT, htobe16(v->dest_port));
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_GENEVE_PORT attribute: %m");
+ }
+
+ if (v->flow_label > 0) {
+ r = sd_netlink_message_append_u32(m, IFLA_GENEVE_LABEL, htobe32(v->flow_label));
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_GENEVE_LABEL attribute: %m");
+ }
+
+ r = sd_netlink_message_close_container(m);
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_INFO_DATA attribute: %m");
+
+ r = sd_netlink_message_close_container(m);
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_LINKINFO attribute: %m");
+
+ r = sd_netlink_call_async(netdev->manager->rtnl, m, geneve_netdev_create_handler, netdev, 0, NULL);
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not send rtnetlink message: %m");
+
+ netdev_ref(netdev);
+
+ netdev->state = NETDEV_STATE_CREATING;
+
+ log_netdev_debug(netdev, "Creating");
+
+
+ return r;
+}
+
+int config_parse_geneve_vni(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) {
+ Geneve *v = userdata;
+ uint32_t f;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ r = safe_atou32(rvalue, &f);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse Geneve VNI '%s'.", rvalue);
+ return 0;
+ }
+
+ if (f > GENEVE_VID_MAX){
+ log_syntax(unit, LOG_ERR, filename, line, r, "Geneve VNI out is of range '%s'.", rvalue);
+ return 0;
+ }
+
+ v->id = f;
+
+ return 0;
+}
+
+int config_parse_geneve_address(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) {
+ Geneve *v = userdata;
+ union in_addr_union *addr = data, buffer;
+ int r, f;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ r = in_addr_from_string_auto(rvalue, &f, &buffer);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "geneve '%s' address is invalid, ignoring assignment: %s", lvalue, rvalue);
+ return 0;
+ }
+
+ r = in_addr_is_multicast(f, &buffer);
+ if (r > 0) {
+ log_syntax(unit, LOG_ERR, filename, line, 0, "geneve invalid multicast '%s' address, ignoring assignment: %s", lvalue, rvalue);
+ return 0;
+ }
+
+ v->remote_family = f;
+ *addr = buffer;
+
+ return 0;
+}
+
+int config_parse_geneve_flow_label(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) {
+ Geneve *v = userdata;
+ uint32_t f;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ r = safe_atou32(rvalue, &f);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse Geneve flow label '%s'.", rvalue);
+ return 0;
+ }
+
+ if (f & ~GENEVE_FLOW_LABEL_MAX_MASK) {
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "Geneve flow label '%s' not valid. Flow label range should be [0-1048575].", rvalue);
+ return 0;
+ }
+
+ v->flow_label = f;
+
+ return 0;
+}
+
+static int netdev_geneve_verify(NetDev *netdev, const char *filename) {
+ Geneve *v = GENEVE(netdev);
+
+ assert(netdev);
+ assert(v);
+ assert(filename);
+
+ if (v->ttl == 0) {
+ log_warning("Invalid Geneve TTL value '0' configured in '%s'. Ignoring", filename);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void geneve_init(NetDev *netdev) {
+ Geneve *v;
+
+ assert(netdev);
+
+ v = GENEVE(netdev);
+
+ assert(v);
+
+ v->id = GENEVE_VID_MAX + 1;
+ v->dest_port = DEFAULT_GENEVE_DESTINATION_PORT;
+ v->udpcsum = false;
+ v->udp6zerocsumtx = false;
+ v->udp6zerocsumrx = false;
+}
+
+const NetDevVTable geneve_vtable = {
+ .object_size = sizeof(Geneve),
+ .init = geneve_init,
+ .sections = "Match\0NetDev\0GENEVE\0",
+ .create = netdev_geneve_create,
+ .create_type = NETDEV_CREATE_INDEPENDENT,
+ .config_verify = netdev_geneve_verify,
+};
diff --git a/src/network/netdev/geneve.h b/src/network/netdev/geneve.h
new file mode 100644
index 0000000000..bde28bac55
--- /dev/null
+++ b/src/network/netdev/geneve.h
@@ -0,0 +1,85 @@
+#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 Geneve Geneve;
+
+#include "in-addr-util.h"
+#include "netdev.h"
+#include "networkd-link.h"
+#include "networkd-network.h"
+
+#define GENEVE_VID_MAX (1u << 24) - 1
+
+struct Geneve {
+ NetDev meta;
+
+ uint32_t id;
+ uint32_t flow_label;
+
+ int remote_family;
+
+ uint8_t tos;
+ uint8_t ttl;
+
+ uint16_t dest_port;
+
+ bool udpcsum;
+ bool udp6zerocsumtx;
+ bool udp6zerocsumrx;
+
+ union in_addr_union remote;
+};
+
+DEFINE_NETDEV_CAST(GENEVE, Geneve);
+extern const NetDevVTable geneve_vtable;
+
+int config_parse_geneve_vni(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_geneve_address(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_geneve_flow_label(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/netdev/netdev-gperf.gperf b/src/network/netdev/netdev-gperf.gperf
index e19fa9817e..8b235a4857 100644
--- a/src/network/netdev/netdev-gperf.gperf
+++ b/src/network/netdev/netdev-gperf.gperf
@@ -4,6 +4,7 @@
#include "network-internal.h"
#include "netdev/bond.h"
#include "netdev/bridge.h"
+#include "netdev/geneve.h"
#include "netdev/ipvlan.h"
#include "netdev/macvlan.h"
#include "netdev/tunnel.h"
@@ -36,6 +37,10 @@ NetDev.Kind, config_parse_netdev_kind, 0,
NetDev.MTUBytes, config_parse_iec_size, 0, offsetof(NetDev, mtu)
NetDev.MACAddress, config_parse_hwaddr, 0, offsetof(NetDev, mac)
VLAN.Id, config_parse_vlanid, 0, offsetof(VLan, id)
+VLAN.GVRP, config_parse_tristate, 0, offsetof(VLan, gvrp)
+VLAN.MVRP, config_parse_tristate, 0, offsetof(VLan, mvrp)
+VLAN.LooseBinding, config_parse_tristate, 0, offsetof(VLan, loose_binding)
+VLAN.ReorderHeader, config_parse_tristate, 0, offsetof(VLan, reorder_hdr)
MACVLAN.Mode, config_parse_macvlan_mode, 0, offsetof(MacVlan, mode)
MACVTAP.Mode, config_parse_macvlan_mode, 0, offsetof(MacVlan, mode)
IPVLAN.Mode, config_parse_ipvlan_mode, 0, offsetof(IPVlan, mode)
@@ -77,7 +82,17 @@ VXLAN.FDBAgeingSec, config_parse_sec, 0,
VXLAN.GroupPolicyExtension, config_parse_bool, 0, offsetof(VxLan, group_policy)
VXLAN.MaximumFDBEntries, config_parse_unsigned, 0, offsetof(VxLan, max_fdb)
VXLAN.PortRange, config_parse_port_range, 0, 0
-VXLAN.DestinationPort, config_parse_destination_port, 0, offsetof(VxLan, dest_port)
+VXLAN.DestinationPort, config_parse_ip_port, 0, offsetof(VxLan, dest_port)
+VXLAN.FlowLabel, config_parse_flow_label, 0, 0
+GENEVE.Id, config_parse_geneve_vni, 0, offsetof(Geneve, id)
+GENEVE.Remote, config_parse_geneve_address, 0, offsetof(Geneve, remote)
+GENEVE.TOS, config_parse_uint8, 0, offsetof(Geneve, tos)
+GENEVE.TTL, config_parse_uint8, 0, offsetof(Geneve, ttl)
+GENEVE.UDPChecksum, config_parse_bool, 0, offsetof(Geneve, udpcsum)
+GENEVE.UDP6ZeroCheckSumRx, config_parse_bool, 0, offsetof(Geneve, udp6zerocsumrx)
+GENEVE.UDP6ZeroCheckSumTx, config_parse_bool, 0, offsetof(Geneve, udp6zerocsumtx)
+GENEVE.DestinationPort, config_parse_ip_port, 0, offsetof(Geneve, dest_port)
+GENEVE.FlowLabel, config_parse_geneve_flow_label, 0, 0
Tun.OneQueue, config_parse_bool, 0, offsetof(TunTap, one_queue)
Tun.MultiQueue, config_parse_bool, 0, offsetof(TunTap, multi_queue)
Tun.PacketInfo, config_parse_bool, 0, offsetof(TunTap, packet_info)
@@ -113,7 +128,7 @@ Bridge.MaxAgeSec, config_parse_sec, 0,
Bridge.AgeingTimeSec, config_parse_sec, 0, offsetof(Bridge, ageing_time)
Bridge.ForwardDelaySec, config_parse_sec, 0, offsetof(Bridge, forward_delay)
Bridge.Priority, config_parse_uint16, 0, offsetof(Bridge, priority)
-Bridge.DefaultPVID, config_parse_vlanid, 0, offsetof(Bridge, default_pvid)
+Bridge.DefaultPVID, config_parse_default_port_vlanid, 0, offsetof(Bridge, default_pvid)
Bridge.MulticastQuerier, config_parse_tristate, 0, offsetof(Bridge, mcast_querier)
Bridge.MulticastSnooping, config_parse_tristate, 0, offsetof(Bridge, mcast_snooping)
Bridge.VLANFiltering, config_parse_tristate, 0, offsetof(Bridge, vlan_filtering)
diff --git a/src/network/netdev/netdev.c b/src/network/netdev/netdev.c
index f70117e6f9..43884581ca 100644
--- a/src/network/netdev/netdev.c
+++ b/src/network/netdev/netdev.c
@@ -36,6 +36,7 @@
#include "netdev/bridge.h"
#include "netdev/bond.h"
+#include "netdev/geneve.h"
#include "netdev/vlan.h"
#include "netdev/macvlan.h"
#include "netdev/ipvlan.h"
@@ -70,6 +71,7 @@ const NetDevVTable * const netdev_vtable[_NETDEV_KIND_MAX] = {
[NETDEV_KIND_IP6TNL] = &ip6tnl_vtable,
[NETDEV_KIND_VRF] = &vrf_vtable,
[NETDEV_KIND_VCAN] = &vcan_vtable,
+ [NETDEV_KIND_GENEVE] = &geneve_vtable,
};
static const char* const netdev_kind_table[_NETDEV_KIND_MAX] = {
@@ -95,6 +97,7 @@ static const char* const netdev_kind_table[_NETDEV_KIND_MAX] = {
[NETDEV_KIND_IP6TNL] = "ip6tnl",
[NETDEV_KIND_VRF] = "vrf",
[NETDEV_KIND_VCAN] = "vcan",
+ [NETDEV_KIND_GENEVE] = "geneve",
};
DEFINE_STRING_TABLE_LOOKUP(netdev_kind, NetDevKind);
diff --git a/src/network/netdev/netdev.h b/src/network/netdev/netdev.h
index 37c7431213..a961e2ac3b 100644
--- a/src/network/netdev/netdev.h
+++ b/src/network/netdev/netdev.h
@@ -57,6 +57,7 @@ typedef enum NetDevKind {
NETDEV_KIND_TAP,
NETDEV_KIND_VRF,
NETDEV_KIND_VCAN,
+ NETDEV_KIND_GENEVE,
_NETDEV_KIND_MAX,
_NETDEV_KIND_INVALID = -1
} NetDevKind;
diff --git a/src/network/netdev/vlan.c b/src/network/netdev/vlan.c
index 28c061fa4f..6f41633ead 100644
--- a/src/network/netdev/vlan.c
+++ b/src/network/netdev/vlan.c
@@ -17,12 +17,14 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include <linux/if_vlan.h>
#include <net/if.h>
#include "netdev/vlan.h"
#include "vlan-util.h"
static int netdev_vlan_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *req) {
+ struct ifla_vlan_flags flags = {};
VLan *v;
int r;
@@ -38,6 +40,30 @@ static int netdev_vlan_fill_message_create(NetDev *netdev, Link *link, sd_netlin
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not append IFLA_VLAN_ID attribute: %m");
+ if (v->gvrp != -1) {
+ flags.mask |= VLAN_FLAG_GVRP;
+ SET_FLAG(flags.flags, VLAN_FLAG_GVRP, v->gvrp);
+ }
+
+ if (v->mvrp != -1) {
+ flags.mask |= VLAN_FLAG_MVRP;
+ SET_FLAG(flags.flags, VLAN_FLAG_MVRP, v->mvrp);
+ }
+
+ if (v->reorder_hdr != -1) {
+ flags.mask |= VLAN_FLAG_REORDER_HDR;
+ SET_FLAG(flags.flags, VLAN_FLAG_REORDER_HDR, v->reorder_hdr);
+ }
+
+ if (v->loose_binding != -1) {
+ flags.mask |= VLAN_FLAG_LOOSE_BINDING;
+ SET_FLAG(flags.flags, VLAN_FLAG_LOOSE_BINDING, v->loose_binding);
+ }
+
+ r = sd_netlink_message_append_data(req, IFLA_VLAN_FLAGS, &flags, sizeof(struct ifla_vlan_flags));
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_VLAN_FLAGS attribute: %m");
+
return 0;
}
@@ -66,6 +92,10 @@ static void vlan_init(NetDev *netdev) {
assert(v);
v->id = VLANID_INVALID;
+ v->gvrp = -1;
+ v->mvrp = -1;
+ v->loose_binding = -1;
+ v->reorder_hdr = -1;
}
const NetDevVTable vlan_vtable = {
diff --git a/src/network/netdev/vlan.h b/src/network/netdev/vlan.h
index fade899997..780d61262a 100644
--- a/src/network/netdev/vlan.h
+++ b/src/network/netdev/vlan.h
@@ -27,6 +27,11 @@ struct VLan {
NetDev meta;
uint16_t id;
+
+ int gvrp;
+ int mvrp;
+ int loose_binding;
+ int reorder_hdr;
};
DEFINE_NETDEV_CAST(VLAN, VLan);
diff --git a/src/network/netdev/vxlan.c b/src/network/netdev/vxlan.c
index b677b000fd..b5b7aec2c0 100644
--- a/src/network/netdev/vxlan.c
+++ b/src/network/netdev/vxlan.c
@@ -157,6 +157,10 @@ static int netdev_vxlan_fill_message_create(NetDev *netdev, Link *link, sd_netli
return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_PORT_RANGE attribute: %m");
}
+ r = sd_netlink_message_append_u32(m, IFLA_VXLAN_LABEL, htobe32(v->flow_label));
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_LABEL attribute: %m");
+
if (v->group_policy) {
r = sd_netlink_message_append_flag(m, IFLA_VXLAN_GBP);
if (r < 0)
@@ -267,18 +271,18 @@ int config_parse_port_range(const char *unit,
return 0;
}
-int config_parse_destination_port(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_flow_label(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) {
VxLan *v = userdata;
- uint16_t port;
+ unsigned f;
int r;
assert(filename);
@@ -286,13 +290,19 @@ int config_parse_destination_port(const char *unit,
assert(rvalue);
assert(data);
- r = parse_ip_port(rvalue, &port);
+ r = safe_atou(rvalue, &f);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse VXLAN destination port '%s'.", rvalue);
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse VXLAN flow label '%s'.", rvalue);
+ return 0;
+ }
+
+ if (f & ~VXLAN_FLOW_LABEL_MAX_MASK) {
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "VXLAN flow label '%s' not valid. Flow label range should be [0-1048575].", rvalue);
return 0;
}
- v->dest_port = port;
+ v->flow_label = f;
return 0;
}
diff --git a/src/network/netdev/vxlan.h b/src/network/netdev/vxlan.h
index dca58e7fe6..1eeda022a2 100644
--- a/src/network/netdev/vxlan.h
+++ b/src/network/netdev/vxlan.h
@@ -25,6 +25,7 @@ typedef struct VxLan VxLan;
#include "netdev/netdev.h"
#define VXLAN_VID_MAX (1u << 24) - 1
+#define VXLAN_FLOW_LABEL_MAX_MASK 0xFFFFFU
struct VxLan {
NetDev meta;
@@ -40,6 +41,7 @@ struct VxLan {
unsigned tos;
unsigned ttl;
unsigned max_fdb;
+ unsigned flow_label;
uint16_t dest_port;
@@ -84,13 +86,13 @@ int config_parse_port_range(const char *unit,
void *data,
void *userdata);
-int config_parse_destination_port(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_flow_label(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/networkctl.c b/src/network/networkctl.c
index 6f7f41bf7d..54d54c8fd5 100644
--- a/src/network/networkctl.c
+++ b/src/network/networkctl.c
@@ -18,6 +18,7 @@
***/
#include <getopt.h>
+#include <linux/if_addrlabel.h>
#include <net/if.h>
#include <stdbool.h>
@@ -35,6 +36,7 @@
#include "hwdb-util.h"
#include "local-addresses.h"
#include "locale-util.h"
+#include "macro.h"
#include "netlink-util.h"
#include "pager.h"
#include "parse-util.h"
@@ -569,6 +571,76 @@ static int dump_addresses(
return 0;
}
+static int dump_address_labels(sd_netlink *rtnl) {
+ _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
+ sd_netlink_message *m;
+ int r;
+
+ assert(rtnl);
+
+ r = sd_rtnl_message_new_addrlabel(rtnl, &req, RTM_GETADDRLABEL, 0, AF_INET6);
+ if (r < 0)
+ return log_error_errno(r, "Could not allocate RTM_GETADDRLABEL message: %m");
+
+ r = sd_netlink_message_request_dump(req, true);
+ if (r < 0)
+ return r;
+
+ r = sd_netlink_call(rtnl, req, 0, &reply);
+ if (r < 0)
+ return r;
+
+ printf("%10s/%s %30s\n", "Prefix", "Prefixlen", "Label");
+
+ for (m = reply; m; m = sd_netlink_message_next(m)) {
+ _cleanup_free_ char *pretty = NULL;
+ union in_addr_union prefix = {};
+ uint8_t prefixlen;
+ uint32_t label;
+
+ r = sd_netlink_message_get_errno(m);
+ if (r < 0) {
+ log_error_errno(r, "got error: %m");
+ continue;
+ }
+
+ r = sd_netlink_message_read_u32(m, IFAL_LABEL, &label);
+ if (r < 0 && r != -ENODATA) {
+ log_error_errno(r, "Could not read IFAL_LABEL, ignoring: %m");
+ continue;
+ }
+
+ r = sd_netlink_message_read_in6_addr(m, IFAL_ADDRESS, &prefix.in6);
+ if (r < 0)
+ continue;
+
+ r = in_addr_to_string(AF_INET6, &prefix, &pretty);
+ if (r < 0)
+ continue;
+
+ r = sd_rtnl_message_addrlabel_get_prefixlen(m, &prefixlen);
+ if (r < 0)
+ continue;
+
+ printf("%10s/%-5u %30u\n", pretty, prefixlen, label);
+ }
+
+ return 0;
+}
+
+static int list_address_labels(int argc, char *argv[], void *userdata) {
+ _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
+ int r;
+
+ r = sd_netlink_open(&rtnl);
+ if (r < 0)
+ return log_error_errno(r, "Failed to connect to netlink: %m");
+
+ dump_address_labels(rtnl);
+
+ return 0;
+}
+
static int open_lldp_neighbors(int ifindex, FILE **ret) {
_cleanup_free_ char *p = NULL;
FILE *f;
@@ -1043,6 +1115,7 @@ static void help(void) {
" list [LINK...] List links\n"
" status [LINK...] Show link status\n"
" lldp [LINK...] Show LLDP neighbors\n"
+ " label Show current address label entries in the kernel\n"
, program_invocation_short_name);
}
@@ -1107,6 +1180,7 @@ static int networkctl_main(int argc, char *argv[]) {
{ "list", VERB_ANY, VERB_ANY, VERB_DEFAULT, list_links },
{ "status", VERB_ANY, VERB_ANY, 0, link_status },
{ "lldp", VERB_ANY, VERB_ANY, 0, link_lldp_status },
+ { "label", VERB_ANY, VERB_ANY, 0, list_address_labels},
{}
};
diff --git a/src/network/networkd-address-label.c b/src/network/networkd-address-label.c
new file mode 100644
index 0000000000..b89995ec44
--- /dev/null
+++ b/src/network/networkd-address-label.c
@@ -0,0 +1,223 @@
+/***
+ 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 <net/if.h>
+#include <linux/if_addrlabel.h>
+
+#include "alloc-util.h"
+#include "conf-parser.h"
+#include "networkd-address-label.h"
+#include "netlink-util.h"
+#include "networkd-manager.h"
+#include "parse-util.h"
+#include "socket-util.h"
+
+int address_label_new(AddressLabel **ret) {
+ _cleanup_address_label_free_ AddressLabel *addrlabel = NULL;
+
+ addrlabel = new0(AddressLabel, 1);
+ if (!addrlabel)
+ return -ENOMEM;
+
+ *ret = addrlabel;
+ addrlabel = NULL;
+
+ return 0;
+}
+
+void address_label_free(AddressLabel *label) {
+ if (!label)
+ return;
+
+ if (label->network) {
+ LIST_REMOVE(labels, label->network->address_labels, label);
+ assert(label->network->n_address_labels > 0);
+ label->network->n_address_labels--;
+
+ if (label->section) {
+ hashmap_remove(label->network->address_labels_by_section, label->section);
+ network_config_section_free(label->section);
+ }
+ }
+
+ free(label);
+}
+
+static int address_label_new_static(Network *network, const char *filename, unsigned section_line, AddressLabel **ret) {
+ _cleanup_network_config_section_free_ NetworkConfigSection *n = NULL;
+ _cleanup_address_label_free_ AddressLabel *label = NULL;
+ int r;
+
+ assert(network);
+ assert(ret);
+ assert(!!filename == (section_line > 0));
+
+ r = network_config_section_new(filename, section_line, &n);
+ if (r < 0)
+ return r;
+
+ label = hashmap_get(network->address_labels_by_section, n);
+ if (label) {
+ *ret = label;
+ label = NULL;
+
+ return 0;
+ }
+
+ r = address_label_new(&label);
+ if (r < 0)
+ return r;
+
+ label->section = n;
+ n = NULL;
+
+ r = hashmap_put(network->address_labels_by_section, label->section, label);
+ if (r < 0)
+ return r;
+
+ label->network = network;
+ LIST_APPEND(labels, network->address_labels, label);
+ network->n_address_labels++;
+
+ *ret = label;
+ label = NULL;
+
+ return 0;
+}
+
+int address_label_configure(
+ AddressLabel *label,
+ Link *link,
+ sd_netlink_message_handler_t callback,
+ bool update) {
+
+ _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
+ int r;
+
+ assert(label);
+ assert(link);
+ assert(link->ifindex > 0);
+ assert(link->manager);
+ assert(link->manager->rtnl);
+
+ r = sd_rtnl_message_new_addrlabel(link->manager->rtnl, &req, RTM_NEWADDRLABEL,
+ link->ifindex, AF_INET6);
+ if (r < 0)
+ return log_error_errno(r, "Could not allocate RTM_NEWADDR message: %m");
+
+ r = sd_rtnl_message_addrlabel_set_prefixlen(req, label->prefixlen);
+ if (r < 0)
+ return log_error_errno(r, "Could not set prefixlen: %m");
+
+ r = sd_netlink_message_append_u32(req, IFAL_LABEL, label->label);
+ if (r < 0)
+ return log_error_errno(r, "Could not append IFAL_LABEL attribute: %m");
+
+ r = sd_netlink_message_append_in6_addr(req, IFA_ADDRESS, &label->in_addr.in6);
+ if (r < 0)
+ return log_error_errno(r, "Could not append IFA_ADDRESS attribute: %m");
+
+ r = sd_netlink_call_async(link->manager->rtnl, req, callback, link, 0, NULL);
+ if (r < 0)
+ return log_error_errno(r, "Could not send rtnetlink message: %m");
+
+ link_ref(link);
+
+ return 0;
+}
+
+int config_parse_address_label_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) {
+
+ _cleanup_address_label_free_ AddressLabel *n = NULL;
+ Network *network = userdata;
+ int r;
+
+ assert(filename);
+ assert(section);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ r = address_label_new_static(network, filename, section_line, &n);
+ if (r < 0)
+ return r;
+
+ r = in_addr_prefix_from_string(rvalue, AF_INET6, &n->in_addr, &n->prefixlen);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "Address label is invalid, ignoring assignment: %s", rvalue);
+ return 0;
+ }
+
+ n = NULL;
+
+ return 0;
+}
+
+int config_parse_address_label(
+ 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_address_label_free_ AddressLabel *n = NULL;
+ Network *network = userdata;
+ uint32_t k;
+ int r;
+
+ assert(filename);
+ assert(section);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ r = address_label_new_static(network, filename, section_line, &n);
+ if (r < 0)
+ return r;
+
+ r = safe_atou32(rvalue, &k);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse address label, ignoring: %s", rvalue);
+ return 0;
+ }
+
+ if (k == 0xffffffffUL) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "Adress label is invalid, ignoring: %s", rvalue);
+ return 0;
+ }
+
+ n->label = k;
+ n = NULL;
+
+ return 0;
+}
diff --git a/src/network/networkd-address-label.h b/src/network/networkd-address-label.h
new file mode 100644
index 0000000000..8724ea8cb5
--- /dev/null
+++ b/src/network/networkd-address-label.h
@@ -0,0 +1,58 @@
+#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/>.
+***/
+
+#include <inttypes.h>
+#include <stdbool.h>
+
+#include "in-addr-util.h"
+
+typedef struct AddressLabel AddressLabel;
+
+#include "networkd-link.h"
+#include "networkd-network.h"
+
+typedef struct Network Network;
+typedef struct Link Link;
+typedef struct NetworkConfigSection NetworkConfigSection;
+
+struct AddressLabel {
+ Network *network;
+ Link *link;
+ NetworkConfigSection *section;
+
+ unsigned char prefixlen;
+ uint32_t label;
+
+ union in_addr_union in_addr;
+
+ LIST_FIELDS(AddressLabel, labels);
+};
+
+int address_label_new(AddressLabel **ret);
+void address_label_free(AddressLabel *label);
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(AddressLabel*, address_label_free);
+#define _cleanup_address_label_free_ _cleanup_(address_label_freep)
+
+int address_label_configure(AddressLabel *address, Link *link, sd_netlink_message_handler_t callback, bool update);
+
+int config_parse_address_label(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_address_label_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);
diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c
index 2e6c763aba..d66b3a288f 100644
--- a/src/network/networkd-address.c
+++ b/src/network/networkd-address.c
@@ -932,3 +932,251 @@ bool address_is_ready(const Address *a) {
return !(a->flags & (IFA_F_TENTATIVE | IFA_F_DEPRECATED));
}
+
+int config_parse_router_preference(const char *unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+ Network *network = userdata;
+
+ assert(filename);
+ assert(section);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ if (streq(rvalue, "high"))
+ network->router_preference = SD_NDISC_PREFERENCE_HIGH;
+ else if (STR_IN_SET(rvalue, "medium", "normal", "default"))
+ network->router_preference = SD_NDISC_PREFERENCE_MEDIUM;
+ else if (streq(rvalue, "low"))
+ network->router_preference = SD_NDISC_PREFERENCE_LOW;
+ else
+ log_syntax(unit, LOG_ERR, filename, line, -EINVAL, "Router preference '%s' is invalid, ignoring assignment: %m", rvalue);
+
+ return 0;
+}
+
+void prefix_free(Prefix *prefix) {
+ if (!prefix)
+ return;
+
+ if (prefix->network) {
+ LIST_REMOVE(prefixes, prefix->network->static_prefixes, prefix);
+ assert(prefix->network->n_static_prefixes > 0);
+ prefix->network->n_static_prefixes--;
+
+ if (prefix->section)
+ hashmap_remove(prefix->network->prefixes_by_section,
+ prefix->section);
+ }
+
+ prefix->radv_prefix = sd_radv_prefix_unref(prefix->radv_prefix);
+
+ free(prefix);
+}
+
+int prefix_new(Prefix **ret) {
+ Prefix *prefix = NULL;
+
+ prefix = new0(Prefix, 1);
+ if (!prefix)
+ return -ENOMEM;
+
+ if (sd_radv_prefix_new(&prefix->radv_prefix) < 0)
+ return -ENOMEM;
+
+ *ret = prefix;
+ prefix = NULL;
+
+ return 0;
+}
+
+int prefix_new_static(Network *network, const char *filename,
+ unsigned section_line, Prefix **ret) {
+ _cleanup_network_config_section_free_ NetworkConfigSection *n = NULL;
+ _cleanup_prefix_free_ Prefix *prefix = NULL;
+ int r;
+
+ assert(network);
+ assert(ret);
+ assert(!!filename == (section_line > 0));
+
+ if (filename) {
+ r = network_config_section_new(filename, section_line, &n);
+ if (r < 0)
+ return r;
+
+ if (section_line) {
+ prefix = hashmap_get(network->prefixes_by_section, n);
+ if (prefix) {
+ *ret = prefix;
+ prefix = NULL;
+
+ return 0;
+ }
+ }
+ }
+
+ r = prefix_new(&prefix);
+ if (r < 0)
+ return r;
+
+ if (filename) {
+ prefix->section = n;
+ n = NULL;
+
+ r = hashmap_put(network->prefixes_by_section, prefix->section,
+ prefix);
+ if (r < 0)
+ return r;
+ }
+
+ prefix->network = network;
+ LIST_APPEND(prefixes, network->static_prefixes, prefix);
+ network->n_static_prefixes++;
+
+ *ret = prefix;
+ prefix = NULL;
+
+ return 0;
+}
+
+int config_parse_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) {
+
+ Network *network = userdata;
+ _cleanup_prefix_free_ Prefix *p = NULL;
+ uint8_t prefixlen = 64;
+ union in_addr_union in6addr;
+ int r;
+
+ assert(filename);
+ assert(section);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ r = prefix_new_static(network, filename, section_line, &p);
+ if (r < 0)
+ return r;
+
+ r = in_addr_prefix_from_string(rvalue, AF_INET6, &in6addr, &prefixlen);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "Prefix is invalid, ignoring assignment: %s", rvalue);
+ return 0;
+ }
+
+ if (sd_radv_prefix_set_prefix(p->radv_prefix, &in6addr.in6, prefixlen) < 0)
+ return -EADDRNOTAVAIL;
+
+ log_syntax(unit, LOG_INFO, filename, line, r, "Found prefix %s", rvalue);
+
+ p = NULL;
+
+ return 0;
+}
+
+int config_parse_prefix_flags(const char *unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+ Network *network = userdata;
+ _cleanup_prefix_free_ Prefix *p = NULL;
+ int r, val;
+
+ assert(filename);
+ assert(section);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ r = prefix_new_static(network, filename, section_line, &p);
+ if (r < 0)
+ return r;
+
+ r = parse_boolean(rvalue);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse address flag, ignoring: %s", rvalue);
+ return 0;
+ }
+
+ val = r;
+
+ if (streq(lvalue, "OnLink"))
+ r = sd_radv_prefix_set_onlink(p->radv_prefix, val);
+ else if (streq(lvalue, "AddressAutoconfiguration"))
+ r = sd_radv_prefix_set_address_autoconfiguration(p->radv_prefix, val);
+ if (r < 0)
+ return r;
+
+ p = NULL;
+
+ return 0;
+}
+
+int config_parse_prefix_lifetime(const char *unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+ Network *network = userdata;
+ _cleanup_prefix_free_ Prefix *p = NULL;
+ usec_t usec;
+ int r;
+
+ assert(filename);
+ assert(section);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ r = prefix_new_static(network, filename, section_line, &p);
+ if (r < 0)
+ return r;
+
+ r = parse_sec(rvalue, &usec);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "Lifetime is invalid, ignoring assignment: %s", rvalue);
+ return 0;
+ }
+
+ /* a value of 0xffffffff represents infinity */
+ if (streq(lvalue, "PreferredLifetimeSec"))
+ r = sd_radv_prefix_set_preferred_lifetime(p->radv_prefix,
+ DIV_ROUND_UP(usec, USEC_PER_SEC));
+ else if (streq(lvalue, "ValidLifetimeSec"))
+ r = sd_radv_prefix_set_valid_lifetime(p->radv_prefix,
+ DIV_ROUND_UP(usec, USEC_PER_SEC));
+ if (r < 0)
+ return r;
+
+ p = NULL;
+
+ return 0;
+};
diff --git a/src/network/networkd-address.h b/src/network/networkd-address.h
index 71a07ea7a3..065328482e 100644
--- a/src/network/networkd-address.h
+++ b/src/network/networkd-address.h
@@ -25,6 +25,7 @@
#include "in-addr-util.h"
typedef struct Address Address;
+typedef struct Prefix Prefix;
#include "networkd-link.h"
#include "networkd-network.h"
@@ -35,6 +36,15 @@ typedef struct Network Network;
typedef struct Link Link;
typedef struct NetworkConfigSection NetworkConfigSection;
+struct Prefix {
+ Network *network;
+ NetworkConfigSection *section;
+
+ sd_radv_prefix *radv_prefix;
+
+ LIST_FIELDS(Prefix, prefixes);
+};
+
struct Address {
Network *network;
NetworkConfigSection *section;
@@ -79,8 +89,20 @@ bool address_is_ready(const Address *a);
DEFINE_TRIVIAL_CLEANUP_FUNC(Address*, address_free);
#define _cleanup_address_free_ _cleanup_(address_freep)
+int prefix_new(Prefix **ret);
+void prefix_free(Prefix *prefix);
+int prefix_new_static(Network *network, const char *filename, unsigned section,
+ Prefix **ret);
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(Prefix*, prefix_free);
+#define _cleanup_prefix_free_ _cleanup_(prefix_freep)
+
int config_parse_address(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_broadcast(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_label(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_lifetime(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_address_flags(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_router_preference(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_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_prefix_flags(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_prefix_lifetime(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-conf.c b/src/network/networkd-conf.c
index aaa27f311d..e28e018116 100644
--- a/src/network/networkd-conf.c
+++ b/src/network/networkd-conf.c
@@ -32,10 +32,10 @@ int manager_parse_config_file(Manager *m) {
assert(m);
return config_parse_many_nulstr(PKGSYSCONFDIR "/networkd.conf",
- CONF_PATHS_NULSTR("systemd/networkd.conf.d"),
- "DHCP\0",
- config_item_perf_lookup, networkd_gperf_lookup,
- false, m);
+ CONF_PATHS_NULSTR("systemd/networkd.conf.d"),
+ "DHCP\0",
+ config_item_perf_lookup, networkd_gperf_lookup,
+ false, m);
}
static const char* const duid_type_table[_DUID_TYPE_MAX] = {
diff --git a/src/network/networkd-ipv4ll.c b/src/network/networkd-ipv4ll.c
index 7ba05dbec3..d2b10107b8 100644
--- a/src/network/networkd-ipv4ll.c
+++ b/src/network/networkd-ipv4ll.c
@@ -109,7 +109,7 @@ static int ipv4ll_address_handler(sd_netlink *rtnl, sd_netlink_message *m, void
link->ipv4ll_address = true;
- if (link->ipv4ll_route == true)
+ if (link->ipv4ll_route)
link_check_ready(link);
return 1;
@@ -179,12 +179,22 @@ static void ipv4ll_handler(sd_ipv4ll *ll, int event, void *userdata) {
switch(event) {
case SD_IPV4LL_EVENT_STOP:
+ r = ipv4ll_address_lost(link);
+ if (r < 0) {
+ link_enter_failed(link);
+ return;
+ }
+ break;
case SD_IPV4LL_EVENT_CONFLICT:
r = ipv4ll_address_lost(link);
if (r < 0) {
link_enter_failed(link);
return;
}
+
+ r = sd_ipv4ll_restart(ll);
+ if (r < 0)
+ log_link_warning(link, "Could not acquire IPv4 link-local address");
break;
case SD_IPV4LL_EVENT_BIND:
r = ipv4ll_address_claimed(ll, link);
diff --git a/src/network/networkd-ipv6-proxy-ndp.c b/src/network/networkd-ipv6-proxy-ndp.c
index 11c1cd9268..00790c0c13 100644
--- a/src/network/networkd-ipv6-proxy-ndp.c
+++ b/src/network/networkd-ipv6-proxy-ndp.c
@@ -38,6 +38,9 @@ static bool ipv6_proxy_ndp_is_needed(Link *link) {
if (!link->network)
return false;
+ if (link->network->ipv6_proxy_ndp != -1)
+ return link->network->ipv6_proxy_ndp;
+
if (link->network->n_ipv6_proxy_ndp_addresses == 0)
return false;
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index b1282931f3..4c57fa1793 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -32,6 +32,7 @@
#include "networkd-lldp-tx.h"
#include "networkd-manager.h"
#include "networkd-ndisc.h"
+#include "networkd-radv.h"
#include "set.h"
#include "socket-util.h"
#include "stdio-util.h"
@@ -119,6 +120,15 @@ static bool link_ipv6_enabled(Link *link) {
return link_ipv6ll_enabled(link) || network_has_static_ipv6_addresses(link->network);
}
+static bool link_radv_enabled(Link *link) {
+ assert(link);
+
+ if (!link_ipv6ll_enabled(link))
+ return false;
+
+ return link->network->router_prefix_delegation;
+}
+
static bool link_lldp_rx_enabled(Link *link) {
assert(link);
@@ -524,6 +534,7 @@ static void link_free(Link *link) {
sd_ipv4ll_unref(link->ipv4ll);
sd_dhcp6_client_unref(link->dhcp6_client);
sd_ndisc_unref(link->ndisc);
+ sd_radv_unref(link->radv);
if (link->manager)
hashmap_remove(link->manager->links, INT_TO_PTR(link->ifindex));
@@ -643,6 +654,12 @@ static int link_stop_clients(Link *link) {
r = log_link_warning_errno(link, k, "Could not stop IPv6 Router Discovery: %m");
}
+ if (link->radv) {
+ k = sd_radv_stop(link->radv);
+ if (k < 0)
+ r = log_link_warning_errno(link, k, "Could not stop IPv6 Router Advertisement: %m");
+ }
+
link_lldp_emit_stop(link);
return r;
}
@@ -856,6 +873,35 @@ static int address_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userda
return 1;
}
+static int address_label_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
+ _cleanup_link_unref_ Link *link = userdata;
+ int r;
+
+ assert(rtnl);
+ assert(m);
+ assert(link);
+ assert(link->ifname);
+ assert(link->link_messages > 0);
+
+ link->link_messages--;
+
+ if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
+ return 1;
+
+ r = sd_netlink_message_get_errno(m);
+ if (r < 0 && r != -EEXIST)
+ log_link_warning_errno(link, r, "could not set address label: %m");
+ else if (r >= 0)
+ manager_rtnl_process_address(rtnl, m, link->manager);
+
+ if (link->link_messages == 0) {
+ log_link_debug(link, "Addresses label set");
+ link_enter_set_routes(link);
+ }
+
+ return 1;
+}
+
static int link_push_uplink_dns_to_dhcp_server(Link *link, sd_dhcp_server *s) {
_cleanup_free_ struct in_addr *addresses = NULL;
size_t n_addresses = 0, n_allocated = 0;
@@ -968,6 +1014,7 @@ static int link_set_bridge_fdb(Link *link) {
}
static int link_enter_set_addresses(Link *link) {
+ AddressLabel *label;
Address *ad;
int r;
@@ -992,6 +1039,17 @@ static int link_enter_set_addresses(Link *link) {
link->link_messages++;
}
+ LIST_FOREACH(labels, label, link->network->address_labels) {
+ r = address_label_configure(label, link, address_label_handler, false);
+ if (r < 0) {
+ log_link_warning_errno(link, r, "Could not set address label: %m");
+ link_enter_failed(link);
+ return r;
+ }
+
+ link->link_messages++;
+ }
+
/* now that we can figure out a default address for the dhcp server,
start it */
if (link_dhcp4_server_enabled(link)) {
@@ -1328,6 +1386,11 @@ static int link_set_bridge(Link *link) {
if (r < 0)
return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_COST attribute: %m");
}
+ if (link->network->priority != LINK_BRIDGE_PORT_PRIORITY_INVALID) {
+ r = sd_netlink_message_append_u16(req, IFLA_BRPORT_PRIORITY, link->network->priority);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_PRIORITY attribute: %m");
+ }
r = sd_netlink_message_close_container(req);
if (r < 0)
@@ -1511,6 +1574,17 @@ static int link_acquire_ipv6_conf(Link *link) {
return log_link_warning_errno(link, r, "Could not start IPv6 Router Discovery: %m");
}
+ if (link_radv_enabled(link)) {
+ assert(link->radv);
+ assert(in_addr_is_link_local(AF_INET6, (const union in_addr_union*)&link->ipv6ll_address) > 0);
+
+ log_link_debug(link, "Starting IPv6 Router Advertisements");
+
+ r = sd_radv_start(link->radv);
+ if (r < 0 && r != -EBUSY)
+ return log_link_warning_errno(link, r, "Could not start IPv6 Router Advertisement: %m");
+ }
+
return 0;
}
@@ -2061,6 +2135,12 @@ static int link_joined(Link *link) {
log_link_error_errno(link, r, "Could not set bridge vlan: %m");
}
+ /* Skip setting up addresses until it gets carrier,
+ or it would try to set addresses twice,
+ which is bad for non-idempotent steps. */
+ if (!link_has_carrier(link))
+ return 0;
+
return link_enter_set_addresses(link);
}
@@ -2369,7 +2449,7 @@ static int link_drop_foreign_config(Link *link) {
}
static int link_drop_config(Link *link) {
- Address *address;
+ Address *address, *pool_address;
Route *route;
Iterator i;
int r;
@@ -2382,6 +2462,15 @@ static int link_drop_config(Link *link) {
r = address_remove(address, link, link_address_remove_handler);
if (r < 0)
return r;
+
+ /* If this address came from an address pool, clean up the pool */
+ LIST_FOREACH(addresses, pool_address, link->pool_addresses) {
+ if (address_equal(address, pool_address)) {
+ LIST_REMOVE(addresses, link->pool_addresses, pool_address);
+ address_free(pool_address);
+ break;
+ }
+ }
}
SET_FOREACH(route, link->routes, i) {
@@ -2519,6 +2608,12 @@ static int link_configure(Link *link) {
return r;
}
+ if (link_radv_enabled(link)) {
+ r = radv_configure(link);
+ if (r < 0)
+ return r;
+ }
+
if (link_lldp_rx_enabled(link)) {
r = sd_lldp_new(&link->lldp);
if (r < 0)
@@ -2965,6 +3060,8 @@ static int link_carrier_lost(Link *link) {
return r;
}
+ (void) sd_dhcp_server_stop(link->dhcp_server);
+
r = link_drop_config(link);
if (r < 0)
return r;
@@ -3055,6 +3152,12 @@ int link_update(Link *link, sd_netlink_message *m) {
return r;
}
}
+
+ if (link->radv) {
+ r = sd_radv_set_mtu(link->radv, link->mtu);
+ if (r < 0)
+ return log_link_warning_errno(link, r, "Could not set MTU for Router Advertisement: %m");
+ }
}
/* The kernel may broadcast NEWLINK messages without the MAC address
@@ -3123,6 +3226,12 @@ int link_update(Link *link, sd_netlink_message *m) {
if (r < 0)
return log_link_warning_errno(link, r, "Could not update DHCPv6 DUID: %m");
}
+
+ if (link->radv) {
+ r = sd_radv_set_mac(link->radv, &link->mac);
+ if (r < 0)
+ return log_link_warning_errno(link, r, "Could not update MAC for Router Advertisement: %m");
+ }
}
}
@@ -3223,6 +3332,7 @@ int link_save(Link *link) {
sd_dhcp6_lease *dhcp6_lease = NULL;
const char *dhcp_domainname = NULL;
char **dhcp6_domains = NULL;
+ char **dhcp_domains = NULL;
unsigned j;
if (link->dhcp6_client) {
@@ -3332,13 +3442,16 @@ int link_save(Link *link) {
fputc('\n', f);
if (link->network->dhcp_use_domains != DHCP_USE_DOMAINS_NO) {
- if (link->dhcp_lease)
+ if (link->dhcp_lease) {
(void) sd_dhcp_lease_get_domainname(link->dhcp_lease, &dhcp_domainname);
+ (void) sd_dhcp_lease_get_search_domains(link->dhcp_lease, &dhcp_domains);
+ }
if (dhcp6_lease)
(void) sd_dhcp6_lease_get_domains(dhcp6_lease, &dhcp6_domains);
}
fputs("DOMAINS=", f);
+ space = false;
fputstrv(f, link->network->search_domains, NULL, &space);
if (link->network->dhcp_use_domains == DHCP_USE_DOMAINS_YES) {
@@ -3346,6 +3459,8 @@ int link_save(Link *link) {
if (dhcp_domainname)
fputs_with_space(f, dhcp_domainname, NULL, &space);
+ if (dhcp_domains)
+ fputstrv(f, dhcp_domains, NULL, &space);
if (dhcp6_domains)
fputstrv(f, dhcp6_domains, NULL, &space);
@@ -3356,13 +3471,16 @@ int link_save(Link *link) {
fputc('\n', f);
fputs("ROUTE_DOMAINS=", f);
- fputstrv(f, link->network->route_domains, NULL, NULL);
+ space = false;
+ fputstrv(f, link->network->route_domains, NULL, &space);
if (link->network->dhcp_use_domains == DHCP_USE_DOMAINS_ROUTE) {
NDiscDNSSL *dd;
if (dhcp_domainname)
fputs_with_space(f, dhcp_domainname, NULL, &space);
+ if (dhcp_domains)
+ fputstrv(f, dhcp_domains, NULL, &space);
if (dhcp6_domains)
fputstrv(f, dhcp6_domains, NULL, &space);
diff --git a/src/network/networkd-link.h b/src/network/networkd-link.h
index be5c4f3284..6479f4a2e5 100644
--- a/src/network/networkd-link.h
+++ b/src/network/networkd-link.h
@@ -28,6 +28,7 @@
#include "sd-ipv4ll.h"
#include "sd-lldp.h"
#include "sd-ndisc.h"
+#include "sd-radv.h"
#include "sd-netlink.h"
#include "list.h"
@@ -117,6 +118,8 @@ typedef struct Link {
Set *ndisc_rdnss;
Set *ndisc_dnssl;
+ sd_radv *radv;
+
sd_dhcp6_client *dhcp6_client;
bool rtnl_extended_attrs;
diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c
index ea1c320809..5f10b4f993 100644
--- a/src/network/networkd-manager.c
+++ b/src/network/networkd-manager.c
@@ -961,15 +961,20 @@ static int manager_save(Manager *m) {
if (link->network->dhcp_use_domains != DHCP_USE_DOMAINS_NO) {
const char *domainname;
+ char **domains = NULL;
+ OrderedSet *target_domains = (link->network->dhcp_use_domains == DHCP_USE_DOMAINS_YES) ? search_domains : route_domains;
r = sd_dhcp_lease_get_domainname(link->dhcp_lease, &domainname);
if (r >= 0) {
+ r = ordered_set_put_strdup(target_domains, domainname);
+ if (r < 0)
+ return r;
+ } else if (r != -ENODATA)
+ return r;
- if (link->network->dhcp_use_domains == DHCP_USE_DOMAINS_YES)
- r = ordered_set_put_strdup(search_domains, domainname);
- else
- r = ordered_set_put_strdup(route_domains, domainname);
-
+ r = sd_dhcp_lease_get_search_domains(link->dhcp_lease, &domains);
+ if (r >= 0) {
+ r = ordered_set_put_strdupv(target_domains, domains);
if (r < 0)
return r;
} else if (r != -ENODATA)
diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf
index 68052ba544..a2d38501a5 100644
--- a/src/network/networkd-network-gperf.gperf
+++ b/src/network/networkd-network-gperf.gperf
@@ -63,6 +63,7 @@ Network.IPv6AcceptRA, config_parse_tristate,
Network.IPv6AcceptRouterAdvertisements, config_parse_tristate, 0, offsetof(Network, ipv6_accept_ra)
Network.IPv6DuplicateAddressDetection, config_parse_int, 0, offsetof(Network, ipv6_dad_transmits)
Network.IPv6HopLimit, config_parse_int, 0, offsetof(Network, ipv6_hop_limit)
+Network.IPv6ProxyNDP, config_parse_tristate, 0, offsetof(Network, ipv6_proxy_ndp)
Network.ActiveSlave, config_parse_bool, 0, offsetof(Network, active_slave)
Network.PrimarySlave, config_parse_bool, 0, offsetof(Network, primary_slave)
Network.IPv4ProxyARP, config_parse_tristate, 0, offsetof(Network, proxy_arp)
@@ -79,6 +80,8 @@ Address.DuplicateAddressDetection, config_parse_address_flags,
Address.ManageTemporaryAddress, config_parse_address_flags, 0, 0
Address.PrefixRoute, config_parse_address_flags, 0, 0
Address.AutoJoin, config_parse_address_flags, 0, 0
+IPv6AddressLabel.Prefix, config_parse_address_label_prefix, 0, 0
+IPv6AddressLabel.Label, config_parse_address_label, 0, 0
Route.Gateway, config_parse_gateway, 0, 0
Route.Destination, config_parse_destination, 0, 0
Route.Source, config_parse_destination, 0, 0
@@ -86,6 +89,9 @@ Route.Metric, config_parse_route_priority,
Route.Scope, config_parse_route_scope, 0, 0
Route.PreferredSource, config_parse_preferred_src, 0, 0
Route.Table, config_parse_route_table, 0, 0
+Route.GatewayOnlink, config_parse_gateway_onlink, 0, 0
+Route.IPv6Preference, config_parse_ipv6_route_preference, 0, 0
+Route.Protocol, config_parse_route_protocol, 0, 0
DHCP.ClientIdentifier, config_parse_dhcp_client_identifier, 0, offsetof(Network, dhcp_client_identifier)
DHCP.UseDNS, config_parse_bool, 0, offsetof(Network, dhcp_use_dns)
DHCP.UseNTP, config_parse_bool, 0, offsetof(Network, dhcp_use_ntp)
@@ -119,17 +125,28 @@ DHCPServer.EmitTimezone, config_parse_bool,
DHCPServer.Timezone, config_parse_timezone, 0, offsetof(Network, dhcp_server_timezone)
DHCPServer.PoolOffset, config_parse_uint32, 0, offsetof(Network, dhcp_server_pool_offset)
DHCPServer.PoolSize, config_parse_uint32, 0, offsetof(Network, dhcp_server_pool_size)
-Bridge.Cost, config_parse_unsigned, 0, offsetof(Network, cost)
+Bridge.Cost, config_parse_uint32, 0, offsetof(Network, cost)
Bridge.UseBPDU, config_parse_bool, 0, offsetof(Network, use_bpdu)
Bridge.HairPin, config_parse_bool, 0, offsetof(Network, hairpin)
Bridge.FastLeave, config_parse_bool, 0, offsetof(Network, fast_leave)
Bridge.AllowPortToBeRoot, config_parse_bool, 0, offsetof(Network, allow_port_to_be_root)
Bridge.UnicastFlood, config_parse_bool, 0, offsetof(Network, unicast_flood)
+Bridge.Priority, config_parse_bridge_port_priority, 0, offsetof(Network, priority)
BridgeFDB.MACAddress, config_parse_fdb_hwaddr, 0, 0
BridgeFDB.VLANId, config_parse_fdb_vlan_id, 0, 0
BridgeVLAN.PVID, config_parse_brvlan_pvid, 0, 0
BridgeVLAN.VLAN, config_parse_brvlan_vlan, 0, 0
BridgeVLAN.EgressUntagged, config_parse_brvlan_untagged, 0, 0
+Network.IPv6PrefixDelegation, config_parse_bool, 0, offsetof(Network, router_prefix_delegation)
+IPv6PrefixDelegation.RouterLifetimeSec, config_parse_sec, 0, offsetof(Network, router_lifetime_usec)
+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
+IPv6Prefix.Prefix, config_parse_prefix, 0, 0
+IPv6Prefix.OnLink, config_parse_prefix_flags, 0, 0
+IPv6Prefix.AddressAutoconfiguration, config_parse_prefix_flags, 0, 0
+IPv6Prefix.ValidLifetimeSec, config_parse_prefix_lifetime, 0, 0
+IPv6Prefix.PreferredLifetimeSec, config_parse_prefix_lifetime, 0, 0
/* backwards compatibility: do not add new entries to this section */
Network.IPv4LL, config_parse_ipv4ll, 0, offsetof(Network, link_local)
DHCPv4.UseDNS, config_parse_bool, 0, offsetof(Network, dhcp_use_dns)
diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c
index fac42d8478..6f2ae66d40 100644
--- a/src/network/networkd-network.c
+++ b/src/network/networkd-network.c
@@ -114,6 +114,8 @@ static int network_load_one(Manager *manager, const char *filename) {
LIST_HEAD_INIT(network->static_routes);
LIST_HEAD_INIT(network->static_fdb_entries);
LIST_HEAD_INIT(network->ipv6_proxy_ndp_addresses);
+ LIST_HEAD_INIT(network->address_labels);
+ LIST_HEAD_INIT(network->static_prefixes);
network->stacked_netdevs = hashmap_new(&string_hash_ops);
if (!network->stacked_netdevs)
@@ -131,6 +133,14 @@ static int network_load_one(Manager *manager, const char *filename) {
if (!network->fdb_entries_by_section)
return log_oom();
+ network->address_labels_by_section = hashmap_new(&network_config_hash_ops);
+ if (!network->address_labels_by_section)
+ log_oom();
+
+ network->prefixes_by_section = hashmap_new(&network_config_hash_ops);
+ if (!network->prefixes_by_section)
+ return log_oom();
+
network->filename = strdup(filename);
if (!network->filename)
return log_oom();
@@ -165,6 +175,7 @@ static int network_load_one(Manager *manager, const char *filename) {
network->use_bpdu = true;
network->allow_port_to_be_root = true;
network->unicast_flood = true;
+ network->priority = LINK_BRIDGE_PORT_PRIORITY_INVALID;
network->lldp_mode = LLDP_MODE_ROUTERS_ONLY;
@@ -178,6 +189,7 @@ static int network_load_one(Manager *manager, const char *filename) {
network->ipv6_accept_ra = -1;
network->ipv6_dad_transmits = -1;
network->ipv6_hop_limit = -1;
+ network->ipv6_proxy_ndp = -1;
network->duid.type = _DUID_TYPE_INVALID;
network->proxy_arp = -1;
network->arp = -1;
@@ -191,6 +203,7 @@ static int network_load_one(Manager *manager, const char *filename) {
"Link\0"
"Network\0"
"Address\0"
+ "IPv6AddressLabel\0"
"Route\0"
"DHCP\0"
"DHCPv4\0" /* compat */
@@ -199,7 +212,9 @@ static int network_load_one(Manager *manager, const char *filename) {
"IPv6NDPProxyAddress\0"
"Bridge\0"
"BridgeFDB\0"
- "BridgeVLAN\0",
+ "BridgeVLAN\0"
+ "IPv6PrefixDelegation\0"
+ "IPv6Prefix\0",
config_item_perf_lookup, network_network_gperf_lookup,
false, network);
if (r < 0)
@@ -270,6 +285,8 @@ void network_free(Network *network) {
Address *address;
FdbEntry *fdb_entry;
IPv6ProxyNDPAddress *ipv6_proxy_ndp_address;
+ AddressLabel *label;
+ Prefix *prefix;
Iterator i;
if (!network)
@@ -317,9 +334,17 @@ void network_free(Network *network) {
while ((ipv6_proxy_ndp_address = network->ipv6_proxy_ndp_addresses))
ipv6_proxy_ndp_address_free(ipv6_proxy_ndp_address);
+ while ((label = network->address_labels))
+ address_label_free(label);
+
+ while ((prefix = network->static_prefixes))
+ prefix_free(prefix);
+
hashmap_free(network->addresses_by_section);
hashmap_free(network->routes_by_section);
hashmap_free(network->fdb_entries_by_section);
+ hashmap_free(network->address_labels_by_section);
+ hashmap_free(network->prefixes_by_section);
if (network->manager) {
if (network->manager->networks)
diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h
index 4ce066a764..b31921947d 100644
--- a/src/network/networkd-network.h
+++ b/src/network/networkd-network.h
@@ -28,6 +28,7 @@
#include "resolve-util.h"
#include "networkd-address.h"
+#include "networkd-address-label.h"
#include "networkd-brvlan.h"
#include "networkd-fdb.h"
#include "networkd-lldp-tx.h"
@@ -157,13 +158,21 @@ struct Network {
AddressFamilyBoolean link_local;
bool ipv4ll_route;
+ /* IPv6 prefix delegation support */
+ bool router_prefix_delegation;
+ usec_t router_lifetime_usec;
+ uint8_t router_preference;
+ bool router_managed;
+ bool router_other_information;
+
/* Bridge Support */
bool use_bpdu;
bool hairpin;
bool fast_leave;
bool allow_port_to_be_root;
bool unicast_flood;
- unsigned cost;
+ uint32_t cost;
+ uint16_t priority;
bool use_br_vlan;
uint16_t pvid;
@@ -176,6 +185,7 @@ struct Network {
int ipv6_accept_ra;
int ipv6_dad_transmits;
int ipv6_hop_limit;
+ int ipv6_proxy_ndp;
int proxy_arp;
bool ipv6_accept_ra_use_dns;
@@ -201,15 +211,21 @@ struct Network {
LIST_HEAD(Route, static_routes);
LIST_HEAD(FdbEntry, static_fdb_entries);
LIST_HEAD(IPv6ProxyNDPAddress, ipv6_proxy_ndp_addresses);
+ LIST_HEAD(AddressLabel, address_labels);
+ LIST_HEAD(Prefix, static_prefixes);
unsigned n_static_addresses;
unsigned n_static_routes;
unsigned n_static_fdb_entries;
unsigned n_ipv6_proxy_ndp_addresses;
+ unsigned n_address_labels;
+ unsigned n_static_prefixes;
Hashmap *addresses_by_section;
Hashmap *routes_by_section;
Hashmap *fdb_entries_by_section;
+ Hashmap *address_labels_by_section;
+ Hashmap *prefixes_by_section;
struct in_addr_data *dns;
unsigned n_dns;
diff --git a/src/network/networkd-radv.c b/src/network/networkd-radv.c
new file mode 100644
index 0000000000..af9e116936
--- /dev/null
+++ b/src/network/networkd-radv.c
@@ -0,0 +1,79 @@
+/***
+ This file is part of systemd.
+
+ Copyright (C) 2017 Intel Corporation. All rights reserved.
+
+ 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 <netinet/icmp6.h>
+#include <arpa/inet.h>
+
+#include "networkd-address.h"
+#include "networkd-radv.h"
+#include "sd-radv.h"
+
+int radv_configure(Link *link) {
+ int r;
+ Prefix *p;
+
+ assert(link);
+ assert(link->network);
+
+ r = sd_radv_new(&link->radv);
+ if (r < 0)
+ return r;
+
+ r = sd_radv_attach_event(link->radv, NULL, 0);
+ if (r < 0)
+ return r;
+
+ r = sd_radv_set_mac(link->radv, &link->mac);
+ if (r < 0)
+ return r;
+
+ r = sd_radv_set_ifindex(link->radv, link->ifindex);
+ if (r < 0)
+ return r;
+
+ r = sd_radv_set_managed_information(link->radv, link->network->router_managed);
+ if (r < 0)
+ return r;
+
+ r = sd_radv_set_other_information(link->radv, link->network->router_other_information);
+ if (r < 0)
+ return r;
+
+ /* a value of 0xffffffff represents infinity, 0x0 means this host is
+ not a router */
+ r = sd_radv_set_router_lifetime(link->radv,
+ DIV_ROUND_UP(link->network->router_lifetime_usec, USEC_PER_SEC));
+ if (r < 0)
+ return r;
+
+ if (link->network->router_lifetime_usec > 0) {
+ r = sd_radv_set_preference(link->radv,
+ link->network->router_preference);
+ if (r < 0)
+ return r;
+ }
+
+ LIST_FOREACH(prefixes, p, link->network->static_prefixes) {
+ r = sd_radv_add_prefix(link->radv, p->radv_prefix);
+ if (r != -EEXIST && r < 0)
+ return r;
+ }
+
+ return 0;
+}
diff --git a/src/network/networkd-radv.h b/src/network/networkd-radv.h
new file mode 100644
index 0000000000..a186b111a1
--- /dev/null
+++ b/src/network/networkd-radv.h
@@ -0,0 +1,24 @@
+#pragma once
+
+/***
+ This file is part of systemd.
+
+ Copyright 2017 Intel Corporation. All rights reserved.
+
+ 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 "networkd-link.h"
+
+int radv_configure(Link *link);
diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c
index 570083f180..e5d61ce8cc 100644
--- a/src/network/networkd-route.c
+++ b/src/network/networkd-route.c
@@ -17,6 +17,8 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include <linux/icmpv6.h>
+
#include "alloc-util.h"
#include "conf-parser.h"
#include "in-addr-util.h"
@@ -228,7 +230,7 @@ int route_get(Link *link,
unsigned char dst_prefixlen,
unsigned char tos,
uint32_t priority,
- unsigned char table,
+ uint32_t table,
Route **ret) {
Route route, *existing;
@@ -270,7 +272,7 @@ static int route_add_internal(
unsigned char dst_prefixlen,
unsigned char tos,
uint32_t priority,
- unsigned char table,
+ uint32_t table,
Route **ret) {
_cleanup_route_free_ Route *route = NULL;
@@ -316,7 +318,7 @@ int route_add_foreign(
unsigned char dst_prefixlen,
unsigned char tos,
uint32_t priority,
- unsigned char table,
+ uint32_t table,
Route **ret) {
return route_add_internal(link, &link->routes_foreign, family, dst, dst_prefixlen, tos, priority, table, ret);
@@ -329,7 +331,7 @@ int route_add(
unsigned char dst_prefixlen,
unsigned char tos,
uint32_t priority,
- unsigned char table,
+ uint32_t table,
Route **ret) {
Route *route;
@@ -755,10 +757,9 @@ int config_parse_destination(const char *unit,
Network *network = userdata;
_cleanup_route_free_ Route *n = NULL;
- const char *address, *e;
union in_addr_union buffer;
unsigned char prefixlen;
- int r, f;
+ int r;
assert(filename);
assert(section);
@@ -770,45 +771,20 @@ int config_parse_destination(const char *unit,
if (r < 0)
return r;
- /* Destination|Source=address/prefixlen */
-
- /* address */
- e = strchr(rvalue, '/');
- if (e)
- address = strndupa(rvalue, e - rvalue);
- else
- address = rvalue;
-
- r = in_addr_from_string_auto(address, &f, &buffer);
+ r = in_addr_prefix_from_string(rvalue, AF_INET, &buffer, &prefixlen);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Destination is invalid, ignoring assignment: %s", address);
- return 0;
- }
-
- if (f != AF_INET && f != AF_INET6) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Unknown address family, ignoring assignment: %s", address);
- return 0;
- }
-
- /* prefixlen */
- if (e) {
- r = safe_atou8(e + 1, &prefixlen);
+ r = in_addr_prefix_from_string(rvalue, AF_INET6, &buffer, &prefixlen);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Route destination prefix length is invalid, ignoring assignment: %s", e + 1);
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "Route %s= prefix is invalid, ignoring assignment: %s",
+ lvalue, rvalue);
return 0;
}
- } else {
- switch (f) {
- case AF_INET:
- prefixlen = 32;
- break;
- case AF_INET6:
- prefixlen = 128;
- break;
- }
- }
- n->family = f;
+ n->family = AF_INET6;
+ } else
+ n->family = AF_INET;
+
if (streq(lvalue, "Destination")) {
n->dst = buffer;
n->dst_prefixlen = prefixlen;
@@ -939,3 +915,111 @@ int config_parse_route_table(const char *unit,
return 0;
}
+
+int config_parse_gateway_onlink(const char *unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+ Network *network = userdata;
+ _cleanup_route_free_ Route *n = NULL;
+ int r;
+
+ assert(filename);
+ assert(section);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ r = route_new_static(network, filename, section_line, &n);
+ if (r < 0)
+ return r;
+
+ r = parse_boolean(rvalue);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "Could not parse gateway onlink \"%s\", ignoring assignment: %m", rvalue);
+ return 0;
+ }
+
+ SET_FLAG(n->flags, RTNH_F_ONLINK, r);
+ n = NULL;
+
+ return 0;
+}
+
+int config_parse_ipv6_route_preference(const char *unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+ Network *network = userdata;
+ _cleanup_route_free_ Route *n = NULL;
+ int r;
+
+ r = route_new_static(network, filename, section_line, &n);
+ if (r < 0)
+ return r;
+
+ if (streq(rvalue, "low"))
+ n->pref = ICMPV6_ROUTER_PREF_LOW;
+ else if (streq(rvalue, "medium"))
+ n->pref = ICMPV6_ROUTER_PREF_MEDIUM;
+ else if (streq(rvalue, "high"))
+ n->pref = ICMPV6_ROUTER_PREF_HIGH;
+ else {
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Unknown route preference: %s", rvalue);
+ return 0;
+ }
+
+ n = NULL;
+
+ return 0;
+}
+
+int config_parse_route_protocol(const char *unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+ Network *network = userdata;
+ _cleanup_route_free_ Route *n = NULL;
+ int r;
+
+ r = route_new_static(network, filename, section_line, &n);
+ if (r < 0)
+ return r;
+
+ if (streq(rvalue, "kernel"))
+ n->protocol = RTPROT_KERNEL;
+ else if (streq(rvalue, "boot"))
+ n->protocol = RTPROT_BOOT;
+ else if (streq(rvalue, "static"))
+ n->protocol = RTPROT_STATIC;
+ else {
+ r = safe_atou8(rvalue , &n->protocol);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "Could not parse route protocol \"%s\", ignoring assignment: %m", rvalue);
+ return 0;
+ }
+ }
+
+ n = NULL;
+
+ return 0;
+}
diff --git a/src/network/networkd-route.h b/src/network/networkd-route.h
index 4ebfa0f0bd..3f389489da 100644
--- a/src/network/networkd-route.h
+++ b/src/network/networkd-route.h
@@ -59,9 +59,9 @@ void route_free(Route *route);
int route_configure(Route *route, Link *link, sd_netlink_message_handler_t callback);
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, unsigned char 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, unsigned char 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, unsigned char table, Route **ret);
+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);
int route_expire_handler(sd_event_source *s, uint64_t usec, void *userdata);
@@ -75,3 +75,6 @@ int config_parse_destination(const char *unit, const char *filename, unsigned li
int config_parse_route_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_route_scope(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_route_table(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_gateway_onlink(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_ipv6_route_preference(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_route_protocol(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/nspawn/meson.build b/src/nspawn/meson.build
new file mode 100644
index 0000000000..b6ac6006ab
--- /dev/null
+++ b/src/nspawn/meson.build
@@ -0,0 +1,40 @@
+systemd_nspawn_sources = files('''
+ nspawn.c
+ nspawn-settings.c
+ nspawn-settings.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-register.c
+ nspawn-register.h
+ nspawn-setuid.c
+ nspawn-setuid.h
+ nspawn-stub-pid1.c
+ nspawn-stub-pid1.h
+ nspawn-patch-uid.c
+ nspawn-patch-uid.h
+'''.split())
+
+nspawn_gperf_c = custom_target(
+ 'nspawn-gperf.c',
+ input : 'nspawn-gperf.gperf',
+ output : 'nspawn-gperf.c',
+ command : [gperf, '@INPUT@', '--output-file', '@OUTPUT@'])
+
+systemd_nspawn_sources += [nspawn_gperf_c]
+
+tests += [
+ [['src/nspawn/test-patch-uid.c',
+ 'src/nspawn/nspawn-patch-uid.c',
+ 'src/nspawn/nspawn-patch-uid.h'],
+ [libshared],
+ [libacl],
+ '', 'manual'],
+]
diff --git a/src/nspawn/nspawn-cgroup.c b/src/nspawn/nspawn-cgroup.c
index 7c4fbc5055..2a15f1892c 100644
--- a/src/nspawn/nspawn-cgroup.c
+++ b/src/nspawn/nspawn-cgroup.c
@@ -121,7 +121,7 @@ static int chown_cgroup_path(const char *path, uid_t uid_shift) {
"cgroup.subtree_control")
if (fchownat(fd, fn, uid_shift, uid_shift, 0) < 0)
log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_WARNING, errno,
- "Failed to chown() cgroup file %s, ignoring: %m", fn);
+ "Failed to chown \"%s/%s\", ignoring: %m", path, fn);
return 0;
}
diff --git a/src/nspawn/nspawn-network.c b/src/nspawn/nspawn-network.c
index 428cc04de0..aa61aaaa79 100644
--- a/src/nspawn/nspawn-network.c
+++ b/src/nspawn/nspawn-network.c
@@ -19,6 +19,7 @@
#include <linux/veth.h>
#include <net/if.h>
+#include <sys/file.h>
#include "libudev.h"
#include "sd-id128.h"
diff --git a/src/nspawn/nspawn-register.c b/src/nspawn/nspawn-register.c
index e3ab39faea..5b0faf809c 100644
--- a/src/nspawn/nspawn-register.c
+++ b/src/nspawn/nspawn-register.c
@@ -27,6 +27,77 @@
#include "strv.h"
#include "util.h"
+static int append_machine_properties(
+ sd_bus_message *m,
+ CustomMount *mounts,
+ unsigned n_mounts,
+ int kill_signal,
+ char **properties) {
+
+ unsigned j;
+ int r;
+
+ assert(m);
+
+ r = sd_bus_message_append(m, "(sv)", "DevicePolicy", "s", "closed");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ /* If you make changes here, also make sure to update systemd-nspawn@.service, to keep the device policies in
+ * sync regardless if we are run with or without the --keep-unit switch. */
+ r = sd_bus_message_append(m, "(sv)", "DeviceAllow", "a(ss)", 2,
+ /* Allow the container to
+ * access and create the API
+ * device nodes, so that
+ * PrivateDevices= in the
+ * container can work
+ * fine */
+ "/dev/net/tun", "rwm",
+ /* Allow the container
+ * access to ptys. However,
+ * do not permit the
+ * container to ever create
+ * these device nodes. */
+ "char-pts", "rw");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ for (j = 0; j < n_mounts; j++) {
+ CustomMount *cm = mounts + j;
+
+ if (cm->type != CUSTOM_MOUNT_BIND)
+ continue;
+
+ r = is_device_node(cm->source);
+ if (r == -ENOENT) {
+ /* The bind source might only appear as the image is put together, hence don't complain */
+ log_debug_errno(r, "Bind mount source %s not found, ignoring: %m", cm->source);
+ continue;
+ }
+ if (r < 0)
+ return log_error_errno(r, "Failed to stat %s: %m", cm->source);
+
+ if (r) {
+ r = sd_bus_message_append(m, "(sv)", "DeviceAllow", "a(ss)", 1,
+ cm->source, cm->read_only ? "r" : "rw");
+ if (r < 0)
+ return log_error_errno(r, "Failed to append message arguments: %m");
+ }
+ }
+
+ if (kill_signal != 0) {
+ r = sd_bus_message_append(m, "(sv)", "KillSignal", "i", kill_signal);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_append(m, "(sv)", "KillMode", "s", "mixed");
+ if (r < 0)
+ return bus_log_create_error(r);
+ }
+
+ return 0;
+}
+
int register_machine(
const char *machine_name,
pid_t pid,
@@ -68,7 +139,6 @@ int register_machine(
local_ifindex > 0 ? 1 : 0, local_ifindex);
} else {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
- unsigned j;
r = sd_bus_message_new_method_call(
bus,
@@ -103,63 +173,14 @@ int register_machine(
return bus_log_create_error(r);
}
- r = sd_bus_message_append(m, "(sv)", "DevicePolicy", "s", "closed");
- if (r < 0)
- return bus_log_create_error(r);
-
- /* If you make changes here, also make sure to update
- * systemd-nspawn@.service, to keep the device
- * policies in sync regardless if we are run with or
- * without the --keep-unit switch. */
- r = sd_bus_message_append(m, "(sv)", "DeviceAllow", "a(ss)", 2,
- /* Allow the container to
- * access and create the API
- * device nodes, so that
- * PrivateDevices= in the
- * container can work
- * fine */
- "/dev/net/tun", "rwm",
- /* Allow the container
- * access to ptys. However,
- * do not permit the
- * container to ever create
- * these device nodes. */
- "char-pts", "rw");
+ r = append_machine_properties(
+ m,
+ mounts,
+ n_mounts,
+ kill_signal,
+ properties);
if (r < 0)
- return bus_log_create_error(r);
-
- for (j = 0; j < n_mounts; j++) {
- CustomMount *cm = mounts + j;
-
- if (cm->type != CUSTOM_MOUNT_BIND)
- continue;
-
- r = is_device_node(cm->source);
- if (r == -ENOENT) {
- /* The bind source might only appear as the image is put together, hence don't complain */
- log_debug_errno(r, "Bind mount source %s not found, ignoring: %m", cm->source);
- continue;
- }
- if (r < 0)
- return log_error_errno(r, "Failed to stat %s: %m", cm->source);
-
- if (r) {
- r = sd_bus_message_append(m, "(sv)", "DeviceAllow", "a(ss)", 1,
- cm->source, cm->read_only ? "r" : "rw");
- if (r < 0)
- return log_error_errno(r, "Failed to append message arguments: %m");
- }
- }
-
- if (kill_signal != 0) {
- r = sd_bus_message_append(m, "(sv)", "KillSignal", "i", kill_signal);
- if (r < 0)
- return bus_log_create_error(r);
-
- r = sd_bus_message_append(m, "(sv)", "KillMode", "s", "mixed");
- if (r < 0)
- return bus_log_create_error(r);
- }
+ return r;
r = bus_append_unit_property_assignment_many(m, properties);
if (r < 0)
@@ -229,3 +250,104 @@ int terminate_machine(pid_t pid) {
return 0;
}
+
+int allocate_scope(
+ const char *machine_name,
+ pid_t pid,
+ const char *slice,
+ CustomMount *mounts,
+ unsigned n_mounts,
+ int kill_signal,
+ char **properties) {
+
+ _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");
+
+ r = bus_wait_for_jobs_new(bus, &w);
+ if (r < 0)
+ return log_error_errno(r, "Could not watch job: %m");
+
+ r = unit_name_mangle_with_suffix(machine_name, UNIT_NAME_NOGLOB, ".scope", &scope);
+ if (r < 0)
+ return log_error_errno(r, "Failed to mangle scope name: %m");
+
+ r = sd_bus_message_new_method_call(
+ bus,
+ &m,
+ "org.freedesktop.systemd1",
+ "/org/freedesktop/systemd1",
+ "org.freedesktop.systemd1.Manager",
+ "StartTransientUnit");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_append(m, "ss", scope, "fail");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ /* Properties */
+ r = sd_bus_message_open_container(m, 'a', "(sv)");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ description = strjoina("Container ", machine_name);
+
+ r = sd_bus_message_append(m, "(sv)(sv)(sv)(sv)",
+ "PIDs", "au", 1, pid,
+ "Description", "s", description,
+ "Delegate", "b", 1,
+ "Slice", "s", isempty(slice) ? "machine.slice" : slice);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = append_machine_properties(
+ m,
+ mounts,
+ n_mounts,
+ kill_signal,
+ properties);
+ if (r < 0)
+ return r;
+
+ r = bus_append_unit_property_assignment_many(m, properties);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_close_container(m);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ /* No auxiliary units */
+ r = sd_bus_message_append(
+ m,
+ "a(sa(sv))",
+ 0);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_call(bus, m, 0, &error, &reply);
+ if (r < 0) {
+ log_error("Failed to allocate scope: %s", bus_error_message(&error, r));
+ return r;
+ }
+
+ r = sd_bus_message_read(reply, "o", &object);
+ if (r < 0)
+ return bus_log_parse_error(r);
+
+ r = bus_wait_for_jobs_one(w, object, false);
+ if (r < 0)
+ return r;
+
+ return 0;
+}
diff --git a/src/nspawn/nspawn-register.h b/src/nspawn/nspawn-register.h
index 304c5a485b..6694b3f6b1 100644
--- a/src/nspawn/nspawn-register.h
+++ b/src/nspawn/nspawn-register.h
@@ -27,3 +27,5 @@
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 allocate_scope(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-stub-pid1.c b/src/nspawn/nspawn-stub-pid1.c
index 7f2a53a245..0c48434db8 100644
--- a/src/nspawn/nspawn-stub-pid1.c
+++ b/src/nspawn/nspawn-stub-pid1.c
@@ -18,9 +18,9 @@
***/
#include <sys/reboot.h>
-#include <sys/unistd.h>
#include <sys/wait.h>
#include <sys/prctl.h>
+#include <unistd.h>
#include "fd-util.h"
#include "log.h"
@@ -188,7 +188,16 @@ int stub_pid1(sd_id128_t uuid) {
else
assert_not_reached("Got unexpected signal");
- /* (void) kill_and_sigcont(pid, SIGTERM); */
+ r = kill_and_sigcont(pid, SIGTERM);
+
+ /* Let's send a SIGHUP after the SIGTERM, as shells tend to ignore SIGTERM but do react to SIGHUP. We
+ * do it strictly in this order, so that the SIGTERM is dispatched first, and SIGHUP second for those
+ * processes which handle both. That's because services tend to bind configuration reload or something
+ * else to SIGHUP. */
+
+ if (r != -ESRCH)
+ (void) kill(pid, SIGHUP);
+
quit_usec = now(CLOCK_MONOTONIC) + DEFAULT_TIMEOUT_USEC;
}
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 670fef2991..6399a9e882 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -18,7 +18,7 @@
***/
#ifdef HAVE_BLKID
-#include <blkid/blkid.h>
+#include <blkid.h>
#endif
#include <errno.h>
#include <getopt.h>
@@ -398,12 +398,10 @@ static void parse_mount_settings_env(void) {
if (r < 0) {
log_warning_errno(r, "Failed to parse SYSTEMD_NSPAWN_API_VFS_WRITABLE from environment, ignoring.");
return;
- } else if (r > 0)
- arg_mount_settings &= ~MOUNT_APPLY_APIVFS_RO;
- else
- arg_mount_settings |= MOUNT_APPLY_APIVFS_RO;
+ }
- arg_mount_settings &= ~MOUNT_APPLY_APIVFS_NETNS;
+ SET_FLAG(arg_mount_settings, MOUNT_APPLY_APIVFS_RO, r == 0);
+ SET_FLAG(arg_mount_settings, MOUNT_APPLY_APIVFS_NETNS, false);
}
static int parse_argv(int argc, char *argv[]) {
@@ -1094,8 +1092,8 @@ static int parse_argv(int argc, char *argv[]) {
if (arg_userns_mode == USER_NAMESPACE_PICK)
arg_userns_chown = true;
- if (arg_keep_unit && cg_pid_get_owner_uid(0, NULL) >= 0) {
- log_error("--keep-unit may not be used when invoked from a user session.");
+ if (arg_keep_unit && arg_register && cg_pid_get_owner_uid(0, NULL) >= 0) {
+ log_error("--keep-unit --register=yes may not be used when invoked from a user session.");
return -EINVAL;
}
@@ -1341,17 +1339,32 @@ static int setup_timezone(const char *dest) {
return 0;
}
-static int resolved_running(void) {
+static int resolved_listening(void) {
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
+ _cleanup_free_ char *dns_stub_listener_mode = NULL;
int r;
- /* Check if resolved is running */
+ /* Check if resolved is listening */
r = sd_bus_open_system(&bus);
if (r < 0)
return r;
- return bus_name_has_owner(bus, "org.freedesktop.resolve1", NULL);
+ r = bus_name_has_owner(bus, "org.freedesktop.resolve1", NULL);
+ if (r <= 0)
+ return r;
+
+ r = sd_bus_get_property_string(bus,
+ "org.freedesktop.resolve1",
+ "/org/freedesktop/resolve1",
+ "org.freedesktop.resolve1.Manager",
+ "DNSStubListener",
+ NULL,
+ &dns_stub_listener_mode);
+ if (r < 0)
+ return r;
+
+ return STR_IN_SET(dns_stub_listener_mode, "udp", "yes");
}
static int setup_resolv_conf(const char *dest) {
@@ -1378,7 +1391,7 @@ static int setup_resolv_conf(const char *dest) {
}
if (access("/usr/lib/systemd/resolv.conf", F_OK) >= 0 &&
- resolved_running() > 0) {
+ resolved_listening() > 0) {
/* resolved is enabled on the host. In this, case bind mount its static resolv.conf file into the
* container, so that the container can use the host's resolver. Given that network namespacing is
@@ -3417,7 +3430,19 @@ static int run(int master,
arg_container_service_name);
if (r < 0)
return r;
- }
+ } else if (!arg_keep_unit) {
+ r = allocate_scope(
+ arg_machine,
+ *main_pid,
+ arg_slice,
+ arg_custom_mounts, arg_n_custom_mounts,
+ arg_kill_signal,
+ arg_property);
+ if (r < 0)
+ return r;
+
+ } else if (arg_slice || arg_property)
+ log_notice("Machine and scope registration turned off, --slice= and --property= settings will have no effect.");
r = cgroup_setup(*main_pid, outer_cgver, arg_unified_cgroup_hierarchy, arg_uid_shift);
if (r < 0)
@@ -3598,10 +3623,6 @@ int main(int argc, char *argv[]) {
log_parse_environment();
log_open();
- cg_unified_flush();
- r = cg_version(&outer_cgver);
- if (r < 0)
- outer_cgver = CGROUP_UNIFIED_UNKNOWN;
/* Make sure rename_process() in the stub init process can work */
saved_argv = argv;
@@ -3611,12 +3632,15 @@ int main(int argc, char *argv[]) {
if (r <= 0)
goto finish;
+ r = cg_version(&outer_cgver);
+ if (r < 0)
+ outer_cgver = CGROUP_UNIFIED_UNKNOWN;
+
if (geteuid() != 0) {
log_error("Need to be root.");
r = -EPERM;
goto finish;
}
-
r = determine_names();
if (r < 0)
goto finish;
diff --git a/src/rc-local-generator/rc-local-generator.c b/src/rc-local-generator/rc-local-generator.c
index b704ca3b4b..db3bf5bd21 100644
--- a/src/rc-local-generator/rc-local-generator.c
+++ b/src/rc-local-generator/rc-local-generator.c
@@ -28,14 +28,6 @@
#include "string-util.h"
#include "util.h"
-#ifndef RC_LOCAL_SCRIPT_PATH_START
-#define RC_LOCAL_SCRIPT_PATH_START "/etc/rc.d/rc.local"
-#endif
-
-#ifndef RC_LOCAL_SCRIPT_PATH_STOP
-#define RC_LOCAL_SCRIPT_PATH_STOP "/sbin/halt.local"
-#endif
-
static const char *arg_dest = "/tmp";
static int add_symlink(const char *service, const char *where) {
diff --git a/src/resolve/dns_type-to-name.awk b/src/resolve/dns_type-to-name.awk
new file mode 100644
index 0000000000..badb1824b5
--- /dev/null
+++ b/src/resolve/dns_type-to-name.awk
@@ -0,0 +1,11 @@
+BEGIN{
+ print "const char *dns_type_to_string(int type) {\n\tswitch(type) {"
+}
+{
+ printf " case DNS_TYPE_%s: return ", $1;
+ sub(/_/, "-");
+ printf "\"%s\";\n", $1
+}
+END{
+ print " default: return NULL;\n\t}\n}\n"
+}
diff --git a/src/resolve/generate-dns_type-gperf.py b/src/resolve/generate-dns_type-gperf.py
new file mode 100755
index 0000000000..8a0b43c277
--- /dev/null
+++ b/src/resolve/generate-dns_type-gperf.py
@@ -0,0 +1,18 @@
+#!/usr/bin/env python3
+
+"""Generate %-from-name.gperf from %-list.txt
+"""
+
+import sys
+
+name, prefix, input = sys.argv[1:]
+
+print("""\
+struct {}_name {{ const char* name; int id; }};
+%null-strings
+%%""".format(name))
+
+for line in open(input):
+ line = line.rstrip()
+ s = line.replace('_', '-')
+ print("{}, {}{}".format(s, prefix, line))
diff --git a/src/resolve/generate-dns_type-list.sed b/src/resolve/generate-dns_type-list.sed
new file mode 100644
index 0000000000..b7bc30f1f2
--- /dev/null
+++ b/src/resolve/generate-dns_type-list.sed
@@ -0,0 +1 @@
+s/.* DNS_TYPE_(\w+).*/\1/p
diff --git a/src/resolve/meson.build b/src/resolve/meson.build
new file mode 100644
index 0000000000..fe228784fa
--- /dev/null
+++ b/src/resolve/meson.build
@@ -0,0 +1,187 @@
+basic_dns_sources = files('''
+ resolved-dns-dnssec.c
+ resolved-dns-dnssec.h
+ resolved-dns-packet.c
+ resolved-dns-packet.h
+ resolved-dns-rr.c
+ resolved-dns-rr.h
+ resolved-dns-answer.c
+ resolved-dns-answer.h
+ resolved-dns-question.c
+ resolved-dns-question.h
+ dns-type.c
+'''.split())
+
+dns_type_h = files('dns-type.h')[0]
+
+systemd_resolved_only_sources = files('''
+ resolved.c
+ resolved-manager.c
+ resolved-manager.h
+ resolved-conf.c
+ resolved-conf.h
+ resolved-resolv-conf.c
+ resolved-resolv-conf.h
+ resolved-bus.c
+ resolved-bus.h
+ resolved-link.h
+ resolved-link.c
+ resolved-link-bus.c
+ resolved-link-bus.h
+ resolved-llmnr.h
+ resolved-llmnr.c
+ resolved-mdns.h
+ resolved-mdns.c
+ resolved-def.h
+ resolved-dns-query.h
+ resolved-dns-query.c
+ resolved-dns-synthesize.h
+ resolved-dns-synthesize.c
+ resolved-dns-transaction.h
+ resolved-dns-transaction.c
+ resolved-dns-scope.h
+ resolved-dns-scope.c
+ resolved-dns-server.h
+ resolved-dns-server.c
+ resolved-dns-search-domain.h
+ resolved-dns-search-domain.c
+ resolved-dns-cache.h
+ resolved-dns-cache.c
+ resolved-dns-zone.h
+ resolved-dns-zone.c
+ resolved-dns-stream.h
+ resolved-dns-stream.c
+ resolved-dns-trust-anchor.h
+ resolved-dns-trust-anchor.c
+ resolved-dns-stub.h
+ resolved-dns-stub.c
+ resolved-etc-hosts.h
+ resolved-etc-hosts.c
+'''.split())
+
+systemd_resolve_only_sources = files('resolve-tool.c')
+
+############################################################
+
+dns_type_list_txt = custom_target(
+ 'dns_type-list.txt',
+ input : ['generate-dns_type-list.sed', dns_type_h],
+ output : 'dns_type-list.txt',
+ command : [sed, '-n', '-r', '-f', '@INPUT0@', '@INPUT1@'],
+ capture : true)
+
+generate_dns_type_gperf = find_program('generate-dns_type-gperf.py')
+
+dns_type_headers = [dns_type_h]
+foreach item : [['dns_type', dns_type_list_txt, 'dns_type', 'DNS_TYPE_']]
+
+ fname = '@0@-from-name.gperf'.format(item[0])
+ gperf_file = custom_target(
+ fname,
+ input : item[1],
+ output : fname,
+ command : [generate_dns_type_gperf, item[2], item[3], '@INPUT@'],
+ capture : true)
+
+ fname = '@0@-from-name.h'.format(item[0])
+ target1 = custom_target(
+ fname,
+ input : gperf_file,
+ output : fname,
+ command : [gperf,
+ '-L', 'ANSI-C', '-t', '--ignore-case',
+ '-N', 'lookup_@0@'.format(item[2]),
+ '-H', 'hash_@0@_name'.format(item[2]),
+ '-p', '-C',
+ '@INPUT@'],
+ capture : true)
+
+ fname = '@0@-to-name.h'.format(item[0])
+ awkscript = '@0@-to-name.awk'.format(item[0])
+ target2 = custom_target(
+ fname,
+ input : [awkscript, item[1]],
+ output : fname,
+ command : [awk, '-f', '@INPUT0@', '@INPUT1@'],
+ capture : true)
+
+ dns_type_headers += [target1, target2]
+endforeach
+
+resolved_gperf_c = custom_target(
+ 'resolved_gperf.c',
+ input : 'resolved-gperf.gperf',
+ output : 'resolved-gperf.c',
+ command : [gperf, '@INPUT@', '--output-file', '@OUTPUT@'])
+
+systemd_resolved_sources = (basic_dns_sources +
+ [resolved_gperf_c] +
+ systemd_resolved_only_sources +
+ dns_type_headers)
+
+systemd_resolve_sources = (basic_dns_sources +
+ systemd_resolve_only_sources +
+ dns_type_headers)
+
+if conf.get('ENABLE_RESOLVED', false)
+ install_data('org.freedesktop.resolve1.conf',
+ install_dir : dbuspolicydir)
+ install_data('org.freedesktop.resolve1.service',
+ install_dir : dbussystemservicedir)
+
+ resolved_conf = configure_file(
+ input : 'resolved.conf.in',
+ output : 'resolved.conf',
+ configuration : substs)
+ install_data(resolved_conf,
+ install_dir : pkgsysconfdir)
+
+ install_data('resolv.conf',
+ install_dir : rootlibexecdir)
+endif
+
+tests += [
+ [['src/resolve/test-resolve-tables.c',
+ basic_dns_sources,
+ dns_type_headers,
+ 'src/shared/test-tables.h'],
+ [],
+ [libgcrypt,
+ libgpg_error,
+ libm],
+ 'ENABLE_RESOLVED'],
+
+ [['src/resolve/test-dns-packet.c',
+ basic_dns_sources,
+ dns_type_headers],
+ [],
+ [libgcrypt,
+ libgpg_error,
+ libm],
+ 'ENABLE_RESOLVED'],
+
+ [['src/resolve/test-resolved-packet.c',
+ basic_dns_sources,
+ dns_type_headers],
+ [],
+ [libgcrypt,
+ libgpg_error,
+ libm],
+ 'ENABLE_RESOLVED'],
+
+ [['src/resolve/test-dnssec.c',
+ basic_dns_sources,
+ dns_type_headers],
+ [],
+ [libgcrypt,
+ libgpg_error,
+ libm],
+ 'ENABLE_RESOLVED'],
+
+ [['src/resolve/test-dnssec-complex.c',
+ 'src/resolve/dns-type.c',
+ dns_type_headers],
+ [],
+ [],
+ 'ENABLE_RESOLVED', 'manual'],
+]
diff --git a/src/resolve/resolved-bus.c b/src/resolve/resolved-bus.c
index 2c50109388..5aa2348576 100644
--- a/src/resolve/resolved-bus.c
+++ b/src/resolve/resolved-bus.c
@@ -345,10 +345,10 @@ static int bus_method_resolve_hostname(sd_bus_message *message, void *userdata,
return r;
r = dns_question_new_address(&question_idna, family, hostname, true);
- if (r < 0)
+ if (r < 0 && r != -EALREADY)
return r;
- r = dns_query_new(m, &q, question_utf8, question_idna, ifindex, flags);
+ r = dns_query_new(m, &q, question_utf8, question_idna ?: question_utf8, ifindex, flags);
if (r < 0)
return r;
@@ -1450,6 +1450,8 @@ static int bus_property_get_ntas(
return sd_bus_message_close_container(reply);
}
+static BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_dns_stub_listener_mode, dns_stub_listener_mode, DnsStubListenerMode);
+
static int bus_method_reset_statistics(sd_bus_message *message, void *userdata, sd_bus_error *error) {
Manager *m = userdata;
DnsScope *s;
@@ -1577,6 +1579,7 @@ static const sd_bus_vtable resolve_vtable[] = {
SD_BUS_PROPERTY("DNSSECStatistics", "(tttt)", bus_property_get_dnssec_statistics, 0, 0),
SD_BUS_PROPERTY("DNSSECSupported", "b", bus_property_get_dnssec_supported, 0, 0),
SD_BUS_PROPERTY("DNSSECNegativeTrustAnchors", "as", bus_property_get_ntas, 0, 0),
+ SD_BUS_PROPERTY("DNSStubListener", "s", bus_property_get_dns_stub_listener_mode, offsetof(Manager, dns_stub_listener_mode), 0),
SD_BUS_METHOD("ResolveHostname", "isit", "a(iiay)st", bus_method_resolve_hostname, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("ResolveAddress", "iiayt", "a(is)t", bus_method_resolve_address, SD_BUS_VTABLE_UNPRIVILEGED),
diff --git a/src/resolve/resolved-conf.c b/src/resolve/resolved-conf.c
index abf3263178..75636e0e56 100644
--- a/src/resolve/resolved-conf.c
+++ b/src/resolve/resolved-conf.c
@@ -233,10 +233,10 @@ int manager_parse_config_file(Manager *m) {
assert(m);
r = config_parse_many_nulstr(PKGSYSCONFDIR "/resolved.conf",
- CONF_PATHS_NULSTR("systemd/resolved.conf.d"),
- "Resolve\0",
- config_item_perf_lookup, resolved_gperf_lookup,
- false, m);
+ CONF_PATHS_NULSTR("systemd/resolved.conf.d"),
+ "Resolve\0",
+ config_item_perf_lookup, resolved_gperf_lookup,
+ false, m);
if (r < 0)
return r;
@@ -246,6 +246,12 @@ int manager_parse_config_file(Manager *m) {
return r;
}
+#ifndef HAVE_GCRYPT
+ if (m->dnssec_mode != DNSSEC_NO) {
+ log_warning("DNSSEC option cannot be enabled or set to allow-downgrade when systemd-resolved is built without gcrypt support. Turning off DNSSEC support.");
+ m->dnssec_mode = DNSSEC_NO;
+ }
+#endif
return 0;
}
diff --git a/src/resolve/resolved-dns-packet.c b/src/resolve/resolved-dns-packet.c
index a486216d68..49a04615d4 100644
--- a/src/resolve/resolved-dns-packet.c
+++ b/src/resolve/resolved-dns-packet.c
@@ -29,7 +29,7 @@
#define EDNS0_OPT_DO (1<<15)
#define DNS_PACKET_SIZE_START 512u
-assert_cc(DNS_PACKET_SIZE_START > UDP_PACKET_HEADER_SIZE)
+assert_cc(DNS_PACKET_SIZE_START > DNS_PACKET_HEADER_SIZE)
typedef struct DnsPacketRewinder {
DnsPacket *packet;
@@ -44,20 +44,28 @@ static void rewind_dns_packet(DnsPacketRewinder *rewinder) {
#define INIT_REWINDER(rewinder, p) do { rewinder.packet = p; rewinder.saved_rindex = p->rindex; } while (0)
#define CANCEL_REWINDER(rewinder) do { rewinder.packet = NULL; } while (0)
-int dns_packet_new(DnsPacket **ret, DnsProtocol protocol, size_t mtu) {
+int dns_packet_new(DnsPacket **ret, DnsProtocol protocol, size_t min_alloc_dsize) {
DnsPacket *p;
size_t a;
assert(ret);
- /* When dns_packet_new() is called with mtu == 0, allocate more than the
+ /* The caller may not check what is going to be truly allocated, so do not allow to
+ * allocate a DNS packet bigger than DNS_PACKET_SIZE_MAX.
+ */
+ if (min_alloc_dsize > DNS_PACKET_SIZE_MAX) {
+ log_error("Requested packet data size too big: %zu", min_alloc_dsize);
+ return -EFBIG;
+ }
+
+ /* When dns_packet_new() is called with min_alloc_dsize == 0, allocate more than the
* absolute minimum (which is the dns packet header size), to avoid
* resizing immediately again after appending the first data to the packet.
*/
- if (mtu < UDP_PACKET_HEADER_SIZE)
+ if (min_alloc_dsize < DNS_PACKET_HEADER_SIZE)
a = DNS_PACKET_SIZE_START;
else
- a = MAX(mtu, DNS_PACKET_HEADER_SIZE);
+ a = min_alloc_dsize;
/* round up to next page size */
a = PAGE_ALIGN(ALIGN(sizeof(DnsPacket)) + a) - ALIGN(sizeof(DnsPacket));
@@ -131,13 +139,13 @@ void dns_packet_set_flags(DnsPacket *p, bool dnssec_checking_disabled, bool trun
}
}
-int dns_packet_new_query(DnsPacket **ret, DnsProtocol protocol, size_t mtu, bool dnssec_checking_disabled) {
+int dns_packet_new_query(DnsPacket **ret, DnsProtocol protocol, size_t min_alloc_dsize, bool dnssec_checking_disabled) {
DnsPacket *p;
int r;
assert(ret);
- r = dns_packet_new(&p, protocol, mtu);
+ r = dns_packet_new(&p, protocol, min_alloc_dsize);
if (r < 0)
return r;
diff --git a/src/resolve/resolved-dns-packet.h b/src/resolve/resolved-dns-packet.h
index 5dff272fd9..a65d6d38cf 100644
--- a/src/resolve/resolved-dns-packet.h
+++ b/src/resolve/resolved-dns-packet.h
@@ -183,8 +183,8 @@ static inline unsigned DNS_PACKET_RRCOUNT(DnsPacket *p) {
(unsigned) DNS_PACKET_ARCOUNT(p);
}
-int dns_packet_new(DnsPacket **p, DnsProtocol protocol, size_t mtu);
-int dns_packet_new_query(DnsPacket **p, DnsProtocol protocol, size_t mtu, bool dnssec_checking_disabled);
+int dns_packet_new(DnsPacket **p, DnsProtocol protocol, size_t min_alloc_dsize);
+int dns_packet_new_query(DnsPacket **p, DnsProtocol protocol, size_t min_alloc_dsize, bool dnssec_checking_disabled);
void dns_packet_set_flags(DnsPacket *p, bool dnssec_checking_disabled, bool truncated);
diff --git a/src/resolve/resolved-dns-question.c b/src/resolve/resolved-dns-question.c
index c8b502d1cd..24f3e8e351 100644
--- a/src/resolve/resolved-dns-question.c
+++ b/src/resolve/resolved-dns-question.c
@@ -309,8 +309,14 @@ int dns_question_new_address(DnsQuestion **ret, int family, const char *name, bo
r = dns_name_apply_idna(name, &buf);
if (r < 0)
return r;
-
- name = buf;
+ if (r > 0 && !streq(name, buf))
+ name = buf;
+ else
+ /* We did not manage to create convert the idna name, or it's
+ * the same as the original name. We assume the caller already
+ * created an uncoverted question, so let's not repeat work
+ * unnecessarily. */
+ return -EALREADY;
}
q = dns_question_new(family == AF_UNSPEC ? 2 : 1);
@@ -422,8 +428,8 @@ int dns_question_new_service(
r = dns_name_apply_idna(domain, &buf);
if (r < 0)
return r;
-
- domain = buf;
+ if (r > 0)
+ domain = buf;
}
r = dns_service_join(service, type, domain, &joined);
diff --git a/src/resolve/resolved-dns-server.c b/src/resolve/resolved-dns-server.c
index 5498f7b9cb..b3d37525f4 100644
--- a/src/resolve/resolved-dns-server.c
+++ b/src/resolve/resolved-dns-server.c
@@ -17,7 +17,7 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <sd-messages.h>
+#include "sd-messages.h"
#include "alloc-util.h"
#include "resolved-dns-server.h"
@@ -304,7 +304,10 @@ void dns_server_packet_received(DnsServer *s, int protocol, DnsServerFeatureLeve
if (s->max_rtt < rtt) {
s->max_rtt = rtt;
s->resend_timeout = CLAMP(s->max_rtt * 2, DNS_TIMEOUT_MIN_USEC, DNS_TIMEOUT_MAX_USEC);
- }
+ } else if (s->resend_timeout > rtt)
+ /* If we received the packet faster than the resend_timeout, bias
+ * the resend_timeout back to the rtt. */
+ s->resend_timeout = CLAMP((2 * s->resend_timeout + rtt) / 3, DNS_TIMEOUT_MIN_USEC, DNS_TIMEOUT_MAX_USEC);
}
void dns_server_packet_lost(DnsServer *s, int protocol, DnsServerFeatureLevel level, usec_t usec) {
@@ -716,9 +719,9 @@ DnsServer *manager_set_dns_server(Manager *m, DnsServer *s) {
return s;
if (s)
- log_info("Switching to %s DNS server %s.",
- dns_server_type_to_string(s->type),
- dns_server_string(s));
+ log_debug("Switching to %s DNS server %s.",
+ dns_server_type_to_string(s->type),
+ dns_server_string(s));
dns_server_unref(m->current_dns_server);
m->current_dns_server = dns_server_ref(s);
diff --git a/src/resolve/resolved-dns-transaction.c b/src/resolve/resolved-dns-transaction.c
index ff2ad9c1de..3075f62b5e 100644
--- a/src/resolve/resolved-dns-transaction.c
+++ b/src/resolve/resolved-dns-transaction.c
@@ -17,7 +17,7 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <sd-messages.h>
+#include "sd-messages.h"
#include "af-list.h"
#include "alloc-util.h"
diff --git a/src/resolve/resolved-dns-trust-anchor.c b/src/resolve/resolved-dns-trust-anchor.c
index 7e9f9e5a20..dda9875063 100644
--- a/src/resolve/resolved-dns-trust-anchor.c
+++ b/src/resolve/resolved-dns-trust-anchor.c
@@ -17,7 +17,7 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <sd-messages.h>
+#include "sd-messages.h"
#include "alloc-util.h"
#include "conf-files.h"
diff --git a/src/resolve/resolved-link.c b/src/resolve/resolved-link.c
index d06096f3f2..61a3f20362 100644
--- a/src/resolve/resolved-link.c
+++ b/src/resolve/resolved-link.c
@@ -313,6 +313,12 @@ void link_set_dnssec_mode(Link *l, DnssecMode mode) {
assert(l);
+#ifndef HAVE_GCRYPT
+ if (mode == DNSSEC_YES || mode == DNSSEC_ALLOW_DOWNGRADE)
+ log_warning("DNSSEC option for the link cannot be enabled or set to allow-downgrade when systemd-resolved is built without gcrypt support. Turning off DNSSEC support.");
+ return;
+#endif
+
if (l->dnssec_mode == mode)
return;
@@ -556,7 +562,7 @@ bool link_relevant(Link *l, int family, bool local_multicast) {
assert(l);
- /* A link is relevant for local multicast traffic if it isn't a loopback or pointopoint device, has a link
+ /* A link is relevant for local multicast traffic if it isn't a loopback device, has a link
* beat, can do multicast and has at least one link-local (or better) IP address.
*
* A link is relevant for non-multicast traffic if it isn't a loopback device, has a link beat, and has at
@@ -569,9 +575,6 @@ bool link_relevant(Link *l, int family, bool local_multicast) {
return false;
if (local_multicast) {
- if (l->flags & IFF_POINTOPOINT)
- return false;
-
if ((l->flags & IFF_MULTICAST) != IFF_MULTICAST)
return false;
}
@@ -611,7 +614,7 @@ DnsServer* link_set_dns_server(Link *l, DnsServer *s) {
return s;
if (s)
- log_info("Switching to DNS server %s for interface %s.", dns_server_string(s), l->name);
+ log_debug("Switching to DNS server %s for interface %s.", dns_server_string(s), l->name);
dns_server_unref(l->current_dns_server);
l->current_dns_server = dns_server_ref(s);
diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c
index bcfe3d3811..7841dd99bc 100644
--- a/src/resolve/resolved-manager.c
+++ b/src/resolve/resolved-manager.c
@@ -21,6 +21,10 @@
#include <poll.h>
#include <sys/ioctl.h>
+#ifdef HAVE_LIBIDN2
+#include <idn2.h>
+#endif
+
#include "af-list.h"
#include "alloc-util.h"
#include "dirent-util.h"
@@ -324,9 +328,14 @@ static int manager_network_monitor_listen(Manager *m) {
static int determine_hostname(char **full_hostname, char **llmnr_hostname, char **mdns_hostname) {
_cleanup_free_ char *h = NULL, *n = NULL;
+#if defined(HAVE_LIBIDN2)
+ _cleanup_free_ char *utf8 = NULL;
+#elif defined(HAVE_LIBIDN)
+ int k;
+#endif
char label[DNS_LABEL_MAX];
- const char *p;
- int r, k;
+ const char *p, *decoded;
+ int r;
assert(full_hostname);
assert(llmnr_hostname);
@@ -339,7 +348,7 @@ static int determine_hostname(char **full_hostname, char **llmnr_hostname, char
return log_debug_errno(r, "Can't determine system hostname: %m");
p = h;
- r = dns_label_unescape(&p, label, sizeof(label));
+ r = dns_label_unescape(&p, label, sizeof label);
if (r < 0)
return log_error_errno(r, "Failed to unescape host name: %m");
if (r == 0) {
@@ -347,7 +356,16 @@ static int determine_hostname(char **full_hostname, char **llmnr_hostname, char
return -EINVAL;
}
- k = dns_label_undo_idna(label, r, label, sizeof(label));
+#if defined(HAVE_LIBIDN2)
+ r = idn2_to_unicode_8z8z(label, &utf8, 0);
+ if (r != IDN2_OK)
+ return log_error("Failed to undo IDNA: %s", idn2_strerror(r));
+ assert(utf8_is_valid(utf8));
+
+ r = strlen(utf8);
+ decoded = utf8;
+#elif defined(HAVE_LIBIDN)
+ k = dns_label_undo_idna(label, r, label, sizeof label);
if (k < 0)
return log_error_errno(k, "Failed to undo IDNA: %m");
if (k > 0)
@@ -357,8 +375,12 @@ static int determine_hostname(char **full_hostname, char **llmnr_hostname, char
log_error("System hostname is not UTF-8 clean.");
return -EINVAL;
}
+ decoded = label;
+#else
+ decoded = label; /* no decoding */
+#endif
- r = dns_label_escape_new(label, r, &n);
+ r = dns_label_escape_new(decoded, r, &n);
if (r < 0)
return log_error_errno(r, "Failed to escape host name: %m");
@@ -561,7 +583,7 @@ int manager_new(Manager **ret) {
r = manager_parse_config_file(m);
if (r < 0)
- return r;
+ log_warning_errno(r, "Failed to parse configuration file: %m");
r = sd_event_default(&m->event);
if (r < 0)
diff --git a/src/resolve/test-dnssec-complex.c b/src/resolve/test-dnssec-complex.c
index 3d7074af11..090b2fac23 100644
--- a/src/resolve/test-dnssec-complex.c
+++ b/src/resolve/test-dnssec-complex.c
@@ -218,7 +218,7 @@ int main(int argc, char* argv[]) {
test_hostname_lookup(bus, "poettering.de", AF_INET, NULL);
test_hostname_lookup(bus, "poettering.de", AF_INET6, NULL);
-#ifdef HAVE_LIBIDN
+#if defined(HAVE_LIBIDN2) || defined(HAVE_LIBIDN)
/* Unsigned A with IDNA conversion necessary */
test_hostname_lookup(bus, "pöttering.de", AF_UNSPEC, NULL);
test_hostname_lookup(bus, "pöttering.de", AF_INET, NULL);
diff --git a/src/resolve/test-resolved-packet.c b/src/resolve/test-resolved-packet.c
index 8b7da1408d..1b0041214b 100644
--- a/src/resolve/test-resolved-packet.c
+++ b/src/resolve/test-resolved-packet.c
@@ -22,8 +22,9 @@
static void test_dns_packet_new(void) {
size_t i;
+ _cleanup_(dns_packet_unrefp) DnsPacket *p2 = NULL;
- for (i = 0; i < DNS_PACKET_SIZE_MAX + 2; i++) {
+ for (i = 0; i <= DNS_PACKET_SIZE_MAX; i++) {
_cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
assert_se(dns_packet_new(&p, DNS_PROTOCOL_DNS, i) == 0);
@@ -31,6 +32,8 @@ static void test_dns_packet_new(void) {
log_debug("dns_packet_new: %zu → %zu", i, p->allocated);
assert_se(p->allocated >= MIN(DNS_PACKET_SIZE_MAX, i));
}
+
+ assert_se(dns_packet_new(&p2, DNS_PROTOCOL_DNS, DNS_PACKET_SIZE_MAX + 1) == -EFBIG);
}
int main(int argc, char **argv) {
diff --git a/src/run/run.c b/src/run/run.c
index 2e6765aa18..86e3040918 100644
--- a/src/run/run.c
+++ b/src/run/run.c
@@ -655,7 +655,7 @@ static int transient_scope_set_properties(sd_bus_message *m) {
if (r < 0)
return r;
- r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, (uint32_t) getpid());
+ r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, (uint32_t) getpid_cached());
if (r < 0)
return r;
diff --git a/src/shared/ask-password-api.c b/src/shared/ask-password-api.c
index e3b29e390c..0ce8e54573 100644
--- a/src/shared/ask-password-api.c
+++ b/src/shared/ask-password-api.c
@@ -49,6 +49,7 @@
#include "macro.h"
#include "missing.h"
#include "mkdir.h"
+#include "process-util.h"
#include "random-util.h"
#include "signal-util.h"
#include "socket-util.h"
@@ -519,7 +520,7 @@ int ask_password_agent(
"AcceptCached=%i\n"
"Echo=%i\n"
"NotAfter="USEC_FMT"\n",
- getpid(),
+ getpid_cached(),
socket_name,
(flags & ASK_PASSWORD_ACCEPT_CACHED) ? 1 : 0,
(flags & ASK_PASSWORD_ECHO) ? 1 : 0,
diff --git a/src/shared/base-filesystem.c b/src/shared/base-filesystem.c
index 127cbe44e3..903a187861 100644
--- a/src/shared/base-filesystem.c
+++ b/src/shared/base-filesystem.c
@@ -51,6 +51,9 @@ static const BaseFilesystem table[] = {
{ "usr", 0755, NULL, NULL },
{ "var", 0755, NULL, NULL },
{ "etc", 0755, NULL, NULL },
+ { "proc", 0755, NULL, NULL, true },
+ { "sys", 0755, NULL, NULL, true },
+ { "dev", 0755, NULL, NULL, true },
#if defined(__i386__) || defined(__x86_64__)
{ "lib64", 0, "usr/lib/x86_64-linux-gnu\0"
"usr/lib64\0", "ld-linux-x86-64.so.2" },
@@ -117,6 +120,8 @@ int base_filesystem_create(const char *root, uid_t uid, gid_t gid) {
if (!table[i].ignore_failure)
return -errno;
+
+ continue;
}
if (uid != UID_INVALID || gid != UID_INVALID) {
diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c
index aae69f6da5..5cbe663fa8 100644
--- a/src/shared/bus-unit-util.c
+++ b/src/shared/bus-unit-util.c
@@ -266,7 +266,8 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
"StandardInput", "StandardOutput", "StandardError",
"Description", "Slice", "Type", "WorkingDirectory",
"RootDirectory", "SyslogIdentifier", "ProtectSystem",
- "ProtectHome", "SELinuxContext", "Restart", "RootImage"))
+ "ProtectHome", "SELinuxContext", "Restart", "RootImage",
+ "NotifyAccess"))
r = sd_bus_message_append(m, "v", "s", eq);
else if (streq(field, "SyslogLevel")) {
@@ -389,6 +390,33 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
r = sd_bus_message_append(m, "v", "i", (int32_t) n);
+ } else if (streq(field, "FileDescriptorStoreMax")) {
+ unsigned u;
+
+ r = safe_atou(eq, &u);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse file descriptor store limit: %s", eq);
+
+ r = sd_bus_message_append(m, "v", "u", (uint32_t) u);
+
+ } else if (streq(field, "IOSchedulingClass")) {
+ int c;
+
+ c = ioprio_class_from_string(eq);
+ if (c < 0)
+ return log_error_errno(r, "Failed to parse IO scheduling class: %s", eq);
+
+ r = sd_bus_message_append(m, "v", "i", (int32_t) c);
+
+ } else if (streq(field, "IOSchedulingPriority")) {
+ int q;
+
+ r = ioprio_parse_priority(eq, &q);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse IO scheduling priority: %s", eq);
+
+ r = sd_bus_message_append(m, "v", "i", (int32_t) q);
+
} else if (STR_IN_SET(field, "Environment", "PassEnvironment")) {
const char *p;
@@ -860,7 +888,7 @@ static void log_job_error_with_service_result(const char* service, const char *r
assert(service);
- service_shell_quoted = shell_maybe_quote(service);
+ service_shell_quoted = shell_maybe_quote(service, ESCAPE_BACKSLASH);
if (extra_args) {
_cleanup_free_ char *t;
diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c
index 8ddfb584ea..207b5e66fc 100644
--- a/src/shared/bus-util.c
+++ b/src/shared/bus-util.c
@@ -725,13 +725,12 @@ int bus_print_property(const char *name, sd_bus_message *property, bool value, b
return r;
if (all || !isempty(s)) {
- _cleanup_free_ char *escaped = NULL;
+ bool good;
- escaped = xescape(s, "\n");
- if (!escaped)
- return -ENOMEM;
-
- print_property(name, "%s", escaped);
+ /* This property has a single value, so we need to take
+ * care not to print a new line, everything else is OK. */
+ good = !strchr(s, '\n');
+ print_property(name, "%s", good ? s : "[unprintable]");
}
return 1;
@@ -852,16 +851,16 @@ int bus_print_property(const char *name, sd_bus_message *property, bool value, b
return r;
while ((r = sd_bus_message_read_basic(property, SD_BUS_TYPE_STRING, &str)) > 0) {
- _cleanup_free_ char *escaped = NULL;
+ bool good;
if (first && !value)
printf("%s=", name);
- escaped = xescape(str, "\n ");
- if (!escaped)
- return -ENOMEM;
+ /* This property has multiple space-seperated values, so
+ * neither spaces not newlines can be allowed in a value. */
+ good = str[strcspn(str, " \n")] == '\0';
- printf("%s%s", first ? "" : " ", escaped);
+ printf("%s%s", first ? "" : " ", good ? str : "[unprintable]");
first = false;
}
diff --git a/src/shared/cgroup-show.c b/src/shared/cgroup-show.c
index 8765cf2f49..436130edea 100644
--- a/src/shared/cgroup-show.c
+++ b/src/shared/cgroup-show.c
@@ -24,8 +24,6 @@
#include <stdlib.h>
#include <string.h>
-#include <systemd/sd-bus.h>
-
#include "alloc-util.h"
#include "bus-error.h"
#include "bus-util.h"
diff --git a/src/shared/cgroup-show.h b/src/shared/cgroup-show.h
index 736f0f34c8..1764f76744 100644
--- a/src/shared/cgroup-show.h
+++ b/src/shared/cgroup-show.h
@@ -22,7 +22,7 @@
#include <stdbool.h>
#include <sys/types.h>
-#include <systemd/sd-bus.h>
+#include "sd-bus.h"
#include "logs-show.h"
#include "output-mode.h"
diff --git a/src/shared/condition.c b/src/shared/condition.c
index 0b77d2c22d..103f8d2e39 100644
--- a/src/shared/condition.c
+++ b/src/shared/condition.c
@@ -24,6 +24,7 @@
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
+#include <sys/types.h>
#include <time.h>
#include <unistd.h>
@@ -47,11 +48,13 @@
#include "parse-util.h"
#include "path-util.h"
#include "proc-cmdline.h"
+#include "process-util.h"
#include "selinux-util.h"
#include "smack-util.h"
#include "stat-util.h"
#include "string-table.h"
#include "string-util.h"
+#include "user-util.h"
#include "util.h"
#include "virt.h"
@@ -138,6 +141,60 @@ static int condition_test_kernel_command_line(Condition *c) {
return false;
}
+static int condition_test_user(Condition *c) {
+ uid_t id;
+ int r;
+ _cleanup_free_ char *username = NULL;
+ const char *u;
+
+ assert(c);
+ assert(c->parameter);
+ assert(c->type == CONDITION_USER);
+
+ r = parse_uid(c->parameter, &id);
+ if (r >= 0)
+ return id == getuid() || id == geteuid();
+
+ if (streq("@system", c->parameter))
+ return getuid() <= SYSTEM_UID_MAX || geteuid() <= SYSTEM_UID_MAX;
+
+ username = getusername_malloc();
+ if (!username)
+ return -ENOMEM;
+
+ if (streq(username, c->parameter))
+ return 1;
+
+ if (getpid_cached() == 1)
+ return streq(c->parameter, "root");
+
+ u = c->parameter;
+ r = get_user_creds(&u, &id, NULL, NULL, NULL);
+ if (r < 0)
+ return 0;
+
+ return id == getuid() || id == geteuid();
+}
+
+static int condition_test_group(Condition *c) {
+ gid_t id;
+ int r;
+
+ assert(c);
+ assert(c->parameter);
+ assert(c->type == CONDITION_GROUP);
+
+ r = parse_gid(c->parameter, &id);
+ if (r >= 0)
+ return in_gid(id);
+
+ /* Avoid any NSS lookups if we are PID1 */
+ if (getpid_cached() == 1)
+ return streq(c->parameter, "root");
+
+ return in_group(c->parameter) > 0;
+}
+
static int condition_test_virtualization(Condition *c) {
int b, v;
@@ -235,7 +292,7 @@ static int condition_test_security(Condition *c) {
assert(c->type == CONDITION_SECURITY);
if (streq(c->parameter, "selinux"))
- return mac_selinux_have();
+ return mac_selinux_use();
if (streq(c->parameter, "smack"))
return mac_smack_use();
if (streq(c->parameter, "apparmor"))
@@ -475,6 +532,8 @@ int condition_test(Condition *c) {
[CONDITION_ARCHITECTURE] = condition_test_architecture,
[CONDITION_NEEDS_UPDATE] = condition_test_needs_update,
[CONDITION_FIRST_BOOT] = condition_test_first_boot,
+ [CONDITION_USER] = condition_test_user,
+ [CONDITION_GROUP] = condition_test_group,
[CONDITION_NULL] = condition_test_null,
};
@@ -538,6 +597,8 @@ static const char* const condition_type_table[_CONDITION_TYPE_MAX] = {
[CONDITION_DIRECTORY_NOT_EMPTY] = "ConditionDirectoryNotEmpty",
[CONDITION_FILE_NOT_EMPTY] = "ConditionFileNotEmpty",
[CONDITION_FILE_IS_EXECUTABLE] = "ConditionFileIsExecutable",
+ [CONDITION_USER] = "ConditionUser",
+ [CONDITION_GROUP] = "ConditionGroup",
[CONDITION_NULL] = "ConditionNull"
};
@@ -562,6 +623,8 @@ static const char* const assert_type_table[_CONDITION_TYPE_MAX] = {
[CONDITION_DIRECTORY_NOT_EMPTY] = "AssertDirectoryNotEmpty",
[CONDITION_FILE_NOT_EMPTY] = "AssertFileNotEmpty",
[CONDITION_FILE_IS_EXECUTABLE] = "AssertFileIsExecutable",
+ [CONDITION_USER] = "AssertUser",
+ [CONDITION_GROUP] = "AssertGroup",
[CONDITION_NULL] = "AssertNull"
};
diff --git a/src/shared/condition.h b/src/shared/condition.h
index bdda04b770..d0b592bc43 100644
--- a/src/shared/condition.h
+++ b/src/shared/condition.h
@@ -49,6 +49,9 @@ typedef enum ConditionType {
CONDITION_NULL,
+ CONDITION_USER,
+ CONDITION_GROUP,
+
_CONDITION_TYPE_MAX,
_CONDITION_TYPE_INVALID = -1
} ConditionType;
diff --git a/src/shared/conf-parser.c b/src/shared/conf-parser.c
index 863034d18a..e08402e3d2 100644
--- a/src/shared/conf-parser.c
+++ b/src/shared/conf-parser.c
@@ -506,6 +506,7 @@ int config_parse_many(
DEFINE_PARSER(int, int, safe_atoi);
DEFINE_PARSER(long, long, safe_atoli);
+DEFINE_PARSER(uint8, uint8_t, safe_atou8);
DEFINE_PARSER(uint16, uint16_t, safe_atou16);
DEFINE_PARSER(uint32, uint32_t, safe_atou32);
DEFINE_PARSER(uint64, uint64_t, safe_atou64);
@@ -614,6 +615,7 @@ int config_parse_bool(const char* unit,
int k;
bool *b = data;
+ bool fatal = ltype;
assert(filename);
assert(lvalue);
@@ -622,8 +624,10 @@ int config_parse_bool(const char* unit,
k = parse_boolean(rvalue);
if (k < 0) {
- log_syntax(unit, LOG_ERR, filename, line, k, "Failed to parse boolean value, ignoring: %s", rvalue);
- return 0;
+ log_syntax(unit, LOG_ERR, filename, line, k,
+ "Failed to parse boolean value%s: %s",
+ fatal ? "" : ", ignoring", rvalue);
+ return fatal ? -ENOEXEC : 0;
}
*b = !!k;
@@ -714,6 +718,7 @@ int config_parse_path(
void *userdata) {
char **s = data, *n;
+ bool fatal = ltype;
assert(filename);
assert(lvalue);
@@ -722,12 +727,14 @@ int config_parse_path(
if (!utf8_is_valid(rvalue)) {
log_syntax_invalid_utf8(unit, LOG_ERR, filename, line, rvalue);
- return 0;
+ return fatal ? -ENOEXEC : 0;
}
if (!path_is_absolute(rvalue)) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Not an absolute path, ignoring: %s", rvalue);
- return 0;
+ log_syntax(unit, LOG_ERR, filename, line, 0,
+ "Not an absolute path%s: %s",
+ fatal ? "" : ", ignoring", rvalue);
+ return fatal ? -ENOEXEC : 0;
}
n = strdup(rvalue);
@@ -959,3 +966,40 @@ int config_parse_ifname(
return 0;
}
+
+int config_parse_ip_port(
+ 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) {
+
+ uint16_t *s = data;
+ uint16_t port;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ if (isempty(rvalue)) {
+ *s = 0;
+ return 0;
+ }
+
+ r = parse_ip_port(rvalue, &port);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse port '%s'.", rvalue);
+ return 0;
+ }
+
+ *s = port;
+
+ return 0;
+}
diff --git a/src/shared/conf-parser.h b/src/shared/conf-parser.h
index 26ff3df16f..ce1113485d 100644
--- a/src/shared/conf-parser.h
+++ b/src/shared/conf-parser.h
@@ -119,6 +119,7 @@ int config_parse_many(
int config_parse_int(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_unsigned(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_long(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_uint8(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_uint16(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_uint32(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_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);
@@ -139,6 +140,7 @@ int config_parse_log_level(const char *unit, const char *filename, unsigned line
int config_parse_signal(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_personality(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_ifname(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_ip_port(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);
#define DEFINE_CONFIG_PARSE_ENUM(function,name,type,msg) \
int function(const char *unit, \
diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c
index 39e724c51a..505a83f54f 100644
--- a/src/shared/dissect-image.c
+++ b/src/shared/dissect-image.c
@@ -20,7 +20,6 @@
#ifdef HAVE_LIBCRYPTSETUP
#include <libcryptsetup.h>
#endif
-#include <linux/dm-ioctl.h>
#include <sys/mount.h>
#include "architecture.h"
@@ -32,6 +31,7 @@
#include "fs-util.h"
#include "gpt.h"
#include "hexdecoct.h"
+#include "linux-3.13/dm-ioctl.h"
#include "mount-util.h"
#include "path-util.h"
#include "stat-util.h"
@@ -42,7 +42,7 @@
#include "udev-util.h"
#include "xattr-util.h"
-static int probe_filesystem(const char *node, char **ret_fstype) {
+_unused_ static int probe_filesystem(const char *node, char **ret_fstype) {
#ifdef HAVE_BLKID
_cleanup_blkid_free_probe_ blkid_probe b = NULL;
const char *fstype;
@@ -301,7 +301,7 @@ int dissect_image(int fd, const void *root_hash, size_t root_hash_size, DissectI
_cleanup_udev_device_unref_ struct udev_device *q;
unsigned long long pflags;
blkid_partition pp;
- const char *node;
+ const char *node, *sysname;
dev_t qn;
int nr;
@@ -316,6 +316,12 @@ int dissect_image(int fd, const void *root_hash, size_t root_hash_size, DissectI
if (st.st_rdev == qn)
continue;
+ /* Filter out weird MMC RPMB partitions, which cannot reasonably be read, see
+ * https://github.com/systemd/systemd/issues/5806 */
+ sysname = udev_device_get_sysname(q);
+ if (sysname && startswith(sysname, "mmcblk") && endswith(sysname, "rpmb"))
+ continue;
+
node = udev_device_get_devnode(q);
if (!node)
continue;
@@ -951,7 +957,7 @@ int dissected_image_decrypt(
*
* = 0 → There was nothing to decrypt
* > 0 → Decrypted successfully
- * -ENOKEY → There's some to decrypt but no key was supplied
+ * -ENOKEY → There's something to decrypt but no key was supplied
* -EKEYREJECTED → Passed key was not correct
*/
diff --git a/src/shared/dns-domain.c b/src/shared/dns-domain.c
index 33debadb15..12c4d65dd3 100644
--- a/src/shared/dns-domain.c
+++ b/src/shared/dns-domain.c
@@ -17,9 +17,11 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#ifdef HAVE_LIBIDN
-#include <idna.h>
-#include <stringprep.h>
+#if defined(HAVE_LIBIDN2)
+# include <idn2.h>
+#elif defined(HAVE_LIBIDN)
+# include <idna.h>
+# include <stringprep.h>
#endif
#include <endian.h>
@@ -299,8 +301,8 @@ int dns_label_escape_new(const char *p, size_t l, char **ret) {
return r;
}
-int dns_label_apply_idna(const char *encoded, size_t encoded_size, char *decoded, size_t decoded_max) {
#ifdef HAVE_LIBIDN
+int dns_label_apply_idna(const char *encoded, size_t encoded_size, char *decoded, size_t decoded_max) {
_cleanup_free_ uint32_t *input = NULL;
size_t input_size, l;
const char *p;
@@ -348,13 +350,9 @@ int dns_label_apply_idna(const char *encoded, size_t encoded_size, char *decoded
decoded[l] = 0;
return (int) l;
-#else
- return 0;
-#endif
}
int dns_label_undo_idna(const char *encoded, size_t encoded_size, char *decoded, size_t decoded_max) {
-#ifdef HAVE_LIBIDN
size_t input_size, output_size;
_cleanup_free_ uint32_t *input = NULL;
_cleanup_free_ char *result = NULL;
@@ -399,10 +397,8 @@ int dns_label_undo_idna(const char *encoded, size_t encoded_size, char *decoded,
decoded[w] = 0;
return w;
-#else
- return 0;
-#endif
}
+#endif
int dns_name_concat(const char *a, const char *b, char **_ret) {
_cleanup_free_ char *ret = NULL;
@@ -1274,6 +1270,26 @@ int dns_name_common_suffix(const char *a, const char *b, const char **ret) {
}
int dns_name_apply_idna(const char *name, char **ret) {
+ /* Return negative on error, 0 if not implemented, positive on success. */
+
+#if defined(HAVE_LIBIDN2)
+ int r;
+
+ assert(name);
+ assert(ret);
+
+ r = idn2_lookup_u8((uint8_t*) name, (uint8_t**) ret,
+ IDN2_NFC_INPUT | IDN2_NONTRANSITIONAL);
+ if (r == IDN2_OK)
+ return 1; /* *ret has been written */
+ log_debug("idn2_lookup_u8(\"%s\") failed: %s", name, idn2_strerror(r));
+ if (r == IDN2_2HYPHEN)
+ /* The name has two hypens — forbidden by IDNA2008 in some cases */
+ return 0;
+ if (IN_SET(r, IDN2_TOO_BIG_DOMAIN, IDN2_TOO_BIG_LABEL))
+ return -ENOSPC;
+ return -EINVAL;
+#elif defined(HAVE_LIBIDN)
_cleanup_free_ char *buf = NULL;
size_t n = 0, allocated = 0;
bool first = true;
@@ -1309,7 +1325,7 @@ int dns_name_apply_idna(const char *name, char **ret) {
else
buf[n++] = '.';
- n +=r;
+ n += r;
}
if (n > DNS_HOSTNAME_MAX)
@@ -1322,7 +1338,10 @@ int dns_name_apply_idna(const char *name, char **ret) {
*ret = buf;
buf = NULL;
- return (int) n;
+ return 1;
+#else
+ return 0;
+#endif
}
int dns_name_is_valid_or_address(const char *name) {
diff --git a/src/shared/dns-domain.h b/src/shared/dns-domain.h
index 03f160369c..fca025def0 100644
--- a/src/shared/dns-domain.h
+++ b/src/shared/dns-domain.h
@@ -51,8 +51,10 @@ static inline int dns_name_parent(const char **name) {
return dns_label_unescape(name, NULL, DNS_LABEL_MAX);
}
+#if defined(HAVE_LIBIDN)
int dns_label_apply_idna(const char *encoded, size_t encoded_size, char *decoded, size_t decoded_max);
int dns_label_undo_idna(const char *encoded, size_t encoded_size, char *decoded, size_t decoded_max);
+#endif
int dns_name_concat(const char *a, const char *b, char **ret);
diff --git a/src/shared/efivars.c b/src/shared/efivars.c
index 8631a5a5d9..8229e6b183 100644
--- a/src/shared/efivars.c
+++ b/src/shared/efivars.c
@@ -269,6 +269,7 @@ int efi_set_variable(
_cleanup_close_ int fd = -1;
assert(name);
+ assert(value);
if (asprintf(&p,
"/sys/firmware/efi/efivars/%s-%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
diff --git a/src/shared/fstab-util.c b/src/shared/fstab-util.c
index c3106f1ae9..ec2e868ca8 100644
--- a/src/shared/fstab-util.c
+++ b/src/shared/fstab-util.c
@@ -34,18 +34,43 @@
#include "strv.h"
#include "util.h"
-bool fstab_is_mount_point(const char *mount) {
+int fstab_has_fstype(const char *fstype) {
_cleanup_endmntent_ FILE *f = NULL;
struct mntent *m;
f = setmntent("/etc/fstab", "re");
if (!f)
- return false;
+ return errno == ENOENT ? false : -errno;
- while ((m = getmntent(f)))
- if (path_equal(m->mnt_dir, mount))
+ for (;;) {
+ errno = 0;
+ m = getmntent(f);
+ if (!m)
+ return errno != 0 ? -errno : false;
+
+ if (streq(m->mnt_type, fstype))
return true;
+ }
+ return false;
+}
+
+int fstab_is_mount_point(const char *mount) {
+ _cleanup_endmntent_ FILE *f = NULL;
+ struct mntent *m;
+ f = setmntent("/etc/fstab", "re");
+ if (!f)
+ return errno == ENOENT ? false : -errno;
+
+ for (;;) {
+ errno = 0;
+ m = getmntent(f);
+ if (!m)
+ return errno != 0 ? -errno : false;
+
+ if (path_equal(m->mnt_dir, mount))
+ return true;
+ }
return false;
}
diff --git a/src/shared/fstab-util.h b/src/shared/fstab-util.h
index 679f6902f7..bbf0441351 100644
--- a/src/shared/fstab-util.h
+++ b/src/shared/fstab-util.h
@@ -24,7 +24,8 @@
#include "macro.h"
-bool fstab_is_mount_point(const char *mount);
+int fstab_is_mount_point(const char *mount);
+int fstab_has_fstype(const char *fstype);
int fstab_filter_options(const char *opts, const char *names, const char **namefound, char **value, char **filtered);
diff --git a/src/shared/generator.c b/src/shared/generator.c
index 9a069b2f97..6a887e3aad 100644
--- a/src/shared/generator.c
+++ b/src/shared/generator.c
@@ -167,12 +167,13 @@ int generator_write_timeouts(
usec_t u;
int r;
- r = fstab_filter_options(opts, "comment=systemd.device-timeout\0" "x-systemd.device-timeout\0",
+ r = fstab_filter_options(opts, "comment=systemd.device-timeout\0"
+ "x-systemd.device-timeout\0",
NULL, &timeout, filtered);
if (r <= 0)
return r;
- r = parse_sec(timeout, &u);
+ r = parse_sec_fix_0(timeout, &u);
if (r < 0) {
log_warning("Failed to parse timeout for %s, ignoring: %s", where, timeout);
return 0;
@@ -181,6 +182,10 @@ int generator_write_timeouts(
node = fstab_node_to_udev_node(what);
if (!node)
return log_oom();
+ if (!is_device_path(node)) {
+ log_warning("x-systemd.device-timeout ignored for %s", what);
+ return 0;
+ }
r = unit_name_from_path(node, ".device", &unit);
if (r < 0)
@@ -188,10 +193,49 @@ int generator_write_timeouts(
return write_drop_in_format(dir, unit, 50, "device-timeout",
"# Automatically generated by %s\n\n"
- "[Unit]\nJobTimeoutSec=%s",
+ "[Unit]\nJobRunningTimeoutSec=%s",
program_invocation_short_name, timeout);
}
+int generator_write_device_deps(
+ const char *dir,
+ const char *what,
+ const char *where,
+ const char *opts) {
+
+ /* fstab records that specify _netdev option should apply the network
+ * ordering on the actual device depending on network connection. If we
+ * are not mounting real device (NFS, CIFS), we rely on _netdev effect
+ * on the mount unit itself. */
+
+ _cleanup_free_ char *node = NULL, *unit = NULL;
+ int r;
+
+ if (!fstab_test_option(opts, "_netdev\0"))
+ return 0;
+
+ node = fstab_node_to_udev_node(what);
+ if (!node)
+ return log_oom();
+
+ /* Nothing to apply dependencies to. */
+ if (!is_device_path(node))
+ return 0;
+
+ r = unit_name_from_path(node, ".device", &unit);
+ if (r < 0)
+ return log_error_errno(r, "Failed to make unit name from path: %m");
+
+ /* See mount_add_default_dependencies for explanation why we create such
+ * dependencies. */
+ return write_drop_in_format(dir, unit, 50, "netdev-dependencies",
+ "# Automatically generated by %s\n\n"
+ "[Unit]\n"
+ "After=" SPECIAL_NETWORK_ONLINE_TARGET " " SPECIAL_NETWORK_TARGET "\n"
+ "Wants=" SPECIAL_NETWORK_ONLINE_TARGET "\n",
+ program_invocation_short_name);
+}
+
int generator_write_initrd_root_device_deps(const char *dir, const char *what) {
_cleanup_free_ char *unit = NULL;
int r;
diff --git a/src/shared/generator.h b/src/shared/generator.h
index a6017c1b76..825d934c8e 100644
--- a/src/shared/generator.h
+++ b/src/shared/generator.h
@@ -35,6 +35,12 @@ int generator_write_timeouts(
const char *opts,
char **filtered);
+int generator_write_device_deps(
+ 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);
diff --git a/src/shared/install.c b/src/shared/install.c
index 58c8e852b2..d0a291b819 100644
--- a/src/shared/install.c
+++ b/src/shared/install.c
@@ -422,7 +422,7 @@ static bool chroot_symlinks_same(const char *root, const char *wd, const char *a
a = strjoina(path_is_absolute(a) ? root : wd, "/", a);
b = strjoina(path_is_absolute(b) ? root : wd, "/", b);
- return path_equal_or_files_same(a, b);
+ return path_equal_or_files_same(a, b, 0);
}
static int create_symlink(
@@ -3045,7 +3045,7 @@ int unit_file_get_list(
if (errno == ENOENT)
continue;
if (IN_SET(errno, ENOTDIR, EACCES)) {
- log_debug("Failed to open \"%s\": %m", *i);
+ log_debug_errno(errno, "Failed to open \"%s\": %m", *i);
continue;
}
diff --git a/src/shared/linux-3.13/dm-ioctl.h b/src/shared/linux-3.13/dm-ioctl.h
new file mode 100644
index 0000000000..c8a4302093
--- /dev/null
+++ b/src/shared/linux-3.13/dm-ioctl.h
@@ -0,0 +1,355 @@
+/*
+ * Copyright (C) 2001 - 2003 Sistina Software (UK) Limited.
+ * Copyright (C) 2004 - 2009 Red Hat, Inc. All rights reserved.
+ *
+ * This file is released under the LGPL.
+ */
+
+#ifndef _LINUX_DM_IOCTL_V4_H
+#define _LINUX_DM_IOCTL_V4_H
+
+#include <linux/types.h>
+
+#define DM_DIR "mapper" /* Slashes not supported */
+#define DM_CONTROL_NODE "control"
+#define DM_MAX_TYPE_NAME 16
+#define DM_NAME_LEN 128
+#define DM_UUID_LEN 129
+
+/*
+ * A traditional ioctl interface for the device mapper.
+ *
+ * Each device can have two tables associated with it, an
+ * 'active' table which is the one currently used by io passing
+ * through the device, and an 'inactive' one which is a table
+ * that is being prepared as a replacement for the 'active' one.
+ *
+ * DM_VERSION:
+ * Just get the version information for the ioctl interface.
+ *
+ * DM_REMOVE_ALL:
+ * Remove all dm devices, destroy all tables. Only really used
+ * for debug.
+ *
+ * DM_LIST_DEVICES:
+ * Get a list of all the dm device names.
+ *
+ * DM_DEV_CREATE:
+ * Create a new device, neither the 'active' or 'inactive' table
+ * slots will be filled. The device will be in suspended state
+ * after creation, however any io to the device will get errored
+ * since it will be out-of-bounds.
+ *
+ * DM_DEV_REMOVE:
+ * Remove a device, destroy any tables.
+ *
+ * DM_DEV_RENAME:
+ * Rename a device or set its uuid if none was previously supplied.
+ *
+ * DM_SUSPEND:
+ * This performs both suspend and resume, depending which flag is
+ * passed in.
+ * Suspend: This command will not return until all pending io to
+ * the device has completed. Further io will be deferred until
+ * the device is resumed.
+ * Resume: It is no longer an error to issue this command on an
+ * unsuspended device. If a table is present in the 'inactive'
+ * slot, it will be moved to the active slot, then the old table
+ * from the active slot will be _destroyed_. Finally the device
+ * is resumed.
+ *
+ * DM_DEV_STATUS:
+ * Retrieves the status for the table in the 'active' slot.
+ *
+ * DM_DEV_WAIT:
+ * Wait for a significant event to occur to the device. This
+ * could either be caused by an event triggered by one of the
+ * targets of the table in the 'active' slot, or a table change.
+ *
+ * DM_TABLE_LOAD:
+ * Load a table into the 'inactive' slot for the device. The
+ * device does _not_ need to be suspended prior to this command.
+ *
+ * DM_TABLE_CLEAR:
+ * Destroy any table in the 'inactive' slot (ie. abort).
+ *
+ * DM_TABLE_DEPS:
+ * Return a set of device dependencies for the 'active' table.
+ *
+ * DM_TABLE_STATUS:
+ * Return the targets status for the 'active' table.
+ *
+ * DM_TARGET_MSG:
+ * Pass a message string to the target at a specific offset of a device.
+ *
+ * DM_DEV_SET_GEOMETRY:
+ * Set the geometry of a device by passing in a string in this format:
+ *
+ * "cylinders heads sectors_per_track start_sector"
+ *
+ * Beware that CHS geometry is nearly obsolete and only provided
+ * for compatibility with dm devices that can be booted by a PC
+ * BIOS. See struct hd_geometry for range limits. Also note that
+ * the geometry is erased if the device size changes.
+ */
+
+/*
+ * All ioctl arguments consist of a single chunk of memory, with
+ * this structure at the start. If a uuid is specified any
+ * lookup (eg. for a DM_INFO) will be done on that, *not* the
+ * name.
+ */
+struct dm_ioctl {
+ /*
+ * The version number is made up of three parts:
+ * major - no backward or forward compatibility,
+ * minor - only backwards compatible,
+ * patch - both backwards and forwards compatible.
+ *
+ * All clients of the ioctl interface should fill in the
+ * version number of the interface that they were
+ * compiled with.
+ *
+ * All recognised ioctl commands (ie. those that don't
+ * return -ENOTTY) fill out this field, even if the
+ * command failed.
+ */
+ __u32 version[3]; /* in/out */
+ __u32 data_size; /* total size of data passed in
+ * including this struct */
+
+ __u32 data_start; /* offset to start of data
+ * relative to start of this struct */
+
+ __u32 target_count; /* in/out */
+ __s32 open_count; /* out */
+ __u32 flags; /* in/out */
+
+ /*
+ * event_nr holds either the event number (input and output) or the
+ * udev cookie value (input only).
+ * The DM_DEV_WAIT ioctl takes an event number as input.
+ * The DM_SUSPEND, DM_DEV_REMOVE and DM_DEV_RENAME ioctls
+ * use the field as a cookie to return in the DM_COOKIE
+ * variable with the uevents they issue.
+ * For output, the ioctls return the event number, not the cookie.
+ */
+ __u32 event_nr; /* in/out */
+ __u32 padding;
+
+ __u64 dev; /* in/out */
+
+ char name[DM_NAME_LEN]; /* device name */
+ char uuid[DM_UUID_LEN]; /* unique identifier for
+ * the block device */
+ char data[7]; /* padding or data */
+};
+
+/*
+ * Used to specify tables. These structures appear after the
+ * dm_ioctl.
+ */
+struct dm_target_spec {
+ __u64 sector_start;
+ __u64 length;
+ __s32 status; /* used when reading from kernel only */
+
+ /*
+ * Location of the next dm_target_spec.
+ * - When specifying targets on a DM_TABLE_LOAD command, this value is
+ * the number of bytes from the start of the "current" dm_target_spec
+ * to the start of the "next" dm_target_spec.
+ * - When retrieving targets on a DM_TABLE_STATUS command, this value
+ * is the number of bytes from the start of the first dm_target_spec
+ * (that follows the dm_ioctl struct) to the start of the "next"
+ * dm_target_spec.
+ */
+ __u32 next;
+
+ char target_type[DM_MAX_TYPE_NAME];
+
+ /*
+ * Parameter string starts immediately after this object.
+ * Be careful to add padding after string to ensure correct
+ * alignment of subsequent dm_target_spec.
+ */
+};
+
+/*
+ * Used to retrieve the target dependencies.
+ */
+struct dm_target_deps {
+ __u32 count; /* Array size */
+ __u32 padding; /* unused */
+ __u64 dev[0]; /* out */
+};
+
+/*
+ * Used to get a list of all dm devices.
+ */
+struct dm_name_list {
+ __u64 dev;
+ __u32 next; /* offset to the next record from
+ the _start_ of this */
+ char name[0];
+};
+
+/*
+ * Used to retrieve the target versions
+ */
+struct dm_target_versions {
+ __u32 next;
+ __u32 version[3];
+
+ char name[0];
+};
+
+/*
+ * Used to pass message to a target
+ */
+struct dm_target_msg {
+ __u64 sector; /* Device sector */
+
+ char message[0];
+};
+
+/*
+ * If you change this make sure you make the corresponding change
+ * to dm-ioctl.c:lookup_ioctl()
+ */
+enum {
+ /* Top level cmds */
+ DM_VERSION_CMD = 0,
+ DM_REMOVE_ALL_CMD,
+ DM_LIST_DEVICES_CMD,
+
+ /* device level cmds */
+ DM_DEV_CREATE_CMD,
+ DM_DEV_REMOVE_CMD,
+ DM_DEV_RENAME_CMD,
+ DM_DEV_SUSPEND_CMD,
+ DM_DEV_STATUS_CMD,
+ DM_DEV_WAIT_CMD,
+
+ /* Table level cmds */
+ DM_TABLE_LOAD_CMD,
+ DM_TABLE_CLEAR_CMD,
+ DM_TABLE_DEPS_CMD,
+ DM_TABLE_STATUS_CMD,
+
+ /* Added later */
+ DM_LIST_VERSIONS_CMD,
+ DM_TARGET_MSG_CMD,
+ DM_DEV_SET_GEOMETRY_CMD
+};
+
+#define DM_IOCTL 0xfd
+
+#define DM_VERSION _IOWR(DM_IOCTL, DM_VERSION_CMD, struct dm_ioctl)
+#define DM_REMOVE_ALL _IOWR(DM_IOCTL, DM_REMOVE_ALL_CMD, struct dm_ioctl)
+#define DM_LIST_DEVICES _IOWR(DM_IOCTL, DM_LIST_DEVICES_CMD, struct dm_ioctl)
+
+#define DM_DEV_CREATE _IOWR(DM_IOCTL, DM_DEV_CREATE_CMD, struct dm_ioctl)
+#define DM_DEV_REMOVE _IOWR(DM_IOCTL, DM_DEV_REMOVE_CMD, struct dm_ioctl)
+#define DM_DEV_RENAME _IOWR(DM_IOCTL, DM_DEV_RENAME_CMD, struct dm_ioctl)
+#define DM_DEV_SUSPEND _IOWR(DM_IOCTL, DM_DEV_SUSPEND_CMD, struct dm_ioctl)
+#define DM_DEV_STATUS _IOWR(DM_IOCTL, DM_DEV_STATUS_CMD, struct dm_ioctl)
+#define DM_DEV_WAIT _IOWR(DM_IOCTL, DM_DEV_WAIT_CMD, struct dm_ioctl)
+
+#define DM_TABLE_LOAD _IOWR(DM_IOCTL, DM_TABLE_LOAD_CMD, struct dm_ioctl)
+#define DM_TABLE_CLEAR _IOWR(DM_IOCTL, DM_TABLE_CLEAR_CMD, struct dm_ioctl)
+#define DM_TABLE_DEPS _IOWR(DM_IOCTL, DM_TABLE_DEPS_CMD, struct dm_ioctl)
+#define DM_TABLE_STATUS _IOWR(DM_IOCTL, DM_TABLE_STATUS_CMD, struct dm_ioctl)
+
+#define DM_LIST_VERSIONS _IOWR(DM_IOCTL, DM_LIST_VERSIONS_CMD, struct dm_ioctl)
+
+#define DM_TARGET_MSG _IOWR(DM_IOCTL, DM_TARGET_MSG_CMD, struct dm_ioctl)
+#define DM_DEV_SET_GEOMETRY _IOWR(DM_IOCTL, DM_DEV_SET_GEOMETRY_CMD, struct dm_ioctl)
+
+#define DM_VERSION_MAJOR 4
+#define DM_VERSION_MINOR 27
+#define DM_VERSION_PATCHLEVEL 0
+#define DM_VERSION_EXTRA "-ioctl (2013-10-30)"
+
+/* Status bits */
+#define DM_READONLY_FLAG (1 << 0) /* In/Out */
+#define DM_SUSPEND_FLAG (1 << 1) /* In/Out */
+#define DM_PERSISTENT_DEV_FLAG (1 << 3) /* In */
+
+/*
+ * Flag passed into ioctl STATUS command to get table information
+ * rather than current status.
+ */
+#define DM_STATUS_TABLE_FLAG (1 << 4) /* In */
+
+/*
+ * Flags that indicate whether a table is present in either of
+ * the two table slots that a device has.
+ */
+#define DM_ACTIVE_PRESENT_FLAG (1 << 5) /* Out */
+#define DM_INACTIVE_PRESENT_FLAG (1 << 6) /* Out */
+
+/*
+ * Indicates that the buffer passed in wasn't big enough for the
+ * results.
+ */
+#define DM_BUFFER_FULL_FLAG (1 << 8) /* Out */
+
+/*
+ * This flag is now ignored.
+ */
+#define DM_SKIP_BDGET_FLAG (1 << 9) /* In */
+
+/*
+ * Set this to avoid attempting to freeze any filesystem when suspending.
+ */
+#define DM_SKIP_LOCKFS_FLAG (1 << 10) /* In */
+
+/*
+ * Set this to suspend without flushing queued ios.
+ * Also disables flushing uncommitted changes in the thin target before
+ * generating statistics for DM_TABLE_STATUS and DM_DEV_WAIT.
+ */
+#define DM_NOFLUSH_FLAG (1 << 11) /* In */
+
+/*
+ * If set, any table information returned will relate to the inactive
+ * table instead of the live one. Always check DM_INACTIVE_PRESENT_FLAG
+ * is set before using the data returned.
+ */
+#define DM_QUERY_INACTIVE_TABLE_FLAG (1 << 12) /* In */
+
+/*
+ * If set, a uevent was generated for which the caller may need to wait.
+ */
+#define DM_UEVENT_GENERATED_FLAG (1 << 13) /* Out */
+
+/*
+ * If set, rename changes the uuid not the name. Only permitted
+ * if no uuid was previously supplied: an existing uuid cannot be changed.
+ */
+#define DM_UUID_FLAG (1 << 14) /* In */
+
+/*
+ * If set, all buffers are wiped after use. Use when sending
+ * or requesting sensitive data such as an encryption key.
+ */
+#define DM_SECURE_DATA_FLAG (1 << 15) /* In */
+
+/*
+ * If set, a message generated output data.
+ */
+#define DM_DATA_OUT_FLAG (1 << 16) /* Out */
+
+/*
+ * If set with DM_DEV_REMOVE or DM_REMOVE_ALL this indicates that if
+ * the device cannot be removed immediately because it is still in use
+ * it should instead be scheduled for removal when it gets closed.
+ *
+ * On return from DM_DEV_REMOVE, DM_DEV_STATUS or other ioctls, this
+ * flag indicates that the device is scheduled to be removed when it
+ * gets closed.
+ */
+#define DM_DEFERRED_REMOVE (1 << 17) /* In/Out */
+
+#endif /* _LINUX_DM_IOCTL_H */
diff --git a/src/shared/logs-show.c b/src/shared/logs-show.c
index b4c72215c4..02ae4265c6 100644
--- a/src/shared/logs-show.c
+++ b/src/shared/logs-show.c
@@ -264,6 +264,8 @@ static int output_timestamp_realtime(FILE *f, sd_journal *j, OutputMode mode, Ou
}
} else {
+ char usec[7];
+
gettime_r = (flags & OUTPUT_UTC) ? gmtime_r : localtime_r;
t = (time_t) (x / USEC_PER_SEC);
@@ -275,9 +277,19 @@ static int output_timestamp_realtime(FILE *f, sd_journal *j, OutputMode mode, Ou
case OUTPUT_SHORT_ISO:
if (strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%S%z", gettime_r(&t, &tm)) <= 0) {
- log_error("Failed for format ISO time");
+ log_error("Failed to format ISO time");
+ return -EINVAL;
+ }
+ break;
+
+ case OUTPUT_SHORT_ISO_PRECISE:
+ /* No usec in strftime, so we leave space and copy over */
+ if (strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%S.xxxxxx%z", gettime_r(&t, &tm)) <= 0) {
+ log_error("Failed to format ISO-precise time");
return -EINVAL;
}
+ xsprintf(usec, "%06"PRI_USEC, x % USEC_PER_SEC);
+ memcpy(buf + 20, usec, 6);
break;
case OUTPUT_SHORT:
@@ -950,6 +962,7 @@ static int (*output_funcs[_OUTPUT_MODE_MAX])(
[OUTPUT_SHORT] = output_short,
[OUTPUT_SHORT_ISO] = output_short,
+ [OUTPUT_SHORT_ISO_PRECISE] = output_short,
[OUTPUT_SHORT_PRECISE] = output_short,
[OUTPUT_SHORT_MONOTONIC] = output_short,
[OUTPUT_SHORT_UNIX] = output_short,
@@ -978,7 +991,6 @@ int output_journal(
n_columns = columns();
ret = output_funcs[mode](f, j, mode, n_columns, flags);
- fflush(stdout);
if (ellipsized && ret > 0)
*ellipsized = true;
diff --git a/src/shared/meson.build b/src/shared/meson.build
new file mode 100644
index 0000000000..2eaef11a2d
--- /dev/null
+++ b/src/shared/meson.build
@@ -0,0 +1,158 @@
+shared_sources = '''
+ acl-util.h
+ acpi-fpdt.c
+ acpi-fpdt.h
+ apparmor-util.c
+ apparmor-util.h
+ ask-password-api.c
+ ask-password-api.h
+ base-filesystem.c
+ base-filesystem.h
+ boot-timestamps.c
+ boot-timestamps.h
+ bus-unit-util.c
+ bus-unit-util.h
+ bus-util.c
+ bus-util.h
+ cgroup-show.c
+ cgroup-show.h
+ clean-ipc.c
+ clean-ipc.h
+ condition.c
+ condition.h
+ conf-parser.c
+ conf-parser.h
+ dev-setup.c
+ dev-setup.h
+ dissect-image.c
+ dissect-image.h
+ dns-domain.c
+ dns-domain.h
+ dropin.c
+ dropin.h
+ efivars.c
+ efivars.h
+ fdset.c
+ fdset.h
+ firewall-util.h
+ fstab-util.c
+ fstab-util.h
+ gcrypt-util.c
+ gcrypt-util.h
+ generator.c
+ generator.h
+ gpt.h
+ ima-util.c
+ ima-util.h
+ import-util.c
+ import-util.h
+ initreq.h
+ install.c
+ install.h
+ install-printf.c
+ install-printf.h
+ journal-util.c
+ journal-util.h
+ logs-show.c
+ logs-show.h
+ loop-util.c
+ loop-util.h
+ machine-image.c
+ machine-image.h
+ machine-pool.c
+ machine-pool.h
+ nsflags.c
+ nsflags.h
+ output-mode.c
+ output-mode.h
+ pager.c
+ pager.h
+ path-lookup.c
+ path-lookup.h
+ ptyfwd.c
+ ptyfwd.h
+ resolve-util.c
+ resolve-util.h
+ seccomp-util.h
+ sleep-config.c
+ sleep-config.h
+ spawn-ask-password-agent.c
+ spawn-ask-password-agent.h
+ spawn-polkit-agent.c
+ spawn-polkit-agent.h
+ specifier.c
+ specifier.h
+ switch-root.c
+ switch-root.h
+ sysctl-util.c
+ sysctl-util.h
+ tests.c
+ tests.h
+ udev-util.h
+ udev-util.c
+ uid-range.c
+ uid-range.h
+ utmp-wtmp.h
+ vlan-util.c
+ vlan-util.h
+ volatile-util.c
+ volatile-util.h
+ watchdog.c
+ watchdog.h
+'''.split()
+
+test_tables_h = files('test-tables.h')
+shared_sources += [test_tables_h]
+
+if conf.get('HAVE_ACL', false)
+ shared_sources += ['acl-util.c']
+endif
+
+if conf.get('HAVE_UTMP', false)
+ shared_sources += ['utmp-wtmp.c']
+endif
+
+if conf.get('HAVE_SECCOMP', false)
+ shared_sources += ['seccomp-util.c']
+endif
+
+if conf.get('HAVE_LIBIPTC', false)
+ shared_sources += ['firewall-util.c']
+endif
+
+libshared_name = 'systemd-shared-@0@'.format(meson.project_version())
+
+libshared_deps = [threads,
+ librt,
+ libcap,
+ libacl,
+ libcryptsetup,
+ libgcrypt,
+ libiptc,
+ libseccomp,
+ libselinux,
+ libidn,
+ libxz,
+ liblz4,
+ libblkid]
+
+libshared = shared_library(
+ libshared_name,
+ shared_sources,
+ basic_sources,
+ journal_internal_sources,
+ libsystemd_internal_sources,
+ libudev_sources,
+ include_directories : includes,
+ link_args : ['-shared'],
+ c_args : ['-fvisibility=default'],
+ dependencies : libshared_deps,
+ install : true,
+ install_dir : rootlibexecdir)
+
+libshared_static = static_library(
+ libshared_name,
+ shared_sources,
+ basic_sources,
+ include_directories : includes,
+ dependencies : libshared_deps)
diff --git a/src/shared/output-mode.c b/src/shared/output-mode.c
index 67d8208ad2..29dcba9f6b 100644
--- a/src/shared/output-mode.c
+++ b/src/shared/output-mode.c
@@ -24,6 +24,7 @@ static const char *const output_mode_table[_OUTPUT_MODE_MAX] = {
[OUTPUT_SHORT] = "short",
[OUTPUT_SHORT_FULL] = "short-full",
[OUTPUT_SHORT_ISO] = "short-iso",
+ [OUTPUT_SHORT_ISO_PRECISE] = "short-iso-precise",
[OUTPUT_SHORT_PRECISE] = "short-precise",
[OUTPUT_SHORT_MONOTONIC] = "short-monotonic",
[OUTPUT_SHORT_UNIX] = "short-unix",
diff --git a/src/shared/output-mode.h b/src/shared/output-mode.h
index ff29dafcb5..2a1bfd98d0 100644
--- a/src/shared/output-mode.h
+++ b/src/shared/output-mode.h
@@ -25,6 +25,7 @@ typedef enum OutputMode {
OUTPUT_SHORT,
OUTPUT_SHORT_FULL,
OUTPUT_SHORT_ISO,
+ OUTPUT_SHORT_ISO_PRECISE,
OUTPUT_SHORT_PRECISE,
OUTPUT_SHORT_MONOTONIC,
OUTPUT_SHORT_UNIX,
diff --git a/src/shared/pager.c b/src/shared/pager.c
index f00ba9e1e7..ad48652527 100644
--- a/src/shared/pager.c
+++ b/src/shared/pager.c
@@ -53,6 +53,11 @@ noreturn static void pager_fallback(void) {
_exit(EXIT_SUCCESS);
}
+static int stored_stdout = -1;
+static int stored_stderr = -1;
+static bool stdout_redirected = false;
+static bool stderr_redirected = false;
+
int pager_open(bool no_pager, bool jump_to_end) {
_cleanup_close_pair_ int fd[2] = { -1, -1 };
const char *pager;
@@ -82,7 +87,7 @@ int pager_open(bool no_pager, bool jump_to_end) {
if (pipe(fd) < 0)
return log_error_errno(errno, "Failed to create pager pipe: %m");
- parent_pid = getpid();
+ parent_pid = getpid_cached();
pager_pid = fork();
if (pager_pid < 0)
@@ -147,10 +152,19 @@ int pager_open(bool no_pager, bool jump_to_end) {
}
/* Return in the parent */
- if (dup2(fd[1], STDOUT_FILENO) < 0)
+ stored_stdout = fcntl(STDOUT_FILENO, F_DUPFD_CLOEXEC, 3);
+ if (dup2(fd[1], STDOUT_FILENO) < 0) {
+ stored_stdout = safe_close(stored_stdout);
return log_error_errno(errno, "Failed to duplicate pager pipe: %m");
- if (dup2(fd[1], STDERR_FILENO) < 0)
+ }
+ stdout_redirected = true;
+
+ stored_stderr = fcntl(STDERR_FILENO, F_DUPFD_CLOEXEC, 3);
+ if (dup2(fd[1], STDERR_FILENO) < 0) {
+ stored_stderr = safe_close(stored_stderr);
return log_error_errno(errno, "Failed to duplicate pager pipe: %m");
+ }
+ stderr_redirected = true;
return 1;
}
@@ -161,8 +175,17 @@ void pager_close(void) {
return;
/* Inform pager that we are done */
- stdout = safe_fclose(stdout);
- stderr = safe_fclose(stderr);
+ (void) fflush(stdout);
+ if (stdout_redirected)
+ if (stored_stdout < 0 || dup2(stored_stdout, STDOUT_FILENO) < 0)
+ (void) close(STDOUT_FILENO);
+ stored_stdout = safe_close(stored_stdout);
+ (void) fflush(stderr);
+ if (stderr_redirected)
+ if (stored_stderr < 0 || dup2(stored_stderr, STDERR_FILENO) < 0)
+ (void) close(STDERR_FILENO);
+ stored_stderr = safe_close(stored_stderr);
+ stdout_redirected = stderr_redirected = false;
(void) kill(pager_pid, SIGCONT);
(void) wait_for_terminate(pager_pid, NULL);
diff --git a/src/shared/seccomp-util.c b/src/shared/seccomp-util.c
index 2631856563..637ee8526e 100644
--- a/src/shared/seccomp-util.c
+++ b/src/shared/seccomp-util.c
@@ -792,37 +792,10 @@ int seccomp_restrict_namespaces(unsigned long retain) {
SECCOMP_FOREACH_LOCAL_ARCH(arch) {
_cleanup_(seccomp_releasep) scmp_filter_ctx seccomp = NULL;
- int clone_reversed_order = -1;
unsigned i;
log_debug("Operating on architecture: %s", seccomp_arch_to_string(arch));
- switch (arch) {
-
- case SCMP_ARCH_X86_64:
- case SCMP_ARCH_X86:
- case SCMP_ARCH_X32:
- case SCMP_ARCH_PPC64:
- case SCMP_ARCH_PPC64LE:
- clone_reversed_order = 0;
- break;
-
- case SCMP_ARCH_S390:
- case SCMP_ARCH_S390X:
- /* On s390/s390x the first two parameters to clone are switched */
- clone_reversed_order = 1;
- break;
-
- /* Please add more definitions here, if you port systemd to other architectures! */
-
-#if SECCOMP_RESTRICT_NAMESPACES_BROKEN
-# warning "Consider adding the right clone() syscall definitions here!"
-#endif
- }
-
- if (clone_reversed_order < 0) /* we don't know the right order, let's ignore this arch... */
- continue;
-
r = seccomp_init_for_arch(&seccomp, arch, SCMP_ACT_ALLOW);
if (r < 0)
return r;
@@ -871,7 +844,8 @@ int seccomp_restrict_namespaces(unsigned long retain) {
break;
}
- if (clone_reversed_order == 0)
+ /* On s390/s390x the first two parameters to clone are switched */
+ if (!IN_SET(arch, SCMP_ARCH_S390, SCMP_ARCH_S390X))
r = seccomp_rule_add_exact(
seccomp,
SCMP_ACT_ERRNO(EPERM),
@@ -925,6 +899,10 @@ int seccomp_protect_sysctl(void) {
log_debug("Operating on architecture: %s", seccomp_arch_to_string(arch));
+ if (IN_SET(arch, SCMP_ARCH_X32, SCMP_ARCH_AARCH64))
+ /* No _sysctl syscall */
+ continue;
+
r = seccomp_init_for_arch(&seccomp, arch, SCMP_ACT_ALLOW);
if (r < 0)
return r;
@@ -966,16 +944,16 @@ int seccomp_restrict_address_families(Set *address_families, bool whitelist) {
case SCMP_ARCH_X32:
case SCMP_ARCH_ARM:
case SCMP_ARCH_AARCH64:
+ case SCMP_ARCH_PPC64:
+ case SCMP_ARCH_PPC64LE:
/* These we know we support (i.e. are the ones that do not use socketcall()) */
supported = true;
break;
- case SCMP_ARCH_X86:
case SCMP_ARCH_S390:
case SCMP_ARCH_S390X:
case SCMP_ARCH_PPC:
- case SCMP_ARCH_PPC64:
- case SCMP_ARCH_PPC64LE:
+ case SCMP_ARCH_X86:
default:
/* These we either know we don't support (i.e. are the ones that do use socketcall()), or we
* don't know */
@@ -1186,6 +1164,37 @@ int seccomp_restrict_realtime(void) {
return 0;
}
+static int add_seccomp_syscall_filter(scmp_filter_ctx seccomp,
+ uint32_t arch,
+ int nr,
+ unsigned int arg_cnt,
+ const struct scmp_arg_cmp arg) {
+ int r;
+
+ r = seccomp_rule_add_exact(seccomp, SCMP_ACT_ERRNO(EPERM), nr, arg_cnt, arg);
+ if (r < 0) {
+ _cleanup_free_ char *n = NULL;
+
+ n = seccomp_syscall_resolve_num_arch(arch, nr);
+ log_debug_errno(r, "Failed to add %s() rule for architecture %s, skipping: %m",
+ strna(n),
+ seccomp_arch_to_string(arch));
+ }
+
+ return r;
+}
+
+/* For known architectures, check that syscalls are indeed defined or not. */
+#if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__)
+assert_cc(SCMP_SYS(shmget) > 0);
+assert_cc(SCMP_SYS(shmat) > 0);
+assert_cc(SCMP_SYS(shmdt) > 0);
+#elif defined(__i386__) || defined(__powerpc64__)
+assert_cc(SCMP_SYS(shmget) < 0);
+assert_cc(SCMP_SYS(shmat) < 0);
+assert_cc(SCMP_SYS(shmdt) < 0);
+#endif
+
int seccomp_memory_deny_write_execute(void) {
uint32_t arch;
@@ -1202,21 +1211,33 @@ int seccomp_memory_deny_write_execute(void) {
case SCMP_ARCH_X86:
filter_syscall = SCMP_SYS(mmap2);
block_syscall = SCMP_SYS(mmap);
+ break;
- /* Note that shmat() isn't available on i386, where the call is multiplexed through ipc(). We
- * ignore that here, which means there's still a way to get writable/executable memory, if an
- * IPC key is mapped like this on i386. That's a pity, but no total loss. */
+ case SCMP_ARCH_PPC64:
+ case SCMP_ARCH_PPC64LE:
+ filter_syscall = SCMP_SYS(mmap);
+
+ /* Note that shmat() isn't available, and the call is multiplexed through ipc().
+ * We ignore that here, which means there's still a way to get writable/executable
+ * memory, if an IPC key is mapped like this. That's a pity, but no total loss. */
+
+ break;
+
+ case SCMP_ARCH_ARM:
+ filter_syscall = SCMP_SYS(mmap2); /* arm has only mmap2 */
+ shmat_syscall = SCMP_SYS(shmat);
break;
case SCMP_ARCH_X86_64:
case SCMP_ARCH_X32:
- filter_syscall = SCMP_SYS(mmap);
+ case SCMP_ARCH_AARCH64:
+ filter_syscall = SCMP_SYS(mmap); /* amd64, x32, and arm64 have only mmap */
shmat_syscall = SCMP_SYS(shmat);
break;
/* Please add more definitions here, if you port systemd to other architectures! */
-#if !defined(__i386__) && !defined(__x86_64__)
+#if !defined(__i386__) && !defined(__x86_64__) && !defined(__powerpc64__) && !defined(__arm__) && !defined(__aarch64__)
#warning "Consider adding the right mmap() syscall definitions here!"
#endif
}
@@ -1229,63 +1250,30 @@ int seccomp_memory_deny_write_execute(void) {
if (r < 0)
return r;
- if (filter_syscall != 0) {
- r = seccomp_rule_add_exact(
- seccomp,
- SCMP_ACT_ERRNO(EPERM),
- filter_syscall,
- 1,
- SCMP_A2(SCMP_CMP_MASKED_EQ, PROT_EXEC|PROT_WRITE, PROT_EXEC|PROT_WRITE));
- if (r < 0) {
- _cleanup_free_ char *n = NULL;
-
- n = seccomp_syscall_resolve_num_arch(arch, filter_syscall);
- log_debug_errno(r, "Failed to add %s() rule for architecture %s, skipping: %m",
- strna(n),
- seccomp_arch_to_string(arch));
- continue;
- }
- }
+ r = add_seccomp_syscall_filter(seccomp, arch, filter_syscall,
+ 1,
+ SCMP_A2(SCMP_CMP_MASKED_EQ, PROT_EXEC|PROT_WRITE, PROT_EXEC|PROT_WRITE));
+ if (r < 0)
+ continue;
if (block_syscall != 0) {
- r = seccomp_rule_add_exact(
- seccomp,
- SCMP_ACT_ERRNO(EPERM),
- block_syscall,
- 0);
- if (r < 0) {
- _cleanup_free_ char *n = NULL;
-
- n = seccomp_syscall_resolve_num_arch(arch, block_syscall);
- log_debug_errno(r, "Failed to add %s() rule for architecture %s, skipping: %m",
- strna(n),
- seccomp_arch_to_string(arch));
+ r = add_seccomp_syscall_filter(seccomp, arch, block_syscall, 0, (const struct scmp_arg_cmp){} );
+ if (r < 0)
continue;
- }
}
- r = seccomp_rule_add_exact(
- seccomp,
- SCMP_ACT_ERRNO(EPERM),
- SCMP_SYS(mprotect),
- 1,
- SCMP_A2(SCMP_CMP_MASKED_EQ, PROT_EXEC, PROT_EXEC));
- if (r < 0) {
- log_debug_errno(r, "Failed to add mprotect() rule for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
+ r = add_seccomp_syscall_filter(seccomp, arch, SCMP_SYS(mprotect),
+ 1,
+ SCMP_A2(SCMP_CMP_MASKED_EQ, PROT_EXEC, PROT_EXEC));
+ if (r < 0)
continue;
- }
if (shmat_syscall != 0) {
- r = seccomp_rule_add_exact(
- seccomp,
- SCMP_ACT_ERRNO(EPERM),
- SCMP_SYS(shmat),
- 1,
- SCMP_A2(SCMP_CMP_MASKED_EQ, SHM_EXEC, SHM_EXEC));
- if (r < 0) {
- log_debug_errno(r, "Failed to add shmat() rule for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
+ r = add_seccomp_syscall_filter(seccomp, arch, SCMP_SYS(shmat),
+ 1,
+ SCMP_A2(SCMP_CMP_MASKED_EQ, SHM_EXEC, SHM_EXEC));
+ if (r < 0)
continue;
- }
}
r = seccomp_load(seccomp);
diff --git a/src/shared/seccomp-util.h b/src/shared/seccomp-util.h
index b56ac3f763..4438e87fa6 100644
--- a/src/shared/seccomp-util.h
+++ b/src/shared/seccomp-util.h
@@ -76,28 +76,6 @@ int seccomp_restrict_address_families(Set *address_families, bool whitelist);
int seccomp_restrict_realtime(void);
int seccomp_memory_deny_write_execute(void);
-#if defined(__i386__) || defined(__s390x__) || defined(__s390__) || defined(__powerpc64__) || defined(__powerpc__) || defined (__mips__)
-/* On these archs, socket() is implemented via the socketcall() syscall multiplexer, and we can't restrict it hence via
- * seccomp */
-#define SECCOMP_RESTRICT_ADDRESS_FAMILIES_BROKEN 1
-#else
-#define SECCOMP_RESTRICT_ADDRESS_FAMILIES_BROKEN 0
-#endif
-
-/* mmap() blocking is only available on some archs for now */
-#if defined(__x86_64__) || defined(__i386__)
-#define SECCOMP_MEMORY_DENY_WRITE_EXECUTE_BROKEN 0
-#else
-#define SECCOMP_MEMORY_DENY_WRITE_EXECUTE_BROKEN 1
-#endif
-
-/* we don't know the right order of the clone() parameters except for these archs, for now */
-#if defined(__x86_64__) || defined(__i386__) || defined(__s390x__) || defined(__s390__) || defined(__powerpc64__)
-#define SECCOMP_RESTRICT_NAMESPACES_BROKEN 0
-#else
-#define SECCOMP_RESTRICT_NAMESPACES_BROKEN 1
-#endif
-
extern const uint32_t seccomp_local_archs[];
#define SECCOMP_FOREACH_LOCAL_ARCH(arch) \
diff --git a/src/shared/sleep-config.c b/src/shared/sleep-config.c
index ed31a80c8d..8c1624ff46 100644
--- a/src/shared/sleep-config.c
+++ b/src/shared/sleep-config.c
@@ -59,9 +59,9 @@ 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);
+ CONF_PATHS_NULSTR("systemd/sleep.conf.d"),
+ "Sleep\0", config_item_table_lookup, items,
+ false, NULL);
if (streq(verb, "suspend")) {
/* empty by default */
diff --git a/src/shared/udev-util.c b/src/shared/udev-util.c
new file mode 100644
index 0000000000..f708dcfa14
--- /dev/null
+++ b/src/shared/udev-util.c
@@ -0,0 +1,56 @@
+/***
+ 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 <string.h>
+
+#include "fileio.h"
+#include "log.h"
+#include "string-util.h"
+#include "udev-util.h"
+
+int udev_parse_config(void) {
+ _cleanup_free_ char *val = NULL;
+ const char *log;
+ size_t n;
+ int r;
+
+ r = parse_env_file("/etc/udev/udev.conf", NEWLINE, "udev_log", &val, NULL);
+ if (r == -ENOENT || !val)
+ return 0;
+ if (r < 0)
+ return r;
+
+ /* unquote */
+ n = strlen(val);
+ if (n >= 2 &&
+ ((val[0] == '"' && val[n-1] == '"') ||
+ (val[0] == '\'' && val[n-1] == '\''))) {
+ val[n - 1] = '\0';
+ log = val + 1;
+ } else
+ log = val;
+
+ /* we set the udev log level here explicitly, this is supposed
+ * to regulate the code in libudev/ and udev/. */
+ r = log_set_max_level_from_string_realm(LOG_REALM_UDEV, log);
+ if (r < 0)
+ log_debug_errno(r, "/etc/udev/udev.conf: failed to set udev log level '%s', ignoring: %m", log);
+
+ return 0;
+}
diff --git a/src/shared/udev-util.h b/src/shared/udev-util.h
index ca0889f8a6..a415be249e 100644
--- a/src/shared/udev-util.h
+++ b/src/shared/udev-util.h
@@ -42,3 +42,5 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev_monitor*, udev_monitor_unref);
#define _cleanup_udev_ctrl_msg_unref_ _cleanup_(udev_ctrl_msg_unrefp)
#define _cleanup_udev_monitor_unref_ _cleanup_(udev_monitor_unrefp)
#define _cleanup_udev_list_cleanup_ _cleanup_(udev_list_cleanup)
+
+int udev_parse_config(void);
diff --git a/src/shared/vlan-util.c b/src/shared/vlan-util.c
index 78d66dd3d9..1edd96fbe7 100644
--- a/src/shared/vlan-util.c
+++ b/src/shared/vlan-util.c
@@ -17,9 +17,10 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include "vlan-util.h"
-#include "parse-util.h"
#include "conf-parser.h"
+#include "parse-util.h"
+#include "string-util.h"
+#include "vlan-util.h"
int parse_vlanid(const char *p, uint16_t *ret) {
uint16_t id;
@@ -35,6 +36,32 @@ int parse_vlanid(const char *p, uint16_t *ret) {
return 0;
}
+int config_parse_default_port_vlanid(
+ 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) {
+ uint16_t *id = data;
+
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ if (streq(rvalue, "none")) {
+ *id = 0;
+ return 0;
+ }
+
+ return config_parse_vlanid(unit, filename, line, section, section_line,
+ lvalue, ltype, rvalue, data, userdata);
+}
+
int config_parse_vlanid(
const char *unit,
const char *filename,
diff --git a/src/shared/vlan-util.h b/src/shared/vlan-util.h
index ce6763b3a3..365ed14d88 100644
--- a/src/shared/vlan-util.h
+++ b/src/shared/vlan-util.h
@@ -32,4 +32,5 @@ static inline bool vlanid_is_valid(uint16_t id) {
int parse_vlanid(const char *p, uint16_t *ret);
+int config_parse_default_port_vlanid(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_vlanid(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/stdio-bridge/stdio-bridge.c b/src/stdio-bridge/stdio-bridge.c
index 02ba5269dd..097f8c1a4b 100644
--- a/src/stdio-bridge/stdio-bridge.c
+++ b/src/stdio-bridge/stdio-bridge.c
@@ -292,7 +292,7 @@ int main(int argc, char *argv[]) {
r = ppoll(p, ELEMENTSOF(p), ts, NULL);
}
if (r < 0) {
- log_error("ppoll() failed: %m");
+ log_error_errno(errno, "ppoll() failed: %m");
goto finish;
}
}
diff --git a/src/sulogin-shell/.gitignore b/src/sulogin-shell/.gitignore
new file mode 100644
index 0000000000..01a315524b
--- /dev/null
+++ b/src/sulogin-shell/.gitignore
@@ -0,0 +1 @@
+systemd-sulogin-shell
diff --git a/src/sulogin-shell/meson.build b/src/sulogin-shell/meson.build
new file mode 100644
index 0000000000..4ec0d3da1a
--- /dev/null
+++ b/src/sulogin-shell/meson.build
@@ -0,0 +1,7 @@
+gen = configure_file(
+ input : 'systemd-sulogin-shell.in',
+ output : 'systemd-sulogin-shell',
+ configuration : substs)
+
+install_data(gen,
+ install_dir : rootlibexecdir)
diff --git a/src/sulogin-shell/systemd-sulogin-shell.in b/src/sulogin-shell/systemd-sulogin-shell.in
new file mode 100755
index 0000000000..103f841a57
--- /dev/null
+++ b/src/sulogin-shell/systemd-sulogin-shell.in
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+if [ -x /bin/plymouth ]; then
+ /bin/plymouth --wait quit
+fi
+
+echo "You are in $1 mode. After logging in, type \"journalctl -xb\" to view"
+echo "system logs, \"systemctl reboot\" to reboot, \"systemctl default\" or ^D to boot"
+echo "into default mode."
+
+@SULOGIN@
+@SYSTEMCTL@ --job-mode=fail --no-block default
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 1a47cb564e..83ed9ef9f7 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -47,6 +47,7 @@
#include "dropin.h"
#include "efivars.h"
#include "env-util.h"
+#include "escape.h"
#include "exit-status.h"
#include "fd-util.h"
#include "fileio.h"
@@ -3191,8 +3192,8 @@ static int start_unit(int argc, char *argv[], void *userdata) {
return r;
}
+#ifdef ENABLE_LOGIND
static int logind_set_wall_message(void) {
-#ifdef HAVE_LOGIND
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
sd_bus *bus;
_cleanup_free_ char *m = NULL;
@@ -3220,15 +3221,14 @@ static int logind_set_wall_message(void) {
if (r < 0)
return log_warning_errno(r, "Failed to set wall message, ignoring: %s", bus_error_message(&error, r));
-
-#endif
return 0;
}
+#endif
/* Ask systemd-logind, which might grant access to unprivileged users
* through PolicyKit */
static int logind_reboot(enum action a) {
-#ifdef HAVE_LOGIND
+#ifdef ENABLE_LOGIND
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
const char *method, *description;
sd_bus *bus;
@@ -3291,7 +3291,7 @@ static int logind_reboot(enum action a) {
}
static int logind_check_inhibitors(enum action a) {
-#ifdef HAVE_LOGIND
+#ifdef ENABLE_LOGIND
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
_cleanup_strv_free_ char **sessions = NULL;
const char *what, *who, *why, *mode;
@@ -3410,7 +3410,7 @@ static int logind_check_inhibitors(enum action a) {
}
static int logind_prepare_firmware_setup(void) {
-#ifdef HAVE_LOGIND
+#ifdef ENABLE_LOGIND
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
sd_bus *bus;
int r;
@@ -3818,6 +3818,8 @@ typedef struct UnitStatusInfo {
bool failed_assert_negate;
const char *failed_assert;
const char *failed_assert_parameter;
+ usec_t next_elapse_real;
+ usec_t next_elapse_monotonic;
/* Socket */
unsigned n_accepted;
@@ -3987,6 +3989,31 @@ static void print_status_info(
else
printf("\n");
+ if (endswith(i->id, ".timer")) {
+ char tstamp1[FORMAT_TIMESTAMP_RELATIVE_MAX],
+ tstamp2[FORMAT_TIMESTAMP_MAX];
+ char *next_rel_time, *next_time;
+ dual_timestamp nw, next = {i->next_elapse_real,
+ i->next_elapse_monotonic};
+ usec_t next_elapse;
+
+ printf(" Trigger: ");
+
+ dual_timestamp_get(&nw);
+ next_elapse = calc_next_elapse(&nw, &next);
+ next_rel_time = format_timestamp_relative(tstamp1,
+ sizeof(tstamp1),
+ next_elapse);
+ next_time = format_timestamp(tstamp2,
+ sizeof(tstamp2),
+ next_elapse);
+
+ if (next_time && next_rel_time)
+ printf("%s; %s\n", next_time, next_rel_time);
+ else
+ printf("n/a\n");
+ }
+
if (!i->condition_result && i->condition_timestamp > 0) {
UnitCondition *c;
int n = 0;
@@ -4424,6 +4451,10 @@ static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *
i->tasks_max = u;
else if (streq(name, "CPUUsageNSec"))
i->cpu_usage_nsec = u;
+ else if (streq(name, "NextElapseUSecMonotonic"))
+ i->next_elapse_monotonic = u;
+ else if (streq(name, "NextElapseUSecRealtime"))
+ i->next_elapse_real = u;
break;
}
@@ -5574,6 +5605,24 @@ static int reset_failed(int argc, char *argv[], void *userdata) {
return r;
}
+static int print_variable(const char *s) {
+ const char *sep;
+ _cleanup_free_ char *esc = NULL;
+
+ sep = strchr(s, '=');
+ if (!sep) {
+ log_error("Invalid environment block");
+ return -EUCLEAN;
+ }
+
+ esc = shell_maybe_quote(sep + 1, ESCAPE_POSIX);
+ if (!esc)
+ return log_oom();
+
+ printf("%.*s=%s\n", (int)(sep-s), s, esc);
+ return 0;
+}
+
static int show_environment(int argc, char *argv[], void *userdata) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
@@ -5603,8 +5652,11 @@ static int show_environment(int argc, char *argv[], void *userdata) {
if (r < 0)
return bus_log_parse_error(r);
- while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0)
- puts(text);
+ while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0) {
+ r = print_variable(text);
+ if (r < 0)
+ return r;
+ }
if (r < 0)
return bus_log_parse_error(r);
@@ -5655,7 +5707,7 @@ static int switch_root(int argc, char *argv[], void *userdata) {
/* If the passed init is actually the same as the
* systemd binary, then let's suppress it. */
- if (files_same(root_init_path, root_systemd_path) > 0)
+ if (files_same(root_init_path, root_systemd_path, 0) > 0)
init = NULL;
}
@@ -5891,7 +5943,8 @@ static int enable_sysv_units(const char *verb, char **args) {
if (!l)
return log_oom();
- log_info("Executing: %s", l);
+ if (!arg_quiet)
+ log_info("Executing: %s", l);
pid = fork();
if (pid < 0)
@@ -5980,6 +6033,34 @@ static int mangle_names(char **original_names, char ***mangled_names) {
return 0;
}
+static int normalize_filenames(char **names) {
+ char **u;
+ int r;
+
+ STRV_FOREACH(u, names)
+ if (!path_is_absolute(*u)) {
+ char* normalized_path;
+
+ if (!isempty(arg_root)) {
+ log_error("Non-absolute paths are not allowed when --root is used: %s", *u);
+ return -EINVAL;
+ }
+
+ if (!strchr(*u,'/')) {
+ log_error("Link argument does contain at least one directory separator: %s", *u);
+ return -EINVAL;
+ }
+
+ r = path_make_absolute_cwd(*u, &normalized_path);
+ if (r < 0)
+ return r;
+
+ free_and_replace(*u, normalized_path);
+ }
+
+ return 0;
+}
+
static int normalize_names(char **names, bool warn_if_path) {
char **u;
bool was_path = false;
@@ -6076,6 +6157,12 @@ static int enable_unit(int argc, char *argv[], void *userdata) {
return r;
}
+ if (streq(verb, "link")) {
+ r = normalize_filenames(names);
+ if (r < 0)
+ return r;
+ }
+
if (install_client_side()) {
UnitFileFlags flags;
@@ -7002,7 +7089,8 @@ static void systemctl_help(void) {
" --root=PATH Enable unit files in the specified root 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-full, short-monotonic, short-unix,\n"
+ " short-iso, short-iso-precise, short-full,\n"
+ " short-monotonic, short-unix,\n"
" verbose, export, json, json-pretty, json-sse, cat)\n"
" --firmware-setup Tell the firmware to show the setup menu on next boot\n"
" --plain Print unit dependencies as a list instead of a tree\n\n"
@@ -8246,12 +8334,14 @@ static int halt_now(enum action a) {
switch (a) {
case ACTION_HALT:
- log_info("Halting.");
+ if (!arg_quiet)
+ log_info("Halting.");
(void) reboot(RB_HALT_SYSTEM);
return -errno;
case ACTION_POWEROFF:
- log_info("Powering off.");
+ if (!arg_quiet)
+ log_info("Powering off.");
(void) reboot(RB_POWER_OFF);
return -errno;
@@ -8264,12 +8354,14 @@ static int halt_now(enum action a) {
log_warning_errno(r, "Failed to read reboot parameter file: %m");
if (!isempty(param)) {
- log_info("Rebooting with argument '%s'.", 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");
}
- log_info("Rebooting.");
+ if (!arg_quiet)
+ log_info("Rebooting.");
(void) reboot(RB_AUTOBOOT);
return -errno;
}
@@ -8281,7 +8373,7 @@ static int halt_now(enum action a) {
static int logind_schedule_shutdown(void) {
-#ifdef HAVE_LOGIND
+#ifdef ENABLE_LOGIND
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
char date[FORMAT_TIMESTAMP_MAX];
const char *action;
@@ -8330,7 +8422,8 @@ static int logind_schedule_shutdown(void) {
if (r < 0)
return log_warning_errno(r, "Failed to call ScheduleShutdown in logind, proceeding with immediate shutdown: %s", bus_error_message(&error, r));
- log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.", format_timestamp(date, sizeof(date), arg_when));
+ if (!arg_quiet)
+ log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.", format_timestamp(date, sizeof(date), arg_when));
return 0;
#else
log_error("Cannot schedule shutdown without logind support, proceeding with immediate shutdown.");
@@ -8409,7 +8502,7 @@ static int runlevel_main(void) {
}
static int logind_cancel_shutdown(void) {
-#ifdef HAVE_LOGIND
+#ifdef ENABLE_LOGIND
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
sd_bus *bus;
int r;
@@ -8458,7 +8551,9 @@ int main(int argc, char*argv[]) {
goto finish;
if (arg_action != ACTION_SYSTEMCTL && running_in_chroot() > 0) {
- log_info("Running in chroot, ignoring request.");
+
+ if (!arg_quiet)
+ log_info("Running in chroot, ignoring request.");
r = 0;
goto finish;
}
diff --git a/src/systemd/meson.build b/src/systemd/meson.build
new file mode 100644
index 0000000000..debbd46dff
--- /dev/null
+++ b/src/systemd/meson.build
@@ -0,0 +1,59 @@
+_systemd_headers = '''
+ sd-bus.h
+ sd-bus-protocol.h
+ sd-bus-vtable.h
+ sd-daemon.h
+ sd-event.h
+ sd-id128.h
+ sd-journal.h
+ sd-login.h
+ sd-messages.h
+'''.split()
+
+# https://github.com/mesonbuild/meson/issues/1633
+systemd_headers = files(_systemd_headers)
+
+# sd-device.h
+# sd-hwdb.h
+# sd-dhcp6-client.h
+# sd-dhcp6-lease.h
+# sd-dhcp-client.h
+# sd-dhcp-lease.h
+# sd-dhcp-server.h
+# sd-ipv4acd.h
+# sd-ipv4ll.h
+# sd-lldp.h
+# sd-ndisc.h
+# sd-netlink.h
+# sd-network.h
+# sd-path.h
+# sd-resolve.h
+# sd-utf8.h
+
+install_headers(
+ systemd_headers,
+ '_sd-common.h',
+ subdir : 'systemd')
+
+
+############################################################
+
+opts = [['c'],
+ ['c', '-ansi'],
+ ['c', '-std=iso9899:1990']]
+
+cxx = find_program('c++', required : false)
+if cxx.found()
+ opts += [['c++']]
+endif
+
+foreach header : _systemd_headers
+ foreach opt : opts
+ name = ''.join([header, ':'] + opt)
+ test('cc-' + name,
+ check_compilation_sh,
+ args : cc.cmd_array() + ['-c', '-x'] + opt +
+ ['-Werror', '-include',
+ join_paths(meson.current_source_dir(), header)])
+ endforeach
+endforeach
diff --git a/src/systemd/sd-bus.h b/src/systemd/sd-bus.h
index c47459c9ad..2b6aeb7989 100644
--- a/src/systemd/sd-bus.h
+++ b/src/systemd/sd-bus.h
@@ -266,6 +266,7 @@ int sd_bus_message_set_destination(sd_bus_message *m, const char *destination);
int sd_bus_message_set_priority(sd_bus_message *m, int64_t priority);
int sd_bus_message_append(sd_bus_message *m, const char *types, ...);
+int sd_bus_message_appendv(sd_bus_message *m, const char *types, va_list ap);
int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p);
int sd_bus_message_append_array(sd_bus_message *m, char type, const void *ptr, size_t size);
int sd_bus_message_append_array_space(sd_bus_message *m, char type, size_t size, void **ptr);
diff --git a/src/systemd/sd-dhcp-client.h b/src/systemd/sd-dhcp-client.h
index ffe7f836de..f731fdcbd4 100644
--- a/src/systemd/sd-dhcp-client.h
+++ b/src/systemd/sd-dhcp-client.h
@@ -76,6 +76,7 @@ enum {
SD_DHCP_OPTION_FQDN = 81,
SD_DHCP_OPTION_NEW_POSIX_TIMEZONE = 100,
SD_DHCP_OPTION_NEW_TZDB_TIMEZONE = 101,
+ SD_DHCP_OPTION_DOMAIN_SEARCH_LIST = 119,
SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE = 121,
SD_DHCP_OPTION_PRIVATE_BASE = 224,
SD_DHCP_OPTION_PRIVATE_LAST = 254,
diff --git a/src/systemd/sd-dhcp-lease.h b/src/systemd/sd-dhcp-lease.h
index 2f565ca825..7ab99cccd1 100644
--- a/src/systemd/sd-dhcp-lease.h
+++ b/src/systemd/sd-dhcp-lease.h
@@ -49,6 +49,7 @@ int sd_dhcp_lease_get_dns(sd_dhcp_lease *lease, const struct in_addr **addr);
int sd_dhcp_lease_get_ntp(sd_dhcp_lease *lease, const struct in_addr **addr);
int sd_dhcp_lease_get_mtu(sd_dhcp_lease *lease, uint16_t *mtu);
int sd_dhcp_lease_get_domainname(sd_dhcp_lease *lease, const char **domainname);
+int sd_dhcp_lease_get_search_domains(sd_dhcp_lease *lease, char ***domains);
int sd_dhcp_lease_get_hostname(sd_dhcp_lease *lease, const char **hostname);
int sd_dhcp_lease_get_root_path(sd_dhcp_lease *lease, const char **root_path);
int sd_dhcp_lease_get_routes(sd_dhcp_lease *lease, sd_dhcp_route ***routes);
diff --git a/src/systemd/sd-event.h b/src/systemd/sd-event.h
index cc26b7df55..f8cb895660 100644
--- a/src/systemd/sd-event.h
+++ b/src/systemd/sd-event.h
@@ -69,7 +69,7 @@ typedef int (*sd_event_handler_t)(sd_event_source *s, void *userdata);
typedef int (*sd_event_io_handler_t)(sd_event_source *s, int fd, uint32_t revents, void *userdata);
typedef int (*sd_event_time_handler_t)(sd_event_source *s, uint64_t usec, void *userdata);
typedef int (*sd_event_signal_handler_t)(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata);
-#if defined __USE_POSIX199309 || defined __USE_XOPEN_EXTENDED
+#if defined _GNU_SOURCE || _POSIX_C_SOURCE >= 199309L
typedef int (*sd_event_child_handler_t)(sd_event_source *s, const siginfo_t *si, void *userdata);
#else
typedef void* sd_event_child_handler_t;
diff --git a/src/systemd/sd-ipv4ll.h b/src/systemd/sd-ipv4ll.h
index 1109ec52e0..5ba92083f4 100644
--- a/src/systemd/sd-ipv4ll.h
+++ b/src/systemd/sd-ipv4ll.h
@@ -47,6 +47,7 @@ int sd_ipv4ll_set_ifindex(sd_ipv4ll *ll, int interface_index);
int sd_ipv4ll_set_address(sd_ipv4ll *ll, const struct in_addr *address);
int sd_ipv4ll_set_address_seed(sd_ipv4ll *ll, uint64_t seed);
int sd_ipv4ll_is_running(sd_ipv4ll *ll);
+int sd_ipv4ll_restart(sd_ipv4ll *ll);
int sd_ipv4ll_start(sd_ipv4ll *ll);
int sd_ipv4ll_stop(sd_ipv4ll *ll);
sd_ipv4ll *sd_ipv4ll_ref(sd_ipv4ll *ll);
diff --git a/src/systemd/sd-netlink.h b/src/systemd/sd-netlink.h
index 7efa8ebe5a..3f5a6673cf 100644
--- a/src/systemd/sd-netlink.h
+++ b/src/systemd/sd-netlink.h
@@ -155,6 +155,10 @@ int sd_rtnl_message_neigh_get_ifindex(sd_netlink_message *m, int *family);
int sd_rtnl_message_neigh_get_state(sd_netlink_message *m, uint16_t *state);
int sd_rtnl_message_neigh_get_flags(sd_netlink_message *m, uint8_t *flags);
+int sd_rtnl_message_new_addrlabel(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t nlmsg_type, int ifindex, int ifal_family);
+int sd_rtnl_message_addrlabel_set_prefixlen(sd_netlink_message *m, unsigned char prefixlen);
+int sd_rtnl_message_addrlabel_get_prefixlen(sd_netlink_message *m, unsigned char *prefixlen);
+
_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_netlink, sd_netlink_unref);
_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_netlink_message, sd_netlink_message_unref);
diff --git a/src/systemd/sd-radv.h b/src/systemd/sd-radv.h
new file mode 100644
index 0000000000..4cbd80db68
--- /dev/null
+++ b/src/systemd/sd-radv.h
@@ -0,0 +1,81 @@
+#ifndef foosdradvfoo
+#define foosdradvfoo
+
+/***
+ This file is part of systemd.
+
+ Copyright (C) 2017 Intel Corporation. All rights reserved.
+
+ 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 <inttypes.h>
+#include <net/ethernet.h>
+#include <netinet/in.h>
+#include <sys/types.h>
+
+#include "sd-ndisc.h"
+
+#include "sd-event.h"
+
+#include "_sd-common.h"
+
+_SD_BEGIN_DECLARATIONS;
+
+typedef struct sd_radv sd_radv;
+typedef struct sd_radv_prefix sd_radv_prefix;
+
+/* Router Advertisment */
+int sd_radv_new(sd_radv **ret);
+sd_radv *sd_radv_ref(sd_radv *ra);
+sd_radv *sd_radv_unref(sd_radv *ra);
+
+int sd_radv_attach_event(sd_radv *ra, sd_event *event, int64_t priority);
+int sd_radv_detach_event(sd_radv *nd);
+sd_event *sd_radv_get_event(sd_radv *ra);
+
+int sd_radv_start(sd_radv *ra);
+int sd_radv_stop(sd_radv *ra);
+
+int sd_radv_set_ifindex(sd_radv *ra, int interface_index);
+int sd_radv_set_mac(sd_radv *ra, const struct ether_addr *mac_addr);
+int sd_radv_set_mtu(sd_radv *ra, uint32_t mtu);
+int sd_radv_set_hop_limit(sd_radv *ra, uint8_t hop_limit);
+int sd_radv_set_router_lifetime(sd_radv *ra, uint32_t router_lifetime);
+int sd_radv_set_managed_information(sd_radv *ra, int managed);
+int sd_radv_set_other_information(sd_radv *ra, int other);
+int sd_radv_set_preference(sd_radv *ra, unsigned preference);
+int sd_radv_add_prefix(sd_radv *ra, sd_radv_prefix *p);
+
+/* Advertised prefixes */
+int sd_radv_prefix_new(sd_radv_prefix **ret);
+sd_radv_prefix *sd_radv_prefix_ref(sd_radv_prefix *ra);
+sd_radv_prefix *sd_radv_prefix_unref(sd_radv_prefix *ra);
+
+int sd_radv_prefix_set_prefix(sd_radv_prefix *p, struct in6_addr *in6_addr,
+ unsigned char prefixlen);
+int sd_radv_prefix_set_onlink(sd_radv_prefix *p, int onlink);
+int sd_radv_prefix_set_address_autoconfiguration(sd_radv_prefix *p,
+ int address_autoconfiguration);
+int sd_radv_prefix_set_valid_lifetime(sd_radv_prefix *p,
+ uint32_t valid_lifetime);
+int sd_radv_prefix_set_preferred_lifetime(sd_radv_prefix *p,
+ uint32_t preferred_lifetime);
+
+_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_radv, sd_radv_unref);
+_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_radv_prefix, sd_radv_prefix_unref);
+
+_SD_END_DECLARATIONS;
+
+#endif
diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c
index 4a0a49f2bb..fbe51a6ed5 100644
--- a/src/sysusers/sysusers.c
+++ b/src/sysusers/sysusers.c
@@ -29,6 +29,7 @@
#include "copy.h"
#include "def.h"
#include "fd-util.h"
+#include "fs-util.h"
#include "fileio-label.h"
#include "format-util.h"
#include "hashmap.h"
@@ -292,6 +293,7 @@ static int putgrent_with_members(const struct group *gr, FILE *group) {
return 0;
}
+#ifdef ENABLE_GSHADOW
static int putsgent_with_members(const struct sgrp *sg, FILE *gshadow) {
char **a;
@@ -341,6 +343,7 @@ static int putsgent_with_members(const struct sgrp *sg, FILE *gshadow) {
return 0;
}
+#endif
static int sync_rights(FILE *from, FILE *to) {
struct stat st;
@@ -370,400 +373,424 @@ static int rename_and_apply_smack(const char *temp_path, const char *dest_path)
return r;
}
-static int write_files(void) {
-
- _cleanup_fclose_ FILE *passwd = NULL, *group = NULL, *shadow = NULL, *gshadow = NULL;
- _cleanup_free_ char *passwd_tmp = NULL, *group_tmp = NULL, *shadow_tmp = NULL, *gshadow_tmp = NULL;
- const char *passwd_path = NULL, *group_path = NULL, *shadow_path = NULL, *gshadow_path = NULL;
- bool group_changed = false;
+static int write_temporary_passwd(const char *passwd_path, FILE **tmpfile, char **tmpfile_path) {
+ _cleanup_fclose_ FILE *original = NULL, *passwd = NULL;
+ _cleanup_(unlink_and_freep) char *passwd_tmp = NULL;
Iterator iterator;
Item *i;
int r;
- if (hashmap_size(todo_gids) > 0 || hashmap_size(members) > 0) {
- _cleanup_fclose_ FILE *original = NULL;
+ if (hashmap_size(todo_uids) == 0)
+ return 0;
- /* First we update the actual group list file */
- group_path = prefix_roota(arg_root, "/etc/group");
- r = fopen_temporary_label("/etc/group", group_path, &group, &group_tmp);
+ r = fopen_temporary_label("/etc/passwd", passwd_path, &passwd, &passwd_tmp);
+ if (r < 0)
+ return r;
+
+ original = fopen(passwd_path, "re");
+ if (original) {
+ struct passwd *pw;
+
+ r = sync_rights(original, passwd);
if (r < 0)
- goto finish;
+ return r;
- original = fopen(group_path, "re");
- if (original) {
- struct group *gr;
+ errno = 0;
+ while ((pw = fgetpwent(original))) {
- r = sync_rights(original, group);
- if (r < 0)
- goto finish;
+ i = hashmap_get(users, pw->pw_name);
+ if (i && i->todo_user) {
+ log_error("%s: User \"%s\" already exists.", passwd_path, pw->pw_name);
+ return -EEXIST;
+ }
+
+ if (hashmap_contains(todo_uids, UID_TO_PTR(pw->pw_uid))) {
+ log_error("%s: Detected collision for UID " UID_FMT ".", passwd_path, pw->pw_uid);
+ return -EEXIST;
+ }
errno = 0;
- while ((gr = fgetgrent(original))) {
- /* Safety checks against name and GID
- * collisions. Normally, this should
- * be unnecessary, but given that we
- * look at the entries anyway here,
- * let's make an extra verification
- * step that we don't generate
- * duplicate entries. */
-
- i = hashmap_get(groups, gr->gr_name);
- if (i && i->todo_group) {
- log_error("%s: Group \"%s\" already exists.", group_path, gr->gr_name);
- r = -EEXIST;
- goto finish;
- }
+ if (putpwent(pw, passwd) < 0)
+ return errno ? -errno : -EIO;
- if (hashmap_contains(todo_gids, GID_TO_PTR(gr->gr_gid))) {
- log_error("%s: Detected collision for GID " GID_FMT ".", group_path, gr->gr_gid);
- r = -EEXIST;
- goto finish;
- }
+ errno = 0;
+ }
+ if (!IN_SET(errno, 0, ENOENT))
+ return -errno;
- r = putgrent_with_members(gr, group);
- if (r < 0)
- goto finish;
- if (r > 0)
- group_changed = true;
+ } else {
+ if (errno != ENOENT)
+ return -errno;
+ if (fchmod(fileno(passwd), 0644) < 0)
+ return -errno;
+ }
- errno = 0;
- }
- if (!IN_SET(errno, 0, ENOENT)) {
- r = -errno;
- goto finish;
- }
+ HASHMAP_FOREACH(i, todo_uids, iterator) {
+ struct passwd n = {
+ .pw_name = i->name,
+ .pw_uid = i->uid,
+ .pw_gid = i->gid,
+ .pw_gecos = i->description,
- } else if (errno != ENOENT) {
- r = -errno;
- goto finish;
- } else if (fchmod(fileno(group), 0644) < 0) {
- r = -errno;
- goto finish;
- }
+ /* "x" means the password is stored in the shadow file */
+ .pw_passwd = (char*) "x",
- HASHMAP_FOREACH(i, todo_gids, iterator) {
- struct group n = {
- .gr_name = i->name,
- .gr_gid = i->gid,
- .gr_passwd = (char*) "x",
- };
+ /* We default to the root directory as home */
+ .pw_dir = i->home ? i->home : (char*) "/",
- r = putgrent_with_members(&n, group);
- if (r < 0)
- goto finish;
+ /* Initialize the shell to nologin, with one exception:
+ * for root we patch in something special */
+ .pw_shell = i->uid == 0 ? (char*) "/bin/sh" : (char*) "/sbin/nologin",
+ };
- group_changed = true;
- }
+ errno = 0;
+ if (putpwent(&n, passwd) != 0)
+ return errno ? -errno : -EIO;
+ }
- r = fflush_and_check(group);
- if (r < 0)
- goto finish;
+ r = fflush_and_check(passwd);
+ if (r < 0)
+ return r;
- if (original) {
- fclose(original);
- original = NULL;
- }
+ *tmpfile = passwd;
+ *tmpfile_path = passwd_tmp;
+ passwd = NULL;
+ passwd_tmp = NULL;
+ return 0;
+}
- /* OK, now also update the shadow file for the group list */
- gshadow_path = prefix_roota(arg_root, "/etc/gshadow");
- r = fopen_temporary_label("/etc/gshadow", gshadow_path, &gshadow, &gshadow_tmp);
- if (r < 0)
- goto finish;
+static int write_temporary_shadow(const char *shadow_path, FILE **tmpfile, char **tmpfile_path) {
+ _cleanup_fclose_ FILE *original = NULL, *shadow = NULL;
+ _cleanup_(unlink_and_freep) char *shadow_tmp = NULL;
+ Iterator iterator;
+ long lstchg;
+ Item *i;
+ int r;
- original = fopen(gshadow_path, "re");
- if (original) {
- struct sgrp *sg;
+ if (hashmap_size(todo_uids) == 0)
+ return 0;
- r = sync_rights(original, gshadow);
- if (r < 0)
- goto finish;
+ r = fopen_temporary_label("/etc/shadow", shadow_path, &shadow, &shadow_tmp);
+ if (r < 0)
+ return r;
- errno = 0;
- while ((sg = fgetsgent(original))) {
+ lstchg = (long) (now(CLOCK_REALTIME) / USEC_PER_DAY);
- i = hashmap_get(groups, sg->sg_namp);
- if (i && i->todo_group) {
- log_error("%s: Group \"%s\" already exists.", gshadow_path, sg->sg_namp);
- r = -EEXIST;
- goto finish;
- }
+ original = fopen(shadow_path, "re");
+ if (original) {
+ struct spwd *sp;
- r = putsgent_with_members(sg, gshadow);
- if (r < 0)
- goto finish;
- if (r > 0)
- group_changed = true;
+ r = sync_rights(original, shadow);
+ if (r < 0)
+ return r;
- errno = 0;
- }
- if (!IN_SET(errno, 0, ENOENT)) {
- r = -errno;
- goto finish;
- }
+ errno = 0;
+ while ((sp = fgetspent(original))) {
- } else if (errno != ENOENT) {
- r = -errno;
- goto finish;
- } else if (fchmod(fileno(gshadow), 0000) < 0) {
- r = -errno;
- goto finish;
- }
+ i = hashmap_get(users, sp->sp_namp);
+ if (i && i->todo_user) {
+ /* we will update the existing entry */
+ sp->sp_lstchg = lstchg;
- HASHMAP_FOREACH(i, todo_gids, iterator) {
- struct sgrp n = {
- .sg_namp = i->name,
- .sg_passwd = (char*) "!!",
- };
+ /* only the /etc/shadow stage is left, so we can
+ * safely remove the item from the todo set */
+ i->todo_user = false;
+ hashmap_remove(todo_uids, UID_TO_PTR(i->uid));
+ }
- r = putsgent_with_members(&n, gshadow);
- if (r < 0)
- goto finish;
+ errno = 0;
+ if (putspent(sp, shadow) < 0)
+ return errno ? -errno : -EIO;
- group_changed = true;
+ errno = 0;
}
+ if (!IN_SET(errno, 0, ENOENT))
+ return -errno;
- r = fflush_and_check(gshadow);
- if (r < 0)
- goto finish;
+ } else {
+ if (errno != ENOENT)
+ return -errno;
+ if (fchmod(fileno(shadow), 0000) < 0)
+ return -errno;
}
- if (hashmap_size(todo_uids) > 0) {
- _cleanup_fclose_ FILE *original = NULL;
- long lstchg;
-
- /* First we update the user database itself */
- passwd_path = prefix_roota(arg_root, "/etc/passwd");
- r = fopen_temporary_label("/etc/passwd", passwd_path, &passwd, &passwd_tmp);
- if (r < 0)
- goto finish;
-
- original = fopen(passwd_path, "re");
- if (original) {
- struct passwd *pw;
+ HASHMAP_FOREACH(i, todo_uids, iterator) {
+ struct spwd n = {
+ .sp_namp = i->name,
+ .sp_pwdp = (char*) "!!",
+ .sp_lstchg = lstchg,
+ .sp_min = -1,
+ .sp_max = -1,
+ .sp_warn = -1,
+ .sp_inact = -1,
+ .sp_expire = -1,
+ .sp_flag = (unsigned long) -1, /* this appears to be what everybody does ... */
+ };
- r = sync_rights(original, passwd);
- if (r < 0)
- goto finish;
+ errno = 0;
+ if (putspent(&n, shadow) != 0)
+ return errno ? -errno : -EIO;
+ }
- errno = 0;
- while ((pw = fgetpwent(original))) {
+ r = fflush_and_check(shadow);
+ if (r < 0)
+ return r;
- i = hashmap_get(users, pw->pw_name);
- if (i && i->todo_user) {
- log_error("%s: User \"%s\" already exists.", passwd_path, pw->pw_name);
- r = -EEXIST;
- goto finish;
- }
+ *tmpfile = shadow;
+ *tmpfile_path = shadow_tmp;
+ shadow = NULL;
+ shadow_tmp = NULL;
+ return 0;
+}
- if (hashmap_contains(todo_uids, UID_TO_PTR(pw->pw_uid))) {
- log_error("%s: Detected collision for UID " UID_FMT ".", passwd_path, pw->pw_uid);
- r = -EEXIST;
- goto finish;
- }
+static int write_temporary_group(const char *group_path, FILE **tmpfile, char **tmpfile_path) {
+ _cleanup_fclose_ FILE *original = NULL, *group = NULL;
+ _cleanup_(unlink_and_freep) char *group_tmp = NULL;
+ bool group_changed = false;
+ Iterator iterator;
+ Item *i;
+ int r;
- errno = 0;
- if (putpwent(pw, passwd) < 0) {
- r = errno ? -errno : -EIO;
- goto finish;
- }
+ if (hashmap_size(todo_gids) == 0 && hashmap_size(members) == 0)
+ return 0;
- errno = 0;
- }
- if (!IN_SET(errno, 0, ENOENT)) {
- r = -errno;
- goto finish;
- }
+ r = fopen_temporary_label("/etc/group", group_path, &group, &group_tmp);
+ if (r < 0)
+ return r;
- } else if (errno != ENOENT) {
- r = -errno;
- goto finish;
- } else if (fchmod(fileno(passwd), 0644) < 0) {
- r = -errno;
- goto finish;
- }
+ original = fopen(group_path, "re");
+ if (original) {
+ struct group *gr;
- HASHMAP_FOREACH(i, todo_uids, iterator) {
- struct passwd n = {
- .pw_name = i->name,
- .pw_uid = i->uid,
- .pw_gid = i->gid,
- .pw_gecos = i->description,
+ r = sync_rights(original, group);
+ if (r < 0)
+ return r;
- /* "x" means the password is stored in
- * the shadow file */
- .pw_passwd = (char*) "x",
+ errno = 0;
+ while ((gr = fgetgrent(original))) {
+ /* Safety checks against name and GID collisions. Normally,
+ * this should be unnecessary, but given that we look at the
+ * entries anyway here, let's make an extra verification
+ * step that we don't generate duplicate entries. */
+
+ i = hashmap_get(groups, gr->gr_name);
+ if (i && i->todo_group) {
+ log_error("%s: Group \"%s\" already exists.", group_path, gr->gr_name);
+ return -EEXIST;
+ }
- /* We default to the root directory as home */
- .pw_dir = i->home ? i->home : (char*) "/",
+ if (hashmap_contains(todo_gids, GID_TO_PTR(gr->gr_gid))) {
+ log_error("%s: Detected collision for GID " GID_FMT ".", group_path, gr->gr_gid);
+ return -EEXIST;
+ }
- /* Initialize the shell to nologin,
- * with one exception: for root we
- * patch in something special */
- .pw_shell = i->uid == 0 ? (char*) "/bin/sh" : (char*) "/sbin/nologin",
- };
+ r = putgrent_with_members(gr, group);
+ if (r < 0)
+ return r;
+ if (r > 0)
+ group_changed = true;
errno = 0;
- if (putpwent(&n, passwd) != 0) {
- r = errno ? -errno : -EIO;
- goto finish;
- }
}
+ if (!IN_SET(errno, 0, ENOENT))
+ return -errno;
- r = fflush_and_check(passwd);
- if (r < 0)
- goto finish;
+ } else {
+ if (errno != ENOENT)
+ return -errno;
+ if (fchmod(fileno(group), 0644) < 0)
+ return -errno;
+ }
- if (original) {
- fclose(original);
- original = NULL;
- }
+ HASHMAP_FOREACH(i, todo_gids, iterator) {
+ struct group n = {
+ .gr_name = i->name,
+ .gr_gid = i->gid,
+ .gr_passwd = (char*) "x",
+ };
- /* The we update the shadow database */
- shadow_path = prefix_roota(arg_root, "/etc/shadow");
- r = fopen_temporary_label("/etc/shadow", shadow_path, &shadow, &shadow_tmp);
+ r = putgrent_with_members(&n, group);
if (r < 0)
- goto finish;
+ return r;
- lstchg = (long) (now(CLOCK_REALTIME) / USEC_PER_DAY);
+ group_changed = true;
+ }
- original = fopen(shadow_path, "re");
- if (original) {
- struct spwd *sp;
+ r = fflush_and_check(group);
+ if (r < 0)
+ return r;
- r = sync_rights(original, shadow);
- if (r < 0)
- goto finish;
+ if (group_changed) {
+ *tmpfile = group;
+ *tmpfile_path = group_tmp;
+ group = NULL;
+ group_tmp = NULL;
+ }
+ return 0;
+}
- errno = 0;
- while ((sp = fgetspent(original))) {
+static int write_temporary_gshadow(const char * gshadow_path, FILE **tmpfile, char **tmpfile_path) {
+#ifdef ENABLE_GSHADOW
+ _cleanup_fclose_ FILE *original = NULL, *gshadow = NULL;
+ _cleanup_(unlink_and_freep) char *gshadow_tmp = NULL;
+ bool group_changed = false;
+ Iterator iterator;
+ Item *i;
+ int r;
- i = hashmap_get(users, sp->sp_namp);
- if (i && i->todo_user) {
- /* we will update the existing entry */
- sp->sp_lstchg = lstchg;
+ if (hashmap_size(todo_gids) == 0 && hashmap_size(members) == 0)
+ return 0;
- /* only the /etc/shadow stage is left, so we can
- * safely remove the item from the todo set */
- i->todo_user = false;
- hashmap_remove(todo_uids, UID_TO_PTR(i->uid));
- }
+ r = fopen_temporary_label("/etc/gshadow", gshadow_path, &gshadow, &gshadow_tmp);
+ if (r < 0)
+ return r;
- errno = 0;
- if (putspent(sp, shadow) < 0) {
- r = errno ? -errno : -EIO;
- goto finish;
- }
+ original = fopen(gshadow_path, "re");
+ if (original) {
+ struct sgrp *sg;
- errno = 0;
- }
- if (!IN_SET(errno, 0, ENOENT)) {
- r = -errno;
- goto finish;
+ r = sync_rights(original, gshadow);
+ if (r < 0)
+ return r;
+
+ errno = 0;
+ while ((sg = fgetsgent(original))) {
+
+ i = hashmap_get(groups, sg->sg_namp);
+ if (i && i->todo_group) {
+ log_error("%s: Group \"%s\" already exists.", gshadow_path, sg->sg_namp);
+ return -EEXIST;
}
- } else if (errno != ENOENT) {
- r = -errno;
- goto finish;
- } else if (fchmod(fileno(shadow), 0000) < 0) {
- r = -errno;
- goto finish;
- }
- HASHMAP_FOREACH(i, todo_uids, iterator) {
- struct spwd n = {
- .sp_namp = i->name,
- .sp_pwdp = (char*) "!!",
- .sp_lstchg = lstchg,
- .sp_min = -1,
- .sp_max = -1,
- .sp_warn = -1,
- .sp_inact = -1,
- .sp_expire = -1,
- .sp_flag = (unsigned long) -1, /* this appears to be what everybody does ... */
- };
+ r = putsgent_with_members(sg, gshadow);
+ if (r < 0)
+ return r;
+ if (r > 0)
+ group_changed = true;
errno = 0;
- if (putspent(&n, shadow) != 0) {
- r = errno ? -errno : -EIO;
- goto finish;
- }
}
+ if (!IN_SET(errno, 0, ENOENT))
+ return -errno;
+
+ } else {
+ if (errno != ENOENT)
+ return -errno;
+ if (fchmod(fileno(gshadow), 0000) < 0)
+ return -errno;
+ }
+
+ HASHMAP_FOREACH(i, todo_gids, iterator) {
+ struct sgrp n = {
+ .sg_namp = i->name,
+ .sg_passwd = (char*) "!!",
+ };
- r = fflush_and_check(shadow);
+ r = putsgent_with_members(&n, gshadow);
if (r < 0)
- goto finish;
+ return r;
+
+ group_changed = true;
}
- /* Make a backup of the old files */
+ r = fflush_and_check(gshadow);
+ if (r < 0)
+ return r;
+
if (group_changed) {
- if (group) {
- r = make_backup("/etc/group", group_path);
- if (r < 0)
- goto finish;
- }
- if (gshadow) {
- r = make_backup("/etc/gshadow", gshadow_path);
- if (r < 0)
- goto finish;
- }
+ *tmpfile = gshadow;
+ *tmpfile_path = gshadow_tmp;
+ gshadow = NULL;
+ gshadow_tmp = NULL;
+ }
+ return 0;
+#else
+ return 0;
+#endif
+}
+
+static int write_files(void) {
+ _cleanup_fclose_ FILE *passwd = NULL, *group = NULL, *shadow = NULL, *gshadow = NULL;
+ _cleanup_(unlink_and_freep) char *passwd_tmp = NULL, *group_tmp = NULL, *shadow_tmp = NULL, *gshadow_tmp = NULL;
+ const char *passwd_path = NULL, *group_path = NULL, *shadow_path = NULL, *gshadow_path = NULL;
+ int r;
+
+ passwd_path = prefix_roota(arg_root, "/etc/passwd");
+ shadow_path = prefix_roota(arg_root, "/etc/shadow");
+ group_path = prefix_roota(arg_root, "/etc/group");
+ gshadow_path = prefix_roota(arg_root, "/etc/gshadow");
+
+ r = write_temporary_group(group_path, &group, &group_tmp);
+ if (r < 0)
+ return r;
+
+ r = write_temporary_gshadow(gshadow_path, &gshadow, &gshadow_tmp);
+ if (r < 0)
+ return r;
+
+ r = write_temporary_passwd(passwd_path, &passwd, &passwd_tmp);
+ if (r < 0)
+ return r;
+
+ r = write_temporary_shadow(shadow_path, &shadow, &shadow_tmp);
+ if (r < 0)
+ return r;
+
+ /* Make a backup of the old files */
+ if (group) {
+ r = make_backup("/etc/group", group_path);
+ if (r < 0)
+ return r;
+ }
+ if (gshadow) {
+ r = make_backup("/etc/gshadow", gshadow_path);
+ if (r < 0)
+ return r;
}
if (passwd) {
r = make_backup("/etc/passwd", passwd_path);
if (r < 0)
- goto finish;
+ return r;
}
if (shadow) {
r = make_backup("/etc/shadow", shadow_path);
if (r < 0)
- goto finish;
+ return r;
}
/* And make the new files count */
- if (group_changed) {
- if (group) {
- r = rename_and_apply_smack(group_tmp, group_path);
- if (r < 0)
- goto finish;
+ if (group) {
+ r = rename_and_apply_smack(group_tmp, group_path);
+ if (r < 0)
+ return r;
- group_tmp = mfree(group_tmp);
- }
- if (gshadow) {
- r = rename_and_apply_smack(gshadow_tmp, gshadow_path);
- if (r < 0)
- goto finish;
+ group_tmp = mfree(group_tmp);
+ }
+ if (gshadow) {
+ r = rename_and_apply_smack(gshadow_tmp, gshadow_path);
+ if (r < 0)
+ return r;
- gshadow_tmp = mfree(gshadow_tmp);
- }
+ gshadow_tmp = mfree(gshadow_tmp);
}
if (passwd) {
r = rename_and_apply_smack(passwd_tmp, passwd_path);
if (r < 0)
- goto finish;
+ return r;
passwd_tmp = mfree(passwd_tmp);
}
if (shadow) {
r = rename_and_apply_smack(shadow_tmp, shadow_path);
if (r < 0)
- goto finish;
+ return r;
shadow_tmp = mfree(shadow_tmp);
}
- r = 0;
-
-finish:
- if (passwd_tmp)
- unlink(passwd_tmp);
- if (shadow_tmp)
- unlink(shadow_tmp);
- if (group_tmp)
- unlink(group_tmp);
- if (gshadow_tmp)
- unlink(gshadow_tmp);
-
- return r;
+ return 0;
}
static int uid_is_ok(uid_t uid, const char *name) {
diff --git a/src/sysv-generator/sysv-generator.c b/src/sysv-generator/sysv-generator.c
index 9fde9b1884..9828078443 100644
--- a/src/sysv-generator/sysv-generator.c
+++ b/src/sysv-generator/sysv-generator.c
@@ -389,6 +389,9 @@ static int handle_provides(SysvStub *s, unsigned line, const char *full_text, co
r = strv_extend(&s->before, SPECIAL_NETWORK_TARGET);
if (r < 0)
return log_oom();
+ r = strv_extend(&s->wants, SPECIAL_NETWORK_TARGET);
+ if (r < 0)
+ return log_oom();
}
break;
diff --git a/src/test/generate-sym-test.py b/src/test/generate-sym-test.py
new file mode 100755
index 0000000000..357cce8e44
--- /dev/null
+++ b/src/test/generate-sym-test.py
@@ -0,0 +1,23 @@
+#!/usr/bin/env python3
+import sys, re
+
+print('#include <stdio.h>')
+for header in sys.argv[2:]:
+ print('#include "{}"'.format(header.split('/')[-1]))
+
+print('''
+void* functions[] = {''')
+
+for line in open(sys.argv[1]):
+ match = re.search('^ +([a-zA-Z0-9_]+);', line)
+ if match:
+ print(' {},'.format(match.group(1)))
+
+print('''};
+
+int main(void) {
+ unsigned i;
+ for (i = 0; i < sizeof(functions)/sizeof(void*); i++)
+ printf("%p\\n", functions[i]);
+ return 0;
+}''')
diff --git a/src/test/meson.build b/src/test/meson.build
new file mode 100644
index 0000000000..7b493a4d05
--- /dev/null
+++ b/src/test/meson.build
@@ -0,0 +1,906 @@
+awkscript = 'test-hashmap-ordered.awk'
+test_hashmap_ordered_c = custom_target(
+ 'test-hashmap-ordered.c',
+ input : [awkscript, 'test-hashmap-plain.c'],
+ output : 'test-hashmap-ordered.c',
+ command : [awk, '-f', '@INPUT0@', '@INPUT1@'],
+ capture : true)
+
+test_include_dir = include_directories('.')
+
+path = run_command('sh', ['-c', 'echo "$PATH"']).stdout()
+test_env = environment()
+test_env.set('SYSTEMD_KBD_MODEL_MAP', kbd_model_map)
+test_env.set('SYSTEMD_LANGUAGE_FALLBACK_MAP', language_fallback_map)
+test_env.set('PATH', path)
+test_env.prepend('PATH', meson.build_root())
+
+############################################################
+
+generate_sym_test_py = find_program('generate-sym-test.py')
+
+test_libsystemd_sym_c = custom_target(
+ 'test-libsystemd-sym.c',
+ input : [libsystemd_sym_path] + systemd_headers,
+ output : 'test-libsystemd-sym.c',
+ command : [generate_sym_test_py, libsystemd_sym_path] + systemd_headers,
+ capture : true)
+
+test_libudev_sym_c = custom_target(
+ 'test-libudev-sym.c',
+ input : [libudev_sym_path, libudev_h_path],
+ output : 'test-libudev-sym.c',
+ command : [generate_sym_test_py, '@INPUT0@', '@INPUT1@'],
+ capture : true)
+
+test_dlopen_c = files('test-dlopen.c')
+
+############################################################
+
+tests += [
+ [['src/test/test-device-nodes.c'],
+ [],
+ []],
+
+ [['src/test/test-engine.c'],
+ [libcore,
+ libudev,
+ libsystemd_internal],
+ [threads,
+ librt,
+ libseccomp,
+ libselinux,
+ libmount,
+ libblkid]],
+
+ [['src/test/test-job-type.c'],
+ [libcore,
+ libshared],
+ [threads,
+ librt,
+ libseccomp,
+ libselinux,
+ libmount,
+ libblkid]],
+
+ [['src/test/test-ns.c'],
+ [libcore,
+ libshared],
+ [threads,
+ librt,
+ libseccomp,
+ libselinux,
+ libmount,
+ libblkid],
+ '', 'manual'],
+
+ [['src/test/test-loopback.c'],
+ [libcore,
+ libshared],
+ [threads,
+ librt,
+ libseccomp,
+ libselinux,
+ libmount,
+ libblkid]],
+
+ [['src/test/test-hostname.c'],
+ [libcore,
+ libshared],
+ [threads,
+ librt,
+ libseccomp,
+ libselinux,
+ libmount,
+ libblkid],
+ '', 'unsafe'],
+
+ [['src/test/test-dns-domain.c'],
+ [libcore,
+ libsystemd_network],
+ []],
+
+ [['src/test/test-boot-timestamps.c'],
+ [],
+ [],
+ 'ENABLE_EFI'],
+
+ [['src/test/test-unit-name.c'],
+ [libcore,
+ libshared],
+ [threads,
+ librt,
+ libseccomp,
+ libselinux,
+ libmount,
+ libblkid]],
+
+ [['src/test/test-unit-file.c'],
+ [libcore,
+ libshared],
+ [threads,
+ librt,
+ libseccomp,
+ libselinux,
+ libmount,
+ libblkid]],
+
+ [['src/test/test-utf8.c'],
+ [],
+ []],
+
+ [['src/test/test-capability.c'],
+ [],
+ [libcap]],
+
+ [['src/test/test-async.c'],
+ [],
+ []],
+
+ [['src/test/test-locale-util.c'],
+ [],
+ []],
+
+ [['src/test/test-copy.c'],
+ [libshared_static],
+ []],
+
+ [['src/test/test-sigbus.c'],
+ [],
+ []],
+
+ [['src/test/test-condition.c'],
+ [],
+ []],
+
+ [['src/test/test-fdset.c'],
+ [],
+ []],
+
+ [['src/test/test-fstab-util.c'],
+ [],
+ []],
+
+ [['src/test/test-random-util.c'],
+ [],
+ []],
+
+ [['src/test/test-ratelimit.c'],
+ [],
+ []],
+
+ [['src/test/test-util.c'],
+ [],
+ []],
+
+ [['src/test/test-mount-util.c'],
+ [],
+ []],
+
+ [['src/test/test-exec-util.c'],
+ [],
+ []],
+
+ [['src/test/test-hexdecoct.c'],
+ [],
+ []],
+
+ [['src/test/test-alloc-util.c'],
+ [],
+ []],
+
+ [['src/test/test-xattr-util.c'],
+ [],
+ []],
+
+ [['src/test/test-io-util.c'],
+ [],
+ []],
+
+ [['src/test/test-glob-util.c'],
+ [],
+ []],
+
+ [['src/test/test-fs-util.c'],
+ [],
+ []],
+
+ [['src/test/test-proc-cmdline.c'],
+ [],
+ []],
+
+ [['src/test/test-fd-util.c'],
+ [],
+ []],
+
+ [['src/test/test-web-util.c'],
+ [],
+ []],
+
+ [['src/test/test-cpu-set-util.c'],
+ [],
+ []],
+
+ [['src/test/test-stat-util.c'],
+ [],
+ []],
+
+ [['src/test/test-escape.c'],
+ [],
+ []],
+
+ [['src/test/test-string-util.c'],
+ [],
+ []],
+
+ [['src/test/test-extract-word.c'],
+ [],
+ []],
+
+ [['src/test/test-parse-util.c'],
+ [],
+ []],
+
+ [['src/test/test-user-util.c'],
+ [],
+ []],
+
+ [['src/test/test-hostname-util.c'],
+ [],
+ []],
+
+ [['src/test/test-process-util.c'],
+ [],
+ []],
+
+ [['src/test/test-terminal-util.c'],
+ [],
+ []],
+
+ [['src/test/test-path-lookup.c'],
+ [],
+ []],
+
+ [['src/test/test-uid-range.c'],
+ [],
+ []],
+
+ [['src/test/test-cap-list.c',
+ generated_gperf_headers],
+ [],
+ [libcap]],
+
+ [['src/test/test-socket-util.c'],
+ [],
+ []],
+
+ [['src/test/test-barrier.c'],
+ [],
+ []],
+
+ [['src/test/test-tmpfiles.c'],
+ [],
+ []],
+
+ [['src/test/test-namespace.c'],
+ [libcore,
+ libshared],
+ [threads,
+ libblkid]],
+
+ [['src/test/test-verbs.c'],
+ [],
+ []],
+
+ [['src/test/test-install-root.c'],
+ [],
+ []],
+
+ [['src/test/test-acl-util.c'],
+ [],
+ [],
+ 'HAVE_ACL'],
+
+ [['src/test/test-seccomp.c'],
+ [],
+ [libseccomp],
+ 'HAVE_SECCOMP'],
+
+ [['src/test/test-rlimit-util.c'],
+ [],
+ []],
+
+ [['src/test/test-ask-password-api.c'],
+ [],
+ [],
+ '', 'manual'],
+
+ [['src/test/test-dissect-image.c'],
+ [],
+ [libblkid],
+ '', 'manual'],
+
+ [['src/test/test-signal-util.c'],
+ [],
+ []],
+
+ [['src/test/test-selinux.c'],
+ [],
+ []],
+
+ [['src/test/test-sizeof.c'],
+ [libbasic],
+ []],
+
+ [['src/test/test-hashmap.c',
+ 'src/test/test-hashmap-plain.c',
+ test_hashmap_ordered_c],
+ [],
+ [],
+ '', 'timeout=90'],
+
+ [['src/test/test-set.c'],
+ [],
+ []],
+
+ [['src/test/test-bitmap.c'],
+ [],
+ []],
+
+ [['src/test/test-xml.c'],
+ [],
+ []],
+
+ [['src/test/test-list.c'],
+ [],
+ []],
+
+ [['src/test/test-unaligned.c'],
+ [],
+ []],
+
+ [['src/test/test-tables.c',
+ 'src/shared/test-tables.h',
+ 'src/journal/journald-server.c',
+ 'src/journal/journald-server.h'],
+ [libcore,
+ libjournal_core,
+ libudev_core,
+ libudev_internal,
+ libsystemd_network,
+ libshared],
+ [threads,
+ libseccomp,
+ libmount,
+ libxz,
+ liblz4,
+ libblkid],
+ '', '', [], libudev_core_includes],
+
+ [['src/test/test-prioq.c'],
+ [],
+ []],
+
+ [['src/test/test-fileio.c'],
+ [],
+ []],
+
+ [['src/test/test-time.c'],
+ [],
+ []],
+
+ [['src/test/test-clock.c'],
+ [],
+ []],
+
+ [['src/test/test-architecture.c'],
+ [],
+ []],
+
+ [['src/test/test-log.c'],
+ [],
+ []],
+
+ [['src/test/test-ipcrm.c'],
+ [],
+ [],
+ '', 'unsafe'],
+
+ [['src/test/test-btrfs.c'],
+ [],
+ [],
+ '', 'manual'],
+
+
+ [['src/test/test-firewall-util.c'],
+ [libshared],
+ [],
+ 'HAVE_LIBIPTC'],
+
+ [['src/test/test-netlink-manual.c'],
+ [],
+ [libkmod],
+ 'HAVE_KMOD', 'manual'],
+
+ [['src/test/test-ellipsize.c'],
+ [],
+ []],
+
+ [['src/test/test-date.c'],
+ [],
+ []],
+
+ [['src/test/test-sleep.c'],
+ [],
+ []],
+
+ [['src/test/test-replace-var.c'],
+ [],
+ []],
+
+ [['src/test/test-calendarspec.c'],
+ [],
+ []],
+
+ [['src/test/test-strip-tab-ansi.c'],
+ [],
+ []],
+
+ [['src/test/test-daemon.c'],
+ [],
+ []],
+
+ [['src/test/test-cgroup.c'],
+ [],
+ [],
+ '', 'manual'],
+
+
+ [['src/test/test-cgroup-mask.c'],
+ [libcore,
+ libshared],
+ [threads,
+ librt,
+ libseccomp,
+ libselinux,
+ libmount,
+ libblkid]],
+
+ [['src/test/test-cgroup-util.c'],
+ [],
+ []],
+
+ [['src/test/test-env-util.c'],
+ [],
+ []],
+
+ [['src/test/test-strbuf.c'],
+ [],
+ []],
+
+ [['src/test/test-strv.c'],
+ [],
+ []],
+
+ [['src/test/test-path-util.c'],
+ [],
+ []],
+
+ [['src/test/test-path.c'],
+ [libcore,
+ libshared],
+ [threads,
+ librt,
+ libseccomp,
+ libselinux,
+ libmount,
+ libblkid]],
+
+ [['src/test/test-execute.c'],
+ [libcore,
+ libshared],
+ [threads,
+ librt,
+ libseccomp,
+ libselinux,
+ libmount,
+ libblkid]],
+
+ [['src/test/test-siphash24.c'],
+ [],
+ []],
+
+ [['src/test/test-strxcpyx.c'],
+ [],
+ []],
+
+ [['src/test/test-install.c'],
+ [libcore,
+ libshared],
+ [],
+ '', 'manual'],
+
+ [['src/test/test-watchdog.c'],
+ [],
+ []],
+
+ [['src/test/test-sched-prio.c'],
+ [libcore,
+ libshared],
+ [threads,
+ librt,
+ libseccomp,
+ libselinux,
+ libmount,
+ libblkid]],
+
+ [['src/test/test-conf-files.c'],
+ [],
+ []],
+
+ [['src/test/test-conf-parser.c'],
+ [],
+ []],
+
+ [['src/test/test-af-list.c',
+ generated_gperf_headers],
+ [],
+ []],
+
+ [['src/test/test-arphrd-list.c',
+ generated_gperf_headers],
+ [],
+ []],
+
+ [['src/test/test-journal-importer.c'],
+ [],
+ []],
+
+ [['src/test/test-libudev.c'],
+ [libshared],
+ []],
+
+ [['src/test/test-udev.c'],
+ [libudev_core,
+ libudev_internal,
+ libsystemd_network,
+ libshared],
+ [threads,
+ librt,
+ libblkid,
+ libkmod,
+ libacl],
+ '', 'manual'],
+
+ [['src/test/test-id128.c'],
+ [],
+ []],
+
+ [['src/test/test-hash.c'],
+ [],
+ []],
+
+ [['src/test/test-nss.c'],
+ [],
+ [libdl],
+ '', 'manual'],
+]
+
+############################################################
+
+# define some tests here, because the link_with deps were not defined earlier
+
+tests += [
+ [['src/journal/test-journal.c'],
+ [libjournal_core,
+ libshared],
+ [threads,
+ libxz,
+ liblz4]],
+
+ [['src/journal/test-journal-send.c'],
+ [libjournal_core,
+ libshared],
+ [threads,
+ libxz,
+ liblz4]],
+
+ [['src/journal/test-journal-syslog.c'],
+ [libjournal_core,
+ libshared],
+ [threads,
+ libxz,
+ liblz4,
+ libselinux]],
+
+ [['src/journal/test-journal-match.c'],
+ [libjournal_core,
+ libshared],
+ [threads,
+ libxz,
+ liblz4]],
+
+ [['src/journal/test-journal-enum.c'],
+ [libjournal_core,
+ libshared],
+ [threads,
+ libxz,
+ liblz4]],
+
+ [['src/journal/test-journal-stream.c'],
+ [libjournal_core,
+ libshared],
+ [threads,
+ libxz,
+ liblz4]],
+
+ [['src/journal/test-journal-flush.c'],
+ [libjournal_core,
+ libshared],
+ [threads,
+ libxz,
+ liblz4]],
+
+ [['src/journal/test-journal-init.c'],
+ [libjournal_core,
+ libshared],
+ [threads,
+ libxz,
+ liblz4]],
+
+ [['src/journal/test-journal-verify.c'],
+ [libjournal_core,
+ libshared],
+ [threads,
+ libxz,
+ liblz4]],
+
+ [['src/journal/test-journal-interleaving.c'],
+ [libjournal_core,
+ libshared],
+ [threads,
+ libxz,
+ liblz4]],
+
+ [['src/journal/test-mmap-cache.c'],
+ [libjournal_core,
+ libshared],
+ [threads,
+ libxz,
+ liblz4]],
+
+ [['src/journal/test-catalog.c'],
+ [libjournal_core,
+ libshared],
+ [threads,
+ libxz,
+ liblz4],
+ '', '', '-DCATALOG_DIR="@0@"'.format(build_catalog_dir)],
+
+ [['src/journal/test-compress.c'],
+ [libjournal_core,
+ libshared],
+ [liblz4,
+ libxz]],
+
+ [['src/journal/test-compress-benchmark.c'],
+ [libjournal_core,
+ libshared],
+ [liblz4,
+ libxz],
+ '', 'timeout=90'],
+
+ [['src/journal/test-audit-type.c'],
+ [libjournal_core,
+ libshared],
+ [liblz4,
+ libxz]],
+]
+
+############################################################
+
+tests += [
+ [['src/libsystemd/sd-bus/test-bus-marshal.c'],
+ [],
+ [threads,
+ libglib,
+ libgobject,
+ libgio,
+ libdbus]],
+
+ [['src/libsystemd/sd-bus/test-bus-signature.c'],
+ [],
+ [threads]],
+
+ [['src/libsystemd/sd-bus/test-bus-chat.c'],
+ [],
+ [threads]],
+
+ [['src/libsystemd/sd-bus/test-bus-cleanup.c'],
+ [],
+ [threads,
+ libseccomp]],
+
+ [['src/libsystemd/sd-bus/test-bus-error.c'],
+ [libshared_static,
+ libsystemd_internal],
+ []],
+
+ [['src/libsystemd/sd-bus/test-bus-track.c'],
+ [],
+ [libseccomp]],
+
+ [['src/libsystemd/sd-bus/test-bus-server.c'],
+ [],
+ [threads]],
+
+ [['src/libsystemd/sd-bus/test-bus-objects.c'],
+ [],
+ [threads]],
+
+ [['src/libsystemd/sd-bus/test-bus-vtable.c'],
+ [],
+ []],
+
+ [['src/libsystemd/sd-bus/test-bus-gvariant.c'],
+ [],
+ [libglib,
+ libgobject,
+ libgio]],
+
+ [['src/libsystemd/sd-bus/test-bus-creds.c'],
+ [],
+ []],
+
+ [['src/libsystemd/sd-bus/test-bus-match.c'],
+ [],
+ []],
+
+ [['src/libsystemd/sd-bus/test-bus-kernel.c'],
+ [],
+ []],
+
+ [['src/libsystemd/sd-bus/test-bus-kernel-bloom.c'],
+ [],
+ []],
+
+ [['src/libsystemd/sd-bus/test-bus-benchmark.c'],
+ [],
+ [threads]],
+
+ [['src/libsystemd/sd-bus/test-bus-zero-copy.c'],
+ [],
+ []],
+
+ [['src/libsystemd/sd-bus/test-bus-introspect.c'],
+ [],
+ []],
+
+ [['src/libsystemd/sd-event/test-event.c'],
+ [],
+ []],
+
+ [['src/libsystemd/sd-netlink/test-netlink.c'],
+ [],
+ []],
+
+ [['src/libsystemd/sd-netlink/test-local-addresses.c'],
+ [],
+ []],
+
+ [['src/libsystemd/sd-resolve/test-resolve.c'],
+ [],
+ [threads]],
+
+ [['src/libsystemd/sd-login/test-login.c'],
+ [],
+ []],
+]
+
+if cxx.found()
+ tests += [
+ [['src/libsystemd/sd-bus/test-bus-vtable-cc.cc'],
+ [],
+ []]
+ ]
+endif
+
+############################################################
+
+tests += [
+ [['src/libsystemd-network/test-dhcp-option.c',
+ 'src/libsystemd-network/dhcp-protocol.h',
+ 'src/libsystemd-network/dhcp-internal.h'],
+ [libshared,
+ libsystemd_network],
+ []],
+
+ [['src/libsystemd-network/test-sd-dhcp-lease.c',
+ 'src/libsystemd-network/dhcp-lease-internal.h'],
+ [libshared,
+ libsystemd_network],
+ []],
+
+ [['src/libsystemd-network/test-dhcp-client.c',
+ 'src/libsystemd-network/dhcp-protocol.h',
+ 'src/libsystemd-network/dhcp-internal.h',
+ 'src/systemd/sd-dhcp-client.h'],
+ [libshared,
+ libsystemd_network],
+ []],
+
+ [['src/libsystemd-network/test-dhcp-server.c'],
+ [libshared,
+ libsystemd_network],
+ []],
+
+ [['src/libsystemd-network/test-ipv4ll.c',
+ 'src/libsystemd-network/arp-util.h',
+ 'src/systemd/sd-ipv4ll.h'],
+ [libshared,
+ libsystemd_network],
+ []],
+
+ [['src/libsystemd-network/test-ipv4ll-manual.c',
+ 'src/systemd/sd-ipv4ll.h'],
+ [libshared,
+ libsystemd_network],
+ [],
+ '', 'manual'],
+
+ [['src/libsystemd-network/test-acd.c',
+ 'src/systemd/sd-ipv4acd.h'],
+ [libshared,
+ libsystemd_network],
+ [],
+ '', 'manual'],
+
+ [['src/libsystemd-network/test-ndisc-rs.c',
+ 'src/libsystemd-network/dhcp-identifier.h',
+ 'src/libsystemd-network/dhcp-identifier.c',
+ 'src/libsystemd-network/icmp6-util.h',
+ 'src/systemd/sd-dhcp6-client.h',
+ 'src/systemd/sd-ndisc.h'],
+ [libshared,
+ libsystemd_network],
+ []],
+
+ [['src/libsystemd-network/test-ndisc-ra.c',
+ 'src/libsystemd-network/icmp6-util.h',
+ 'src/systemd/sd-ndisc.h'],
+ [libshared,
+ libsystemd_network],
+ []],
+
+ [['src/libsystemd-network/test-dhcp6-client.c',
+ 'src/libsystemd-network/dhcp-identifier.h',
+ 'src/libsystemd-network/dhcp-identifier.c',
+ 'src/libsystemd-network/dhcp6-internal.h',
+ 'src/systemd/sd-dhcp6-client.h'],
+ [libshared,
+ libsystemd_network],
+ []],
+
+ [['src/libsystemd-network/test-lldp.c'],
+ [libshared,
+ libsystemd_network],
+ []],
+]
+
+############################################################
+
+tests += [
+ [['src/login/test-login-shared.c'],
+ [],
+ []],
+
+ [['src/login/test-inhibit.c'],
+ [],
+ [],
+ '', 'manual'],
+
+ [['src/login/test-login-tables.c'],
+ [liblogind_core,
+ libshared],
+ [threads]],
+]
diff --git a/src/test/test-af-list.c b/src/test/test-af-list.c
index e5ca54c8e7..bbaf18b08a 100644
--- a/src/test/test-af-list.c
+++ b/src/test/test-af-list.c
@@ -24,7 +24,7 @@
#include "string-util.h"
#include "util.h"
-_unused_ \
+_unused_
static const struct af_name* lookup_af(register const char *str, register GPERF_LEN_TYPE len);
#include "af-from-name.h"
diff --git a/src/test/test-calendarspec.c b/src/test/test-calendarspec.c
index f90b73aeaf..a026ce4ef1 100644
--- a/src/test/test-calendarspec.c
+++ b/src/test/test-calendarspec.c
@@ -193,6 +193,11 @@ int main(int argc, char* argv[]) {
test_one("*:20..39/5", "*-*-* *:20..35/5:00");
test_one("00:00:20..40/1", "*-*-* 00:00:20..40");
test_one("*~03/1,03..05", "*-*~03/1,03..05 00:00:00");
+ /* UNIX timestamps are always UTC */
+ test_one("@1493187147", "2017-04-26 06:12:27 UTC");
+ test_one("@1493187147 UTC", "2017-04-26 06:12:27 UTC");
+ test_one("@0", "1970-01-01 00:00:00 UTC");
+ test_one("@0 UTC", "1970-01-01 00:00:00 UTC");
test_next("2016-03-27 03:17:00", "", 12345, 1459048620000000);
test_next("2016-03-27 03:17:00", "CET", 12345, 1459041420000000);
diff --git a/src/test/test-cgroup.c b/src/test/test-cgroup.c
index 5336c19652..71e318a15b 100644
--- a/src/test/test-cgroup.c
+++ b/src/test/test-cgroup.c
@@ -35,19 +35,19 @@ int main(int argc, char*argv[]) {
assert_se(cg_create(SYSTEMD_CGROUP_CONTROLLER, "/test-b/test-c") == 0);
assert_se(cg_create_and_attach(SYSTEMD_CGROUP_CONTROLLER, "/test-b", 0) == 0);
- assert_se(cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, getpid(), &path) == 0);
+ assert_se(cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, getpid_cached(), &path) == 0);
assert_se(streq(path, "/test-b"));
free(path);
assert_se(cg_attach(SYSTEMD_CGROUP_CONTROLLER, "/test-a", 0) == 0);
- assert_se(cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, getpid(), &path) == 0);
+ assert_se(cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, getpid_cached(), &path) == 0);
assert_se(path_equal(path, "/test-a"));
free(path);
assert_se(cg_create_and_attach(SYSTEMD_CGROUP_CONTROLLER, "/test-b/test-d", 0) == 0);
- assert_se(cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, getpid(), &path) == 0);
+ assert_se(cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, getpid_cached(), &path) == 0);
assert_se(path_equal(path, "/test-b/test-d"));
free(path);
diff --git a/src/test/test-condition.c b/src/test/test-condition.c
index dd985f5863..121345cfd1 100644
--- a/src/test/test-condition.c
+++ b/src/test/test-condition.c
@@ -17,6 +17,10 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+
#include "sd-id128.h"
#include "alloc-util.h"
@@ -34,6 +38,7 @@
#include "strv.h"
#include "virt.h"
#include "util.h"
+#include "user-util.h"
static void test_condition_test_path(void) {
Condition *condition;
@@ -243,7 +248,7 @@ static void test_condition_test_security(void) {
condition = condition_new(CONDITION_SECURITY, "selinux", false, true);
assert_se(condition);
- assert_se(condition_test(condition) != mac_selinux_have());
+ assert_se(condition_test(condition) != mac_selinux_use());
condition_free(condition);
condition = condition_new(CONDITION_SECURITY, "ima", false, false);
@@ -323,6 +328,150 @@ static void test_condition_test_virtualization(void) {
}
}
+static void test_condition_test_user(void) {
+ Condition *condition;
+ char* uid;
+ char* username;
+ int r;
+
+ condition = condition_new(CONDITION_USER, "garbage oifdsjfoidsjoj", false, false);
+ assert_se(condition);
+ r = condition_test(condition);
+ log_info("ConditionUser=garbage → %i", r);
+ assert_se(r == 0);
+ condition_free(condition);
+
+ assert_se(asprintf(&uid, "%"PRIu32, UINT32_C(0xFFFF)) > 0);
+ condition = condition_new(CONDITION_USER, uid, false, false);
+ assert_se(condition);
+ r = condition_test(condition);
+ log_info("ConditionUser=%s → %i", uid, r);
+ assert_se(r == 0);
+ condition_free(condition);
+ free(uid);
+
+ assert_se(asprintf(&uid, "%u", (unsigned)getuid()) > 0);
+ condition = condition_new(CONDITION_USER, uid, false, false);
+ assert_se(condition);
+ r = condition_test(condition);
+ log_info("ConditionUser=%s → %i", uid, r);
+ assert_se(r > 0);
+ condition_free(condition);
+ free(uid);
+
+ assert_se(asprintf(&uid, "%u", (unsigned)getuid()+1) > 0);
+ condition = condition_new(CONDITION_USER, uid, false, false);
+ assert_se(condition);
+ r = condition_test(condition);
+ log_info("ConditionUser=%s → %i", uid, r);
+ assert_se(r == 0);
+ condition_free(condition);
+ free(uid);
+
+ username = getusername_malloc();
+ assert_se(username);
+ condition = condition_new(CONDITION_USER, username, false, false);
+ assert_se(condition);
+ r = condition_test(condition);
+ log_info("ConditionUser=%s → %i", username, r);
+ assert_se(r > 0);
+ condition_free(condition);
+ free(username);
+
+ username = (char*)(geteuid() == 0 ? NOBODY_USER_NAME : "root");
+ condition = condition_new(CONDITION_USER, username, false, false);
+ assert_se(condition);
+ r = condition_test(condition);
+ log_info("ConditionUser=%s → %i", username, r);
+ assert_se(r == 0);
+ condition_free(condition);
+
+ condition = condition_new(CONDITION_USER, "@system", false, false);
+ assert_se(condition);
+ r = condition_test(condition);
+ log_info("ConditionUser=@system → %i", r);
+ if (geteuid() == 0)
+ assert_se(r > 0);
+ else
+ assert_se(r == 0);
+ condition_free(condition);
+}
+
+static void test_condition_test_group(void) {
+ Condition *condition;
+ char* gid;
+ char* groupname;
+ gid_t *gids, max_gid;
+ int ngroups_max, r, i;
+
+ assert_se(0 < asprintf(&gid, "%u", UINT32_C(0xFFFF)));
+ condition = condition_new(CONDITION_GROUP, gid, false, false);
+ assert_se(condition);
+ r = condition_test(condition);
+ log_info("ConditionGroup=%s → %i", gid, r);
+ assert_se(r == 0);
+ condition_free(condition);
+ free(gid);
+
+ assert_se(0 < asprintf(&gid, "%u", getgid()));
+ condition = condition_new(CONDITION_GROUP, gid, false, false);
+ assert_se(condition);
+ r = condition_test(condition);
+ log_info("ConditionGroup=%s → %i", gid, r);
+ assert_se(r > 0);
+ condition_free(condition);
+ free(gid);
+
+ ngroups_max = sysconf(_SC_NGROUPS_MAX);
+ assert(ngroups_max > 0);
+
+ gids = alloca(sizeof(gid_t) * ngroups_max);
+
+ r = getgroups(ngroups_max, gids);
+ assert(r >= 0);
+
+ max_gid = getgid();
+ for (i = 0; i < r; i++) {
+ assert_se(0 < asprintf(&gid, "%u", gids[i]));
+ condition = condition_new(CONDITION_GROUP, gid, false, false);
+ assert_se(condition);
+ r = condition_test(condition);
+ log_info("ConditionGroup=%s → %i", gid, r);
+ assert_se(r > 0);
+ condition_free(condition);
+ free(gid);
+ max_gid = gids[i] > max_gid ? gids[i] : max_gid;
+
+ groupname = gid_to_name(gids[i]);
+ assert_se(groupname);
+ condition = condition_new(CONDITION_GROUP, groupname, false, false);
+ assert_se(condition);
+ r = condition_test(condition);
+ log_info("ConditionGroup=%s → %i", groupname, r);
+ assert_se(r > 0);
+ condition_free(condition);
+ free(groupname);
+ max_gid = gids[i] > max_gid ? gids[i] : max_gid;
+ }
+
+ assert_se(0 < asprintf(&gid, "%u", max_gid+1));
+ condition = condition_new(CONDITION_GROUP, gid, false, false);
+ assert_se(condition);
+ r = condition_test(condition);
+ log_info("ConditionGroup=%s → %i", gid, r);
+ assert_se(r == 0);
+ condition_free(condition);
+ free(gid);
+
+ groupname = (char*)(geteuid() == 0 ? NOBODY_GROUP_NAME : "root");
+ condition = condition_new(CONDITION_GROUP, groupname, false, false);
+ assert_se(condition);
+ r = condition_test(condition);
+ log_info("ConditionGroup=%s → %i", groupname, r);
+ assert_se(r == 0);
+ condition_free(condition);
+}
+
int main(int argc, char *argv[]) {
log_set_max_level(LOG_DEBUG);
log_parse_environment();
@@ -336,6 +485,8 @@ int main(int argc, char *argv[]) {
test_condition_test_null();
test_condition_test_security();
test_condition_test_virtualization();
+ test_condition_test_user();
+ test_condition_test_group();
return 0;
}
diff --git a/src/test/test-date.c b/src/test/test-date.c
index b77598c81d..0e7d44fade 100644
--- a/src/test/test-date.c
+++ b/src/test/test-date.c
@@ -25,41 +25,44 @@
static void test_should_pass(const char *p) {
usec_t t, q;
- char buf[FORMAT_TIMESTAMP_MAX], buf_relative[FORMAT_TIMESTAMP_RELATIVE_MAX], *sp;
+ char buf[FORMAT_TIMESTAMP_MAX], buf_relative[FORMAT_TIMESTAMP_RELATIVE_MAX];
+ log_info("Test: %s", p);
assert_se(parse_timestamp(p, &t) >= 0);
- format_timestamp_us(buf, sizeof(buf), t);
- log_info("%s", buf);
-
- /* Chop off timezone */
- sp = strrchr(buf, ' ');
- assert_se(sp);
- *sp = 0;
+ assert_se(format_timestamp_us(buf, sizeof(buf), t));
+ log_info("\"%s\" → \"%s\"", p, buf);
assert_se(parse_timestamp(buf, &q) >= 0);
assert_se(q == t);
- format_timestamp_relative(buf_relative, sizeof(buf_relative), t);
+ assert_se(format_timestamp_relative(buf_relative, sizeof(buf_relative), t));
log_info("%s", strna(buf_relative));
- assert_se(parse_timestamp(buf, &q) >= 0);
}
static void test_should_parse(const char *p) {
usec_t t;
+ log_info("Test: %s", p);
assert_se(parse_timestamp(p, &t) >= 0);
+ log_info("\"%s\" → \"@%" PRI_USEC "\"", p, t);
}
static void test_should_fail(const char *p) {
usec_t t;
+ int r;
- assert_se(parse_timestamp(p, &t) < 0);
+ log_info("Test: %s", p);
+ r = parse_timestamp(p, &t);
+ if (r >= 0)
+ log_info("\"%s\" → \"@%" PRI_USEC "\" (unexpected)", p, t);
+ else
+ log_info("parse_timestamp() returns %d (expected)", r);
+ assert_se(r < 0);
}
static void test_one(const char *p) {
_cleanup_free_ char *with_utc;
- log_info("Test: %s", p);
with_utc = strjoin(p, " UTC");
test_should_pass(p);
test_should_pass(with_utc);
@@ -68,7 +71,6 @@ static void test_one(const char *p) {
static void test_one_noutc(const char *p) {
_cleanup_free_ char *with_utc;
- log_info("Test: %s", p);
with_utc = strjoin(p, " UTC");
test_should_pass(p);
test_should_fail(with_utc);
@@ -85,25 +87,26 @@ int main(int argc, char *argv[]) {
test_one("2012-12-30 18:42");
test_one("2012-10-02");
test_one("Tue 2012-10-02");
- test_one_noutc("now");
test_one("yesterday");
test_one("today");
test_one("tomorrow");
+ test_one_noutc("now");
test_one_noutc("+2d");
test_one_noutc("+2y 4d");
test_one_noutc("5months ago");
test_one_noutc("@1395716396");
- test_should_parse("today UTC");
- test_should_fail("today UTC UTC");
test_should_parse("1970-1-1 UTC");
- test_should_fail("1969-1-1 UTC");
+ test_should_pass("1970-1-1 00:00:01 UTC");
+ test_should_fail("1969-12-31 UTC");
+ test_should_fail("-100y");
+ test_should_fail("today UTC UTC");
#if SIZEOF_TIME_T == 8
- test_should_parse("9999-12-30 23:59:59 UTC");
+ test_should_pass("9999-12-30 23:59:59 UTC");
test_should_fail("9999-12-31 00:00:00 UTC");
test_should_fail("10000-01-01 00:00:00 UTC");
#elif SIZEOF_TIME_T == 4
- test_should_parse("2038-01-19 03:14:07 UTC");
- test_should_fail( "2038-01-19 03:14:08 UTC");
+ test_should_pass("2038-01-19 03:14:07 UTC");
+ test_should_fail("2038-01-19 03:14:08 UTC");
#endif
return 0;
diff --git a/src/test/test-dlopen.c b/src/test/test-dlopen.c
new file mode 100644
index 0000000000..9f5343a7ea
--- /dev/null
+++ b/src/test/test-dlopen.c
@@ -0,0 +1,32 @@
+/***
+ This file is part of systemd.
+
+ 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/>.
+***/
+
+#include <dlfcn.h>
+#include <stdlib.h>
+
+#include "macro.h"
+
+int main(int argc, char **argv) {
+ void *handle;
+
+ assert_se((handle = dlopen(argv[1], RTLD_NOW)));
+ assert_se(dlclose(handle) == 0);
+
+ return EXIT_SUCCESS;
+}
diff --git a/src/test/test-dns-domain.c b/src/test/test-dns-domain.c
index a7cd8e4b51..11cf0b1f0b 100644
--- a/src/test/test-dns-domain.c
+++ b/src/test/test-dns-domain.c
@@ -607,24 +607,53 @@ static void test_dns_name_common_suffix(void) {
test_dns_name_common_suffix_one("FOO.BAR", "tEST.bAR", "BAR");
}
-static void test_dns_name_apply_idna_one(const char *s, const char *result) {
-#ifdef HAVE_LIBIDN
+static void test_dns_name_apply_idna_one(const char *s, int expected, const char *result) {
_cleanup_free_ char *buf = NULL;
- assert_se(dns_name_apply_idna(s, &buf) >= 0);
- assert_se(dns_name_equal(buf, result) > 0);
-#endif
+ int r;
+
+ r = dns_name_apply_idna(s, &buf);
+ log_debug("dns_name_apply_idna: \"%s\" → %d/\"%s\" (expected %d/\"%s\")",
+ s, r, strnull(buf), expected, strnull(result));
+
+ assert_se(r == expected);
+ if (expected == 1)
+ assert_se(dns_name_equal(buf, result) == 1);
}
static void test_dns_name_apply_idna(void) {
- test_dns_name_apply_idna_one("", "");
- test_dns_name_apply_idna_one("foo", "foo");
- test_dns_name_apply_idna_one("foo.", "foo");
- test_dns_name_apply_idna_one("foo.bar", "foo.bar");
- test_dns_name_apply_idna_one("foo.bar.", "foo.bar");
- test_dns_name_apply_idna_one("föö", "xn--f-1gaa");
- test_dns_name_apply_idna_one("föö.", "xn--f-1gaa");
- test_dns_name_apply_idna_one("föö.bär", "xn--f-1gaa.xn--br-via");
- test_dns_name_apply_idna_one("föö.bär.", "xn--f-1gaa.xn--br-via");
+#if defined HAVE_LIBIDN2 || defined HAVE_LIBIDN
+ const int ret = 1;
+#else
+ const int ret = 0;
+#endif
+
+ /* IDNA2008 forbids names with hyphens in third and fourth positions
+ * (https://tools.ietf.org/html/rfc5891#section-4.2.3.1).
+ * IDNA2003 does not have this restriction
+ * (https://tools.ietf.org/html/rfc3490#section-5).
+ * This means that when using libidn we will transform and test more
+ * labels. If registrars follow IDNA2008 we'll just be performing a
+ * useless lookup.
+ */
+#if defined HAVE_LIBIDN
+ const int ret2 = 1;
+#else
+ const int ret2 = 0;
+#endif
+
+ test_dns_name_apply_idna_one("", ret, "");
+ test_dns_name_apply_idna_one("foo", ret, "foo");
+ test_dns_name_apply_idna_one("foo.", ret, "foo");
+ test_dns_name_apply_idna_one("foo.bar", ret, "foo.bar");
+ test_dns_name_apply_idna_one("foo.bar.", ret, "foo.bar");
+ test_dns_name_apply_idna_one("föö", ret, "xn--f-1gaa");
+ test_dns_name_apply_idna_one("föö.", ret, "xn--f-1gaa");
+ test_dns_name_apply_idna_one("föö.bär", ret, "xn--f-1gaa.xn--br-via");
+ test_dns_name_apply_idna_one("föö.bär.", ret, "xn--f-1gaa.xn--br-via");
+ test_dns_name_apply_idna_one("xn--f-1gaa.xn--br-via", ret, "xn--f-1gaa.xn--br-via");
+
+ test_dns_name_apply_idna_one("r3---sn-ab5l6ne7.googlevideo.com", ret2,
+ ret2 ? "r3---sn-ab5l6ne7.googlevideo.com" : "");
}
static void test_dns_name_is_valid_or_address(void) {
@@ -640,6 +669,9 @@ static void test_dns_name_is_valid_or_address(void) {
}
int main(int argc, char *argv[]) {
+ log_set_max_level(LOG_DEBUG);
+ log_parse_environment();
+ log_open();
test_dns_label_unescape();
test_dns_label_unescape_suffix();
diff --git a/src/test/test-env-util.c b/src/test/test-env-util.c
index 904c50f0ed..3a2492dc6f 100644
--- a/src/test/test-env-util.c
+++ b/src/test/test-env-util.c
@@ -21,6 +21,8 @@
#include <string.h>
#include "env-util.h"
+#include "fd-util.h"
+#include "fileio.h"
#include "string-util.h"
#include "strv.h"
#include "util.h"
@@ -323,6 +325,48 @@ static void test_deserialize_environment(void) {
assert_se(strv_equal(env, STRV_MAKE("A=1", "B=2")));
}
+static void test_serialize_environment(void) {
+ char fn[] = "/tmp/test-env-util.XXXXXXX";
+ int fd, r;
+ _cleanup_fclose_ FILE *f = NULL;
+
+ _cleanup_strv_free_ char **env = strv_new("A=1",
+ "B=2",
+ "C=ąęółń",
+ "D=D=a\\x0Ab",
+ NULL);
+ _cleanup_strv_free_ char **env2 = NULL;
+
+ fd = mkostemp_safe(fn);
+ assert_se(fd >= 0);
+
+ assert_se(f = fdopen(fd, "r+"));
+
+ assert_se(serialize_environment(f, env) == 0);
+ assert_se(fflush_and_check(f) == 0);
+
+ rewind(f);
+
+ for (;;) {
+ char line[LINE_MAX];
+ const char *l;
+
+ if (!fgets(line, sizeof line, f))
+ break;
+
+ char_array_0(line);
+ l = strstrip(line);
+
+ r = deserialize_environment(&env2, l);
+ assert_se(r == 1);
+ }
+ assert_se(feof(f));
+
+ assert_se(strv_equal(env, env2));
+
+ unlink(fn);
+}
+
int main(int argc, char *argv[]) {
test_strv_env_delete();
test_strv_env_get();
@@ -340,6 +384,7 @@ int main(int argc, char *argv[]) {
test_env_value_is_valid();
test_env_assignment_is_valid();
test_deserialize_environment();
+ test_serialize_environment();
return 0;
}
diff --git a/src/test/test-escape.c b/src/test/test-escape.c
index 6cbb8443fe..d060afaffa 100644
--- a/src/test/test-escape.c
+++ b/src/test/test-escape.c
@@ -69,6 +69,14 @@ static void test_cunescape(void) {
assert_se(cunescape("\\073", 0, &unescaped) >= 0);
assert_se(streq_ptr(unescaped, ";"));
+ unescaped = mfree(unescaped);
+
+ assert_se(cunescape("A=A\\\\x0aB", 0, &unescaped) >= 0);
+ assert_se(streq_ptr(unescaped, "A=A\\x0aB"));
+ unescaped = mfree(unescaped);
+
+ assert_se(cunescape("A=A\\\\x0aB", UNESCAPE_RELAX, &unescaped) >= 0);
+ assert_se(streq_ptr(unescaped, "A=A\\x0aB"));
}
static void test_shell_escape_one(const char *s, const char *bad, const char *expected) {
@@ -86,25 +94,52 @@ static void test_shell_escape(void) {
test_shell_escape_one("foo:bar,baz", ",:", "foo\\:bar\\,baz");
}
-static void test_shell_maybe_quote_one(const char *s, const char *expected) {
- _cleanup_free_ char *r;
+static void test_shell_maybe_quote_one(const char *s,
+ EscapeStyle style,
+ const char *expected) {
+ _cleanup_free_ char *ret = NULL;
- assert_se(r = shell_maybe_quote(s));
- assert_se(streq(r, expected));
+ assert_se(ret = shell_maybe_quote(s, style));
+ log_debug("[%s] → [%s] (%s)", s, ret, expected);
+ assert_se(streq(ret, expected));
}
static void test_shell_maybe_quote(void) {
- test_shell_maybe_quote_one("", "");
- test_shell_maybe_quote_one("\\", "\"\\\\\"");
- test_shell_maybe_quote_one("\"", "\"\\\"\"");
- test_shell_maybe_quote_one("foobar", "foobar");
- test_shell_maybe_quote_one("foo bar", "\"foo bar\"");
- test_shell_maybe_quote_one("foo \"bar\" waldo", "\"foo \\\"bar\\\" waldo\"");
- test_shell_maybe_quote_one("foo$bar", "\"foo\\$bar\"");
+ test_shell_maybe_quote_one("", ESCAPE_BACKSLASH, "");
+ test_shell_maybe_quote_one("", ESCAPE_POSIX, "");
+ test_shell_maybe_quote_one("\\", ESCAPE_BACKSLASH, "\"\\\\\"");
+ test_shell_maybe_quote_one("\\", ESCAPE_POSIX, "$'\\\\'");
+ test_shell_maybe_quote_one("\"", ESCAPE_BACKSLASH, "\"\\\"\"");
+ test_shell_maybe_quote_one("\"", ESCAPE_POSIX, "$'\"'");
+ test_shell_maybe_quote_one("foobar", ESCAPE_BACKSLASH, "foobar");
+ test_shell_maybe_quote_one("foobar", ESCAPE_POSIX, "foobar");
+ test_shell_maybe_quote_one("foo bar", ESCAPE_BACKSLASH, "\"foo bar\"");
+ test_shell_maybe_quote_one("foo bar", ESCAPE_POSIX, "$'foo bar'");
+ test_shell_maybe_quote_one("foo\tbar", ESCAPE_BACKSLASH, "\"foo\tbar\"");
+ test_shell_maybe_quote_one("foo\tbar", ESCAPE_POSIX, "$'foo\\tbar'");
+ test_shell_maybe_quote_one("foo\nbar", ESCAPE_BACKSLASH, "\"foo\nbar\"");
+ test_shell_maybe_quote_one("foo\nbar", ESCAPE_POSIX, "$'foo\\nbar'");
+ test_shell_maybe_quote_one("foo \"bar\" waldo", ESCAPE_BACKSLASH, "\"foo \\\"bar\\\" waldo\"");
+ test_shell_maybe_quote_one("foo \"bar\" waldo", ESCAPE_POSIX, "$'foo \"bar\" waldo'");
+ test_shell_maybe_quote_one("foo$bar", ESCAPE_BACKSLASH, "\"foo\\$bar\"");
+ test_shell_maybe_quote_one("foo$bar", ESCAPE_POSIX, "$'foo$bar'");
+
+ /* Note that current users disallow control characters, so this "test"
+ * is here merely to establish current behaviour. If control characters
+ * were allowed, they should be quoted, i.e. \001 should become \\001. */
+ test_shell_maybe_quote_one("a\nb\001", ESCAPE_BACKSLASH, "\"a\nb\001\"");
+ test_shell_maybe_quote_one("a\nb\001", ESCAPE_POSIX, "$'a\\nb\001'");
+
+ test_shell_maybe_quote_one("foo!bar", ESCAPE_BACKSLASH, "\"foo!bar\"");
+ test_shell_maybe_quote_one("foo!bar", ESCAPE_POSIX, "$'foo!bar'");
}
int main(int argc, char *argv[]) {
+ log_set_max_level(LOG_DEBUG);
+ log_parse_environment();
+ log_open();
+
test_cescape();
test_cunescape();
test_shell_escape();
diff --git a/src/test/test-exec-util.c b/src/test/test-exec-util.c
index 482b0751b9..30c92019d9 100644
--- a/src/test/test-exec-util.c
+++ b/src/test/test-exec-util.c
@@ -223,7 +223,7 @@ static int gather_stdout_three(int fd, void *arg) {
return 0;
}
-const gather_stdout_callback_t const gather_stdout[] = {
+const gather_stdout_callback_t gather_stdout[] = {
gather_stdout_one,
gather_stdout_two,
gather_stdout_three,
diff --git a/src/test/test-execute.c b/src/test/test-execute.c
index 90540b884b..29c8fd613f 100644
--- a/src/test/test-execute.c
+++ b/src/test/test-execute.c
@@ -233,6 +233,15 @@ static void test_exec_inaccessiblepaths(Manager *m) {
test(m, "exec-inaccessiblepaths-mount-propagation.service", 0, CLD_EXITED);
}
+static void test_exec_inaccessiblepaths_proc(Manager *m) {
+ if (!is_inaccessible_available()) {
+ log_notice("testing without inaccessible, skipping %s", __func__);
+ return;
+ }
+
+ test(m, "exec-inaccessiblepaths-proc.service", 0, CLD_EXITED);
+}
+
static void test_exec_systemcallfilter(Manager *m) {
#ifdef HAVE_SECCOMP
if (!is_seccomp_available())
@@ -479,6 +488,7 @@ int main(int argc, char *argv[]) {
test_exec_readonlypaths,
test_exec_readwritepaths,
test_exec_inaccessiblepaths,
+ test_exec_inaccessiblepaths_proc,
test_exec_privatenetwork,
test_exec_systemcallfilter,
test_exec_systemcallerrornumber,
diff --git a/src/test/test-fs-util.c b/src/test/test-fs-util.c
index e774f567e0..9e964a8bbb 100644
--- a/src/test/test-fs-util.c
+++ b/src/test/test-fs-util.c
@@ -317,8 +317,8 @@ static void test_dot_or_dot_dot(void) {
int main(int argc, char *argv[]) {
test_unlink_noerrno();
- test_readlink_and_make_absolute();
test_get_files_in_directory();
+ test_readlink_and_make_absolute();
test_var_tmp();
test_chase_symlinks();
test_dot_or_dot_dot();
diff --git a/src/test/test-glob-util.c b/src/test/test-glob-util.c
index 9eea3eb608..af866e004b 100644
--- a/src/test/test-glob-util.c
+++ b/src/test/test-glob-util.c
@@ -18,12 +18,17 @@
***/
#include <fcntl.h>
+#include <glob.h>
+#include <sys/stat.h>
#include <unistd.h>
#include "alloc-util.h"
+#include "dirent-util.h"
#include "fileio.h"
+#include "fs-util.h"
#include "glob-util.h"
#include "macro.h"
+#include "rm-rf.h"
static void test_glob_exists(void) {
char name[] = "/tmp/test-glob_exists.XXXXXX";
@@ -43,8 +48,69 @@ static void test_glob_exists(void) {
assert_se(r == 0);
}
+static void test_glob_no_dot(void) {
+ char template[] = "/tmp/test-glob-util.XXXXXXX";
+ const char *fn;
+
+ _cleanup_globfree_ glob_t g = {
+ .gl_closedir = (void (*)(void *)) closedir,
+ .gl_readdir = (struct dirent *(*)(void *)) readdir_no_dot,
+ .gl_opendir = (void *(*)(const char *)) opendir,
+ .gl_lstat = lstat,
+ .gl_stat = stat,
+ };
+
+ int r;
+
+ assert_se(mkdtemp(template));
+
+ fn = strjoina(template, "/*");
+ r = glob(fn, GLOB_NOSORT|GLOB_BRACE|GLOB_ALTDIRFUNC, NULL, &g);
+ assert_se(r == GLOB_NOMATCH);
+
+ fn = strjoina(template, "/.*");
+ r = glob(fn, GLOB_NOSORT|GLOB_BRACE|GLOB_ALTDIRFUNC, NULL, &g);
+ assert_se(r == GLOB_NOMATCH);
+
+ (void) rm_rf(template, REMOVE_ROOT|REMOVE_PHYSICAL);
+}
+
+static void test_safe_glob(void) {
+ char template[] = "/tmp/test-glob-util.XXXXXXX";
+ const char *fn, *fn2, *fname;
+
+ _cleanup_globfree_ glob_t g = {};
+ int r;
+
+ assert_se(mkdtemp(template));
+
+ fn = strjoina(template, "/*");
+ r = safe_glob(fn, 0, &g);
+ assert_se(r == -ENOENT);
+
+ fn2 = strjoina(template, "/.*");
+ r = safe_glob(fn2, GLOB_NOSORT|GLOB_BRACE, &g);
+ assert_se(r == -ENOENT);
+
+ fname = strjoina(template, "/.foobar");
+ assert_se(touch(fname) == 0);
+
+ r = safe_glob(fn, 0, &g);
+ assert_se(r == -ENOENT);
+
+ r = safe_glob(fn2, GLOB_NOSORT|GLOB_BRACE, &g);
+ assert_se(r == 0);
+ assert_se(g.gl_pathc == 1);
+ assert_se(streq(g.gl_pathv[0], fname));
+ assert_se(g.gl_pathv[1] == NULL);
+
+ (void) rm_rf(template, REMOVE_ROOT|REMOVE_PHYSICAL);
+}
+
int main(void) {
test_glob_exists();
+ test_glob_no_dot();
+ test_safe_glob();
return 0;
}
diff --git a/src/test/test-hash.c b/src/test/test-hash.c
index 1972b94cfe..02d1cfaee3 100644
--- a/src/test/test-hash.c
+++ b/src/test/test-hash.c
@@ -17,6 +17,8 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include <stdio.h>
+
#include "alloc-util.h"
#include "log.h"
#include "string-util.h"
@@ -25,12 +27,18 @@
int main(int argc, char *argv[]) {
_cleanup_(khash_unrefp) khash *h = NULL, *copy = NULL;
_cleanup_free_ char *s = NULL;
+ int r;
log_set_max_level(LOG_DEBUG);
assert_se(khash_new(&h, NULL) == -EINVAL);
assert_se(khash_new(&h, "") == -EINVAL);
- assert_se(khash_new(&h, "foobar") == -EOPNOTSUPP);
+ r = khash_new(&h, "foobar");
+ if (r == -EAFNOSUPPORT) {
+ puts("khash not supported on this kernel, skipping");
+ return EXIT_TEST_SKIP;
+ }
+ assert_se(r == -EOPNOTSUPP);
assert_se(khash_new(&h, "sha256") >= 0);
assert_se(khash_get_size(h) == 32);
diff --git a/src/test/test-hashmap-ordered.awk b/src/test/test-hashmap-ordered.awk
new file mode 100644
index 0000000000..10f4386fa4
--- /dev/null
+++ b/src/test/test-hashmap-ordered.awk
@@ -0,0 +1,11 @@
+BEGIN {
+ print "/* GENERATED FILE */";
+ print "#define ORDERED"
+}
+{
+ if (!match($0, "^#include"))
+ gsub(/hashmap/, "ordered_hashmap");
+ gsub(/HASHMAP/, "ORDERED_HASHMAP");
+ gsub(/Hashmap/, "OrderedHashmap");
+ print
+}
diff --git a/src/test/test-id128.c b/src/test/test-id128.c
index ab5a111ba9..e5f45206f1 100644
--- a/src/test/test-id128.c
+++ b/src/test/test-id128.c
@@ -39,6 +39,7 @@ int main(int argc, char *argv[]) {
char t[33], q[37];
_cleanup_free_ char *b = NULL;
_cleanup_close_ int fd = -1;
+ int r;
assert_se(sd_id128_randomize(&id) == 0);
printf("random: %s\n", sd_id128_to_string(id, t));
@@ -153,11 +154,23 @@ int main(int argc, char *argv[]) {
assert_se(id128_read_fd(fd, ID128_UUID, &id2) >= 0);
assert_se(sd_id128_equal(id, id2));
- assert_se(sd_id128_get_machine_app_specific(SD_ID128_MAKE(f0,3d,aa,eb,1c,33,4b,43,a7,32,17,29,44,bf,77,2e), &id) >= 0);
- assert_se(sd_id128_get_machine_app_specific(SD_ID128_MAKE(f0,3d,aa,eb,1c,33,4b,43,a7,32,17,29,44,bf,77,2e), &id2) >= 0);
- assert_se(sd_id128_equal(id, id2));
- assert_se(sd_id128_get_machine_app_specific(SD_ID128_MAKE(51,df,0b,4b,c3,b0,4c,97,80,e2,99,b9,8c,a3,73,b8), &id2) >= 0);
- assert_se(!sd_id128_equal(id, id2));
+ r = sd_id128_get_machine_app_specific(SD_ID128_MAKE(f0,3d,aa,eb,1c,33,4b,43,a7,32,17,29,44,bf,77,2e), &id);
+ if (r == -EAFNOSUPPORT) {
+ log_info("khash not supported on this kernel, skipping sd_id128_get_machine_app_specific() checks");
+ } else {
+ assert_se(r >= 0);
+ assert_se(sd_id128_get_machine_app_specific(SD_ID128_MAKE(f0,3d,aa,eb,1c,33,4b,43,a7,32,17,29,44,bf,77,2e), &id2) >= 0);
+ assert_se(sd_id128_equal(id, id2));
+ assert_se(sd_id128_get_machine_app_specific(SD_ID128_MAKE(51,df,0b,4b,c3,b0,4c,97,80,e2,99,b9,8c,a3,73,b8), &id2) >= 0);
+ assert_se(!sd_id128_equal(id, id2));
+ }
+
+ /* Query the invocation ID */
+ r = sd_id128_get_invocation(&id);
+ if (r < 0)
+ log_warning_errno(r, "Failed to get invocation ID, ignoring: %m");
+ else
+ log_info("Invocation ID: " SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(id));
return 0;
}
diff --git a/src/test/test-libudev.c b/src/test/test-libudev.c
index e28de9b37b..0f71c18b65 100644
--- a/src/test/test-libudev.c
+++ b/src/test/test-libudev.c
@@ -392,7 +392,7 @@ int main(int argc, char *argv[]) {
return EXIT_SUCCESS;
case 'V':
- printf("%s\n", VERSION);
+ printf("%s\n", PACKAGE_VERSION);
return EXIT_SUCCESS;
case 'm':
diff --git a/src/test/test-log.c b/src/test/test-log.c
index ae9e113efb..8ab569f477 100644
--- a/src/test/test-log.c
+++ b/src/test/test-log.c
@@ -24,13 +24,22 @@
#include "log.h"
#include "util.h"
+assert_cc(LOG_REALM_REMOVE_LEVEL(LOG_REALM_PLUS_LEVEL(LOG_REALM_SYSTEMD, LOG_FTP | LOG_DEBUG))
+ == LOG_REALM_SYSTEMD);
+assert_cc(LOG_REALM_REMOVE_LEVEL(LOG_REALM_PLUS_LEVEL(LOG_REALM_UDEV, LOG_LOCAL7 | LOG_DEBUG))
+ == LOG_REALM_UDEV);
+assert_cc((LOG_REALM_PLUS_LEVEL(LOG_REALM_SYSTEMD, LOG_LOCAL3 | LOG_DEBUG) & LOG_FACMASK)
+ == LOG_LOCAL3);
+assert_cc((LOG_REALM_PLUS_LEVEL(LOG_REALM_UDEV, LOG_USER | LOG_INFO) & LOG_PRIMASK)
+ == LOG_INFO);
+
int main(int argc, char* argv[]) {
log_set_target(LOG_TARGET_CONSOLE);
log_open();
log_struct(LOG_INFO,
- "MESSAGE=Waldo PID="PID_FMT, getpid(),
+ "MESSAGE=Waldo PID="PID_FMT, getpid_cached(),
"SERVICE=piepapo",
NULL);
@@ -38,12 +47,12 @@ int main(int argc, char* argv[]) {
log_open();
log_struct(LOG_INFO,
- "MESSAGE=Foobar PID="PID_FMT, getpid(),
+ "MESSAGE=Foobar PID="PID_FMT, getpid_cached(),
"SERVICE=foobar",
NULL);
log_struct(LOG_INFO,
- "MESSAGE=Foobar PID="PID_FMT, getpid(),
+ "MESSAGE=Foobar PID="PID_FMT, getpid_cached(),
"FORMAT_STR_TEST=1=%i A=%c 2=%hi 3=%li 4=%lli 1=%p foo=%s 2.5=%g 3.5=%g 4.5=%Lg",
(int) 1, 'A', (short) 2, (long int) 3, (long long int) 4, (void*) 1, "foo", (float) 2.5f, (double) 3.5, (long double) 4.5,
"SUFFIX=GOT IT",
diff --git a/src/test/test-loopback.c b/src/test/test-loopback.c
index 8ebd0e0e01..c70633a0f3 100644
--- a/src/test/test-loopback.c
+++ b/src/test/test-loopback.c
@@ -27,6 +27,7 @@ int main(int argc, char* argv[]) {
int r;
log_open();
+ log_set_max_level(LOG_DEBUG);
log_parse_environment();
r = loopback_setup();
diff --git a/src/test/test-nss.c b/src/test/test-nss.c
index b59cb7aa69..57eeb8e40c 100644
--- a/src/test/test-nss.c
+++ b/src/test/test-nss.c
@@ -71,9 +71,11 @@ static void* open_handle(const char* dir, const char* module, int flags) {
const char *path;
void *handle;
- if (dir)
- path = strjoina(dir, "/.libs/libnss_", module, ".so.2");
- else
+ if (dir) {
+ path = strjoina(dir, "/libnss_", module, ".so.2");
+ if (access(path, F_OK) < 0)
+ path = strjoina(dir, "/.libs/libnss_", module, ".so.2");
+ } else
path = strjoina("libnss_", module, ".so.2");
handle = dlopen(path, flags);
@@ -103,7 +105,7 @@ static int print_gaih_addrtuples(const struct gaih_addrtuple *tuples) {
goto numerical_index;
if (if_indextoname(it->scopeid, ifname) == NULL) {
- log_warning("if_indextoname(%d) failed: %m", it->scopeid);
+ log_warning_errno(errno, "if_indextoname(%d) failed: %m", it->scopeid);
numerical_index:
xsprintf(ifname, "%i", it->scopeid);
};
diff --git a/src/test/test-parse-util.c b/src/test/test-parse-util.c
index d08014100b..1b29b2ea87 100644
--- a/src/test/test-parse-util.c
+++ b/src/test/test-parse-util.c
@@ -395,6 +395,9 @@ static void test_safe_atou16(void) {
r = safe_atou16("junk", &l);
assert_se(r == -EINVAL);
+
+ r = safe_atou16("123x", &l);
+ assert_se(r == -EINVAL);
}
static void test_safe_atoi16(void) {
@@ -425,6 +428,70 @@ static void test_safe_atoi16(void) {
r = safe_atoi16("junk", &l);
assert_se(r == -EINVAL);
+
+ r = safe_atoi16("123x", &l);
+ assert_se(r == -EINVAL);
+}
+
+static void test_safe_atou64(void) {
+ int r;
+ uint64_t l;
+
+ r = safe_atou64("12345", &l);
+ assert_se(r == 0);
+ assert_se(l == 12345);
+
+ r = safe_atou64(" 12345", &l);
+ assert_se(r == 0);
+ assert_se(l == 12345);
+
+ r = safe_atou64("18446744073709551617", &l);
+ assert_se(r == -ERANGE);
+
+ r = safe_atou64("-1", &l);
+ assert_se(r == -ERANGE);
+
+ r = safe_atou64(" -1", &l);
+ assert_se(r == -ERANGE);
+
+ r = safe_atou64("junk", &l);
+ assert_se(r == -EINVAL);
+
+ r = safe_atou64("123x", &l);
+ assert_se(r == -EINVAL);
+}
+
+static void test_safe_atoi64(void) {
+ int r;
+ int64_t l;
+
+ r = safe_atoi64("-12345", &l);
+ assert_se(r == 0);
+ assert_se(l == -12345);
+
+ r = safe_atoi64(" -12345", &l);
+ assert_se(r == 0);
+ assert_se(l == -12345);
+
+ r = safe_atoi64("32767", &l);
+ assert_se(r == 0);
+ assert_se(l == 32767);
+
+ r = safe_atoi64(" 32767", &l);
+ assert_se(r == 0);
+ assert_se(l == 32767);
+
+ r = safe_atoi64("9223372036854775813", &l);
+ assert_se(r == -ERANGE);
+
+ r = safe_atoi64("-9223372036854775813", &l);
+ assert_se(r == -ERANGE);
+
+ r = safe_atoi64("junk", &l);
+ assert_se(r == -EINVAL);
+
+ r = safe_atoi64("123x", &l);
+ assert_se(r == -EINVAL);
}
static void test_safe_atod(void) {
@@ -526,6 +593,19 @@ static void test_parse_nice(void) {
assert_se(parse_nice("+20", &n) == -ERANGE);
}
+static void test_parse_dev(void) {
+ dev_t dev;
+
+ assert_se(parse_dev("0", &dev) == -EINVAL);
+ assert_se(parse_dev("5", &dev) == -EINVAL);
+ assert_se(parse_dev("5:", &dev) == -EINVAL);
+ assert_se(parse_dev(":5", &dev) == -EINVAL);
+#if SIZEOF_DEV_T < 8
+ assert_se(parse_dev("4294967295:4294967295", &dev) == -EINVAL);
+#endif
+ assert_se(parse_dev("8:11", &dev) >= 0 && major(dev) == 8 && minor(dev) == 11);
+}
+
int main(int argc, char *argv[]) {
log_parse_environment();
log_open();
@@ -538,10 +618,13 @@ int main(int argc, char *argv[]) {
test_safe_atolli();
test_safe_atou16();
test_safe_atoi16();
+ test_safe_atou64();
+ test_safe_atoi64();
test_safe_atod();
test_parse_percent();
test_parse_percent_unbounded();
test_parse_nice();
+ test_parse_dev();
return 0;
}
diff --git a/src/test/test-path-util.c b/src/test/test-path-util.c
index 22df20a1eb..e5644246c2 100644
--- a/src/test/test-path-util.c
+++ b/src/test/test-path-util.c
@@ -27,6 +27,7 @@
#include "mount-util.h"
#include "path-util.h"
#include "rm-rf.h"
+#include "stat-util.h"
#include "string-util.h"
#include "strv.h"
#include "util.h"
@@ -104,6 +105,48 @@ static void test_path(void) {
assert_se(!path_equal_ptr(NULL, "/a"));
}
+static void test_path_equal_root(void) {
+ /* Nail down the details of how path_equal("/", ...) works. */
+
+ assert_se(path_equal("/", "/"));
+ assert_se(path_equal("/", "//"));
+
+ assert_se(!path_equal("/", "/./"));
+ assert_se(!path_equal("/", "/../"));
+
+ assert_se(!path_equal("/", "/.../"));
+
+ /* Make sure that files_same works as expected. */
+
+ assert_se(files_same("/", "/", 0) > 0);
+ assert_se(files_same("/", "/", AT_SYMLINK_NOFOLLOW) > 0);
+ assert_se(files_same("/", "//", 0) > 0);
+ assert_se(files_same("/", "//", AT_SYMLINK_NOFOLLOW) > 0);
+
+ assert_se(files_same("/", "/./", 0) > 0);
+ assert_se(files_same("/", "/./", AT_SYMLINK_NOFOLLOW) > 0);
+ assert_se(files_same("/", "/../", 0) > 0);
+ assert_se(files_same("/", "/../", AT_SYMLINK_NOFOLLOW) > 0);
+
+ assert_se(files_same("/", "/.../", 0) == -ENOENT);
+ assert_se(files_same("/", "/.../", AT_SYMLINK_NOFOLLOW) == -ENOENT);
+
+ /* The same for path_equal_or_files_same. */
+
+ assert_se(path_equal_or_files_same("/", "/", 0));
+ assert_se(path_equal_or_files_same("/", "/", AT_SYMLINK_NOFOLLOW));
+ assert_se(path_equal_or_files_same("/", "//", 0));
+ assert_se(path_equal_or_files_same("/", "//", AT_SYMLINK_NOFOLLOW));
+
+ assert_se(path_equal_or_files_same("/", "/./", 0));
+ assert_se(path_equal_or_files_same("/", "/./", AT_SYMLINK_NOFOLLOW));
+ assert_se(path_equal_or_files_same("/", "/../", 0));
+ assert_se(path_equal_or_files_same("/", "/../", AT_SYMLINK_NOFOLLOW));
+
+ assert_se(!path_equal_or_files_same("/", "/.../", 0));
+ assert_se(!path_equal_or_files_same("/", "/.../", AT_SYMLINK_NOFOLLOW));
+}
+
static void test_find_binary(const char *self) {
char *p;
@@ -551,6 +594,7 @@ int main(int argc, char **argv) {
log_open();
test_path();
+ test_path_equal_root();
test_find_binary(argv[0]);
test_prefixes();
test_path_join();
diff --git a/src/test/test-process-util.c b/src/test/test-process-util.c
index c5edbcc5d2..046a96fdc8 100644
--- a/src/test/test-process-util.c
+++ b/src/test/test-process-util.c
@@ -115,7 +115,7 @@ static void test_pid_is_unwaited(void) {
waitpid(pid, &status, 0);
assert_se(!pid_is_unwaited(pid));
}
- assert_se(pid_is_unwaited(getpid()));
+ assert_se(pid_is_unwaited(getpid_cached()));
assert_se(!pid_is_unwaited(-1));
}
@@ -132,7 +132,7 @@ static void test_pid_is_alive(void) {
waitpid(pid, &status, 0);
assert_se(!pid_is_alive(pid));
}
- assert_se(pid_is_alive(getpid()));
+ assert_se(pid_is_alive(getpid_cached()));
assert_se(!pid_is_alive(-1));
}
@@ -205,149 +205,149 @@ static void test_get_process_cmdline_harder(void) {
assert_se(prctl(PR_SET_NAME, "testa") >= 0);
- assert_se(get_process_cmdline(getpid(), 0, false, &line) == -ENOENT);
+ assert_se(get_process_cmdline(getpid_cached(), 0, false, &line) == -ENOENT);
- assert_se(get_process_cmdline(getpid(), 0, true, &line) >= 0);
+ assert_se(get_process_cmdline(getpid_cached(), 0, true, &line) >= 0);
assert_se(streq(line, "[testa]"));
line = mfree(line);
- assert_se(get_process_cmdline(getpid(), 1, true, &line) >= 0);
+ assert_se(get_process_cmdline(getpid_cached(), 1, true, &line) >= 0);
assert_se(streq(line, ""));
line = mfree(line);
- assert_se(get_process_cmdline(getpid(), 2, true, &line) >= 0);
+ assert_se(get_process_cmdline(getpid_cached(), 2, true, &line) >= 0);
assert_se(streq(line, "["));
line = mfree(line);
- assert_se(get_process_cmdline(getpid(), 3, true, &line) >= 0);
+ assert_se(get_process_cmdline(getpid_cached(), 3, true, &line) >= 0);
assert_se(streq(line, "[."));
line = mfree(line);
- assert_se(get_process_cmdline(getpid(), 4, true, &line) >= 0);
+ assert_se(get_process_cmdline(getpid_cached(), 4, true, &line) >= 0);
assert_se(streq(line, "[.."));
line = mfree(line);
- assert_se(get_process_cmdline(getpid(), 5, true, &line) >= 0);
+ assert_se(get_process_cmdline(getpid_cached(), 5, true, &line) >= 0);
assert_se(streq(line, "[..."));
line = mfree(line);
- assert_se(get_process_cmdline(getpid(), 6, true, &line) >= 0);
+ assert_se(get_process_cmdline(getpid_cached(), 6, true, &line) >= 0);
assert_se(streq(line, "[...]"));
line = mfree(line);
- assert_se(get_process_cmdline(getpid(), 7, true, &line) >= 0);
+ assert_se(get_process_cmdline(getpid_cached(), 7, true, &line) >= 0);
assert_se(streq(line, "[t...]"));
line = mfree(line);
- assert_se(get_process_cmdline(getpid(), 8, true, &line) >= 0);
+ assert_se(get_process_cmdline(getpid_cached(), 8, true, &line) >= 0);
assert_se(streq(line, "[testa]"));
line = mfree(line);
assert_se(write(fd, "\0\0\0\0\0\0\0\0\0", 10) == 10);
- assert_se(get_process_cmdline(getpid(), 0, false, &line) == -ENOENT);
+ assert_se(get_process_cmdline(getpid_cached(), 0, false, &line) == -ENOENT);
- assert_se(get_process_cmdline(getpid(), 0, true, &line) >= 0);
+ assert_se(get_process_cmdline(getpid_cached(), 0, true, &line) >= 0);
assert_se(streq(line, "[testa]"));
line = mfree(line);
assert_se(write(fd, "foo\0bar\0\0\0\0\0", 10) == 10);
- assert_se(get_process_cmdline(getpid(), 0, false, &line) >= 0);
+ assert_se(get_process_cmdline(getpid_cached(), 0, false, &line) >= 0);
assert_se(streq(line, "foo bar"));
line = mfree(line);
- assert_se(get_process_cmdline(getpid(), 0, true, &line) >= 0);
+ assert_se(get_process_cmdline(getpid_cached(), 0, true, &line) >= 0);
assert_se(streq(line, "foo bar"));
line = mfree(line);
assert_se(write(fd, "quux", 4) == 4);
- assert_se(get_process_cmdline(getpid(), 0, false, &line) >= 0);
+ assert_se(get_process_cmdline(getpid_cached(), 0, false, &line) >= 0);
assert_se(streq(line, "foo bar quux"));
line = mfree(line);
- assert_se(get_process_cmdline(getpid(), 0, true, &line) >= 0);
+ assert_se(get_process_cmdline(getpid_cached(), 0, true, &line) >= 0);
assert_se(streq(line, "foo bar quux"));
line = mfree(line);
- assert_se(get_process_cmdline(getpid(), 1, true, &line) >= 0);
+ assert_se(get_process_cmdline(getpid_cached(), 1, true, &line) >= 0);
assert_se(streq(line, ""));
line = mfree(line);
- assert_se(get_process_cmdline(getpid(), 2, true, &line) >= 0);
+ assert_se(get_process_cmdline(getpid_cached(), 2, true, &line) >= 0);
assert_se(streq(line, "."));
line = mfree(line);
- assert_se(get_process_cmdline(getpid(), 3, true, &line) >= 0);
+ assert_se(get_process_cmdline(getpid_cached(), 3, true, &line) >= 0);
assert_se(streq(line, ".."));
line = mfree(line);
- assert_se(get_process_cmdline(getpid(), 4, true, &line) >= 0);
+ assert_se(get_process_cmdline(getpid_cached(), 4, true, &line) >= 0);
assert_se(streq(line, "..."));
line = mfree(line);
- assert_se(get_process_cmdline(getpid(), 5, true, &line) >= 0);
+ assert_se(get_process_cmdline(getpid_cached(), 5, true, &line) >= 0);
assert_se(streq(line, "f..."));
line = mfree(line);
- assert_se(get_process_cmdline(getpid(), 6, true, &line) >= 0);
+ assert_se(get_process_cmdline(getpid_cached(), 6, true, &line) >= 0);
assert_se(streq(line, "fo..."));
line = mfree(line);
- assert_se(get_process_cmdline(getpid(), 7, true, &line) >= 0);
+ assert_se(get_process_cmdline(getpid_cached(), 7, true, &line) >= 0);
assert_se(streq(line, "foo..."));
line = mfree(line);
- assert_se(get_process_cmdline(getpid(), 8, true, &line) >= 0);
+ assert_se(get_process_cmdline(getpid_cached(), 8, true, &line) >= 0);
assert_se(streq(line, "foo..."));
line = mfree(line);
- assert_se(get_process_cmdline(getpid(), 9, true, &line) >= 0);
+ assert_se(get_process_cmdline(getpid_cached(), 9, true, &line) >= 0);
assert_se(streq(line, "foo b..."));
line = mfree(line);
- assert_se(get_process_cmdline(getpid(), 10, true, &line) >= 0);
+ assert_se(get_process_cmdline(getpid_cached(), 10, true, &line) >= 0);
assert_se(streq(line, "foo ba..."));
line = mfree(line);
- assert_se(get_process_cmdline(getpid(), 11, true, &line) >= 0);
+ assert_se(get_process_cmdline(getpid_cached(), 11, true, &line) >= 0);
assert_se(streq(line, "foo bar..."));
line = mfree(line);
- assert_se(get_process_cmdline(getpid(), 12, true, &line) >= 0);
+ assert_se(get_process_cmdline(getpid_cached(), 12, true, &line) >= 0);
assert_se(streq(line, "foo bar..."));
line = mfree(line);
- assert_se(get_process_cmdline(getpid(), 13, true, &line) >= 0);
+ assert_se(get_process_cmdline(getpid_cached(), 13, true, &line) >= 0);
assert_se(streq(line, "foo bar quux"));
line = mfree(line);
- assert_se(get_process_cmdline(getpid(), 14, true, &line) >= 0);
+ assert_se(get_process_cmdline(getpid_cached(), 14, true, &line) >= 0);
assert_se(streq(line, "foo bar quux"));
line = mfree(line);
- assert_se(get_process_cmdline(getpid(), 1000, true, &line) >= 0);
+ assert_se(get_process_cmdline(getpid_cached(), 1000, true, &line) >= 0);
assert_se(streq(line, "foo bar quux"));
line = mfree(line);
assert_se(ftruncate(fd, 0) >= 0);
assert_se(prctl(PR_SET_NAME, "aaaa bbbb cccc") >= 0);
- assert_se(get_process_cmdline(getpid(), 0, false, &line) == -ENOENT);
+ assert_se(get_process_cmdline(getpid_cached(), 0, false, &line) == -ENOENT);
- assert_se(get_process_cmdline(getpid(), 0, true, &line) >= 0);
+ assert_se(get_process_cmdline(getpid_cached(), 0, true, &line) >= 0);
assert_se(streq(line, "[aaaa bbbb cccc]"));
line = mfree(line);
- assert_se(get_process_cmdline(getpid(), 10, true, &line) >= 0);
+ assert_se(get_process_cmdline(getpid_cached(), 10, true, &line) >= 0);
assert_se(streq(line, "[aaaa...]"));
line = mfree(line);
- assert_se(get_process_cmdline(getpid(), 11, true, &line) >= 0);
+ assert_se(get_process_cmdline(getpid_cached(), 11, true, &line) >= 0);
assert_se(streq(line, "[aaaa...]"));
line = mfree(line);
- assert_se(get_process_cmdline(getpid(), 12, true, &line) >= 0);
+ assert_se(get_process_cmdline(getpid_cached(), 12, true, &line) >= 0);
assert_se(streq(line, "[aaaa b...]"));
line = mfree(line);
@@ -410,6 +410,61 @@ static void test_rename_process(void) {
test_rename_process_one("1234567", 1); /* should always fit */
}
+static void test_getpid_cached(void) {
+ siginfo_t si;
+ pid_t a, b, c, d, e, f, child;
+
+ a = raw_getpid();
+ b = getpid_cached();
+ c = getpid();
+
+ assert_se(a == b && a == c);
+
+ child = fork();
+ assert_se(child >= 0);
+
+ if (child == 0) {
+ /* In child */
+ a = raw_getpid();
+ b = getpid_cached();
+ c = getpid();
+
+ assert_se(a == b && a == c);
+ _exit(0);
+ }
+
+ d = raw_getpid();
+ e = getpid_cached();
+ f = getpid();
+
+ assert_se(a == d && a == e && a == f);
+
+ assert_se(wait_for_terminate(child, &si) >= 0);
+ assert_se(si.si_status == 0);
+ assert_se(si.si_code == CLD_EXITED);
+}
+
+#define MEASURE_ITERATIONS (10000000LLU)
+
+static void test_getpid_measure(void) {
+ unsigned long long i;
+ usec_t t, q;
+
+ t = now(CLOCK_MONOTONIC);
+ for (i = 0; i < MEASURE_ITERATIONS; i++)
+ (void) getpid();
+ q = now(CLOCK_MONOTONIC) - t;
+
+ log_info(" glibc getpid(): %llu/s\n", (unsigned long long) (MEASURE_ITERATIONS*USEC_PER_SEC/q));
+
+ t = now(CLOCK_MONOTONIC);
+ for (i = 0; i < MEASURE_ITERATIONS; i++)
+ (void) getpid_cached();
+ q = now(CLOCK_MONOTONIC) - t;
+
+ log_info("getpid_cached(): %llu/s\n", (unsigned long long) (MEASURE_ITERATIONS*USEC_PER_SEC/q));
+}
+
int main(int argc, char *argv[]) {
log_set_max_level(LOG_DEBUG);
@@ -434,6 +489,8 @@ int main(int argc, char *argv[]) {
test_personality();
test_get_process_cmdline_harder();
test_rename_process();
+ test_getpid_cached();
+ test_getpid_measure();
return 0;
}
diff --git a/src/test/test-random-util.c b/src/test/test-random-util.c
new file mode 100644
index 0000000000..50f4da270d
--- /dev/null
+++ b/src/test/test-random-util.c
@@ -0,0 +1,65 @@
+/***
+ 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 "hexdecoct.h"
+#include "random-util.h"
+#include "log.h"
+
+static void test_acquire_random_bytes(bool high_quality_required) {
+ uint8_t buf[16] = {};
+ unsigned i;
+
+ log_info("/* %s */", __func__);
+
+ for (i = 1; i < sizeof buf; i++) {
+ assert_se(acquire_random_bytes(buf, i, high_quality_required) == 0);
+ if (i + 1 < sizeof buf)
+ assert_se(buf[i] == 0);
+
+ hexdump(stdout, buf, i);
+ }
+}
+
+static void test_pseudorandom_bytes(void) {
+ uint8_t buf[16] = {};
+ unsigned i;
+
+ log_info("/* %s */", __func__);
+
+ for (i = 1; i < sizeof buf; i++) {
+ pseudorandom_bytes(buf, i);
+ if (i + 1 < sizeof buf)
+ assert_se(buf[i] == 0);
+
+ hexdump(stdout, buf, i);
+ }
+}
+
+int main(int argc, char **argv) {
+ log_set_max_level(LOG_DEBUG);
+ log_parse_environment();
+ log_open();
+
+ test_acquire_random_bytes(false);
+ test_acquire_random_bytes(true);
+
+ test_pseudorandom_bytes();
+
+ return 0;
+}
diff --git a/src/test/test-seccomp.c b/src/test/test-seccomp.c
index 34a1275162..28fe206507 100644
--- a/src/test/test-seccomp.c
+++ b/src/test/test-seccomp.c
@@ -21,8 +21,10 @@
#include <stdlib.h>
#include <sys/eventfd.h>
#include <sys/mman.h>
-#include <unistd.h>
#include <sys/poll.h>
+#include <sys/shm.h>
+#include <sys/types.h>
+#include <unistd.h>
#include "alloc-util.h"
#include "fd-util.h"
@@ -37,6 +39,15 @@
#include "util.h"
#include "virt.h"
+#if SCMP_SYS(socket) < 0 || defined(__i386__) || defined(__s390x__) || defined(__s390__)
+/* On these archs, socket() is implemented via the socketcall() syscall multiplexer,
+ * and we can't restrict it hence via seccomp. */
+# define SECCOMP_RESTRICT_ADDRESS_FAMILIES_BROKEN 1
+#else
+# define SECCOMP_RESTRICT_ADDRESS_FAMILIES_BROKEN 0
+#endif
+
+
static void test_seccomp_arch_to_string(void) {
uint32_t a, b;
const char *name;
@@ -158,8 +169,6 @@ static void test_restrict_namespace(void) {
assert_se(streq(s, "cgroup ipc net mnt pid user uts"));
assert_se(namespace_flag_from_string_many(s, &ul) == 0 && ul == NAMESPACE_FLAGS_ALL);
-#if SECCOMP_RESTRICT_NAMESPACES_BROKEN == 0
-
if (!is_seccomp_available())
return;
if (geteuid() != 0)
@@ -218,7 +227,6 @@ static void test_restrict_namespace(void) {
}
assert_se(wait_for_terminate_and_warn("nsseccomp", pid, true) == EXIT_SUCCESS);
-#endif
}
static void test_protect_sysctl(void) {
@@ -236,13 +244,17 @@ static void test_protect_sysctl(void) {
assert_se(pid >= 0);
if (pid == 0) {
+#if __NR__sysctl > 0
assert_se(syscall(__NR__sysctl, NULL) < 0);
assert_se(errno == EFAULT);
+#endif
assert_se(seccomp_protect_sysctl() >= 0);
+#if __NR__sysctl > 0
assert_se(syscall(__NR__sysctl, 0, 0, 0) < 0);
assert_se(errno == EPERM);
+#endif
_exit(EXIT_SUCCESS);
}
@@ -286,12 +298,12 @@ static void test_restrict_address_families(void) {
assert_se(fd >= 0);
safe_close(fd);
-#if SECCOMP_RESTRICT_ADDRESS_FAMILIES_BROKEN
fd = socket(AF_UNIX, SOCK_DGRAM, 0);
+#if SECCOMP_RESTRICT_ADDRESS_FAMILIES_BROKEN
assert_se(fd >= 0);
safe_close(fd);
#else
- assert_se(socket(AF_UNIX, SOCK_DGRAM, 0) < 0);
+ assert_se(fd < 0);
assert_se(errno == EAFNOSUPPORT);
#endif
@@ -309,19 +321,21 @@ static void test_restrict_address_families(void) {
assert_se(fd >= 0);
safe_close(fd);
-#if SECCOMP_RESTRICT_ADDRESS_FAMILIES_BROKEN
fd = socket(AF_UNIX, SOCK_DGRAM, 0);
+#if SECCOMP_RESTRICT_ADDRESS_FAMILIES_BROKEN
assert_se(fd >= 0);
safe_close(fd);
+#else
+ assert_se(fd < 0);
+ assert_se(errno == EAFNOSUPPORT);
+#endif
fd = socket(AF_NETLINK, SOCK_DGRAM, 0);
+#if SECCOMP_RESTRICT_ADDRESS_FAMILIES_BROKEN
assert_se(fd >= 0);
safe_close(fd);
#else
- assert_se(socket(AF_UNIX, SOCK_DGRAM, 0) < 0);
- assert_se(errno == EAFNOSUPPORT);
-
- assert_se(socket(AF_NETLINK, SOCK_DGRAM, 0) < 0);
+ assert_se(fd < 0);
assert_se(errno == EAFNOSUPPORT);
#endif
@@ -369,7 +383,7 @@ static void test_restrict_realtime(void) {
assert_se(wait_for_terminate_and_warn("realtimeseccomp", pid, true) == EXIT_SUCCESS);
}
-static void test_memory_deny_write_execute(void) {
+static void test_memory_deny_write_execute_mmap(void) {
pid_t pid;
if (!is_seccomp_available())
@@ -393,14 +407,13 @@ static void test_memory_deny_write_execute(void) {
assert_se(seccomp_memory_deny_write_execute() >= 0);
-#if SECCOMP_MEMORY_DENY_WRITE_EXECUTE_BROKEN
- p = mmap(NULL, page_size(), PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1,0);
- assert_se(p != MAP_FAILED);
- assert_se(munmap(p, page_size()) >= 0);
-#else
p = mmap(NULL, page_size(), PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1,0);
+#if defined(__x86_64__) || defined(__i386__) || defined(__powerpc64__) || defined(__arm__) || defined(__aarch64__)
assert_se(p == MAP_FAILED);
assert_se(errno == EPERM);
+#else /* unknown architectures */
+ assert_se(p != MAP_FAILED);
+ assert_se(munmap(p, page_size()) >= 0);
#endif
p = mmap(NULL, page_size(), PROT_WRITE|PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1,0);
@@ -410,7 +423,54 @@ static void test_memory_deny_write_execute(void) {
_exit(EXIT_SUCCESS);
}
- assert_se(wait_for_terminate_and_warn("memoryseccomp", pid, true) == EXIT_SUCCESS);
+ assert_se(wait_for_terminate_and_warn("memoryseccomp-mmap", pid, true) == EXIT_SUCCESS);
+}
+
+static void test_memory_deny_write_execute_shmat(void) {
+ int shmid;
+ pid_t pid;
+
+ if (!is_seccomp_available())
+ return;
+ if (geteuid() != 0)
+ return;
+
+ shmid = shmget(IPC_PRIVATE, page_size(), 0);
+ assert_se(shmid >= 0);
+
+ pid = fork();
+ assert_se(pid >= 0);
+
+ if (pid == 0) {
+ void *p;
+
+ p = shmat(shmid, NULL, 0);
+ assert_se(p != MAP_FAILED);
+ assert_se(shmdt(p) == 0);
+
+ p = shmat(shmid, NULL, SHM_EXEC);
+ assert_se(p != MAP_FAILED);
+ assert_se(shmdt(p) == 0);
+
+ assert_se(seccomp_memory_deny_write_execute() >= 0);
+
+ p = shmat(shmid, NULL, SHM_EXEC);
+#if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__)
+ assert_se(p == MAP_FAILED);
+ assert_se(errno == EPERM);
+#else /* __i386__, __powerpc64__, and "unknown" architectures */
+ assert_se(p != MAP_FAILED);
+ assert_se(shmdt(p) == 0);
+#endif
+
+ p = shmat(shmid, NULL, 0);
+ assert_se(p != MAP_FAILED);
+ assert_se(shmdt(p) == 0);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ assert_se(wait_for_terminate_and_warn("memoryseccomp-shmat", pid, true) == EXIT_SUCCESS);
}
static void test_restrict_archs(void) {
@@ -469,7 +529,11 @@ static void test_load_syscall_filter_set_raw(void) {
assert_se(poll(NULL, 0, 0) == 0);
assert_se(s = set_new(NULL));
+#if SCMP_SYS(access) >= 0
assert_se(set_put(s, UINT32_TO_PTR(__NR_access + 1)) >= 0);
+#else
+ assert_se(set_put(s, UINT32_TO_PTR(__NR_faccessat + 1)) >= 0);
+#endif
assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, s, SCMP_ACT_ERRNO(EUCLEAN)) >= 0);
@@ -481,7 +545,11 @@ static void test_load_syscall_filter_set_raw(void) {
s = set_free(s);
assert_se(s = set_new(NULL));
+#if SCMP_SYS(poll) >= 0
assert_se(set_put(s, UINT32_TO_PTR(__NR_poll + 1)) >= 0);
+#else
+ assert_se(set_put(s, UINT32_TO_PTR(__NR_ppoll + 1)) >= 0);
+#endif
assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, s, SCMP_ACT_ERRNO(EUNATCH)) >= 0);
@@ -509,7 +577,8 @@ int main(int argc, char *argv[]) {
test_protect_sysctl();
test_restrict_address_families();
test_restrict_realtime();
- test_memory_deny_write_execute();
+ test_memory_deny_write_execute_mmap();
+ test_memory_deny_write_execute_shmat();
test_restrict_archs();
test_load_syscall_filter_set_raw();
diff --git a/src/test/test-selinux.c b/src/test/test-selinux.c
index b676c25913..190736aa47 100644
--- a/src/test/test-selinux.c
+++ b/src/test/test-selinux.c
@@ -35,16 +35,16 @@ static void test_testing(void) {
b = mac_selinux_use();
log_info("mac_selinux_use → %s", yes_no(b));
- b = mac_selinux_have();
- log_info("mac_selinux_have → %s", yes_no(b));
+ b = mac_selinux_use();
+ log_info("mac_selinux_use → %s", yes_no(b));
mac_selinux_retest();
b = mac_selinux_use();
log_info("mac_selinux_use → %s", yes_no(b));
- b = mac_selinux_have();
- log_info("mac_selinux_have → %s", yes_no(b));
+ b = mac_selinux_use();
+ log_info("mac_selinux_use → %s", yes_no(b));
}
static void test_loading(void) {
diff --git a/src/test/test-sigbus.c b/src/test/test-sigbus.c
index 02b8e24308..7a4a8a6636 100644
--- a/src/test/test-sigbus.c
+++ b/src/test/test-sigbus.c
@@ -22,6 +22,9 @@
#include "fd-util.h"
#include "sigbus.h"
#include "util.h"
+#ifdef HAVE_VALGRIND_VALGRIND_H
+#include <valgrind/valgrind.h>
+#endif
int main(int argc, char *argv[]) {
_cleanup_close_ int fd = -1;
@@ -29,6 +32,11 @@ int main(int argc, char *argv[]) {
void *addr = NULL;
uint8_t *p;
+#ifdef HAVE_VALGRIND_VALGRIND_H
+ if (RUNNING_ON_VALGRIND)
+ return EXIT_TEST_SKIP;
+#endif
+
#ifdef __SANITIZE_ADDRESS__
return EXIT_TEST_SKIP;
#endif
@@ -38,7 +46,7 @@ int main(int argc, char *argv[]) {
assert_se((fd = mkostemp(template, O_RDWR|O_CREAT|O_EXCL)) >= 0);
assert_se(unlink(template) >= 0);
- assert_se(fallocate(fd, 0, 0, page_size() * 8) >= 0);
+ assert_se(posix_fallocate(fd, 0, page_size() * 8) >= 0);
p = mmap(NULL, page_size() * 16, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
assert_se(p != MAP_FAILED);
diff --git a/src/test/test-signal-util.c b/src/test/test-signal-util.c
index 671eb869cb..92e3927784 100644
--- a/src/test/test-signal-util.c
+++ b/src/test/test-signal-util.c
@@ -50,12 +50,12 @@ static void test_block_signals(void) {
static void test_ignore_signals(void) {
assert_se(ignore_signals(SIGINT, -1) >= 0);
- assert_se(kill(getpid(), SIGINT) >= 0);
+ assert_se(kill(getpid_cached(), SIGINT) >= 0);
assert_se(ignore_signals(SIGUSR1, SIGUSR2, SIGTERM, SIGPIPE, -1) >= 0);
- assert_se(kill(getpid(), SIGUSR1) >= 0);
- assert_se(kill(getpid(), SIGUSR2) >= 0);
- assert_se(kill(getpid(), SIGTERM) >= 0);
- assert_se(kill(getpid(), SIGPIPE) >= 0);
+ assert_se(kill(getpid_cached(), SIGUSR1) >= 0);
+ assert_se(kill(getpid_cached(), SIGUSR2) >= 0);
+ assert_se(kill(getpid_cached(), SIGTERM) >= 0);
+ assert_se(kill(getpid_cached(), SIGPIPE) >= 0);
assert_se(default_signals(SIGINT, SIGUSR1, SIGUSR2, SIGTERM, SIGPIPE, -1) >= 0);
}
diff --git a/src/test/test-sizeof.c b/src/test/test-sizeof.c
index 8f99a13772..269adfd18f 100644
--- a/src/test/test-sizeof.c
+++ b/src/test/test-sizeof.c
@@ -17,7 +17,8 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include "log.h"
+#include <stdio.h>
+
#include "time-util.h"
/* Print information about various types. Useful when diagnosing
@@ -26,10 +27,18 @@
#pragma GCC diagnostic ignored "-Wtype-limits"
#define info(t) \
- log_info("%s → %zu bits%s", STRINGIFY(t), \
- sizeof(t)*CHAR_BIT, \
- strstr(STRINGIFY(t), "signed") ? "" : \
- ((t)-1 < (t)0 ? ", signed" : ", unsigned"));
+ printf("%s → %zu bits%s\n", STRINGIFY(t), \
+ sizeof(t)*CHAR_BIT, \
+ strstr(STRINGIFY(t), "signed") ? "" : \
+ ((t)-1 < (t)0 ? ", signed" : ", unsigned"));
+
+enum Enum {
+ enum_value,
+};
+
+enum BigEnum {
+ big_enum_value = UINT64_C(-1),
+};
int main(void) {
info(char);
@@ -39,6 +48,8 @@ int main(void) {
info(unsigned);
info(long unsigned);
info(long long unsigned);
+ info(__syscall_ulong_t);
+ info(__syscall_slong_t);
info(float);
info(double);
@@ -48,6 +59,10 @@ int main(void) {
info(ssize_t);
info(time_t);
info(usec_t);
+ info(__time_t);
+
+ info(enum Enum);
+ info(enum BigEnum);
return 0;
}
diff --git a/src/test/test-stat-util.c b/src/test/test-stat-util.c
index 3ff2aadea4..8e027ff26c 100644
--- a/src/test/test-stat-util.c
+++ b/src/test/test-stat-util.c
@@ -38,8 +38,10 @@ static void test_files_same(void) {
assert_se(fd >= 0);
assert_se(symlink(name, name_alias) >= 0);
- assert_se(files_same(name, name));
- assert_se(files_same(name, name_alias));
+ assert_se(files_same(name, name, 0));
+ assert_se(files_same(name, name, AT_SYMLINK_NOFOLLOW));
+ assert_se(files_same(name, name_alias, 0));
+ assert_se(!files_same(name, name_alias, AT_SYMLINK_NOFOLLOW));
unlink(name);
unlink(name_alias);
diff --git a/src/test/test-strxcpyx.c b/src/test/test-strxcpyx.c
index 9bea770131..d95945f6b0 100644
--- a/src/test/test-strxcpyx.c
+++ b/src/test/test-strxcpyx.c
@@ -51,6 +51,13 @@ static void test_strpcpyf(void) {
assert_se(streq(target, "space left: 25. foobar"));
assert_se(space_left == 3);
+
+ /* test overflow */
+ s = target;
+ space_left = strpcpyf(&s, 12, "00 left: %i. ", 999);
+ assert_se(streq(target, "00 left: 99"));
+ assert_se(space_left == 0);
+ assert_se(target[12] == '2');
}
static void test_strpcpyl(void) {
diff --git a/src/test/test-time.c b/src/test/test-time.c
index 911282bf0c..b7a06c7b19 100644
--- a/src/test/test-time.c
+++ b/src/test/test-time.c
@@ -61,6 +61,19 @@ static void test_parse_sec(void) {
assert_se(parse_sec(".3 infinity", &u) < 0);
}
+static void test_parse_sec_fix_0(void) {
+ usec_t u;
+
+ assert_se(parse_sec_fix_0("5s", &u) >= 0);
+ assert_se(u == 5 * USEC_PER_SEC);
+ assert_se(parse_sec_fix_0("0s", &u) >= 0);
+ assert_se(u == 0 * USEC_PER_SEC);
+ assert_se(parse_sec_fix_0("0", &u) >= 0);
+ assert_se(u == USEC_INFINITY);
+ assert_se(parse_sec_fix_0(" 0", &u) >= 0);
+ assert_se(u == USEC_INFINITY);
+}
+
static void test_parse_time(void) {
usec_t u;
@@ -195,16 +208,37 @@ static void test_usec_add(void) {
assert_se(usec_add(USEC_INFINITY, 2) == USEC_INFINITY);
}
-static void test_usec_sub(void) {
- assert_se(usec_sub(0, 0) == 0);
- assert_se(usec_sub(4, 1) == 3);
- assert_se(usec_sub(4, 4) == 0);
- assert_se(usec_sub(4, 5) == 0);
- assert_se(usec_sub(USEC_INFINITY-3, -3) == USEC_INFINITY);
- assert_se(usec_sub(USEC_INFINITY-3, -3) == USEC_INFINITY);
- assert_se(usec_sub(USEC_INFINITY-3, -4) == USEC_INFINITY);
- assert_se(usec_sub(USEC_INFINITY-3, -5) == USEC_INFINITY);
- assert_se(usec_sub(USEC_INFINITY, 5) == USEC_INFINITY);
+static void test_usec_sub_unsigned(void) {
+ assert_se(usec_sub_unsigned(0, 0) == 0);
+ assert_se(usec_sub_unsigned(0, 2) == 0);
+ assert_se(usec_sub_unsigned(0, USEC_INFINITY) == 0);
+ assert_se(usec_sub_unsigned(1, 0) == 1);
+ assert_se(usec_sub_unsigned(1, 1) == 0);
+ assert_se(usec_sub_unsigned(1, 2) == 0);
+ assert_se(usec_sub_unsigned(1, 3) == 0);
+ assert_se(usec_sub_unsigned(1, USEC_INFINITY) == 0);
+ assert_se(usec_sub_unsigned(USEC_INFINITY-1, 0) == USEC_INFINITY-1);
+ assert_se(usec_sub_unsigned(USEC_INFINITY-1, 1) == USEC_INFINITY-2);
+ assert_se(usec_sub_unsigned(USEC_INFINITY-1, 2) == USEC_INFINITY-3);
+ assert_se(usec_sub_unsigned(USEC_INFINITY-1, USEC_INFINITY-2) == 1);
+ assert_se(usec_sub_unsigned(USEC_INFINITY-1, USEC_INFINITY-1) == 0);
+ assert_se(usec_sub_unsigned(USEC_INFINITY-1, USEC_INFINITY) == 0);
+ assert_se(usec_sub_unsigned(USEC_INFINITY, 0) == USEC_INFINITY);
+ assert_se(usec_sub_unsigned(USEC_INFINITY, 1) == USEC_INFINITY);
+ assert_se(usec_sub_unsigned(USEC_INFINITY, 2) == USEC_INFINITY);
+ assert_se(usec_sub_unsigned(USEC_INFINITY, USEC_INFINITY) == USEC_INFINITY);
+}
+
+static void test_usec_sub_signed(void) {
+ assert_se(usec_sub_signed(0, 0) == 0);
+ assert_se(usec_sub_signed(4, 1) == 3);
+ assert_se(usec_sub_signed(4, 4) == 0);
+ assert_se(usec_sub_signed(4, 5) == 0);
+ assert_se(usec_sub_signed(USEC_INFINITY-3, -3) == USEC_INFINITY);
+ assert_se(usec_sub_signed(USEC_INFINITY-3, -3) == USEC_INFINITY);
+ assert_se(usec_sub_signed(USEC_INFINITY-3, -4) == USEC_INFINITY);
+ assert_se(usec_sub_signed(USEC_INFINITY-3, -5) == USEC_INFINITY);
+ assert_se(usec_sub_signed(USEC_INFINITY, 5) == USEC_INFINITY);
}
static void test_format_timestamp(void) {
@@ -273,10 +307,93 @@ static void test_format_timestamp_utc(void) {
test_format_timestamp_utc_one(USEC_INFINITY, NULL);
}
+static void test_dual_timestamp_deserialize(void) {
+ int r;
+ dual_timestamp t;
+
+ r = dual_timestamp_deserialize("1234 5678", &t);
+ assert_se(r == 0);
+ assert_se(t.realtime == 1234);
+ assert_se(t.monotonic == 5678);
+
+ r = dual_timestamp_deserialize("1234x 5678", &t);
+ assert_se(r == -EINVAL);
+
+ r = dual_timestamp_deserialize("1234 5678y", &t);
+ assert_se(r == -EINVAL);
+
+ r = dual_timestamp_deserialize("-1234 5678", &t);
+ assert_se(r == -EINVAL);
+
+ r = dual_timestamp_deserialize("1234 -5678", &t);
+ assert_se(r == -EINVAL);
+
+ /* Check that output wasn't modified. */
+ assert_se(t.realtime == 1234);
+ assert_se(t.monotonic == 5678);
+
+ r = dual_timestamp_deserialize("+123 567", &t);
+ assert_se(r == 0);
+ assert_se(t.realtime == 123);
+ assert_se(t.monotonic == 567);
+
+ /* Check that we get "infinity" on overflow. */
+ r = dual_timestamp_deserialize("18446744073709551617 0", &t);
+ assert_se(r == 0);
+ assert_se(t.realtime == USEC_INFINITY);
+ assert_se(t.monotonic == 0);
+}
+
+static void assert_similar(usec_t a, usec_t b) {
+ usec_t d;
+
+ if (a > b)
+ d = a - b;
+ else
+ d = b - a;
+
+ assert(d < 10*USEC_PER_SEC);
+}
+
+static void test_usec_shift_clock(void) {
+ usec_t rt, mn, bt;
+
+ rt = now(CLOCK_REALTIME);
+ mn = now(CLOCK_MONOTONIC);
+ bt = now(clock_boottime_or_monotonic());
+
+ assert_se(usec_shift_clock(USEC_INFINITY, CLOCK_REALTIME, CLOCK_MONOTONIC) == USEC_INFINITY);
+
+ assert_similar(usec_shift_clock(rt + USEC_PER_HOUR, CLOCK_REALTIME, CLOCK_MONOTONIC), mn + USEC_PER_HOUR);
+ assert_similar(usec_shift_clock(rt + 2*USEC_PER_HOUR, CLOCK_REALTIME, clock_boottime_or_monotonic()), bt + 2*USEC_PER_HOUR);
+ assert_se(usec_shift_clock(rt + 3*USEC_PER_HOUR, CLOCK_REALTIME, CLOCK_REALTIME_ALARM) == rt + 3*USEC_PER_HOUR);
+
+ assert_similar(usec_shift_clock(mn + 4*USEC_PER_HOUR, CLOCK_MONOTONIC, CLOCK_REALTIME_ALARM), rt + 4*USEC_PER_HOUR);
+ assert_similar(usec_shift_clock(mn + 5*USEC_PER_HOUR, CLOCK_MONOTONIC, clock_boottime_or_monotonic()), bt + 5*USEC_PER_HOUR);
+ assert_se(usec_shift_clock(mn + 6*USEC_PER_HOUR, CLOCK_MONOTONIC, CLOCK_MONOTONIC) == mn + 6*USEC_PER_HOUR);
+
+ assert_similar(usec_shift_clock(bt + 7*USEC_PER_HOUR, clock_boottime_or_monotonic(), CLOCK_MONOTONIC), mn + 7*USEC_PER_HOUR);
+ assert_similar(usec_shift_clock(bt + 8*USEC_PER_HOUR, clock_boottime_or_monotonic(), CLOCK_REALTIME_ALARM), rt + 8*USEC_PER_HOUR);
+ assert_se(usec_shift_clock(bt + 9*USEC_PER_HOUR, clock_boottime_or_monotonic(), clock_boottime_or_monotonic()) == bt + 9*USEC_PER_HOUR);
+
+ if (mn > USEC_PER_MINUTE) {
+ assert_similar(usec_shift_clock(rt - 30 * USEC_PER_SEC, CLOCK_REALTIME_ALARM, CLOCK_MONOTONIC), mn - 30 * USEC_PER_SEC);
+ assert_similar(usec_shift_clock(rt - 50 * USEC_PER_SEC, CLOCK_REALTIME, clock_boottime_or_monotonic()), bt - 50 * USEC_PER_SEC);
+ }
+}
+
int main(int argc, char *argv[]) {
uintmax_t x;
+ log_info("realtime=" USEC_FMT "\n"
+ "monotonic=" USEC_FMT "\n"
+ "boottime=" USEC_FMT "\n",
+ now(CLOCK_REALTIME),
+ now(CLOCK_MONOTONIC),
+ now(clock_boottime_or_monotonic()));
+
test_parse_sec();
+ test_parse_sec_fix_0();
test_parse_time();
test_parse_nsec();
test_format_timespan(1);
@@ -285,9 +402,12 @@ int main(int argc, char *argv[]) {
test_timezone_is_valid();
test_get_timezones();
test_usec_add();
- test_usec_sub();
+ test_usec_sub_signed();
+ test_usec_sub_unsigned();
test_format_timestamp();
test_format_timestamp_utc();
+ test_dual_timestamp_deserialize();
+ test_usec_shift_clock();
/* 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 a7c86d155a..b4c76048a4 100644
--- a/src/test/test-tmpfiles.c
+++ b/src/test/test-tmpfiles.c
@@ -45,7 +45,7 @@ int main(int argc, char** argv) {
fd = open_tmpfile_unlinkable(p, O_RDWR|O_CLOEXEC);
assert_se(fd >= 0);
- assert_se(asprintf(&cmd, "ls -l /proc/"PID_FMT"/fd/%d", getpid(), fd) > 0);
+ assert_se(asprintf(&cmd, "ls -l /proc/"PID_FMT"/fd/%d", getpid_cached(), fd) > 0);
(void) system(cmd);
assert_se(readlink_malloc(cmd + 6, &ans) >= 0);
log_debug("link1: %s", ans);
@@ -55,7 +55,7 @@ int main(int argc, char** argv) {
assert_se(fd >= 0);
assert_se(unlink(pattern) == 0);
- assert_se(asprintf(&cmd2, "ls -l /proc/"PID_FMT"/fd/%d", getpid(), fd2) > 0);
+ assert_se(asprintf(&cmd2, "ls -l /proc/"PID_FMT"/fd/%d", getpid_cached(), fd2) > 0);
(void) system(cmd2);
assert_se(readlink_malloc(cmd2 + 6, &ans2) >= 0);
log_debug("link2: %s", ans2);
diff --git a/src/test/test-udev.c b/src/test/test-udev.c
index e965b4494a..c84bd8991e 100644
--- a/src/test/test-udev.c
+++ b/src/test/test-udev.c
@@ -88,7 +88,7 @@ int main(int argc, char *argv[]) {
if (udev == NULL)
return EXIT_FAILURE;
- log_debug("version %s", VERSION);
+ log_debug("version %s", PACKAGE_VERSION);
mac_selinux_init();
action = argv[1];
diff --git a/src/test/test-unit-file.c b/src/test/test-unit-file.c
index 12f48bf435..fd797b587e 100644
--- a/src/test/test-unit-file.c
+++ b/src/test/test-unit-file.c
@@ -146,7 +146,7 @@ static void test_config_parse_exec(void) {
r = config_parse_exec(NULL, "fake", 4, "section", 1,
"LValue", 0, "/RValue/ argv0 r1",
&c, u);
- assert_se(r == 0);
+ assert_se(r == -ENOEXEC);
assert_se(c1->command_next == NULL);
log_info("/* honour_argv0 */");
@@ -161,7 +161,7 @@ static void test_config_parse_exec(void) {
r = config_parse_exec(NULL, "fake", 3, "section", 1,
"LValue", 0, "@/RValue",
&c, u);
- assert_se(r == 0);
+ assert_se(r == -ENOEXEC);
assert_se(c1->command_next == NULL);
log_info("/* no command, whitespace only, reset */");
@@ -220,7 +220,7 @@ static void test_config_parse_exec(void) {
"-@/RValue argv0 r1 ; ; "
"/goo/goo boo",
&c, u);
- assert_se(r >= 0);
+ assert_se(r == -ENOEXEC);
c1 = c1->command_next;
check_execcommand(c1, "/RValue", "argv0", "r1", NULL, true);
@@ -374,7 +374,7 @@ static void test_config_parse_exec(void) {
r = config_parse_exec(NULL, "fake", 4, "section", 1,
"LValue", 0, path,
&c, u);
- assert_se(r == 0);
+ assert_se(r == -ENOEXEC);
assert_se(c1->command_next == NULL);
}
@@ -401,21 +401,21 @@ static void test_config_parse_exec(void) {
r = config_parse_exec(NULL, "fake", 4, "section", 1,
"LValue", 0, "/path\\",
&c, u);
- assert_se(r == 0);
+ assert_se(r == -ENOEXEC);
assert_se(c1->command_next == NULL);
log_info("/* missing ending ' */");
r = config_parse_exec(NULL, "fake", 4, "section", 1,
"LValue", 0, "/path 'foo",
&c, u);
- assert_se(r == 0);
+ assert_se(r == -ENOEXEC);
assert_se(c1->command_next == NULL);
log_info("/* missing ending ' with trailing backslash */");
r = config_parse_exec(NULL, "fake", 4, "section", 1,
"LValue", 0, "/path 'foo\\",
&c, u);
- assert_se(r == 0);
+ assert_se(r == -ENOEXEC);
assert_se(c1->command_next == NULL);
log_info("/* invalid space between modifiers */");
diff --git a/src/timedate/meson.build b/src/timedate/meson.build
new file mode 100644
index 0000000000..63124d665b
--- /dev/null
+++ b/src/timedate/meson.build
@@ -0,0 +1,14 @@
+if conf.get('ENABLE_TIMEDATED', false)
+ install_data('org.freedesktop.timedate1.conf',
+ install_dir : dbuspolicydir)
+ install_data('org.freedesktop.timedate1.service',
+ install_dir : dbussystemservicedir)
+
+ custom_target(
+ 'org.freedesktop.timedate1.policy',
+ input : 'org.freedesktop.timedate1.policy.in',
+ output : 'org.freedesktop.timedate1.policy',
+ command : intltool_command,
+ install : install_polkit,
+ install_dir : polkitpolicydir)
+endif
diff --git a/src/timesync/meson.build b/src/timesync/meson.build
new file mode 100644
index 0000000000..4391afa93a
--- /dev/null
+++ b/src/timesync/meson.build
@@ -0,0 +1,42 @@
+systemd_timesyncd_sources = files('''
+ timesyncd.c
+ timesyncd-manager.c
+ timesyncd-manager.h
+ timesyncd-conf.c
+ timesyncd-conf.h
+ timesyncd-server.c
+ timesyncd-server.h
+'''.split())
+
+timesyncd_gperf_c = custom_target(
+ 'timesyncd-gperf.c',
+ input : 'timesyncd-gperf.gperf',
+ output : 'timesyncd-gperf.c',
+ command : [gperf, '@INPUT@', '--output-file', '@OUTPUT@'])
+
+systemd_timesyncd_sources += [timesyncd_gperf_c]
+
+if conf.get('ENABLE_TIMESYNCD', false)
+ timesyncd_conf = configure_file(
+ input : 'timesyncd.conf.in',
+ output : 'timesyncd.conf',
+ configuration : substs)
+ install_data(timesyncd_conf,
+ install_dir : pkgsysconfdir)
+endif
+
+############################################################
+
+tests += [
+ [['src/timesync/test-timesync.c',
+ 'src/timesync/timesyncd-manager.c',
+ 'src/timesync/timesyncd-manager.h',
+ 'src/timesync/timesyncd-conf.c',
+ 'src/timesync/timesyncd-conf.h',
+ 'src/timesync/timesyncd-server.c',
+ 'src/timesync/timesyncd-server.h',
+ timesyncd_gperf_c],
+ [libshared],
+ [libm],
+ 'ENABLE_TIMESYNCD'],
+]
diff --git a/src/timesync/test-timesync.c b/src/timesync/test-timesync.c
new file mode 100644
index 0000000000..a5a3433022
--- /dev/null
+++ b/src/timesync/test-timesync.c
@@ -0,0 +1,51 @@
+/***
+ 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/>.
+***/
+
+/* Some unit tests for the helper functions in timesyncd. */
+
+#include "log.h"
+#include "macro.h"
+#include "timesyncd-conf.h"
+
+static void test_manager_parse_string(void) {
+ /* Make sure that NTP_SERVERS is configured to something
+ * that we can actually parse successfully. */
+
+ _cleanup_(manager_freep) Manager *m = NULL;
+
+ assert_se(manager_new(&m) == 0);
+
+ assert_se(!m->have_fallbacks);
+ assert_se(manager_parse_server_string(m, SERVER_FALLBACK, NTP_SERVERS) == 0);
+ assert_se(m->have_fallbacks);
+ assert_se(manager_parse_fallback_string(m, NTP_SERVERS) == 0);
+
+ assert_se(manager_parse_server_string(m, SERVER_SYSTEM, "time1.foobar.com time2.foobar.com") == 0);
+ assert_se(manager_parse_server_string(m, SERVER_FALLBACK, "time1.foobar.com time2.foobar.com") == 0);
+ assert_se(manager_parse_server_string(m, SERVER_LINK, "time1.foobar.com time2.foobar.com") == 0);
+}
+
+int main(int argc, char **argv) {
+ log_set_max_level(LOG_DEBUG);
+ log_parse_environment();
+
+ test_manager_parse_string();
+
+ return 0;
+}
diff --git a/src/timesync/timesyncd-conf.c b/src/timesync/timesyncd-conf.c
index b4a4f19976..f394d0a2af 100644
--- a/src/timesync/timesyncd-conf.c
+++ b/src/timesync/timesyncd-conf.c
@@ -109,8 +109,8 @@ int manager_parse_config_file(Manager *m) {
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);
+ CONF_PATHS_NULSTR("systemd/timesyncd.conf.d"),
+ "Time\0",
+ config_item_perf_lookup, timesyncd_gperf_lookup,
+ false, m);
}
diff --git a/src/timesync/timesyncd.c b/src/timesync/timesyncd.c
index ff90f04070..86c14020b4 100644
--- a/src/timesync/timesyncd.c
+++ b/src/timesync/timesyncd.c
@@ -25,6 +25,7 @@
#include "fd-util.h"
#include "fs-util.h"
#include "network-util.h"
+#include "process-util.h"
#include "signal-util.h"
#include "timesyncd-conf.h"
#include "timesyncd-manager.h"
@@ -138,7 +139,7 @@ int main(int argc, char *argv[]) {
goto finish;
}
- log_debug("systemd-timesyncd running as pid " PID_FMT, getpid());
+ log_debug("systemd-timesyncd running as pid " PID_FMT, getpid_cached());
sd_notify(false,
"READY=1\n"
"STATUS=Daemon is running");
diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c
index ed6a9adaa6..9419c99e28 100644
--- a/src/tmpfiles/tmpfiles.c
+++ b/src/tmpfiles/tmpfiles.c
@@ -724,10 +724,9 @@ static int path_set_xattrs(Item *i, const char *path) {
n = strlen(*value);
log_debug("Setting extended attribute '%s=%s' on %s.", *name, *value, path);
- if (lsetxattr(path, *name, *value, n, 0) < 0) {
- log_error("Setting extended attribute %s=%s on %s failed: %m", *name, *value, path);
- return -errno;
- }
+ if (lsetxattr(path, *name, *value, n, 0) < 0)
+ return log_error_errno(errno, "Setting extended attribute %s=%s on %s failed: %m",
+ *name, *value, path);
}
return 0;
}
@@ -1093,19 +1092,14 @@ static int item_do_children(Item *i, const char *path, action_t action) {
static int glob_item(Item *i, action_t action, bool recursive) {
_cleanup_globfree_ glob_t g = {
- .gl_closedir = (void (*)(void *)) closedir,
- .gl_readdir = (struct dirent *(*)(void *)) readdir,
.gl_opendir = (void *(*)(const char *)) opendir_nomod,
- .gl_lstat = lstat,
- .gl_stat = stat,
};
int r = 0, k;
char **fn;
- errno = 0;
- k = glob(i->path, GLOB_NOSORT|GLOB_BRACE|GLOB_ALTDIRFUNC, NULL, &g);
- if (k != 0 && k != GLOB_NOMATCH)
- return log_error_errno(errno ?: EIO, "glob(%s) failed: %m", i->path);
+ k = safe_glob(i->path, GLOB_NOSORT|GLOB_BRACE, &g);
+ if (k < 0 && k != -ENOENT)
+ return log_error_errno(k, "glob(%s) failed: %m", i->path);
STRV_FOREACH(fn, g.gl_pathv) {
k = action(i, *fn);
diff --git a/src/udev/ata_id/ata_id.c b/src/udev/ata_id/ata_id.c
index 1e414664ce..ad152b9d31 100644
--- a/src/udev/ata_id/ata_id.c
+++ b/src/udev/ata_id/ata_id.c
@@ -427,6 +427,8 @@ int main(int argc, char *argv[])
{}
};
+ log_set_target(LOG_TARGET_AUTO);
+ udev_parse_config();
log_parse_environment();
log_open();
diff --git a/src/udev/cdrom_id/cdrom_id.c b/src/udev/cdrom_id/cdrom_id.c
index 72f284f710..1f906a8525 100644
--- a/src/udev/cdrom_id/cdrom_id.c
+++ b/src/udev/cdrom_id/cdrom_id.c
@@ -38,6 +38,7 @@
#include "libudev-private.h"
#include "random-util.h"
+#include "udev-util.h"
/* device info */
static unsigned int cd_cd_rom;
@@ -843,8 +844,7 @@ static int cd_media_toc(struct udev *udev, int fd)
return 0;
}
-int main(int argc, char *argv[])
-{
+int main(int argc, char *argv[]) {
struct udev *udev;
static const struct option options[] = {
{ "lock-media", no_argument, NULL, 'l' },
@@ -862,6 +862,8 @@ int main(int argc, char *argv[])
int cnt;
int rc = 0;
+ log_set_target(LOG_TARGET_AUTO);
+ udev_parse_config();
log_parse_environment();
log_open();
diff --git a/src/udev/collect/collect.c b/src/udev/collect/collect.c
index 0e973cd521..57dfb016f9 100644
--- a/src/udev/collect/collect.c
+++ b/src/udev/collect/collect.c
@@ -29,6 +29,7 @@
#include "macro.h"
#include "stdio-util.h"
#include "string-util.h"
+#include "udev-util.h"
#define BUFSIZE 16
#define UDEV_ALARM_TIMEOUT 180
@@ -343,9 +344,7 @@ static void everybody(void)
}
}
-int main(int argc, char **argv)
-{
- struct udev *udev;
+int main(int argc, char **argv) {
static const struct option options[] = {
{ "add", no_argument, NULL, 'a' },
{ "remove", no_argument, NULL, 'r' },
@@ -361,11 +360,10 @@ int main(int argc, char **argv)
int prune = 0;
char tmpdir[UTIL_PATH_SIZE];
- udev = udev_new();
- if (udev == NULL) {
- ret = EXIT_FAILURE;
- goto exit;
- }
+ log_set_target(LOG_TARGET_AUTO);
+ udev_parse_config();
+ log_parse_environment();
+ log_open();
for (;;) {
int option;
@@ -386,26 +384,23 @@ int main(int argc, char **argv)
break;
case 'h':
usage();
- goto exit;
+ return 0;
default:
- ret = 1;
- goto exit;
+ return 1;
}
}
argi = optind;
if (argi + 2 > argc) {
printf("Missing parameter(s)\n");
- ret = 1;
- goto exit;
+ return 1;
}
checkpoint = argv[argi++];
us = argv[argi++];
if (signal(SIGALRM, sig_alrm) == SIG_ERR) {
fprintf(stderr, "Cannot set SIGALRM: %m\n");
- ret = 2;
- goto exit;
+ return 2;
}
udev_list_node_init(&bunch);
@@ -485,7 +480,5 @@ out:
everybody();
if (ret >= 0)
printf("COLLECT_%s=%d\n", checkpoint, ret);
-exit:
- udev_unref(udev);
return ret;
}
diff --git a/src/udev/generate-keyboard-keys-gperf.sh b/src/udev/generate-keyboard-keys-gperf.sh
new file mode 100755
index 0000000000..5724e4e3dc
--- /dev/null
+++ b/src/udev/generate-keyboard-keys-gperf.sh
@@ -0,0 +1,10 @@
+#!/bin/sh -eu
+awk ' BEGIN {
+ print "struct key_name { const char* name; unsigned short id; };"
+ print "%null-strings"
+ print "%%"
+ }
+
+ /^KEY_/ { print tolower(substr($1 ,5)) ", " $1 }
+ { print tolower($1) ", " $1 }
+' < "$1"
diff --git a/src/udev/generate-keyboard-keys-list.sh b/src/udev/generate-keyboard-keys-list.sh
new file mode 100755
index 0000000000..7a74e0dae1
--- /dev/null
+++ b/src/udev/generate-keyboard-keys-list.sh
@@ -0,0 +1,6 @@
+#!/bin/sh -eu
+
+$1 -dM -include linux/input.h - </dev/null | awk '
+ /\<(KEY_(MAX|MIN_INTERESTING))|(BTN_(MISC|MOUSE|JOYSTICK|GAMEPAD|DIGI|WHEEL|TRIGGER_HAPPY))\>/ { next }
+ /^#define[ \t]+(KEY|BTN)_[^ ]+[ \t]+[0-9BK]/ { print $2 }
+'
diff --git a/src/udev/meson.build b/src/udev/meson.build
new file mode 100644
index 0000000000..eeb341f8d1
--- /dev/null
+++ b/src/udev/meson.build
@@ -0,0 +1,152 @@
+udevadm_sources = files('''
+ udevadm.c
+ udevadm-info.c
+ udevadm-control.c
+ udevadm-monitor.c
+ udevadm-hwdb.c
+ udevadm-settle.c
+ udevadm-trigger.c
+ udevadm-test.c
+ udevadm-test-builtin.c
+ udevadm-util.c
+ udevadm-util.h
+'''.split())
+
+systemd_udevd_sources = files('udevd.c')
+
+libudev_core_sources = '''
+ udev.h
+ udev-event.c
+ udev-watch.c
+ udev-node.c
+ udev-rules.c
+ udev-ctrl.c
+ udev-builtin.c
+ udev-builtin-btrfs.c
+ udev-builtin-hwdb.c
+ udev-builtin-input_id.c
+ udev-builtin-keyboard.c
+ udev-builtin-net_id.c
+ udev-builtin-net_setup_link.c
+ udev-builtin-path_id.c
+ udev-builtin-usb_id.c
+ net/link-config.c
+ net/link-config.h
+ net/ethtool-util.c
+ net/ethtool-util.h
+'''.split()
+
+if conf.get('HAVE_KMOD', false)
+ libudev_core_sources += ['udev-builtin-kmod.c']
+endif
+
+if conf.get('HAVE_BLKID', false)
+ libudev_core_sources += ['udev-builtin-blkid.c']
+endif
+
+if conf.get('HAVE_ACL', false)
+ libudev_core_sources += ['udev-builtin-uaccess.c',
+ logind_acl_c,
+ sd_login_c]
+endif
+
+############################################################
+
+generate_keyboard_keys_list = find_program('generate-keyboard-keys-list.sh')
+keyboard_keys_list_txt = custom_target(
+ 'keyboard-keys-list.txt',
+ output : 'keyboard-keys-list.txt',
+ command : [generate_keyboard_keys_list, cpp],
+ capture : true)
+
+generate_keyboard_keys_gperf = find_program('generate-keyboard-keys-gperf.sh')
+fname = 'keyboard-keys-from-name.gperf'
+gperf_file = custom_target(
+ fname,
+ input : keyboard_keys_list_txt,
+ output : fname,
+ command : [generate_keyboard_keys_gperf, '@INPUT@'],
+ capture : true)
+
+fname = 'keyboard-keys-from-name.h'
+keyboard_keys_from_name_h = custom_target(
+ fname,
+ input : gperf_file,
+ output : fname,
+ command : [gperf,
+ '-L', 'ANSI-C', '-t',
+ '-N', 'keyboard_lookup_key',
+ '-H', 'hash_key_name',
+ '-p', '-C',
+ '@INPUT@'],
+ capture : true)
+
+############################################################
+
+link_config_gperf_c = custom_target(
+ 'link-config-gperf.c',
+ input : 'net/link-config-gperf.gperf',
+ output : 'link-config-gperf.c',
+ command : [gperf, '@INPUT@', '--output-file', '@OUTPUT@'])
+
+############################################################
+
+if get_option('link-udev-shared')
+ udev_link_with = [libshared]
+ udev_rpath = rootlibexecdir
+else
+ udev_link_with = [libshared_static,
+ libsystemd_internal]
+ udev_rpath = ''
+endif
+
+libudev_internal = static_library(
+ 'udev',
+ libudev_sources,
+ include_directories : includes,
+ link_with : udev_link_with)
+
+libudev_core_includes = [includes, include_directories('net')]
+libudev_core = static_library(
+ 'udev-core',
+ libudev_core_sources,
+ link_config_gperf_c,
+ keyboard_keys_from_name_h,
+ include_directories : libudev_core_includes,
+ link_with : udev_link_with,
+ dependencies : [libblkid, libkmod])
+
+foreach prog : [['ata_id/ata_id.c'],
+ ['cdrom_id/cdrom_id.c'],
+ ['collect/collect.c'],
+ ['scsi_id/scsi_id.c',
+ 'scsi_id/scsi_id.h',
+ 'scsi_id/scsi_serial.c',
+ 'scsi_id/scsi.h'],
+ ['v4l_id/v4l_id.c'],
+ ['mtd_probe/mtd_probe.c',
+ 'mtd_probe/mtd_probe.h',
+ 'mtd_probe/probe_smartmedia.c']]
+
+ executable(prog[0].split('/')[0],
+ prog,
+ include_directories : includes,
+ c_args : ['-DLOG_REALM=LOG_REALM_UDEV'],
+ link_with : [libudev_internal],
+ install_rpath : udev_rpath,
+ install : true,
+ install_dir : udevlibexecdir)
+endforeach
+
+install_data('udev.conf',
+ install_dir : join_paths(sysconfdir, 'udev'))
+
+udev_pc = configure_file(
+ input : 'udev.pc.in',
+ output : 'udev.pc',
+ configuration : substs)
+install_data(udev_pc,
+ install_dir : pkgconfigdatadir)
+
+meson.add_install_script('sh', '-c',
+ mkdir_p.format(join_paths(sysconfdir, 'udev/rules.d')))
diff --git a/src/udev/net/ethtool-util.c b/src/udev/net/ethtool-util.c
index d7edbb396b..201fc23437 100644
--- a/src/udev/net/ethtool-util.c
+++ b/src/udev/net/ethtool-util.c
@@ -25,6 +25,7 @@
#include "conf-parser.h"
#include "ethtool-util.h"
#include "log.h"
+#include "link-config.h"
#include "socket-util.h"
#include "string-table.h"
#include "strxcpyx.h"
@@ -48,6 +49,17 @@ static const char* const wol_table[_WOL_MAX] = {
DEFINE_STRING_TABLE_LOOKUP(wol, WakeOnLan);
DEFINE_CONFIG_PARSE_ENUM(config_parse_wol, wol, WakeOnLan, "Failed to parse WakeOnLan setting");
+static const char* const port_table[_NET_DEV_PORT_MAX] = {
+ [NET_DEV_PORT_TP] = "tp",
+ [NET_DEV_PORT_AUI] = "aui",
+ [NET_DEV_PORT_MII] = "mii",
+ [NET_DEV_PORT_FIBRE] = "fibre",
+ [NET_DEV_PORT_BNC] = "bnc"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(port, NetDevPort);
+DEFINE_CONFIG_PARSE_ENUM(config_parse_port, port, NetDevPort, "Failed to parse Port setting");
+
static const char* const netdev_feature_table[_NET_DEV_FEAT_MAX] = {
[NET_DEV_FEAT_GSO] = "tx-generic-segmentation",
[NET_DEV_FEAT_GRO] = "rx-gro",
@@ -488,12 +500,12 @@ static int set_sset(int *fd, struct ifreq *ifr, const struct ethtool_link_usetti
* enabled speed and @duplex is %DUPLEX_UNKNOWN or the best enabled duplex mode.
*/
-int ethtool_set_glinksettings(int *fd, const char *ifname, unsigned int speed, Duplex duplex, int autonegotiation) {
+int ethtool_set_glinksettings(int *fd, const char *ifname, struct link_config *link) {
_cleanup_free_ struct ethtool_link_usettings *u = NULL;
struct ifreq ifr = {};
int r;
- if (autonegotiation != 0) {
+ if (link->autonegotiation != 0) {
log_info("link_config: autonegotiation is unset or enabled, the speed and duplex are not writable.");
return 0;
}
@@ -514,13 +526,16 @@ int ethtool_set_glinksettings(int *fd, const char *ifname, unsigned int speed, D
return log_warning_errno(r, "link_config: Cannot get device settings for %s : %m", ifname);
}
- if (speed)
- u->base.speed = speed;
+ if (link->speed)
+ u->base.speed = DIV_ROUND_UP(link->speed, 1000000);
+
+ if (link->duplex != _DUP_INVALID)
+ u->base.duplex = link->duplex;
- if (duplex != _DUP_INVALID)
- u->base.duplex = duplex;
+ if (link->port != _NET_DEV_PORT_INVALID)
+ u->base.port = link->port;
- u->base.autoneg = autonegotiation;
+ u->base.autoneg = link->autonegotiation;
if (u->base.cmd == ETHTOOL_GLINKSETTINGS)
r = set_slinksettings(fd, &ifr, u);
diff --git a/src/udev/net/ethtool-util.h b/src/udev/net/ethtool-util.h
index 75d6af396b..27ce0e0aba 100644
--- a/src/udev/net/ethtool-util.h
+++ b/src/udev/net/ethtool-util.h
@@ -24,11 +24,13 @@
#include "missing.h"
+struct link_config;
+
/* we can't use DUPLEX_ prefix, as it
* clashes with <linux/ethtool.h> */
typedef enum Duplex {
- DUP_FULL,
- DUP_HALF,
+ DUP_HALF = DUPLEX_HALF,
+ DUP_FULL = DUPLEX_FULL,
_DUP_MAX,
_DUP_INVALID = -1
} Duplex;
@@ -51,6 +53,18 @@ typedef enum NetDevFeature {
_NET_DEV_FEAT_INVALID = -1
} NetDevFeature;
+typedef enum NetDevPort {
+ NET_DEV_PORT_TP = 0x00,
+ NET_DEV_PORT_AUI = 0x01,
+ NET_DEV_PORT_MII = 0x02,
+ NET_DEV_PORT_FIBRE = 0x03,
+ NET_DEV_PORT_BNC = 0x04,
+ NET_DEV_PORT_DA = 0x05,
+ NET_DEV_PORT_NONE = 0xef,
+ NET_DEV_PORT_OTHER = 0xff,
+ _NET_DEV_PORT_MAX,
+ _NET_DEV_PORT_INVALID = -1
+} NetDevPort;
#define ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NU32 (SCHAR_MAX)
@@ -71,7 +85,7 @@ int ethtool_get_driver(int *fd, const char *ifname, char **ret);
int ethtool_set_speed(int *fd, const char *ifname, unsigned int speed, Duplex duplex);
int ethtool_set_wol(int *fd, const char *ifname, WakeOnLan wol);
int ethtool_set_features(int *fd, const char *ifname, NetDevFeature *features);
-int ethtool_set_glinksettings(int *fd, const char *ifname, unsigned int speed, Duplex duplex, int autoneg);
+int ethtool_set_glinksettings(int *fd, const char *ifname, struct link_config *link);
const char *duplex_to_string(Duplex d) _const_;
Duplex duplex_from_string(const char *d) _pure_;
@@ -79,5 +93,9 @@ Duplex duplex_from_string(const char *d) _pure_;
const char *wol_to_string(WakeOnLan wol) _const_;
WakeOnLan wol_from_string(const char *wol) _pure_;
+const char *port_to_string(NetDevPort port) _const_;
+NetDevPort port_from_string(const char *port) _pure_;
+
int config_parse_duplex(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_wol(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_port(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/udev/net/link-config-gperf.gperf b/src/udev/net/link-config-gperf.gperf
index 78e551df22..5488867ba7 100644
--- a/src/udev/net/link-config-gperf.gperf
+++ b/src/udev/net/link-config-gperf.gperf
@@ -36,6 +36,7 @@ Link.BitsPerSecond, config_parse_si_size, 0,
Link.Duplex, config_parse_duplex, 0, offsetof(link_config, duplex)
Link.AutoNegotiation, config_parse_tristate, 0, offsetof(link_config, autonegotiation)
Link.WakeOnLan, config_parse_wol, 0, offsetof(link_config, wol)
+Link.Port, config_parse_port, 0, offsetof(link_config, port)
Link.GenericSegmentationOffload, config_parse_tristate, 0, offsetof(link_config, features[NET_DEV_FEAT_GSO])
Link.TCPSegmentationOffload, config_parse_tristate, 0, offsetof(link_config, features[NET_DEV_FEAT_TSO])
Link.UDPSegmentationOffload, config_parse_tristate, 0, offsetof(link_config, features[NET_DEV_FEAT_UFO])
diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c
index 3af87f1388..05a186357c 100644
--- a/src/udev/net/link-config.c
+++ b/src/udev/net/link-config.c
@@ -167,6 +167,7 @@ static int load_link(link_config_ctx *ctx, const char *filename) {
link->mac_policy = _MACPOLICY_INVALID;
link->wol = _WOL_INVALID;
link->duplex = _DUP_INVALID;
+ link->port = _NET_DEV_PORT_INVALID;
link->autonegotiation = -1;
memset(&link->features, -1, sizeof(link->features));
@@ -377,12 +378,13 @@ int link_config_apply(link_config_ctx *ctx, link_config *config,
if (!old_name)
return -EINVAL;
-
- speed = DIV_ROUND_UP(config->speed, 1000000);
-
- r = ethtool_set_glinksettings(&ctx->ethtool_fd, old_name, speed, config->duplex, config->autonegotiation);
+ r = ethtool_set_glinksettings(&ctx->ethtool_fd, old_name, config);
if (r < 0) {
+ if (config->port != _NET_DEV_PORT_INVALID)
+ log_warning_errno(r, "Could not set port (%s) of %s: %m", port_to_string(config->port), old_name);
+
+ speed = DIV_ROUND_UP(config->speed, 1000000);
if (r == -EOPNOTSUPP)
r = ethtool_set_speed(&ctx->ethtool_fd, old_name, speed, config->duplex);
diff --git a/src/udev/net/link-config.h b/src/udev/net/link-config.h
index 5a25cec6fd..ff91a65135 100644
--- a/src/udev/net/link-config.h
+++ b/src/udev/net/link-config.h
@@ -71,6 +71,7 @@ struct link_config {
Duplex duplex;
int autonegotiation;
WakeOnLan wol;
+ NetDevPort port;
NetDevFeature features[_NET_DEV_FEAT_MAX];
LIST_FIELDS(link_config, links);
diff --git a/src/udev/scsi_id/scsi_id.c b/src/udev/scsi_id/scsi_id.c
index 4655691642..3c3d7a6b33 100644
--- a/src/udev/scsi_id/scsi_id.c
+++ b/src/udev/scsi_id/scsi_id.c
@@ -391,7 +391,7 @@ static int set_options(struct udev *udev,
break;
case 'V':
- printf("%s\n", VERSION);
+ printf("%s\n", PACKAGE_VERSION);
exit(0);
case 'x':
@@ -577,6 +577,8 @@ int main(int argc, char **argv)
int newargc;
char **newargv = NULL;
+ log_set_target(LOG_TARGET_AUTO);
+ udev_parse_config();
log_parse_environment();
log_open();
diff --git a/src/udev/udev-builtin-blkid.c b/src/udev/udev-builtin-blkid.c
index 9037aa1304..11d7085153 100644
--- a/src/udev/udev-builtin-blkid.c
+++ b/src/udev/udev-builtin-blkid.c
@@ -18,7 +18,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <blkid/blkid.h>
+#include <blkid.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
@@ -30,6 +30,7 @@
#include "sd-id128.h"
#include "alloc-util.h"
+#include "blkid-util.h"
#include "efivars.h"
#include "fd-util.h"
#include "gpt.h"
@@ -225,10 +226,9 @@ static int builtin_blkid(struct udev_device *dev, int argc, char *argv[], bool t
int64_t offset = 0;
bool noraid = false;
_cleanup_close_ int fd = -1;
- blkid_probe pr;
+ _cleanup_blkid_free_probe_ blkid_probe pr = NULL;
const char *data;
const char *name;
- const char *prtype = NULL;
int nvals;
int i;
int err = 0;
@@ -264,8 +264,7 @@ static int builtin_blkid(struct udev_device *dev, int argc, char *argv[], bool t
blkid_probe_set_superblocks_flags(pr,
BLKID_SUBLKS_LABEL | BLKID_SUBLKS_UUID |
BLKID_SUBLKS_TYPE | BLKID_SUBLKS_SECTYPE |
- BLKID_SUBLKS_USAGE | BLKID_SUBLKS_VERSION |
- BLKID_SUBLKS_BADCSUM);
+ BLKID_SUBLKS_USAGE | BLKID_SUBLKS_VERSION);
if (noraid)
blkid_probe_filter_superblocks_usage(pr, BLKID_FLTR_NOTIN, BLKID_USAGE_RAID);
@@ -287,15 +286,6 @@ static int builtin_blkid(struct udev_device *dev, int argc, char *argv[], bool t
err = probe_superblocks(pr);
if (err < 0)
goto out;
- if (blkid_probe_has_value(pr, "SBBADCSUM")) {
- if (!blkid_probe_lookup_value(pr, "TYPE", &prtype, NULL))
- log_warning("incorrect %s checksum on %s",
- prtype, udev_device_get_devnode(dev));
- else
- log_warning("incorrect checksum on %s",
- udev_device_get_devnode(dev));
- goto out;
- }
/* If we are a partition then our parent passed on the root
* partition UUID to us */
@@ -321,7 +311,6 @@ static int builtin_blkid(struct udev_device *dev, int argc, char *argv[], bool t
if (is_gpt)
find_gpt_root(dev, pr, test);
- blkid_free_probe(pr);
out:
if (err < 0)
return EXIT_FAILURE;
diff --git a/src/udev/udev-builtin-input_id.c b/src/udev/udev-builtin-input_id.c
index 51f364bf94..60f760ef77 100644
--- a/src/udev/udev-builtin-input_id.c
+++ b/src/udev/udev-builtin-input_id.c
@@ -31,6 +31,7 @@
#include <linux/input.h>
#include "fd-util.h"
+#include "missing.h"
#include "stdio-util.h"
#include "string-util.h"
#include "udev.h"
@@ -44,6 +45,17 @@
#define LONG(x) ((x)/BITS_PER_LONG)
#define test_bit(bit, array) ((array[LONG(bit)] >> OFF(bit)) & 1)
+struct range {
+ unsigned start;
+ unsigned end;
+};
+
+/* key code ranges above BTN_MISC (start is inclusive, stop is exclusive)*/
+static const struct range high_key_blocks[] = {
+ { KEY_OK, BTN_DPAD_UP },
+ { KEY_ALS_TOGGLE, BTN_TRIGGER_HAPPY }
+};
+
static inline int abs_size_mm(const struct input_absinfo *absinfo) {
/* Resolution is defined to be in units/mm for ABS_X/Y */
return (absinfo->maximum - absinfo->minimum) / absinfo->resolution;
@@ -137,6 +149,7 @@ static bool test_pointers(struct udev_device *dev,
const unsigned long* bitmask_rel,
const unsigned long* bitmask_props,
bool test) {
+ int button, axis;
bool has_abs_coordinates = false;
bool has_rel_coordinates = false;
bool has_mt_coordinates = false;
@@ -172,7 +185,8 @@ static bool test_pointers(struct udev_device *dev,
is_pointing_stick = test_bit(INPUT_PROP_POINTING_STICK, bitmask_props);
stylus_or_pen = test_bit(BTN_STYLUS, bitmask_key) || test_bit(BTN_TOOL_PEN, bitmask_key);
finger_but_no_pen = test_bit(BTN_TOOL_FINGER, bitmask_key) && !test_bit(BTN_TOOL_PEN, bitmask_key);
- has_mouse_button = test_bit(BTN_LEFT, bitmask_key);
+ for (button = BTN_MOUSE; button < BTN_JOYSTICK && !has_mouse_button; button++)
+ has_mouse_button = test_bit(button, bitmask_key);
has_rel_coordinates = test_bit(EV_REL, bitmask_ev) && test_bit(REL_X, bitmask_rel) && test_bit(REL_Y, bitmask_rel);
has_mt_coordinates = test_bit(ABS_MT_POSITION_X, bitmask_abs) && test_bit(ABS_MT_POSITION_Y, bitmask_abs);
@@ -183,18 +197,15 @@ static bool test_pointers(struct udev_device *dev,
has_touch = test_bit(BTN_TOUCH, bitmask_key);
/* joysticks don't necessarily have buttons; e. g.
* rudders/pedals are joystick-like, but buttonless; they have
- * other fancy axes */
- has_joystick_axes_or_buttons = test_bit(BTN_TRIGGER, bitmask_key) ||
- test_bit(BTN_A, bitmask_key) ||
- test_bit(BTN_1, bitmask_key) ||
- test_bit(ABS_RX, bitmask_abs) ||
- test_bit(ABS_RY, bitmask_abs) ||
- test_bit(ABS_RZ, bitmask_abs) ||
- test_bit(ABS_THROTTLE, bitmask_abs) ||
- test_bit(ABS_RUDDER, bitmask_abs) ||
- test_bit(ABS_WHEEL, bitmask_abs) ||
- test_bit(ABS_GAS, bitmask_abs) ||
- test_bit(ABS_BRAKE, bitmask_abs);
+ * other fancy axes. Others have buttons only but no axes. */
+ for (button = BTN_JOYSTICK; button < BTN_DIGI && !has_joystick_axes_or_buttons; button++)
+ has_joystick_axes_or_buttons = test_bit(button, bitmask_key);
+ for (button = BTN_TRIGGER_HAPPY1; button <= BTN_TRIGGER_HAPPY40 && !has_joystick_axes_or_buttons; button++)
+ has_joystick_axes_or_buttons = test_bit(button, bitmask_key);
+ for (button = BTN_DPAD_UP; button <= BTN_DPAD_RIGHT && !has_joystick_axes_or_buttons; button++)
+ has_joystick_axes_or_buttons = test_bit(button, bitmask_key);
+ for (axis = ABS_RX; axis < ABS_PRESSURE && !has_joystick_axes_or_buttons; axis++)
+ has_joystick_axes_or_buttons = test_bit(axis, bitmask_abs);
if (has_abs_coordinates) {
if (stylus_or_pen)
@@ -209,7 +220,10 @@ static bool test_pointers(struct udev_device *dev,
is_touchscreen = true;
else if (has_joystick_axes_or_buttons)
is_joystick = true;
+ } else if (has_joystick_axes_or_buttons) {
+ is_joystick = true;
}
+
if (has_mt_coordinates) {
if (stylus_or_pen)
is_tablet = true;
@@ -219,7 +233,9 @@ static bool test_pointers(struct udev_device *dev,
is_touchscreen = true;
}
- if (has_rel_coordinates && has_mouse_button)
+ if (has_mouse_button &&
+ (has_rel_coordinates ||
+ !has_abs_coordinates)) /* mouse buttons and no axis */
is_mouse = true;
if (is_pointing_stick)
@@ -260,13 +276,16 @@ static bool test_key(struct udev_device *dev,
found |= bitmask_key[i];
log_debug("test_key: checking bit block %lu for any keys; found=%i", (unsigned long)i*BITS_PER_LONG, found > 0);
}
- /* If there are no keys in the lower block, check the higher block */
+ /* If there are no keys in the lower block, check the higher blocks */
if (!found) {
- for (i = KEY_OK; i < BTN_TRIGGER_HAPPY; ++i) {
- if (test_bit(i, bitmask_key)) {
- log_debug("test_key: Found key %x in high block", i);
- found = 1;
- break;
+ unsigned block;
+ for (block = 0; block < (sizeof(high_key_blocks) / sizeof(struct range)); ++block) {
+ for (i = high_key_blocks[block].start; i < high_key_blocks[block].end; ++i) {
+ if (test_bit(i, bitmask_key)) {
+ log_debug("test_key: Found key %x in high block", i);
+ found = 1;
+ break;
+ }
}
}
}
diff --git a/src/udev/udev-builtin-keyboard.c b/src/udev/udev-builtin-keyboard.c
index 09024116f2..e316bb93ba 100644
--- a/src/udev/udev-builtin-keyboard.c
+++ b/src/udev/udev-builtin-keyboard.c
@@ -29,7 +29,7 @@
#include "string-util.h"
#include "udev.h"
-static const struct key *keyboard_lookup_key(const char *str, GPERF_LEN_TYPE len);
+static const struct key_name *keyboard_lookup_key(const char *str, GPERF_LEN_TYPE len);
#include "keyboard-keys-from-name.h"
static int install_force_release(struct udev_device *dev, const unsigned *release, unsigned release_count) {
@@ -76,7 +76,7 @@ static void map_keycode(int fd, const char *devnode, int scancode, const char *k
unsigned key;
} map;
char *endptr;
- const struct key *k;
+ const struct key_name *k;
unsigned keycode_num;
/* translate identifier to key code */
@@ -173,6 +173,9 @@ static void set_trackpoint_sensitivity(struct udev_device *dev, const char *valu
if (r < 0) {
log_error("Unable to parse POINTINGSTICK_SENSITIVITY '%s' for '%s'", value, udev_device_get_devnode(dev));
return;
+ } else if (val_i < 0 || val_i > 255) {
+ log_error("POINTINGSTICK_SENSITIVITY %d outside range [0..255] for '%s' ", val_i, udev_device_get_devnode(dev));
+ return;
}
xsprintf(val_s, "%d", val_i);
@@ -198,6 +201,7 @@ static int builtin_keyboard(struct udev_device *dev, int argc, char *argv[], boo
unsigned release_count = 0;
_cleanup_close_ int fd = -1;
const char *node;
+ int has_abs = -1;
node = udev_device_get_devnode(dev);
if (!node) {
@@ -258,6 +262,24 @@ static int builtin_keyboard(struct udev_device *dev, int argc, char *argv[], boo
return EXIT_FAILURE;
}
+ if (has_abs == -1) {
+ unsigned long bits;
+ int rc;
+
+ rc = ioctl(fd, EVIOCGBIT(0, sizeof(bits)), &bits);
+ if (rc < 0) {
+ log_error_errno(errno, "Unable to EVIOCGBIT device \"%s\"", node);
+ return EXIT_FAILURE;
+ }
+
+ has_abs = !!(bits & (1 << EV_ABS));
+ if (!has_abs)
+ log_warning("EVDEV_ABS override set but no EV_ABS present on device \"%s\"", node);
+ }
+
+ if (!has_abs)
+ continue;
+
override_abs(fd, node, evcode, udev_list_entry_get_value(entry));
} else if (streq(key, "POINTINGSTICK_SENSITIVITY"))
set_trackpoint_sensitivity(dev, udev_list_entry_get_value(entry));
diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c
index bd7b789cad..46eb6114ff 100644
--- a/src/udev/udev-builtin-net_id.c
+++ b/src/udev/udev-builtin-net_id.c
@@ -45,6 +45,8 @@
* — PCI geographical location
* [P<domain>]p<bus>s<slot>[f<function>][u<port>][..][c<config>][i<interface>]
* — USB port number chain
+ * v<slot> - VIO slot number (IBM PowerVM)
+ * a<vendor><model>i<instance> — Platform bus ACPI instance id
*
* All multi-function PCI devices will carry the [f<function>] number in the
* device name, including the function 0 device.
@@ -122,6 +124,8 @@ enum netname_type{
NET_BCMA,
NET_VIRTIO,
NET_CCW,
+ NET_VIO,
+ NET_PLATFORM,
};
struct netnames {
@@ -139,6 +143,8 @@ struct netnames {
char usb_ports[IFNAMSIZ];
char bcma_core[IFNAMSIZ];
char ccw_busid[IFNAMSIZ];
+ char vio_slot[IFNAMSIZ];
+ char platform_path[IFNAMSIZ];
};
/* skip intermediate virtio devices */
@@ -319,6 +325,87 @@ out:
return err;
}
+static int names_vio(struct udev_device *dev, struct netnames *names) {
+ struct udev_device *parent;
+ unsigned busid, slotid, ethid;
+ const char *syspath;
+
+ /* check if our direct parent is a VIO device with no other bus in-between */
+ parent = udev_device_get_parent(dev);
+ if (!parent)
+ return -ENOENT;
+
+ if (!streq_ptr("vio", udev_device_get_subsystem(parent)))
+ return -ENOENT;
+
+ /* The devices' $DEVPATH number is tied to (virtual) hardware (slot id
+ * selected in the HMC), thus this provides a reliable naming (e.g.
+ * "/devices/vio/30000002/net/eth1"); we ignore the bus number, as
+ * there should only ever be one bus, and then remove leading zeros. */
+ syspath = udev_device_get_syspath(dev);
+
+ if (sscanf(syspath, "/sys/devices/vio/%4x%4x/net/eth%u", &busid, &slotid, &ethid) != 3)
+ return -EINVAL;
+
+ xsprintf(names->vio_slot, "v%u", slotid);
+ names->type = NET_VIO;
+ return 0;
+}
+
+#define _PLATFORM_TEST "/sys/devices/platform/vvvvPPPP"
+#define _PLATFORM_PATTERN4 "/sys/devices/platform/%4s%4x:%2x/net/eth%u"
+#define _PLATFORM_PATTERN3 "/sys/devices/platform/%3s%4x:%2x/net/eth%u"
+
+static int names_platform(struct udev_device *dev, struct netnames *names, bool test) {
+ struct udev_device *parent;
+ char vendor[5];
+ unsigned model, instance, ethid;
+ const char *syspath, *pattern, *validchars;
+
+ /* check if our direct parent is a platform device with no other bus in-between */
+ parent = udev_device_get_parent(dev);
+ if (!parent)
+ return -ENOENT;
+
+ if (!streq_ptr("platform", udev_device_get_subsystem(parent)))
+ return -ENOENT;
+
+ syspath = udev_device_get_syspath(dev);
+
+ /* syspath is too short, to have a valid ACPI instance */
+ if (strlen(syspath) < sizeof _PLATFORM_TEST)
+ return -EINVAL;
+
+ /* Vendor ID can be either PNP ID (3 chars A-Z) or ACPI ID (4 chars A-Z and numerals) */
+ if (syspath[sizeof _PLATFORM_TEST - 1] == ':') {
+ pattern = _PLATFORM_PATTERN4;
+ validchars = UPPERCASE_LETTERS DIGITS;
+ } else {
+ pattern = _PLATFORM_PATTERN3;
+ validchars = UPPERCASE_LETTERS;
+ }
+
+ /* Platform devices are named after ACPI table match, and instance id
+ * eg. "/sys/devices/platform/HISI00C2:00");
+ * The Vendor (3 or 4 char), followed by hexdecimal model number : instance id.
+ */
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat-nonliteral"
+ if (sscanf(syspath, pattern, vendor, &model, &instance, &ethid) != 4)
+ return -EINVAL;
+#pragma GCC diagnostic pop
+
+ if (!in_charset(vendor, validchars))
+ return -ENOENT;
+
+ ascii_strlower(vendor);
+
+ xsprintf(names->platform_path, "a%s%xi%u", vendor, model, instance);
+ names->type = NET_PLATFORM;
+ return 0;
+}
+
static int names_pci(struct udev_device *dev, struct netnames *names) {
struct udev_device *parent;
@@ -591,6 +678,26 @@ static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool
goto out;
}
+ /* get ibmveth/ibmvnic slot-based names. */
+ err = names_vio(dev, &names);
+ if (err >= 0 && names.type == NET_VIO) {
+ char str[IFNAMSIZ];
+
+ if (snprintf(str, sizeof(str), "%s%s", prefix, names.vio_slot) < (int)sizeof(str))
+ udev_builtin_add_property(dev, test, "ID_NET_NAME_SLOT", str);
+ goto out;
+ }
+
+ /* get ACPI path names for ARM64 platform devices */
+ err = names_platform(dev, &names, test);
+ if (err >= 0 && names.type == NET_PLATFORM) {
+ char str[IFNAMSIZ];
+
+ if (snprintf(str, sizeof(str), "%s%s", prefix, names.platform_path) < (int)sizeof(str))
+ udev_builtin_add_property(dev, test, "ID_NET_NAME_PATH", str);
+ goto out;
+ }
+
/* get PCI based path names, we compose only PCI based paths */
err = names_pci(dev, &names);
if (err < 0)
diff --git a/src/udev/udev-ctrl.c b/src/udev/udev-ctrl.c
index dbefbbe175..92e4f8d9c0 100644
--- a/src/udev/udev-ctrl.c
+++ b/src/udev/udev-ctrl.c
@@ -239,7 +239,7 @@ static int ctrl_send(struct udev_ctrl *uctrl, enum udev_ctrl_msg_type type, int
int err = 0;
memzero(&ctrl_msg_wire, sizeof(struct udev_ctrl_msg_wire));
- strcpy(ctrl_msg_wire.version, "udev-" VERSION);
+ strcpy(ctrl_msg_wire.version, "udev-" PACKAGE_VERSION);
ctrl_msg_wire.magic = UDEV_CTRL_MAGIC;
ctrl_msg_wire.type = type;
diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c
index 3f9c3ed0cf..601f0ee13d 100644
--- a/src/udev/udev-event.c
+++ b/src/udev/udev-event.c
@@ -58,7 +58,7 @@ struct udev_event *udev_event_new(struct udev_device *dev) {
event->udev = udev;
udev_list_init(udev, &event->run_list, false);
udev_list_init(udev, &event->seclabel_list, false);
- event->birth_usec = clock_boottime_or_monotonic();
+ event->birth_usec = now(CLOCK_MONOTONIC);
return event;
}
@@ -520,7 +520,7 @@ static void spawn_read(struct udev_event *event,
if (timeout_usec > 0) {
usec_t age_usec;
- age_usec = clock_boottime_or_monotonic() - event->birth_usec;
+ age_usec = now(CLOCK_MONOTONIC) - event->birth_usec;
if (age_usec >= timeout_usec) {
log_error("timeout '%s'", cmd);
return;
@@ -671,13 +671,13 @@ static int spawn_wait(struct udev_event *event,
if (timeout_usec > 0) {
usec_t usec, age_usec;
- usec = now(clock_boottime_or_monotonic());
+ usec = now(CLOCK_MONOTONIC);
age_usec = usec - event->birth_usec;
if (age_usec < timeout_usec) {
if (timeout_warn_usec > 0 && timeout_warn_usec < timeout_usec && age_usec < timeout_warn_usec) {
spawn.timeout_warn = timeout_warn_usec - age_usec;
- r = sd_event_add_time(e, NULL, clock_boottime_or_monotonic(),
+ r = sd_event_add_time(e, NULL, CLOCK_MONOTONIC,
usec + spawn.timeout_warn, USEC_PER_SEC,
on_spawn_timeout_warning, &spawn);
if (r < 0)
@@ -686,7 +686,7 @@ static int spawn_wait(struct udev_event *event,
spawn.timeout = timeout_usec - age_usec;
- r = sd_event_add_time(e, NULL, clock_boottime_or_monotonic(),
+ r = sd_event_add_time(e, NULL, CLOCK_MONOTONIC,
usec + spawn.timeout, USEC_PER_SEC, on_spawn_timeout, &spawn);
if (r < 0)
return r;
diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c
index 4d07b8fce0..294a322547 100644
--- a/src/udev/udev-rules.c
+++ b/src/udev/udev-rules.c
@@ -474,6 +474,13 @@ static int add_token(struct udev_rules *rules, struct token *token) {
return 0;
}
+static void log_unknown_owner(int error, const char *entity, const char *owner) {
+ if (IN_SET(abs(error), ENOENT, ESRCH))
+ log_error("Specified %s '%s' unknown", entity, owner);
+ else
+ log_error_errno(error, "Error resolving %s '%s': %m", entity, owner);
+}
+
static uid_t add_uid(struct udev_rules *rules, const char *owner) {
unsigned int i;
uid_t uid = 0;
@@ -489,12 +496,8 @@ static uid_t add_uid(struct udev_rules *rules, const char *owner) {
}
}
r = get_user_creds(&owner, &uid, NULL, NULL, NULL);
- if (r < 0) {
- if (r == -ENOENT || r == -ESRCH)
- log_error("specified user '%s' unknown", owner);
- else
- log_error_errno(r, "error resolving user '%s': %m", owner);
- }
+ if (r < 0)
+ log_unknown_owner(r, "user", owner);
/* grow buffer if needed */
if (rules->uids_cur+1 >= rules->uids_max) {
@@ -536,12 +539,8 @@ static gid_t add_gid(struct udev_rules *rules, const char *group) {
}
}
r = get_group_creds(&group, &gid);
- if (r < 0) {
- if (r == -ENOENT || r == -ESRCH)
- log_error("specified group '%s' unknown", group);
- else
- log_error_errno(r, "error resolving group '%s': %m", group);
- }
+ if (r < 0)
+ log_unknown_owner(r, "group", group);
/* grow buffer if needed */
if (rules->gids_cur+1 >= rules->gids_max) {
@@ -814,7 +813,7 @@ static const char *get_key_attribute(struct udev *udev, char *str) {
attr++;
pos = strchr(attr, '}');
if (pos == NULL) {
- log_error("missing closing brace for format");
+ log_error("Missing closing brace for format");
return NULL;
}
pos[0] = '\0';
@@ -2119,11 +2118,7 @@ void udev_rules_apply_to_event(struct udev_rules *rules,
event->owner_set = true;
r = get_user_creds(&ow, &event->uid, NULL, NULL, NULL);
if (r < 0) {
- if (r == -ENOENT || r == -ESRCH)
- log_error("specified user '%s' unknown", owner);
- else
- log_error_errno(r, "error resolving user '%s': %m", owner);
-
+ log_unknown_owner(r, "user", owner);
event->uid = 0;
}
log_debug("OWNER %u %s:%u",
@@ -2145,11 +2140,7 @@ void udev_rules_apply_to_event(struct udev_rules *rules,
event->group_set = true;
r = get_group_creds(&gr, &event->gid);
if (r < 0) {
- if (r == -ENOENT || r == -ESRCH)
- log_error("specified group '%s' unknown", group);
- else
- log_error_errno(r, "error resolving group '%s': %m", group);
-
+ log_unknown_owner(r, "group", group);
event->gid = 0;
}
log_debug("GROUP %u %s:%u",
@@ -2536,19 +2527,19 @@ int udev_rules_apply_static_dev_perms(struct udev_rules *rules) {
}
if (mode != (stats.st_mode & 01777)) {
r = chmod(device_node, mode);
- if (r < 0) {
- log_error("failed to chmod '%s' %#o", device_node, mode);
- return -errno;
- } else
+ if (r < 0)
+ return log_error_errno(errno, "Failed to chmod '%s' %#o: %m",
+ device_node, mode);
+ else
log_debug("chmod '%s' %#o", device_node, mode);
}
if ((uid != 0 && uid != stats.st_uid) || (gid != 0 && gid != stats.st_gid)) {
r = chown(device_node, uid, gid);
- if (r < 0) {
- log_error("failed to chown '%s' %u %u ", device_node, uid, gid);
- return -errno;
- } else
+ if (r < 0)
+ return log_error_errno(errno, "Failed to chown '%s' %u %u: %m",
+ device_node, uid, gid);
+ else
log_debug("chown '%s' %u %u", device_node, uid, gid);
}
diff --git a/src/udev/udev.pc.in b/src/udev/udev.pc.in
index a0c2e82d47..e384a6f7c9 100644
--- a/src/udev/udev.pc.in
+++ b/src/udev/udev.pc.in
@@ -1,5 +1,5 @@
Name: udev
Description: udev
-Version: @VERSION@
+Version: @PACKAGE_VERSION@
udevdir=@udevlibexecdir@
diff --git a/src/udev/udevadm-hwdb.c b/src/udev/udevadm-hwdb.c
index 70a5fa4d7a..69b0b9025c 100644
--- a/src/udev/udevadm-hwdb.c
+++ b/src/udev/udevadm-hwdb.c
@@ -352,7 +352,7 @@ static int trie_store(struct trie *trie, const char *filename) {
int64_t size;
struct trie_header_f h = {
.signature = HWDB_SIG,
- .tool_version = htole64(atoi(VERSION)),
+ .tool_version = htole64(atoi(PACKAGE_VERSION)),
.header_size = htole64(sizeof(struct trie_header_f)),
.node_size = htole64(sizeof(struct trie_node_f)),
.child_entry_size = htole64(sizeof(struct trie_child_entry_f)),
diff --git a/src/udev/udevadm-info.c b/src/udev/udevadm-info.c
index 90cdfa16c7..16b2aab0a1 100644
--- a/src/udev/udevadm-info.c
+++ b/src/udev/udevadm-info.c
@@ -376,7 +376,7 @@ static int uinfo(struct udev *udev, int argc, char *argv[]) {
export_prefix = optarg;
break;
case 'V':
- printf("%s\n", VERSION);
+ printf("%s\n", PACKAGE_VERSION);
return 0;
case 'h':
help();
diff --git a/src/udev/udevadm-test.c b/src/udev/udevadm-test.c
index 07b667f131..e8ffe2f309 100644
--- a/src/udev/udevadm-test.c
+++ b/src/udev/udevadm-test.c
@@ -59,7 +59,7 @@ static int adm_test(struct udev *udev, int argc, char *argv[]) {
{}
};
- log_debug("version %s", VERSION);
+ log_debug("version %s", PACKAGE_VERSION);
while ((c = getopt_long(argc, argv, "a:N:h", options, NULL)) >= 0)
switch (c) {
diff --git a/src/udev/udevadm.c b/src/udev/udevadm.c
index a6a873e5de..befc3bad7b 100644
--- a/src/udev/udevadm.c
+++ b/src/udev/udevadm.c
@@ -23,9 +23,10 @@
#include "selinux-util.h"
#include "string-util.h"
#include "udev.h"
+#include "udev-util.h"
static int adm_version(struct udev *udev, int argc, char *argv[]) {
- printf("%s\n", VERSION);
+ printf("%s\n", PACKAGE_VERSION);
return 0;
}
@@ -87,14 +88,16 @@ int main(int argc, char *argv[]) {
unsigned int i;
int rc = 1, c;
- udev = udev_new();
- if (udev == NULL)
- goto out;
-
+ udev_parse_config();
log_parse_environment();
log_open();
+
mac_selinux_init();
+ udev = udev_new();
+ if (udev == NULL)
+ goto out;
+
while ((c = getopt_long(argc, argv, "+dhV", options, NULL)) >= 0)
switch (c) {
diff --git a/src/udev/udevd.c b/src/udev/udevd.c
index ce2ff89b85..0e49e62688 100644
--- a/src/udev/udevd.c
+++ b/src/udev/udevd.c
@@ -174,7 +174,7 @@ static void event_free(struct event *event) {
if (udev_list_node_is_empty(&event->manager->events)) {
/* only clean up the queue from the process that created it */
- if (event->manager->pid == getpid()) {
+ if (event->manager->pid == getpid_cached()) {
r = unlink("/run/udev/queue");
if (r < 0)
log_warning_errno(errno, "could not unlink /run/udev/queue: %m");
@@ -284,12 +284,12 @@ static void worker_attach_event(struct worker *worker, struct event *event) {
e = worker->manager->event;
- assert_se(sd_event_now(e, clock_boottime_or_monotonic(), &usec) >= 0);
+ assert_se(sd_event_now(e, CLOCK_MONOTONIC, &usec) >= 0);
- (void) sd_event_add_time(e, &event->timeout_warning, clock_boottime_or_monotonic(),
+ (void) sd_event_add_time(e, &event->timeout_warning, CLOCK_MONOTONIC,
usec + arg_event_timeout_warn_usec, USEC_PER_SEC, on_event_timeout_warning, event);
- (void) sd_event_add_time(e, &event->timeout, clock_boottime_or_monotonic(),
+ (void) sd_event_add_time(e, &event->timeout, CLOCK_MONOTONIC,
usec + arg_event_timeout_usec, USEC_PER_SEC, on_event_timeout, event);
}
@@ -593,9 +593,9 @@ static int event_queue_insert(Manager *manager, struct udev_device *dev) {
/* only one process can add events to the queue */
if (manager->pid == 0)
- manager->pid = getpid();
+ manager->pid = getpid_cached();
- assert(manager->pid == getpid());
+ assert(manager->pid == getpid_cached());
event = new0(struct event, 1);
if (!event)
@@ -755,9 +755,9 @@ static void manager_exit(Manager *manager) {
event_queue_cleanup(manager, EVENT_QUEUED);
manager_kill_workers(manager);
- assert_se(sd_event_now(manager->event, clock_boottime_or_monotonic(), &usec) >= 0);
+ assert_se(sd_event_now(manager->event, CLOCK_MONOTONIC, &usec) >= 0);
- r = sd_event_add_time(manager->event, NULL, clock_boottime_or_monotonic(),
+ r = sd_event_add_time(manager->event, NULL, CLOCK_MONOTONIC,
usec + 30 * USEC_PER_SEC, USEC_PER_SEC, on_exit_timeout, manager);
if (r < 0)
return;
@@ -791,7 +791,7 @@ static void event_queue_start(Manager *manager) {
manager->exit || manager->stop_exec_queue)
return;
- assert_se(sd_event_now(manager->event, clock_boottime_or_monotonic(), &usec) >= 0);
+ assert_se(sd_event_now(manager->event, CLOCK_MONOTONIC, &usec) >= 0);
/* check for changed config, every 3 seconds at most */
if (manager->last_usec == 0 ||
(usec - manager->last_usec) > 3 * USEC_PER_SEC) {
@@ -1492,7 +1492,7 @@ static int parse_argv(int argc, char *argv[]) {
help();
return 0;
case 'V':
- printf("%s\n", VERSION);
+ printf("%s\n", PACKAGE_VERSION);
return 0;
case '?':
return -EINVAL;
@@ -1663,6 +1663,7 @@ int main(int argc, char *argv[]) {
int r;
log_set_target(LOG_TARGET_AUTO);
+ udev_parse_config();
log_parse_environment();
log_open();
@@ -1740,7 +1741,7 @@ int main(int argc, char *argv[]) {
if (arg_daemonize) {
pid_t pid;
- log_info("starting version " VERSION);
+ log_info("starting version " PACKAGE_VERSION);
/* connect /dev/null to stdin, stdout, stderr */
if (log_get_max_level() < LOG_DEBUG) {
diff --git a/src/update-done/update-done.c b/src/update-done/update-done.c
index d466e1b759..ec467f1953 100644
--- a/src/update-done/update-done.c
+++ b/src/update-done/update-done.c
@@ -17,9 +17,8 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include "fd-util.h"
-#include "fileio.h"
-#include "io-util.h"
+#include "alloc-util.h"
+#include "fileio-label.h"
#include "selinux-util.h"
#include "util.h"
@@ -29,55 +28,25 @@
"# was updated. See man:systemd-update-done.service(8).\n"
static int apply_timestamp(const char *path, struct timespec *ts) {
- struct timespec twice[2] = {
- *ts,
- *ts
- };
- _cleanup_fclose_ FILE *f = NULL;
- int fd = -1;
+ _cleanup_free_ char *message = NULL;
int r;
- assert(path);
- assert(ts);
-
/*
* We store the timestamp both as mtime of the file and in the file itself,
* to support filesystems which cannot store nanosecond-precision timestamps.
- * Hence, don't bother updating the file, let's just rewrite it.
*/
- r = mac_selinux_create_file_prepare(path, S_IFREG);
- if (r < 0)
- return log_error_errno(r, "Failed to set SELinux context for %s: %m", path);
-
- fd = open(path, O_CREAT|O_WRONLY|O_TRUNC|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, 0644);
- mac_selinux_create_file_clear();
-
- if (fd < 0) {
- if (errno == EROFS)
- return log_debug("Can't create timestamp file %s, file system is read-only.", path);
-
- return log_error_errno(errno, "Failed to create/open timestamp file %s: %m", path);
- }
+ if (asprintf(&message,
+ MESSAGE
+ "TIMESTAMP_NSEC=" NSEC_FMT "\n",
+ timespec_load_nsec(ts)) < 0)
+ return log_oom();
- f = fdopen(fd, "we");
- if (!f) {
- safe_close(fd);
- return log_error_errno(errno, "Failed to fdopen() timestamp file %s: %m", path);
- }
-
- (void) fprintf(f,
- MESSAGE
- "TIMESTAMP_NSEC=" NSEC_FMT "\n",
- timespec_load_nsec(ts));
-
- r = fflush_and_check(f);
+ r = write_string_file_atomic_label_ts(path, message, ts);
+ if (r == -EROFS)
+ return log_debug("Cannot create \"%s\", file system is read-only.", path);
if (r < 0)
- return log_error_errno(r, "Failed to write timestamp file: %m");
-
- if (futimens(fd, twice) < 0)
- return log_error_errno(errno, "Failed to update timestamp on %s: %m", path);
-
+ return log_error_errno(r, "Failed to write \"%s\": %m", path);
return 0;
}
diff --git a/src/update-utmp/update-utmp.c b/src/update-utmp/update-utmp.c
index ae9859ccad..f68d60a134 100644
--- a/src/update-utmp/update-utmp.c
+++ b/src/update-utmp/update-utmp.c
@@ -33,6 +33,7 @@
#include "format-util.h"
#include "log.h"
#include "macro.h"
+#include "process-util.h"
#include "special.h"
#include "strv.h"
#include "unit-name.h"
@@ -258,7 +259,7 @@ int main(int argc, char *argv[]) {
goto finish;
}
- log_debug("systemd-update-utmp running as pid "PID_FMT, getpid());
+ log_debug("systemd-update-utmp running as pid "PID_FMT, getpid_cached());
if (streq(argv[1], "reboot"))
r = on_reboot(&c);
@@ -271,7 +272,7 @@ int main(int argc, char *argv[]) {
r = -EINVAL;
}
- log_debug("systemd-update-utmp stopped as pid "PID_FMT, getpid());
+ log_debug("systemd-update-utmp stopped as pid "PID_FMT, getpid_cached());
finish:
#ifdef HAVE_AUDIT
diff --git a/src/vconsole/meson.build b/src/vconsole/meson.build
new file mode 100644
index 0000000000..1260b53537
--- /dev/null
+++ b/src/vconsole/meson.build
@@ -0,0 +1,8 @@
+if conf.get('ENABLE_VCONSOLE', false)
+ vconsole_rules = configure_file(
+ input : '90-vconsole.rules.in',
+ output : '90-vconsole.rules',
+ configuration : substs)
+ install_data(vconsole_rules,
+ install_dir : udevrulesdir)
+endif
diff --git a/src/vconsole/vconsole-setup.c b/src/vconsole/vconsole-setup.c
index dc63bb530c..f531aece7f 100644
--- a/src/vconsole/vconsole-setup.c
+++ b/src/vconsole/vconsole-setup.c
@@ -47,31 +47,33 @@
#include "util.h"
#include "virt.h"
-static bool is_vconsole(int fd) {
+static int verify_vc_device(int fd) {
unsigned char data[1];
+ int r;
data[0] = TIOCL_GETFGCONSOLE;
- return ioctl(fd, TIOCLINUX, data) >= 0;
+ r = ioctl(fd, TIOCLINUX, data);
+ return r < 0 ? -errno : r;
}
-static bool is_allocated(unsigned int idx) {
- char vcname[strlen("/dev/vcs") + DECIMAL_STR_MAX(int)];
+static int verify_vc_allocation(unsigned idx) {
+ char vcname[sizeof("/dev/vcs") + DECIMAL_STR_MAX(unsigned) - 2];
+ int r;
- xsprintf(vcname, "/dev/vcs%i", idx);
- return access(vcname, F_OK) == 0;
+ xsprintf(vcname, "/dev/vcs%u", idx);
+ r = access(vcname, F_OK);
+ return r < 0 ? -errno : r;
}
-static bool is_allocated_byfd(int fd) {
+static int verify_vc_allocation_byfd(int fd) {
struct vt_stat vcs = {};
+ int r;
- if (ioctl(fd, VT_GETSTATE, &vcs) < 0) {
- log_warning_errno(errno, "VT_GETSTATE failed: %m");
- return false;
- }
- return is_allocated(vcs.v_active);
+ r = ioctl(fd, VT_GETSTATE, &vcs);
+ return r < 0 ? -errno : verify_vc_allocation(vcs.v_active);
}
-static bool is_settable(int fd) {
+static int verify_vc_kbmode(int fd) {
int r, curr_mode;
r = ioctl(fd, KDGKBMODE, &curr_mode);
@@ -82,7 +84,10 @@ static bool is_settable(int fd) {
*
* http://lists.freedesktop.org/archives/systemd-devel/2013-February/008573.html
*/
- return r == 0 && IN_SET(curr_mode, K_XLATE, K_UNICODE);
+ if (r < 0)
+ return -errno;
+
+ return IN_SET(curr_mode, K_XLATE, K_UNICODE) ? 0 : -EBUSY;
}
static int toggle_utf8(const char *name, int fd, bool utf8) {
@@ -101,10 +106,7 @@ static int toggle_utf8(const char *name, int fd, bool utf8) {
r = tcgetattr(fd, &tc);
if (r >= 0) {
- if (utf8)
- tc.c_iflag |= IUTF8;
- else
- tc.c_iflag &= ~IUTF8;
+ SET_FLAG(tc.c_iflag, IUTF8, utf8);
r = tcsetattr(fd, TCSANOW, &tc);
}
if (r < 0)
@@ -128,7 +130,7 @@ static int toggle_utf8_sysfs(bool utf8) {
static int keyboard_load_and_wait(const char *vc, const char *map, const char *map_toggle, bool utf8) {
_cleanup_free_ char *cmd = NULL;
const char *args[8];
- int i = 0;
+ unsigned i = 0;
pid_t pid;
/* An empty map means kernel map */
@@ -167,7 +169,7 @@ static int keyboard_load_and_wait(const char *vc, const char *map, const char *m
static int font_load_and_wait(const char *vc, const char *font, const char *map, const char *unimap) {
_cleanup_free_ char *cmd = NULL;
const char *args[9];
- int i = 0;
+ unsigned i = 0;
pid_t pid;
/* Any part can be set independently */
@@ -208,7 +210,7 @@ static int font_load_and_wait(const char *vc, const char *font, const char *map,
}
/*
- * A newly allocated VT uses the font from the active VT. Here
+ * A newly allocated VT uses the font from the source VT. Here
* we update all possibly already allocated VTs with the configured
* font. It also allows to restart systemd-vconsole-setup.service,
* to apply a new font to all VTs.
@@ -216,18 +218,18 @@ static int font_load_and_wait(const char *vc, const char *font, const char *map,
* We also setup per-console utf8 related stuff: kbdmode, term
* processing, stty iutf8.
*/
-static void setup_remaining_vcs(int fd, bool utf8) {
+static void setup_remaining_vcs(int src_fd, unsigned src_idx, bool utf8) {
struct console_font_op cfo = {
.op = KD_FONT_OP_GET,
.width = UINT_MAX, .height = UINT_MAX,
.charcount = UINT_MAX,
};
- struct vt_stat vcs = {};
struct unimapinit adv = {};
struct unimapdesc unimapd;
_cleanup_free_ struct unipair* unipairs = NULL;
_cleanup_free_ void *fontbuf = NULL;
- int i, r;
+ unsigned i;
+ int r;
unipairs = new(struct unipair, USHRT_MAX);
if (!unipairs) {
@@ -235,15 +237,8 @@ static void setup_remaining_vcs(int fd, bool utf8) {
return;
}
- /* get active, and 16 bit mask of used VT numbers */
- r = ioctl(fd, VT_GETSTATE, &vcs);
- if (r < 0) {
- log_warning_errno(errno, "VT_GETSTATE failed, ignoring remaining consoles: %m");
- return;
- }
-
/* get metadata of the current font (width, height, count) */
- r = ioctl(fd, KDFONTOP, &cfo);
+ r = ioctl(src_fd, KDFONTOP, &cfo);
if (r < 0)
log_warning_errno(errno, "KD_FONT_OP_GET failed while trying to get the font metadata: %m");
else {
@@ -263,15 +258,15 @@ static void setup_remaining_vcs(int fd, bool utf8) {
log_oom();
return;
}
- /* get fonts from source console */
+ /* get fonts from the source console */
cfo.data = fontbuf;
- r = ioctl(fd, KDFONTOP, &cfo);
+ r = ioctl(src_fd, KDFONTOP, &cfo);
if (r < 0)
log_warning_errno(errno, "KD_FONT_OP_GET failed while trying to read the font data: %m");
else {
unimapd.entries = unipairs;
unimapd.entry_ct = USHRT_MAX;
- r = ioctl(fd, GIO_UNIMAP, &unimapd);
+ r = ioctl(src_fd, GIO_UNIMAP, &unimapd);
if (r < 0)
log_warning_errno(errno, "GIO_UNIMAP failed while trying to read unicode mappings: %m");
else
@@ -284,21 +279,21 @@ static void setup_remaining_vcs(int fd, bool utf8) {
log_warning("Fonts will not be copied to remaining consoles");
for (i = 1; i <= 63; i++) {
- char ttyname[strlen("/dev/tty") + DECIMAL_STR_MAX(int)];
+ char ttyname[sizeof("/dev/tty63")];
_cleanup_close_ int fd_d = -1;
- if (i == vcs.v_active || !is_allocated(i))
+ if (i == src_idx || verify_vc_allocation(i) < 0)
continue;
/* try to open terminal */
- xsprintf(ttyname, "/dev/tty%i", i);
- fd_d = open_terminal(ttyname, O_RDWR|O_CLOEXEC);
+ xsprintf(ttyname, "/dev/tty%u", i);
+ fd_d = open_terminal(ttyname, O_RDWR|O_CLOEXEC|O_NOCTTY);
if (fd_d < 0) {
- log_warning_errno(fd_d, "Unable to open tty%i, fonts will not be copied: %m", i);
+ log_warning_errno(fd_d, "Unable to open tty%u, fonts will not be copied: %m", i);
continue;
}
- if (!is_settable(fd_d))
+ if (verify_vc_kbmode(fd_d) < 0)
continue;
toggle_utf8(ttyname, fd_d, utf8);
@@ -308,22 +303,24 @@ static void setup_remaining_vcs(int fd, bool utf8) {
r = ioctl(fd_d, KDFONTOP, &cfo);
if (r < 0) {
- log_warning_errno(errno, "KD_FONT_OP_SET failed, fonts will not be copied to tty%i: %m", i);
+ log_warning_errno(errno, "KD_FONT_OP_SET failed, fonts will not be copied to tty%u: %m", i);
continue;
}
- /* copy unicode translation table */
- /* unimapd is a ushort count and a pointer to an
- array of struct unipair { ushort, ushort } */
+ /*
+ * copy unicode translation table
+ * unimapd is a ushort count and a pointer to an
+ * array of struct unipair { ushort, ushort }
+ */
r = ioctl(fd_d, PIO_UNIMAPCLR, &adv);
if (r < 0) {
- log_warning_errno(errno, "PIO_UNIMAPCLR failed, unimaps might be incorrect for tty%i: %m", i);
+ log_warning_errno(errno, "PIO_UNIMAPCLR failed, unimaps might be incorrect for tty%u: %m", i);
continue;
}
r = ioctl(fd_d, PIO_UNIMAP, &unimapd);
if (r < 0) {
- log_warning_errno(errno, "PIO_UNIMAP failed, unimaps might be incorrect for tty%i: %m", i);
+ log_warning_errno(errno, "PIO_UNIMAP failed, unimaps might be incorrect for tty%u: %m", i);
continue;
}
@@ -331,13 +328,90 @@ static void setup_remaining_vcs(int fd, bool utf8) {
}
}
+static int find_source_vc(char **ret_path, unsigned *ret_idx) {
+ _cleanup_free_ char *path = NULL;
+ unsigned i;
+ int ret_fd, r, err = 0;
+
+ path = new(char, sizeof("/dev/tty63"));
+ if (path == NULL)
+ return log_oom();
+
+ for (i = 1; i <= 63; i++) {
+ _cleanup_close_ int fd = -1;
+
+ r = verify_vc_allocation(i);
+ if (r < 0) {
+ if (!err)
+ err = -r;
+ continue;
+ }
+
+ sprintf(path, "/dev/tty%u", i);
+ fd = open_terminal(path, O_RDWR|O_CLOEXEC|O_NOCTTY);
+ if (fd < 0) {
+ if (!err)
+ err = -fd;
+ continue;
+ }
+ r = verify_vc_kbmode(fd);
+ if (r < 0) {
+ if (!err)
+ err = -r;
+ continue;
+ }
+
+ /* all checks passed, return this one as a source console */
+ *ret_idx = i;
+ *ret_path = path;
+ path = NULL;
+ ret_fd = fd;
+ fd = -1;
+ return ret_fd;
+ }
+
+ return log_error_errno(err, "No usable source console found: %m");
+}
+
+static int verify_source_vc(char **ret_path, const char *src_vc) {
+ char *path;
+ _cleanup_close_ int fd = -1;
+ int ret_fd, r;
+
+ fd = open_terminal(src_vc, O_RDWR|O_CLOEXEC|O_NOCTTY);
+ if (fd < 0)
+ return log_error_errno(fd, "Failed to open %s: %m", src_vc);
+
+ r = verify_vc_device(fd);
+ if (r < 0)
+ return log_error_errno(r, "Device %s is not a virtual console: %m", src_vc);
+
+ r = verify_vc_allocation_byfd(fd);
+ if (r < 0)
+ return log_error_errno(r, "Virtual console %s is not allocated: %m", src_vc);
+
+ r = verify_vc_kbmode(fd);
+ if (r < 0)
+ 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)
+ return log_oom();
+
+ *ret_path = path;
+ ret_fd = fd;
+ fd = -1;
+ return ret_fd;
+}
+
int main(int argc, char **argv) {
- const char *vc;
_cleanup_free_ char
+ *vc = NULL,
*vc_keymap = NULL, *vc_keymap_toggle = NULL,
*vc_font = NULL, *vc_font_map = NULL, *vc_font_unimap = NULL;
_cleanup_close_ int fd = -1;
- bool utf8, font_copy = false, keyboard_ok;
+ bool utf8, keyboard_ok;
+ unsigned idx = 0;
int r;
log_set_target(LOG_TARGET_AUTO);
@@ -347,32 +421,12 @@ int main(int argc, char **argv) {
umask(0022);
if (argv[1])
- vc = argv[1];
- else {
- vc = "/dev/tty0";
- font_copy = true;
- }
-
- fd = open_terminal(vc, O_RDWR|O_CLOEXEC);
- if (fd < 0) {
- log_error_errno(fd, "Failed to open %s: %m", vc);
- return EXIT_FAILURE;
- }
+ fd = verify_source_vc(&vc, argv[1]);
+ else
+ fd = find_source_vc(&vc, &idx);
- if (!is_vconsole(fd)) {
- log_error("Device %s is not a virtual console.", vc);
+ if (fd < 0)
return EXIT_FAILURE;
- }
-
- if (!is_allocated_byfd(fd)) {
- log_error("Virtual console %s is not allocated.", vc);
- return EXIT_FAILURE;
- }
-
- if (!is_settable(fd)) {
- log_error("Virtual console %s is not in K_XLATE or K_UNICODE.", vc);
- return EXIT_FAILURE;
- }
utf8 = is_locale_utf8();
@@ -409,9 +463,9 @@ int main(int argc, char **argv) {
r = font_load_and_wait(vc, vc_font, vc_font_map, vc_font_unimap);
keyboard_ok = keyboard_load_and_wait(vc, vc_keymap, vc_keymap_toggle, utf8) == 0;
- if (font_copy) {
+ if (idx > 0) {
if (r == 0)
- setup_remaining_vcs(fd, utf8);
+ setup_remaining_vcs(fd, idx, utf8);
else if (r == EX_OSERR)
/* setfont returns EX_OSERR when ioctl(KDFONTOP/PIO_FONTX/PIO_FONTX) fails.
* This might mean various things, but in particular lack of a graphical
diff --git a/sysctl.d/meson.build b/sysctl.d/meson.build
new file mode 100644
index 0000000000..1b6707df77
--- /dev/null
+++ b/sysctl.d/meson.build
@@ -0,0 +1,21 @@
+install_data(
+ '50-default.conf',
+ install_dir : sysctldir)
+
+in_files = []
+
+if conf.get('ENABLE_COREDUMP', false)
+ in_files += ['50-coredump.conf']
+endif
+
+foreach file : in_files
+ gen = configure_file(
+ input : file + '.in',
+ output : file,
+ configuration : substs)
+ install_data(gen,
+ install_dir : sysctldir)
+endforeach
+
+meson.add_install_script('sh', '-c',
+ mkdir_p.format(join_paths(sysconfdir, 'sysctl.d')))
diff --git a/sysusers.d/basic.conf.in b/sysusers.d/basic.conf.in
index b2dc5ebd4f..7d6021e855 100644
--- a/sysusers.d/basic.conf.in
+++ b/sysusers.d/basic.conf.in
@@ -29,6 +29,7 @@ g dialout - - -
g disk - - -
g input - - -
g lp - - -
+g kvm - - -
g tape - - -
g video - - -
diff --git a/sysusers.d/meson.build b/sysusers.d/meson.build
new file mode 100644
index 0000000000..b7c02cf882
--- /dev/null
+++ b/sysusers.d/meson.build
@@ -0,0 +1,31 @@
+in_files = ['basic.conf']
+
+enable_sysusers = conf.get('ENABLE_SYSUSERS', false)
+
+foreach file : in_files
+ gen = configure_file(
+ input : file + '.in',
+ output : file,
+ configuration : substs)
+ if enable_sysusers
+ install_data(gen,
+ install_dir : sysusersdir)
+ endif
+endforeach
+
+m4_files = ['systemd.conf']
+
+if conf.get('ENABLE_REMOTE', false) and conf.get('HAVE_MICROHTTPD', false)
+ m4_files += ['systemd-remote.conf']
+endif
+
+foreach file : m4_files
+ custom_target(
+ 'sysusers.d_' + file,
+ input : file + '.m4',
+ output: file,
+ command : [m4, '-P'] + m4_defines + ['@INPUT@'],
+ capture : true,
+ install : enable_sysusers,
+ install_dir : sysusersdir)
+endforeach
diff --git a/test/README.testsuite b/test/README.testsuite
index fa7e73ce3a..58f67f50fd 100644
--- a/test/README.testsuite
+++ b/test/README.testsuite
@@ -3,7 +3,7 @@ subdirectories named "test/TEST-??-*", which are run one by one.
To run the extended testsuite do the following:
-$ make all
+$ make all # Avoid the "sudo make" below building anything as root
$ cd test
$ sudo make clean check
...
diff --git a/test/TEST-12-ISSUE-3171/test.sh b/test/TEST-12-ISSUE-3171/test.sh
index e20f470143..c252bdfbad 100755
--- a/test/TEST-12-ISSUE-3171/test.sh
+++ b/test/TEST-12-ISSUE-3171/test.sh
@@ -67,23 +67,23 @@ EOL
systemctl start test.socket
systemctl is-active test.socket
[[ "$(stat --format='%G' /run/test.socket)" == adm ]]
-echo A | nc -U /run/test.socket
+echo A | nc -w1 -U /run/test.socket
mv $U ${U}.disabled
systemctl daemon-reload
systemctl is-active test.socket
[[ "$(stat --format='%G' /run/test.socket)" == adm ]]
-echo B | nc -U /run/test.socket && exit 1
+echo B | nc -w1 -U /run/test.socket && exit 1
mv ${U}.disabled $U
systemctl daemon-reload
systemctl is-active test.socket
-echo C | nc -U /run/test.socket && exit 1
+echo C | nc -w1 -U /run/test.socket && exit 1
[[ "$(stat --format='%G' /run/test.socket)" == adm ]]
systemctl restart test.socket
systemctl is-active test.socket
-echo D | nc -U /run/test.socket
+echo D | nc -w1 -U /run/test.socket
[[ "$(stat --format='%G' /run/test.socket)" == adm ]]
diff --git a/test/create-sys-script.py b/test/create-sys-script.py
index 4b7abd24ae..402b4f83ab 100755
--- a/test/create-sys-script.py
+++ b/test/create-sys-script.py
@@ -1,6 +1,6 @@
-#!/usr/bin/python3
+#!/usr/bin/env python3
-OUTFILE_HEADER = """#!/usr/bin/python3
+OUTFILE_HEADER = """#!/usr/bin/env python3
#
# create-sys-script.py
#
diff --git a/test/meson.build b/test/meson.build
new file mode 100644
index 0000000000..55e693ac72
--- /dev/null
+++ b/test/meson.build
@@ -0,0 +1,167 @@
+test_data_files = '''
+ a.service
+ basic.target
+ b.service
+ c.service
+ daughter.service
+ d.service
+ end.service
+ e.service
+ f.service
+ grandchild.service
+ g.service
+ hello-after-sleep.target
+ hello.service
+ h.service
+ parent-deep.slice
+ parent.slice
+ sched_idle_bad.service
+ sched_idle_ok.service
+ sched_rr_bad.service
+ sched_rr_change.service
+ sched_rr_ok.service
+ shutdown.target
+ sleep.service
+ 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-environment-empty.service
+ test-execute/exec-environment-multiple.service
+ test-execute/exec-environment.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-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-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-privatedevices-no-capability-mknod.service
+ test-execute/exec-privatedevices-yes-capability-mknod.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-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-systemcallfilter-failing.service
+ test-execute/exec-systemcallfilter-not-failing2.service
+ test-execute/exec-systemcallfilter-not-failing.service
+ test-execute/exec-systemcallfilter-system-user.service
+ test-execute/exec-systemcallfilter-system-user-nfsnobody.service
+ test-execute/exec-user.service
+ test-execute/exec-user-nfsnobody.service
+ test-execute/exec-workingdirectory.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
+ bus-policy/hello.conf
+ bus-policy/methods.conf
+ bus-policy/ownerships.conf
+ bus-policy/signals.conf
+ bus-policy/check-own-rules.conf
+ bus-policy/many-rules.conf
+ bus-policy/test.conf
+ hwdb/10-bad.hwdb
+ journal-data/journal-1.txt
+ journal-data/journal-2.txt
+'''.split()
+
+if conf.get('ENABLE_RESOLVED', false)
+ test_data_files += '''
+ test-resolve/_openpgpkey.fedoraproject.org.pkts
+ test-resolve/fedoraproject.org.pkts
+ test-resolve/gandi.net.pkts
+ test-resolve/google.com.pkts
+ test-resolve/root.pkts
+ test-resolve/sw1a1aa-sw1a2aa-sw1a2ab-sw1a2ac.find.me.uk.pkts
+ test-resolve/teamits.com.pkts
+ test-resolve/zbyszek@fedoraproject.org.pkts
+ test-resolve/_443._tcp.fedoraproject.org.pkts
+ test-resolve/kyhwana.org.pkts
+ test-resolve/fake-caa.pkts
+ '''.split()
+endif
+
+if install_tests
+ foreach file : test_data_files
+ subdir = file.split('/')[0]
+ if subdir == file
+ subdir = ''
+ endif
+
+ install_data(file,
+ install_dir : testsdir + '/testdata/' + subdir)
+ endforeach
+endif
diff --git a/test/networkd-test.py b/test/networkd-test.py
index e0dddeb053..eee8b65ec0 100755
--- a/test/networkd-test.py
+++ b/test/networkd-test.py
@@ -96,10 +96,20 @@ class NetworkdTestingUtilities:
dropin_path = os.path.join(dropin_dir, "%s.conf" % dropin_name)
os.makedirs(dropin_dir, exist_ok=True)
+ self.addCleanup(os.rmdir, dropin_dir)
with open(dropin_path, 'w') as dropin:
dropin.write(contents)
self.addCleanup(os.remove, dropin_path)
+ def read_attr(self, link, attribute):
+ """Read a link attributed from the sysfs."""
+ # Note we we don't want to check if interface `link' is managed, we
+ # want to evaluate link variable and pass the value of the link to
+ # assert_link_states e.g. eth0=managed.
+ self.assert_link_states(**{link:'managed'})
+ with open(os.path.join('/sys/class/net', link, attribute)) as f:
+ return f.readline().strip()
+
def assert_link_states(self, **kwargs):
"""Match networkctl link states to the given ones.
@@ -140,6 +150,74 @@ class NetworkdTestingUtilities:
self.fail("Missing links in status output: %s" % interfaces)
+class BridgeTest(NetworkdTestingUtilities, unittest.TestCase):
+ """Provide common methods for testing networkd against servers."""
+
+ def setUp(self):
+ self.write_network('port1.netdev', '''\
+[NetDev]
+Name=port1
+Kind=dummy
+MACAddress=12:34:56:78:9a:bc''')
+ self.write_network('port2.netdev', '''\
+[NetDev]
+Name=port2
+Kind=dummy
+MACAddress=12:34:56:78:9a:bd''')
+ self.write_network('mybridge.netdev', '''\
+[NetDev]
+Name=mybridge
+Kind=bridge''')
+ self.write_network('port1.network', '''\
+[Match]
+Name=port1
+[Network]
+Bridge=mybridge''')
+ self.write_network('port2.network', '''\
+[Match]
+Name=port2
+[Network]
+Bridge=mybridge''')
+ self.write_network('mybridge.network', '''\
+[Match]
+Name=mybridge
+[Network]
+DNS=192.168.250.1
+Address=192.168.250.33/24
+Gateway=192.168.250.1''')
+ subprocess.check_call(['systemctl', 'start', 'systemd-networkd'])
+
+ def tearDown(self):
+ subprocess.check_call(['systemctl', 'stop', 'systemd-networkd'])
+ subprocess.check_call(['ip', 'link', 'del', 'mybridge'])
+ subprocess.check_call(['ip', 'link', 'del', 'port1'])
+ subprocess.check_call(['ip', 'link', 'del', 'port2'])
+
+ def test_bridge_init(self):
+ self.assert_link_states(
+ port1='managed',
+ port2='managed',
+ mybridge='managed')
+
+ def test_bridge_port_priority(self):
+ self.assertEqual(self.read_attr('port1', 'brport/priority'), '32')
+ self.write_network_dropin('port1.network', 'priority', '''\
+[Bridge]
+Priority=28
+''')
+ subprocess.check_call(['systemctl', 'restart', 'systemd-networkd'])
+ self.assertEqual(self.read_attr('port1', 'brport/priority'), '28')
+
+ def test_bridge_port_priority_set_zero(self):
+ """It should be possible to set the bridge port priority to 0"""
+ self.assertEqual(self.read_attr('port2', 'brport/priority'), '32')
+ self.write_network_dropin('port2.network', 'priority', '''\
+[Bridge]
+Priority=0
+''')
+ subprocess.check_call(['systemctl', 'restart', 'systemd-networkd'])
+ self.assertEqual(self.read_attr('port2', 'brport/priority'), '0')
+
class ClientTestBase(NetworkdTestingUtilities):
"""Provide common methods for testing networkd against servers."""
diff --git a/test/rule-syntax-check.py b/test/rule-syntax-check.py
index dab01f1d8a..14739df493 100755
--- a/test/rule-syntax-check.py
+++ b/test/rule-syntax-check.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python3
+#!/usr/bin/env python3
# Simple udev rules syntax checker
#
# (C) 2010 Canonical Ltd.
diff --git a/test/sys-script.py b/test/sys-script.py
index a9c0046667..6c9ee5ff83 100755
--- a/test/sys-script.py
+++ b/test/sys-script.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python3
+#!/usr/bin/env python3
#
# sys-script.py
#
diff --git a/test/sysv-generator-test.py b/test/sysv-generator-test.py
index 16ea65690a..d116fffe38 100755
--- a/test/sysv-generator-test.py
+++ b/test/sysv-generator-test.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python3
+#!/usr/bin/env python3
#
# systemd-sysv-generator integration test
#
diff --git a/test/test-efi-create-disk.sh b/test/test-efi-create-disk.sh
index cd4699dc18..0216c83c12 100755
--- a/test/test-efi-create-disk.sh
+++ b/test/test-efi-create-disk.sh
@@ -1,30 +1,38 @@
#!/bin/bash -e
+out="$1"
+systemd_efi="$2"
+boot_stub="$3"
+splash_bmp="$4"
+if [ -z "$out" -o -z "$systemd_efi" -o -z "$boot_stub" -o -z "$splash_bmp" ]; then
+ exit 1
+fi
+
# create GPT table with EFI System Partition
-rm -f test-efi-disk.img
-dd if=/dev/null of=test-efi-disk.img bs=1M seek=512 count=1
-parted --script test-efi-disk.img "mklabel gpt" "mkpart ESP fat32 1MiB 511MiB" "set 1 boot on"
+rm -f "$out"
+dd if=/dev/null of="$out" bs=1M seek=512 count=1 status=none
+parted --script "$out" "mklabel gpt" "mkpart ESP fat32 1MiB 511MiB" "set 1 boot on"
# create FAT32 file system
-LOOP=$(losetup --show -f -P test-efi-disk.img)
+LOOP=$(losetup --show -f -P "$out")
mkfs.vfat -F32 ${LOOP}p1
mkdir -p mnt
mount ${LOOP}p1 mnt
mkdir -p mnt/EFI/{BOOT,systemd}
-cp systemd-bootx64.efi mnt/EFI/BOOT/BOOTX64.efi
+cp "$systemd_efi" mnt/EFI/BOOT/BOOTX64.efi
[ -e /boot/shellx64.efi ] && cp /boot/shellx64.efi mnt/
mkdir mnt/EFI/Linux
-echo -n "foo=yes bar=no root=/dev/fakeroot debug rd.break=initqueue" > mnt/cmdline.txt
+echo -n "foo=yes bar=no root=/dev/fakeroot debug rd.break=initqueue" >mnt/cmdline.txt
objcopy \
- --add-section .osrel=/etc/os-release --change-section-vma .osrel=0x20000 \
- --add-section .cmdline=mnt/cmdline.txt --change-section-vma .cmdline=0x30000 \
- --add-section .splash=test/splash.bmp --change-section-vma .splash=0x40000 \
- --add-section .linux=/boot/$(cat /etc/machine-id)/$(uname -r)/linux --change-section-vma .linux=0x2000000 \
- --add-section .initrd=/boot/$(cat /etc/machine-id)/$(uname -r)/initrd --change-section-vma .initrd=0x3000000 \
- linuxx64.efi.stub mnt/EFI/Linux/linux-test.efi
+ --add-section .osrel=/etc/os-release --change-section-vma .osrel=0x20000 \
+ --add-section .cmdline=mnt/cmdline.txt --change-section-vma .cmdline=0x30000 \
+ --add-section .splash="$splash_bmp" --change-section-vma .splash=0x40000 \
+ --add-section .linux=/boot/$(cat /etc/machine-id)/$(uname -r)/linux --change-section-vma .linux=0x2000000 \
+ --add-section .initrd=/boot/$(cat /etc/machine-id)/$(uname -r)/initrd --change-section-vma .initrd=0x3000000 \
+ "$boot_stub" mnt/EFI/Linux/linux-test.efi
# install entries
mkdir -p mnt/loader/entries
diff --git a/test/test-exec-deserialization.py b/test/test-exec-deserialization.py
new file mode 100755
index 0000000000..39a9e62e15
--- /dev/null
+++ b/test/test-exec-deserialization.py
@@ -0,0 +1,192 @@
+#!/usr/bin/env python3
+
+#
+# Copyright 2017 Michal Sekletar <msekleta@redhat.com>
+#
+# 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/>.
+
+# ATTENTION: This uses the *installed* systemd, not the one from the built
+# source tree.
+
+import unittest
+import time
+import os
+import tempfile
+import subprocess
+
+from enum import Enum
+
+class UnitFileChange(Enum):
+ NO_CHANGE = 0
+ LINES_SWAPPED = 1
+ COMMAND_ADDED_BEFORE = 2
+ COMMAND_ADDED_AFTER = 3
+ COMMAND_INTERLEAVED = 4
+ REMOVAL = 5
+
+class ExecutionResumeTest(unittest.TestCase):
+ def setUp(self):
+ self.unit = 'test-issue-518.service'
+ self.unitfile_path = '/run/systemd/system/{0}'.format(self.unit)
+ self.output_file = tempfile.mktemp()
+ self.unit_files = {}
+
+ unit_file_content = '''
+ [Service]
+ Type=oneshot
+ ExecStart=/bin/sleep 2
+ ExecStart=/bin/bash -c "echo foo >> {0}"
+ '''.format(self.output_file)
+ self.unit_files[UnitFileChange.NO_CHANGE] = unit_file_content
+
+ unit_file_content = '''
+ [Service]
+ Type=oneshot
+ ExecStart=/bin/bash -c "echo foo >> {0}"
+ ExecStart=/bin/sleep 2
+ '''.format(self.output_file)
+ self.unit_files[UnitFileChange.LINES_SWAPPED] = unit_file_content
+
+ unit_file_content = '''
+ [Service]
+ Type=oneshot
+ ExecStart=/bin/bash -c "echo bar >> {0}"
+ ExecStart=/bin/sleep 2
+ ExecStart=/bin/bash -c "echo foo >> {0}"
+ '''.format(self.output_file)
+ self.unit_files[UnitFileChange.COMMAND_ADDED_BEFORE] = unit_file_content
+
+ unit_file_content = '''
+ [Service]
+ Type=oneshot
+ ExecStart=/bin/sleep 2
+ ExecStart=/bin/bash -c "echo foo >> {0}"
+ ExecStart=/bin/bash -c "echo bar >> {0}"
+ '''.format(self.output_file)
+ self.unit_files[UnitFileChange.COMMAND_ADDED_AFTER] = unit_file_content
+
+ unit_file_content = '''
+ [Service]
+ Type=oneshot
+ ExecStart=/bin/bash -c "echo baz >> {0}"
+ ExecStart=/bin/sleep 2
+ ExecStart=/bin/bash -c "echo foo >> {0}"
+ ExecStart=/bin/bash -c "echo bar >> {0}"
+ '''.format(self.output_file)
+ self.unit_files[UnitFileChange.COMMAND_INTERLEAVED] = unit_file_content
+
+ unit_file_content = '''
+ [Service]
+ Type=oneshot
+ ExecStart=/bin/bash -c "echo bar >> {0}"
+ ExecStart=/bin/bash -c "echo baz >> {0}"
+ '''.format(self.output_file)
+ self.unit_files[UnitFileChange.REMOVAL] = unit_file_content
+
+ def reload(self):
+ subprocess.check_call(['systemctl', 'daemon-reload'])
+
+ def write_unit_file(self, unit_file_change):
+ if not isinstance(unit_file_change, UnitFileChange):
+ raise ValueError('Unknown unit file change')
+
+ content = self.unit_files[unit_file_change]
+
+ with open(self.unitfile_path, 'w') as f:
+ f.write(content)
+
+ self.reload()
+
+ def check_output(self, expected_output):
+ try:
+ with open(self.output_file, 'r') as log:
+ output = log.read()
+ except IOError:
+ self.fail()
+
+ self.assertEqual(output, expected_output)
+
+ def setup_unit(self):
+ self.write_unit_file(UnitFileChange.NO_CHANGE)
+ subprocess.check_call(['systemctl', '--job-mode=replace', '--no-block', 'start', self.unit])
+
+ def test_no_change(self):
+ expected_output = 'foo\n'
+
+ self.setup_unit()
+ self.reload()
+ time.sleep(4)
+
+ self.check_output(expected_output)
+
+ def test_swapped(self):
+ expected_output = ''
+
+ self.setup_unit()
+ self.write_unit_file(UnitFileChange.LINES_SWAPPED)
+ self.reload()
+ time.sleep(4)
+
+ self.assertTrue(not os.path.exists(self.output_file))
+
+ def test_added_before(self):
+ expected_output = 'foo\n'
+
+ self.setup_unit()
+ self.write_unit_file(UnitFileChange.COMMAND_ADDED_BEFORE)
+ self.reload()
+ time.sleep(4)
+
+ self.check_output(expected_output)
+
+ def test_added_after(self):
+ expected_output = 'foo\nbar\n'
+
+ self.setup_unit()
+ self.write_unit_file(UnitFileChange.COMMAND_ADDED_AFTER)
+ self.reload()
+ time.sleep(4)
+
+ self.check_output(expected_output)
+
+ def test_interleaved(self):
+ expected_output = 'foo\nbar\n'
+
+ self.setup_unit()
+ self.write_unit_file(UnitFileChange.COMMAND_INTERLEAVED)
+ self.reload()
+ time.sleep(4)
+
+ self.check_output(expected_output)
+
+ def test_removal(self):
+ self.setup_unit()
+ self.write_unit_file(UnitFileChange.REMOVAL)
+ self.reload()
+ time.sleep(4)
+
+ self.assertTrue(not os.path.exists(self.output_file))
+
+ def tearDown(self):
+ for f in [self.output_file, self.unitfile_path]:
+ try:
+ os.remove(f)
+ except OSError:
+ # ignore error if log file doesn't exist
+ pass
+
+ self.reload()
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/test/test-execute/exec-inaccessiblepaths-mount-propagation.service b/test/test-execute/exec-inaccessiblepaths-mount-propagation.service
index 23c6ff3f93..430a6b78c2 100644
--- a/test/test-execute/exec-inaccessiblepaths-mount-propagation.service
+++ b/test/test-execute/exec-inaccessiblepaths-mount-propagation.service
@@ -3,5 +3,5 @@ Description=Test to make sure that InaccessiblePaths= disconnect mount propagati
[Service]
InaccessiblePaths=-/i-dont-exist
-ExecStart=/bin/sh -x -c 'mkdir -p /TEST; mount -t tmpfs tmpfs /TEST; grep TEST /proc/self/mountinfo && ! grep TEST /proc/$${PPID}/mountinfo && ! grep TEST /proc/1/mountinfo'
+ExecStart=/bin/sh -x -c 'd=$$(mktemp -d -p /tmp); trap "umount \'$$d\' && rmdir \'$$d\'" EXIT; mount -t tmpfs tmpfs "$$d"; grep "$$d" /proc/self/mountinfo && ! grep "$$d" /proc/$${PPID}/mountinfo && ! grep "$$d" /proc/1/mountinfo'
Type=oneshot
diff --git a/test/test-execute/exec-inaccessiblepaths-proc.service b/test/test-execute/exec-inaccessiblepaths-proc.service
new file mode 100644
index 0000000000..ebdb4843d1
--- /dev/null
+++ b/test/test-execute/exec-inaccessiblepaths-proc.service
@@ -0,0 +1,7 @@
+[Unit]
+Description=Test to make sure that mount namespace setup works properly with the 'InaccessiblePaths=/proc' option
+
+[Service]
+InaccessiblePaths=/proc
+ExecStart=/bin/sh -x -c 'test "$$(stat -c %%a /proc)" = "0"'
+Type=oneshot
diff --git a/test/test-execute/exec-protectkernelmodules-yes-mount-propagation.service b/test/test-execute/exec-protectkernelmodules-yes-mount-propagation.service
index e438783df3..07758121cd 100644
--- a/test/test-execute/exec-protectkernelmodules-yes-mount-propagation.service
+++ b/test/test-execute/exec-protectkernelmodules-yes-mount-propagation.service
@@ -3,5 +3,5 @@ Description=Test to make sure that passing ProtectKernelModules=yes disconnect m
[Service]
ProtectKernelModules=yes
-ExecStart=/bin/sh -x -c 'mkdir -p /TEST; mount -t tmpfs tmpfs /TEST; grep TEST /proc/self/mountinfo && ! grep TEST /proc/$${PPID}/mountinfo && ! grep TEST /proc/1/mountinfo'
+ExecStart=/bin/sh -x -c 'd=$$(mktemp -d -p /tmp); trap "umount \'$$d\' && rmdir \'$$d\'" EXIT; mount -t tmpfs tmpfs "$$d"; grep "$$d" /proc/self/mountinfo && ! grep "$$d" /proc/$${PPID}/mountinfo && ! grep "$$d" /proc/1/mountinfo'
Type=oneshot
diff --git a/test/test-execute/exec-readonlypaths-mount-propagation.service b/test/test-execute/exec-readonlypaths-mount-propagation.service
index 237cbb2efb..7edb0daa36 100644
--- a/test/test-execute/exec-readonlypaths-mount-propagation.service
+++ b/test/test-execute/exec-readonlypaths-mount-propagation.service
@@ -3,5 +3,5 @@ Description=Test to make sure that passing ReadOnlyPaths= disconnect mount propa
[Service]
ReadOnlyPaths=-/i-dont-exist
-ExecStart=/bin/sh -x -c 'mkdir -p /TEST; mount -t tmpfs tmpfs /TEST; grep TEST /proc/self/mountinfo && ! grep TEST /proc/$${PPID}/mountinfo && ! grep TEST /proc/1/mountinfo'
+ExecStart=/bin/sh -x -c 'd=$$(mktemp -d -p /tmp); trap "umount \'$$d\' && rmdir \'$$d\'" EXIT; mount -t tmpfs tmpfs "$$d"; grep "$$d" /proc/self/mountinfo && ! grep "$$d" /proc/$${PPID}/mountinfo && ! grep "$$d" /proc/1/mountinfo'
Type=oneshot
diff --git a/test/test-execute/exec-readwritepaths-mount-propagation.service b/test/test-execute/exec-readwritepaths-mount-propagation.service
index 466ce6c747..b38978df42 100644
--- a/test/test-execute/exec-readwritepaths-mount-propagation.service
+++ b/test/test-execute/exec-readwritepaths-mount-propagation.service
@@ -3,5 +3,5 @@ Description=Test to make sure that passing ReadWritePaths= disconnect mount prop
[Service]
ReadWritePaths=-/i-dont-exist
-ExecStart=/bin/sh -x -c 'mkdir -p /TEST; mount -t tmpfs tmpfs /TEST; grep TEST /proc/self/mountinfo && ! grep TEST /proc/$${PPID}/mountinfo && ! grep TEST /proc/1/mountinfo'
+ExecStart=/bin/sh -x -c 'd=$$(mktemp -d -p /tmp); trap "umount \'$$d\' && rmdir \'$$d\'" EXIT; mount -t tmpfs tmpfs "$$d"; grep "$$d" /proc/self/mountinfo && ! grep "$$d" /proc/$${PPID}/mountinfo && ! grep "$$d" /proc/1/mountinfo'
Type=oneshot
diff --git a/test/test-functions b/test/test-functions
index fd7c198166..ea4f700841 100644
--- a/test/test-functions
+++ b/test/test-functions
@@ -6,12 +6,13 @@ export PATH
LOOKS_LIKE_DEBIAN=$(source /etc/os-release && [[ "$ID" = "debian" || "$ID_LIKE" = "debian" ]] && echo yes)
LOOKS_LIKE_ARCH=$(source /etc/os-release && [[ "$ID" = "arch" ]] && echo yes)
+LOOKS_LIKE_SUSE=$(source /etc/os-release && [[ "$ID_LIKE" = "suse" ]] && echo yes)
KERNEL_VER=${KERNEL_VER-$(uname -r)}
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
-FSTYPE="${FSTYPE:-ext3}"
+[[ "$LOOKS_LIKE_SUSE" ]] && FSTYPE="${FSTYPE:-btrfs}" || FSTYPE="${FSTYPE:-ext3}"
UNIFIED_CGROUP_HIERARCHY="${UNIFIED_CGROUP_HIERARCHY:-default}"
if ! ROOTLIBDIR=$(pkg-config --variable=systemdutildir systemd); then
@@ -73,6 +74,7 @@ run_qemu() {
default_fedora_initrd=/boot/initramfs-${KERNEL_VER}.img
default_debian_initrd=/boot/initrd.img-${KERNEL_VER}
default_arch_initrd=/boot/initramfs-linux.img
+ default_suse_initrd=/boot/initrd-${KERNEL_VER}
if [[ ! "$INITRD" ]]; then
if [[ -e "$default_fedora_initrd" ]]; then
INITRD="$default_fedora_initrd"
@@ -80,6 +82,8 @@ run_qemu() {
INITRD="$default_debian_initrd"
elif [[ "$LOOKS_LIKE_ARCH" && -e "$default_arch_initrd" ]]; then
INITRD="$default_arch_initrd"
+ elif [[ "$LOOKS_LIKE_SUSE" && -e "$default_suse_initrd" ]]; then
+ INITRD="$default_suse_initrd"
fi
fi
@@ -99,11 +103,17 @@ run_qemu() {
exit 1
fi
- KERNEL_APPEND="root=/dev/sda1 \
+if [[ "$LOOKS_LIKE_SUSE" ]]; then
+ PARAMS+="rd.hostonly=0"
+else
+ PARAMS+="ro"
+fi
+
+KERNEL_APPEND="$PARAMS \
+root=/dev/sda1 \
raid=noautodetect \
loglevel=2 \
init=$ROOTLIBDIR/systemd \
-ro \
console=ttyS0 \
selinux=0 \
$_cgroup_args \
@@ -314,6 +324,8 @@ install_systemd() {
# and it could fill the available space
strip_binaries
+ [[ "$LOOKS_LIKE_SUSE" ]] && setup_suse
+
# enable debug logging in PID1
echo LogLevel=debug >> $initdir/etc/systemd/system.conf
}
@@ -442,8 +454,14 @@ install_config_files() {
# set the hostname
echo systemd-testsuite > $initdir/etc/hostname
# fstab
+ if [[ "$LOOKS_LIKE_SUSE" ]]; then
+ ROOTMOUNT="/dev/sda1 / ${FSTYPE} rw 0 1"
+ else
+ ROOTMOUNT="LABEL=systemd / ${FSTYPE} rw 0 1"
+ fi
+
cat >$initdir/etc/fstab <<EOF
-LABEL=systemd / ${FSTYPE} rw 0 1
+$ROOTMOUNT
EOF
}
@@ -1336,6 +1354,12 @@ inst_libdir_file() {
fi
}
+setup_suse() {
+ ln -s ../usr/bin/systemctl $initdir/bin/systemctl
+ ln -s ../usr/lib/systemd $initdir/lib/systemd
+ inst_simple "/usr/lib/systemd/system/haveged.service"
+}
+
do_test() {
if [[ $UID != "0" ]]; then
echo "TEST: $TEST_DESCRIPTION [SKIPPED]: not root" >&2
diff --git a/tmpfiles.d/.gitignore b/tmpfiles.d/.gitignore
index 4f0ecaa9c3..73c62c1045 100644
--- a/tmpfiles.d/.gitignore
+++ b/tmpfiles.d/.gitignore
@@ -1,2 +1,4 @@
/etc.conf
/systemd.conf
+/systemd-remote.conf
+/var.conf
diff --git a/tmpfiles.d/meson.build b/tmpfiles.d/meson.build
new file mode 100644
index 0000000000..29efe21f9d
--- /dev/null
+++ b/tmpfiles.d/meson.build
@@ -0,0 +1,51 @@
+enable_tmpfiles = conf.get('ENABLE_TMPFILES', false)
+
+tmpfiles = [['home.conf', ''],
+ ['journal-nocow.conf', ''],
+ ['systemd-nologin.conf', ''],
+ ['systemd-nspawn.conf', ''],
+ ['tmp.conf', ''],
+ ['x11.conf', ''],
+ ['legacy.conf', 'HAVE_SYSV_COMPAT'],
+ ]
+
+foreach pair : tmpfiles
+ if not enable_tmpfiles
+ # do nothing
+ elif pair[1] == '' or conf.get(pair[1], false)
+ install_data(pair[0], install_dir : tmpfilesdir)
+ else
+ message('Not installing tmpfiles.d/@0@ because @1@ is @2@'
+ .format(pair[0], pair[1], conf.get(pair[1], 0)))
+ endif
+endforeach
+
+m4_files = [['etc.conf', ''],
+ ['systemd.conf', ''],
+ ['systemd-remote.conf', 'ENABLE_REMOTE'],
+ ['var.conf', ''],
+ ]
+
+foreach pair : m4_files
+ if not enable_tmpfiles
+ # do nothing
+ elif pair[1] == '' or conf.get(pair[1], false)
+ custom_target(
+ 'tmpfiles.d_' + pair[0],
+ input : pair[0] + '.m4',
+ output: pair[0],
+ command : [m4, '-P'] + m4_defines + ['@INPUT@'],
+ capture : true,
+ install : true,
+ install_dir : tmpfilesdir)
+ else
+ message('Not installing tmpfiles.d/@0@.m4 because @1@ is @2@'
+ .format(pair[0], pair[1], conf.get(pair[1], 0)))
+ endif
+endforeach
+
+if enable_tmpfiles
+ meson.add_install_script(
+ 'sh', '-c',
+ mkdir_p.format(join_paths(sysconfdir, 'tmpfiles.d')))
+endif
diff --git a/tmpfiles.d/systemd-remote.conf b/tmpfiles.d/systemd-remote.conf.m4
index e19230f648..7a0f698c11 100644
--- a/tmpfiles.d/systemd-remote.conf
+++ b/tmpfiles.d/systemd-remote.conf.m4
@@ -6,8 +6,12 @@
# (at your option) any later version.
# See tmpfiles.d(5) for details
+m4_ifdef(`HAVE_LIBCURL',
d /var/lib/systemd/journal-upload 0755 systemd-journal-upload systemd-journal-upload - -
+)m4_dnl
+m4_ifdef(`HAVE_MICROHTTPD',
z /var/log/journal/remote 2755 systemd-journal-remote systemd-journal-remote - -
z /run/log/journal/remote 2755 systemd-journal-remote systemd-journal-remote - -
+)m4_dnl
diff --git a/tmpfiles.d/var.conf b/tmpfiles.d/var.conf.m4
index ae7952e77a..e640fcd8c0 100644
--- a/tmpfiles.d/var.conf
+++ b/tmpfiles.d/var.conf.m4
@@ -12,8 +12,11 @@ q /var 0755 - - -
L /var/run - - - - ../run
d /var/log 0755 - - -
+m4_ifdef(`HAVE_UTMP',
f /var/log/wtmp 0664 root utmp -
f /var/log/btmp 0600 root utmp -
+f /var/log/lastlog 0664 root utmp -
+)m4_dnl
d /var/cache 0755 - - -
diff --git a/tools/catalog-report.py b/tools/catalog-report.py
index b220060cc8..357e498cdc 100644..100755
--- a/tools/catalog-report.py
+++ b/tools/catalog-report.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python3
+#!/usr/bin/env python3
# -*- Mode: python; coding: utf-8; indent-tabs-mode: nil -*- */
#
# This file is part of systemd. It is distrubuted under the MIT license, see
diff --git a/tools/gdb-sd_dump_hashmaps.py b/tools/gdb-sd_dump_hashmaps.py
index d20016e005..62ce8006f5 100644
--- a/tools/gdb-sd_dump_hashmaps.py
+++ b/tools/gdb-sd_dump_hashmaps.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python3
+#!/usr/bin/env python3
# -*- Mode: python; coding: utf-8; indent-tabs-mode: nil -*- */
#
# This file is part of systemd.
diff --git a/tools/make-directive-index.py b/tools/make-directive-index.py
index 8ce09ca2fa..1b287997fa 100755
--- a/tools/make-directive-index.py
+++ b/tools/make-directive-index.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python3
+#!/usr/bin/env python3
# -*- Mode: python; coding: utf-8; indent-tabs-mode: nil -*- */
#
# This file is part of systemd.
diff --git a/tools/make-man-index.py b/tools/make-man-index.py
index 50ad9532cd..abc33e7394 100755
--- a/tools/make-man-index.py
+++ b/tools/make-man-index.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python3
+#!/usr/bin/env python3
# -*- Mode: python; coding: utf-8; indent-tabs-mode: nil -*- */
#
# This file is part of systemd.
diff --git a/tools/make-man-rules.py b/tools/make-man-rules.py
index 18aa513952..e9e39f10af 100644..100755
--- a/tools/make-man-rules.py
+++ b/tools/make-man-rules.py
@@ -1,9 +1,9 @@
-#!/usr/bin/python3
+#!/usr/bin/env python3
# -*- Mode: python; coding: utf-8; indent-tabs-mode: nil -*- */
#
# This file is part of systemd.
#
-# Copyright 2013 Zbigniew Jędrzejewski-Szmek
+# Copyright 2013, 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
@@ -22,6 +22,7 @@ from __future__ import print_function
import collections
import sys
import os.path
+import pprint
from xml_helper import *
SECTION = '''\
@@ -66,11 +67,13 @@ EXTRA_DIST += \\
{dist_files}
'''
+meson = False
+
def man(page, number):
- return 'man/{}.{}'.format(page, number)
+ return ('man/' if not meson else '') + '{}.{}'.format(page, number)
def xml(file):
- return 'man/{}'.format(os.path.basename(file))
+ return ('man/' if not meson else '') + os.path.basename(file)
def add_rules(rules, name):
xml = xml_parse(name)
@@ -122,9 +125,40 @@ def make_makefile(rules, dist_files):
for conditional,rulegroup in sorted(rules.items())
) + FOOTER.format(dist_files=mjoin(sorted(dist_files)))
+MESON_HEADER = '''\
+# Do not edit. Generated by make-man-rules.py.
+manpages = ['''
+
+MESON_FOOTER = '''\
+]
+# Really, do not edit.'''
+
+def make_mesonfile(rules, dist_files):
+ # reformat rules as
+ # grouped = [ [name, section, [alias...], condition], ...]
+ #
+ # but first create a dictionary like
+ # lists = { (name, condition) => [alias...]
+ grouped = collections.defaultdict(list)
+ for condition, items in rules.items():
+ for alias, name in items.items():
+ group = grouped[(name, condition)]
+ if name != alias:
+ group.append(alias)
+
+ lines = [ [p[0][:-2], p[0][-1], sorted(a[:-2] for a in aliases), p[1]]
+ for p, aliases in sorted(grouped.items()) ]
+ return '\n'.join((MESON_HEADER, pprint.pformat(lines)[1:-1], MESON_FOOTER))
+
if __name__ == '__main__':
- rules = create_rules(sys.argv[1:])
- dist_files = (xml(file) for file in sys.argv[1:]
+ meson = sys.argv[1] == '--meson'
+ pages = sys.argv[1+meson:]
+
+ rules = create_rules(pages)
+ dist_files = (xml(file) for file in pages
if not file.endswith(".directives.xml") and
not file.endswith(".index.xml"))
- print(make_makefile(rules, dist_files), end='')
+ if meson:
+ print(make_mesonfile(rules, dist_files))
+ else:
+ print(make_makefile(rules, dist_files), end='')
diff --git a/tools/meson-check-compilation.sh b/tools/meson-check-compilation.sh
new file mode 100755
index 0000000000..d3b2a312fd
--- /dev/null
+++ b/tools/meson-check-compilation.sh
@@ -0,0 +1,3 @@
+#!/bin/sh -eu
+
+"$@" '-' -o/dev/null </dev/null
diff --git a/tools/meson-check-help.sh b/tools/meson-check-help.sh
new file mode 100755
index 0000000000..47a5099a04
--- /dev/null
+++ b/tools/meson-check-help.sh
@@ -0,0 +1,20 @@
+#!/bin/sh -eu
+
+# output width
+if "$1" --help | grep -v 'default:' | grep -E -q '.{80}.'; then
+ echo "$(basename "$1") --help output is too wide:"
+ "$1" --help | awk 'length > 80' | grep -E --color=yes '.{80}'
+ exit 1
+fi
+
+# no --help output to stdout
+if "$1" --help 2>&1 1>/dev/null | grep .; then
+ echo "$(basename "$1") --help prints to stderr"
+ exit 2
+fi
+
+# error output to stderr
+if ! "$1" --no-such-parameter 2>&1 1>/dev/null | grep -q .; then
+ echo "$(basename "$1") with an unknown parameter does not print to stderr"
+ exit 3
+fi
diff --git a/tools/meson-git-contrib.sh b/tools/meson-git-contrib.sh
new file mode 100755
index 0000000000..c543b3a5fa
--- /dev/null
+++ b/tools/meson-git-contrib.sh
@@ -0,0 +1,8 @@
+#!/bin/sh -eu
+
+git shortlog -s `git describe --abbrev=0`.. | \
+ cut -c8- | \
+ sed 's/ / /g' | \
+ awk '{ print $$0 "," }' | \
+ sed -e 's/ / /g' | \
+ sort -u
diff --git a/tools/meson-hwdb-update.sh b/tools/meson-hwdb-update.sh
new file mode 100755
index 0000000000..4c919073bb
--- /dev/null
+++ b/tools/meson-hwdb-update.sh
@@ -0,0 +1,15 @@
+#!/bin/sh -eu
+
+cd "$1"
+
+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'
+curl -L -o ma-medium.txt 'http://standards-oui.ieee.org/oui28/mam.txt'
+curl -L -o ma-small.txt 'http://standards-oui.ieee.org/oui36/oui36.txt'
+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'
+./ids-update.pl
+./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
diff --git a/tools/meson-link-test.c b/tools/meson-link-test.c
new file mode 100644
index 0000000000..825bbff05f
--- /dev/null
+++ b/tools/meson-link-test.c
@@ -0,0 +1 @@
+int main(void) {return 0;}
diff --git a/tools/meson-make-symlink.sh b/tools/meson-make-symlink.sh
new file mode 100755
index 0000000000..47a5e70ae5
--- /dev/null
+++ b/tools/meson-make-symlink.sh
@@ -0,0 +1,11 @@
+#!/bin/sh -eu
+
+# this is needed mostly because $DESTDIR is provided as a variable,
+# and we need to create the target directory...
+
+mkdir -vp "$(dirname "${DESTDIR:-}$2")"
+if [ "$(dirname $1)" = . ]; then
+ ln -vfs -T "$1" "${DESTDIR:-}$2"
+else
+ ln -vfs -T --relative "${DESTDIR:-}$1" "${DESTDIR:-}$2"
+fi
diff --git a/tools/xml_helper.py b/tools/xml_helper.py
index b2c036909d..0088be5bd9 100644..100755
--- a/tools/xml_helper.py
+++ b/tools/xml_helper.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python3
+#!/usr/bin/env python3
# -*- Mode: python; coding: utf-8; indent-tabs-mode: nil -*- */
#
# This file is part of systemd.
diff --git a/units/console-getty.service.m4.in b/units/console-getty.service.m4.in
index 413d94094b..d9d0cba4d9 100644
--- a/units/console-getty.service.m4.in
+++ b/units/console-getty.service.m4.in
@@ -16,7 +16,10 @@ After=rc-local.service
Before=getty.target
[Service]
-ExecStart=-/sbin/agetty --noclear --keep-baud console 115200,38400,9600 $TERM
+# The '-o' option value tells agetty to replace 'login' arguments with an
+# option to preserve environment (-p), followed by '--' for safety, and then
+# the entered username.
+ExecStart=-/sbin/agetty -o '-p -- \\u' --noclear --keep-baud console 115200,38400,9600 $TERM
Type=idle
Restart=always
RestartSec=0
diff --git a/units/container-getty@.service.m4.in b/units/container-getty@.service.m4.in
index e126f3a489..fd0be86ba7 100644
--- a/units/container-getty@.service.m4.in
+++ b/units/container-getty@.service.m4.in
@@ -17,7 +17,10 @@ IgnoreOnIsolate=yes
ConditionPathExists=/dev/pts/%I
[Service]
-ExecStart=-/sbin/agetty --noclear --keep-baud pts/%I 115200,38400,9600 $TERM
+# The '-o' option value tells agetty to replace 'login' arguments with an
+# option to preserve environment (-p), followed by '--' for safety, and then
+# the entered username.
+ExecStart=-/sbin/agetty -o '-p -- \\u' --noclear --keep-baud pts/%I 115200,38400,9600 $TERM
Type=idle
Restart=always
RestartSec=0
diff --git a/units/dev-hugepages.mount b/units/dev-hugepages.mount
index 489cc777e4..86ad7ac2c9 100644
--- a/units/dev-hugepages.mount
+++ b/units/dev-hugepages.mount
@@ -8,7 +8,7 @@
[Unit]
Description=Huge Pages File System
Documentation=https://www.kernel.org/doc/Documentation/vm/hugetlbpage.txt
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
DefaultDependencies=no
Before=sysinit.target
ConditionPathExists=/sys/kernel/mm/hugepages
diff --git a/units/dev-mqueue.mount b/units/dev-mqueue.mount
index 8d29f96ca6..b2adfeb835 100644
--- a/units/dev-mqueue.mount
+++ b/units/dev-mqueue.mount
@@ -8,7 +8,7 @@
[Unit]
Description=POSIX Message Queue File System
Documentation=man:mq_overview(7)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
DefaultDependencies=no
Before=sysinit.target
ConditionPathExists=/proc/sys/fs/mqueue
diff --git a/units/emergency.service.in b/units/emergency.service.in
index da68eb8faa..e9eb238b98 100644
--- a/units/emergency.service.in
+++ b/units/emergency.service.in
@@ -17,9 +17,7 @@ Before=shutdown.target
[Service]
Environment=HOME=/root
WorkingDirectory=-/root
-ExecStartPre=-/bin/plymouth --wait quit
-ExecStartPre=-/bin/echo -e 'You are in emergency mode. After logging in, type "journalctl -xb" to view\\nsystem logs, "systemctl reboot" to reboot, "systemctl default" or ^D to\\ntry again to boot into default mode.'
-ExecStart=-/bin/sh -c "@SULOGIN@; @SYSTEMCTL@ --job-mode=fail --no-block default"
+ExecStart=-@rootlibexecdir@/systemd-sulogin-shell emergency
Type=idle
StandardInput=tty-force
StandardOutput=inherit
diff --git a/units/getty@.service.m4 b/units/getty@.service.m4
index 5b82c13fc5..2a84061ed6 100644
--- a/units/getty@.service.m4
+++ b/units/getty@.service.m4
@@ -33,7 +33,10 @@ ConditionPathExists=/dev/tty0
[Service]
# the VT is cleared by TTYVTDisallocate
-ExecStart=-/sbin/agetty --noclear %I $TERM
+# The '-o' option value tells agetty to replace 'login' arguments with an
+# option to preserve environment (-p), followed by '--' for safety, and then
+# the entered username.
+ExecStart=-/sbin/agetty -o '-p -- \\u' --noclear %I $TERM
Type=idle
Restart=always
RestartSec=0
diff --git a/units/meson-add-wants.sh b/units/meson-add-wants.sh
new file mode 100755
index 0000000000..dfd287e172
--- /dev/null
+++ b/units/meson-add-wants.sh
@@ -0,0 +1,27 @@
+#!/bin/sh -eu
+
+unitdir="$1"
+target="$2"
+unit="$3"
+
+case "$target" in
+ */?*) # a path, but not just a slash at the end
+ dir="${DESTDIR:-}${target}"
+ ;;
+ *)
+ dir="${DESTDIR:-}${unitdir}/${target}"
+ ;;
+esac
+
+unitpath="${DESTDIR:-}${unitdir}/${unit}"
+
+case "$target" in
+ */)
+ mkdir -p -m 0755 "$dir"
+ ;;
+ *)
+ mkdir -p -m 0755 "$(basename "$dir")"
+ ;;
+esac
+
+ln -vfs --relative "$unitpath" "$dir"
diff --git a/units/meson.build b/units/meson.build
new file mode 100644
index 0000000000..e94add6a6f
--- /dev/null
+++ b/units/meson.build
@@ -0,0 +1,329 @@
+units = [
+ ['basic.target', ''],
+ ['bluetooth.target', ''],
+ ['cryptsetup-pre.target', 'HAVE_LIBCRYPTSETUP'],
+ ['cryptsetup.target', 'HAVE_LIBCRYPTSETUP',
+ 'sysinit.target.wants/'],
+ ['dev-hugepages.mount', '',
+ 'sysinit.target.wants/'],
+ ['dev-mqueue.mount', '',
+ 'sysinit.target.wants/'],
+ ['emergency.target', ''],
+ ['exit.target', ''],
+ ['final.target', ''],
+ ['getty.target', '',
+ 'multi-user.target.wants/'],
+ ['graphical.target', '',
+ 'runlevel5.target default.target'],
+ ['halt.target', ''],
+ ['hibernate.target', 'ENABLE_HIBERNATE'],
+ ['hybrid-sleep.target', 'ENABLE_HIBERNATE'],
+ ['initrd-fs.target', ''],
+ ['initrd-root-device.target', ''],
+ ['initrd-root-fs.target', ''],
+ ['initrd-switch-root.target', ''],
+ ['initrd.target', ''],
+ ['kexec.target', ''],
+ ['ldconfig.service', 'ENABLE_LDCONFIG',
+ 'sysinit.target.wants/'],
+ ['local-fs-pre.target', ''],
+ ['local-fs.target', ''],
+ ['machine.slice', 'ENABLE_MACHINED'],
+ ['machines.target', 'ENABLE_MACHINED',
+ join_paths(pkgsysconfdir, 'system/multi-user.target.wants/')],
+ ['multi-user.target', '',
+ 'runlevel2.target runlevel3.target runlevel4.target'],
+ ['network-online.target', ''],
+ ['network-pre.target', ''],
+ ['network.target', ''],
+ ['nss-lookup.target', ''],
+ ['nss-user-lookup.target', ''],
+ ['paths.target', ''],
+ ['poweroff.target', '',
+ 'runlevel0.target'],
+ ['printer.target', ''],
+ ['proc-sys-fs-binfmt_misc.automount', 'ENABLE_BINFMT',
+ 'sysinit.target.wants/'],
+ ['proc-sys-fs-binfmt_misc.mount', 'ENABLE_BINFMT'],
+ ['reboot.target', '',
+ 'runlevel6.target ctrl-alt-del.target'],
+ ['remote-fs-pre.target', ''],
+ ['remote-fs.target', '',
+ join_paths(pkgsysconfdir, 'system/multi-user.target.wants/')],
+ ['rescue.target', '',
+ 'runlevel1.target'],
+ ['rpcbind.target', ''],
+ ['shutdown.target', ''],
+ ['sigpwr.target', ''],
+ ['sleep.target', ''],
+ ['slices.target', ''],
+ ['smartcard.target', ''],
+ ['sockets.target', ''],
+ ['sound.target', ''],
+ ['suspend.target', ''],
+ ['swap.target', ''],
+ ['sys-fs-fuse-connections.mount', '',
+ 'sysinit.target.wants/'],
+ ['sys-kernel-config.mount', '',
+ 'sysinit.target.wants/'],
+ ['sys-kernel-debug.mount', '',
+ 'sysinit.target.wants/'],
+ ['sysinit.target', ''],
+ ['syslog.socket', ''],
+ ['system-update.target', ''],
+ ['system.slice', ''],
+ ['systemd-ask-password-console.path', '',
+ 'sysinit.target.wants/'],
+ ['systemd-ask-password-wall.path', '',
+ 'multi-user.target.wants/'],
+ ['systemd-coredump.socket', 'ENABLE_COREDUMP',
+ 'sockets.target.wants/'],
+ ['systemd-initctl.socket', '',
+ 'sockets.target.wants/'],
+ ['systemd-journal-gatewayd.socket', 'ENABLE_REMOTE HAVE_MICROHTTPD'],
+ ['systemd-journal-remote.socket', 'ENABLE_REMOTE HAVE_MICROHTTPD'],
+ ['systemd-journald-audit.socket', '',
+ 'sockets.target.wants/'],
+ ['systemd-journald-dev-log.socket', '',
+ 'sockets.target.wants/'],
+ ['systemd-journald.socket', '',
+ 'sockets.target.wants/'],
+ ['systemd-networkd.socket', '',
+ join_paths(pkgsysconfdir, 'system/sockets.target.wants/')],
+ ['systemd-rfkill.socket', 'ENABLE_RFKILL'],
+ ['systemd-tmpfiles-clean.timer', '',
+ 'timers.target.wants/'],
+ ['systemd-udevd-control.socket', '',
+ 'sockets.target.wants/'],
+ ['systemd-udevd-kernel.socket', '',
+ 'sockets.target.wants/'],
+ ['time-sync.target', ''],
+ ['timers.target', ''],
+ ['umount.target', ''],
+ ['user.slice', ''],
+ ['var-lib-machines.mount', 'ENABLE_MACHINED',
+ 'remote-fs.target.wants/ machines.target.wants/'],
+]
+
+in_units = [
+ ['debug-shell.service', ''],
+ ['emergency.service', ''],
+ ['halt-local.service', 'HAVE_SYSV_COMPAT'],
+ ['initrd-cleanup.service', ''],
+ ['initrd-parse-etc.service', ''],
+ ['initrd-switch-root.service', ''],
+ ['initrd-udevadm-cleanup-db.service', ''],
+ ['kmod-static-nodes.service', 'HAVE_KMOD ENABLE_TMPFILES',
+ 'sysinit.target.wants/'],
+ ['quotaon.service', 'ENABLE_QUOTACHECK'],
+ ['rc-local.service', 'HAVE_SYSV_COMPAT'],
+ ['rescue.service', ''],
+ ['system-update-cleanup.service', ''],
+ ['systemd-ask-password-console.service', ''],
+ ['systemd-ask-password-wall.service', ''],
+ ['systemd-backlight@.service', 'ENABLE_BACKLIGHT'],
+ ['systemd-binfmt.service', 'ENABLE_BINFMT',
+ 'sysinit.target.wants/'],
+ ['systemd-coredump@.service', 'ENABLE_COREDUMP'],
+ ['systemd-exit.service', ''],
+ ['systemd-firstboot.service', 'ENABLE_FIRSTBOOT',
+ 'sysinit.target.wants/'],
+ ['systemd-fsck-root.service', ''],
+ ['systemd-fsck@.service', ''],
+ ['systemd-halt.service', ''],
+ ['systemd-hibernate-resume@.service', 'ENABLE_HIBERNATE'],
+ ['systemd-hibernate.service', 'ENABLE_HIBERNATE'],
+ ['systemd-hybrid-sleep.service', 'ENABLE_HIBERNATE'],
+ ['systemd-hostnamed.service', 'ENABLE_HOSTNAMED',
+ 'dbus-org.freedesktop.hostname1.service'],
+ ['systemd-hwdb-update.service', 'ENABLE_HWDB',
+ 'sysinit.target.wants/'],
+ ['systemd-importd.service', 'ENABLE_IMPORTD',
+ 'dbus-org.freedesktop.import1.service'],
+ ['systemd-initctl.service', ''],
+ ['systemd-journal-catalog-update.service', '',
+ 'sysinit.target.wants/'],
+ ['systemd-journal-flush.service', '',
+ 'sysinit.target.wants/'],
+ ['systemd-journal-gatewayd.service', 'ENABLE_REMOTE HAVE_MICROHTTPD'],
+ ['systemd-journal-remote.service', 'ENABLE_REMOTE HAVE_MICROHTTPD'],
+ ['systemd-journal-upload.service', 'ENABLE_REMOTE HAVE_LIBCURL'],
+ ['systemd-journald.service', '',
+ 'sysinit.target.wants/'],
+ ['systemd-kexec.service', ''],
+ ['systemd-localed.service', 'ENABLE_LOCALED',
+ 'dbus-org.freedesktop.locale1.service'],
+ ['systemd-logind.service', 'ENABLE_LOGIND',
+ 'multi-user.target.wants/ dbus-org.freedesktop.login1.service'],
+ ['systemd-machine-id-commit.service', '',
+ 'sysinit.target.wants/'],
+ ['systemd-machined.service', 'ENABLE_MACHINED',
+ 'dbus-org.freedesktop.machine1.service'],
+ ['systemd-modules-load.service', 'HAVE_KMOD',
+ 'sysinit.target.wants/'],
+ ['systemd-networkd-wait-online.service', 'ENABLE_NETWORKD',
+ join_paths(pkgsysconfdir, 'system/network-online.target.wants/')],
+ ['systemd-nspawn@.service', ''],
+ ['systemd-poweroff.service', ''],
+ ['systemd-quotacheck.service', 'ENABLE_QUOTACHECK'],
+ ['systemd-random-seed.service', 'ENABLE_RANDOMSEED',
+ 'sysinit.target.wants/'],
+ ['systemd-reboot.service', ''],
+ ['systemd-remount-fs.service', '',
+ 'local-fs.target.wants/'],
+ ['systemd-rfkill.service', 'ENABLE_RFKILL'],
+ ['systemd-suspend.service', ''],
+ ['systemd-sysctl.service', '',
+ 'sysinit.target.wants/'],
+ ['systemd-sysusers.service', 'ENABLE_SYSUSERS',
+ 'sysinit.target.wants/'],
+ ['systemd-timedated.service', 'ENABLE_TIMEDATED',
+ 'dbus-org.freedesktop.timedate1.service'],
+ ['systemd-timesyncd.service', 'ENABLE_TIMESYNCD',
+ join_paths(pkgsysconfdir, 'system/sysinit.target.wants/')],
+ ['systemd-tmpfiles-clean.service', 'ENABLE_TMPFILES'],
+ ['systemd-tmpfiles-setup-dev.service', 'ENABLE_TMPFILES',
+ 'sysinit.target.wants/'],
+ ['systemd-tmpfiles-setup.service', 'ENABLE_TMPFILES',
+ 'sysinit.target.wants/'],
+ ['systemd-udev-settle.service', ''],
+ ['systemd-udev-trigger.service', '',
+ 'sysinit.target.wants/'],
+ ['systemd-udevd.service', '',
+ 'sysinit.target.wants/'],
+ ['systemd-update-done.service', '',
+ 'sysinit.target.wants/'],
+ ['systemd-update-utmp-runlevel.service', 'HAVE_UTMP HAVE_SYSV_COMPAT',
+ 'multi-user.target.wants/ graphical.target.wants/ rescue.target.wants/'],
+ ['systemd-update-utmp.service', 'HAVE_UTMP',
+ 'sysinit.target.wants/'],
+ ['systemd-user-sessions.service', '',
+ 'multi-user.target.wants/'],
+ ['systemd-vconsole-setup.service', 'ENABLE_VCONSOLE'],
+ ['systemd-volatile-root.service', ''],
+]
+
+m4_units = [
+ ['getty@.service', '',
+ 'autovt@.service ' +
+ join_paths(pkgsysconfdir, 'system/getty.target.wants/getty@tty1.service')],
+ ['serial-getty@.service', ''],
+ ['tmp.mount', '',
+ 'local-fs.target.wants/'],
+]
+
+m4_in_units = [
+ ['console-getty.service', ''],
+ ['container-getty@.service', ''],
+ ['systemd-networkd.service', 'ENABLE_NETWORKD',
+ join_paths(pkgsysconfdir, 'system/dbus-org.freedesktop.network1.service') + ' ' +
+ join_paths(pkgsysconfdir, 'system/multi-user.target.wants/')],
+ ['systemd-resolved.service', 'ENABLE_RESOLVED',
+ join_paths(pkgsysconfdir, 'system/dbus-org.freedesktop.resolve1.service') + ' ' +
+ join_paths(pkgsysconfdir, 'system/multi-user.target.wants/')],
+ ['user@.service', ''],
+]
+
+foreach tuple : m4_in_units
+ file = tuple[0]
+
+ gen = configure_file(
+ input : file + '.m4.in',
+ output : file + '.m4',
+ configuration : substs)
+
+ m4_units += [[file, tuple.get(1, ''), tuple.get(2, ''), gen]]
+endforeach
+
+foreach tuple : in_units
+ file = tuple[0]
+
+ # we do this here because install_data does not accept custom_target output
+ conds = tuple[1].split(' ')
+ install = ((conds.get(0, '') == '' or conf.get(conds[0], false)) and
+ (conds.get(1, '') == '' or conf.get(conds[1], false)))
+
+ gen1 = configure_file(
+ input : file + '.in',
+ output : file + '.tmp',
+ configuration : substs)
+ gen2 = custom_target(
+ file,
+ input : gen1,
+ output : file,
+ command : [sed, '/^## /d', '@INPUT@'],
+ capture : true,
+ install : install,
+ install_dir : systemunitdir)
+
+ if install and tuple.length() > 2
+ foreach target : tuple[2].split()
+ meson.add_install_script('meson-add-wants.sh', systemunitdir, target, file)
+ endforeach
+ endif
+endforeach
+
+foreach tuple : m4_units
+ file = tuple[0]
+ input = tuple.get(3, file + '.m4')
+
+ # we do this here because install_data does not accept custom_target output
+ conds = tuple[1].split(' ')
+ install = ((conds.get(0, '') == '' or conf.get(conds[0], false)) and
+ (conds.get(1, '') == '' or conf.get(conds[1], false)))
+
+ custom_target(
+ file,
+ input : input,
+ output: file,
+ command : [m4, '-P'] + m4_defines + ['@INPUT@'],
+ capture : true,
+ install : install,
+ install_dir : systemunitdir)
+
+ if tuple.length() > 2 and install
+ foreach target : tuple[2].split()
+ meson.add_install_script('meson-add-wants.sh', systemunitdir, target, file)
+ endforeach
+ endif
+endforeach
+
+foreach tuple : units
+ file = tuple[0]
+ input = tuple.get(3, file)
+
+ conds = tuple[1].split(' ')
+ install = ((conds.get(0, '') == '' or conf.get(conds[0], false)) and
+ (conds.get(1, '') == '' or conf.get(conds[1], false)))
+
+ if install
+ install_data(input,
+ install_dir : systemunitdir)
+
+ if tuple.length() > 2
+ foreach target : tuple[2].split()
+ meson.add_install_script(
+ 'meson-add-wants.sh', systemunitdir, target, file)
+ endforeach
+ endif
+ endif
+endforeach
+
+############################################################
+
+meson.add_install_script(meson_make_symlink,
+ join_paths(pkgsysconfdir, 'user'),
+ join_paths(sysconfdir, 'xdg/systemd/user'))
+meson.add_install_script(meson_make_symlink,
+ join_paths(dbussystemservicedir, 'org.freedesktop.systemd1.service'),
+ join_paths(dbussessionservicedir, 'org.freedesktop.systemd1.service'))
+if conf.get('HAVE_SYSV_COMPAT', false)
+ foreach i : [1, 2, 3, 4, 5]
+ meson.add_install_script(
+ 'sh', '-c',
+ mkdir_p
+ .format(join_paths(systemunitdir, 'runlevel@0@.target.wants'.format(i))))
+ endforeach
+endif
+
+subdir('user')
diff --git a/units/network-online.target b/units/network-online.target
index 67bc4fa471..5130d8c5e3 100644
--- a/units/network-online.target
+++ b/units/network-online.target
@@ -8,5 +8,5 @@
[Unit]
Description=Network is Online
Documentation=man:systemd.special(7)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/NetworkTarget
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/NetworkTarget
After=network.target
diff --git a/units/network-pre.target b/units/network-pre.target
index 0ea4bc739a..0d54a4cff8 100644
--- a/units/network-pre.target
+++ b/units/network-pre.target
@@ -8,5 +8,5 @@
[Unit]
Description=Network (Pre)
Documentation=man:systemd.special(7)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/NetworkTarget
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/NetworkTarget
RefuseManualStart=yes
diff --git a/units/network.target b/units/network.target
index 61ebdcadd0..f8331b6124 100644
--- a/units/network.target
+++ b/units/network.target
@@ -8,6 +8,6 @@
[Unit]
Description=Network
Documentation=man:systemd.special(7)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/NetworkTarget
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/NetworkTarget
After=network-pre.target
RefuseManualStart=yes
diff --git a/units/org.freedesktop.hostname1.busname b/units/org.freedesktop.hostname1.busname
index d64c36486d..f7b41331bf 100644
--- a/units/org.freedesktop.hostname1.busname
+++ b/units/org.freedesktop.hostname1.busname
@@ -8,7 +8,7 @@
[Unit]
Description=Hostname Service Bus Name
Documentation=man:systemd-hostnamed.service(8) man:hostname(5) man:machine-info(5)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/hostnamed
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/hostnamed
[BusName]
Service=systemd-hostnamed.service
diff --git a/units/org.freedesktop.locale1.busname b/units/org.freedesktop.locale1.busname
index 3cd201180b..e0c498e8ff 100644
--- a/units/org.freedesktop.locale1.busname
+++ b/units/org.freedesktop.locale1.busname
@@ -8,7 +8,7 @@
[Unit]
Description=Locale Service Bus Name
Documentation=man:systemd-localed.service(8) man:locale.conf(5) man:vconsole.conf(5)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/localed
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/localed
[BusName]
Service=systemd-localed.service
diff --git a/units/org.freedesktop.login1.busname b/units/org.freedesktop.login1.busname
index d0686b17e0..b169720f8e 100644
--- a/units/org.freedesktop.login1.busname
+++ b/units/org.freedesktop.login1.busname
@@ -8,8 +8,8 @@
[Unit]
Description=Login Service Bus Name
Documentation=man:systemd-logind.service(8) man:logind.conf(5)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/logind
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/logind
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/multiseat
[BusName]
Service=systemd-logind.service
diff --git a/units/org.freedesktop.machine1.busname b/units/org.freedesktop.machine1.busname
index 7df8e9e732..a1f0154778 100644
--- a/units/org.freedesktop.machine1.busname
+++ b/units/org.freedesktop.machine1.busname
@@ -8,7 +8,7 @@
[Unit]
Description=Virtual Machine and Container Registration Service Bus Name
Documentation=man:systemd-machined.service(8)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/machined
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/machined
[BusName]
Service=systemd-machined.service
diff --git a/units/org.freedesktop.resolve1.busname b/units/org.freedesktop.resolve1.busname
index 5b7a7fed3f..28c8f97037 100644
--- a/units/org.freedesktop.resolve1.busname
+++ b/units/org.freedesktop.resolve1.busname
@@ -8,7 +8,7 @@
[Unit]
Description=Network Name Resolution Service Bus Name
Documentation=man:systemd-resolved.service(8)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/resolved
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/resolved
# This is pulled in by systemd-resolved.service, since it cannot run
# without its policy set. However, let's conditionalize this unit on
diff --git a/units/org.freedesktop.systemd1.busname b/units/org.freedesktop.systemd1.busname
index 9ec055e3f2..f9f41cbaf0 100644
--- a/units/org.freedesktop.systemd1.busname
+++ b/units/org.freedesktop.systemd1.busname
@@ -8,7 +8,7 @@
[Unit]
Description=System and Service Manager Bus Name
Documentation=man:systemd(1)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd
+Documentation=https://www.freedesktop.org/wiki/Software/systemd
[BusName]
Activating=no
diff --git a/units/org.freedesktop.timedate1.busname b/units/org.freedesktop.timedate1.busname
index eae4e536b8..1c962b5f8a 100644
--- a/units/org.freedesktop.timedate1.busname
+++ b/units/org.freedesktop.timedate1.busname
@@ -8,7 +8,7 @@
[Unit]
Description=Time & Date Service Bus Name
Documentation=man:systemd-timedated.service(8) man:localtime(5)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/timedated
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/timedated
[BusName]
Service=systemd-timedated.service
diff --git a/units/proc-sys-fs-binfmt_misc.automount b/units/proc-sys-fs-binfmt_misc.automount
index 6be38937b1..1067bcd839 100644
--- a/units/proc-sys-fs-binfmt_misc.automount
+++ b/units/proc-sys-fs-binfmt_misc.automount
@@ -7,8 +7,8 @@
[Unit]
Description=Arbitrary Executable File Formats File System Automount Point
-Documentation=https://www.kernel.org/doc/Documentation/binfmt_misc.txt
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
+Documentation=https://www.kernel.org/doc/html/latest/admin-guide/binfmt-misc.html
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
DefaultDependencies=no
Before=sysinit.target
ConditionPathExists=/proc/sys/fs/binfmt_misc/
diff --git a/units/proc-sys-fs-binfmt_misc.mount b/units/proc-sys-fs-binfmt_misc.mount
index 8c7c386318..27773cd4ea 100644
--- a/units/proc-sys-fs-binfmt_misc.mount
+++ b/units/proc-sys-fs-binfmt_misc.mount
@@ -7,8 +7,8 @@
[Unit]
Description=Arbitrary Executable File Formats File System
-Documentation=https://www.kernel.org/doc/Documentation/binfmt_misc.txt
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
+Documentation=https://www.kernel.org/doc/html/latest/admin-guide/binfmt-misc.html
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
DefaultDependencies=no
[Mount]
diff --git a/units/quotaon.service.in b/units/quotaon.service.in
index 7d59a40195..f3e1e270c9 100644
--- a/units/quotaon.service.in
+++ b/units/quotaon.service.in
@@ -10,7 +10,7 @@ Description=Enable File System Quotas
Documentation=man:quotaon(8)
DefaultDependencies=no
After=systemd-quotacheck.service
-Before=local-fs.target shutdown.target
+Before=remote-fs.target shutdown.target
ConditionPathExists=@QUOTAON@
[Service]
diff --git a/units/rescue.service.in b/units/rescue.service.in
index 5feff69c89..4ab66f4856 100644
--- a/units/rescue.service.in
+++ b/units/rescue.service.in
@@ -16,9 +16,7 @@ Before=shutdown.target
[Service]
Environment=HOME=/root
WorkingDirectory=-/root
-ExecStartPre=-/bin/plymouth --wait quit
-ExecStartPre=-/bin/echo -e 'You are in rescue mode. After logging in, type "journalctl -xb" to view\\nsystem logs, "systemctl reboot" to reboot, "systemctl default" or ^D to\\nboot into default mode.'
-ExecStart=-/bin/sh -c "@SULOGIN@; @SYSTEMCTL@ --job-mode=fail --no-block default"
+ExecStart=-@rootlibexecdir@/systemd-sulogin-shell rescue
Type=idle
StandardInput=tty-force
StandardOutput=inherit
diff --git a/units/serial-getty@.service.m4 b/units/serial-getty@.service.m4
index 4522d0d2be..b7caeaff44 100644
--- a/units/serial-getty@.service.m4
+++ b/units/serial-getty@.service.m4
@@ -21,8 +21,17 @@ After=rc-local.service
Before=getty.target
IgnoreOnIsolate=yes
+# IgnoreOnIsolate causes issues with sulogin, if someone isolates
+# rescue.target or starts rescue.service from multi-user.target or
+# graphical.target.
+Conflicts=rescue.service
+Before=rescue.service
+
[Service]
-ExecStart=-/sbin/agetty --keep-baud 115200,38400,9600 %I $TERM
+# The '-o' option value tells agetty to replace 'login' arguments with an
+# option to preserve environment (-p), followed by '--' for safety, and then
+# the entered username.
+ExecStart=-/sbin/agetty -o '-p -- \\u' --keep-baud 115200,38400,9600 %I $TERM
Type=idle
Restart=always
UtmpIdentifier=%I
diff --git a/units/sys-fs-fuse-connections.mount b/units/sys-fs-fuse-connections.mount
index 336b5f6277..492ceb16f3 100644
--- a/units/sys-fs-fuse-connections.mount
+++ b/units/sys-fs-fuse-connections.mount
@@ -8,7 +8,7 @@
[Unit]
Description=FUSE Control File System
Documentation=https://www.kernel.org/doc/Documentation/filesystems/fuse.txt
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
DefaultDependencies=no
ConditionPathExists=/sys/fs/fuse/connections
ConditionCapability=CAP_SYS_ADMIN
diff --git a/units/sys-kernel-config.mount b/units/sys-kernel-config.mount
index 21648eff6a..b585f32561 100644
--- a/units/sys-kernel-config.mount
+++ b/units/sys-kernel-config.mount
@@ -6,9 +6,9 @@
# (at your option) any later version.
[Unit]
-Description=Configuration File System
+Description=Kernel Configuration File System
Documentation=https://www.kernel.org/doc/Documentation/filesystems/configfs/configfs.txt
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
DefaultDependencies=no
ConditionPathExists=/sys/kernel/config
ConditionCapability=CAP_SYS_RAWIO
diff --git a/units/sys-kernel-debug.mount b/units/sys-kernel-debug.mount
index 1e94387bac..808dbf08f4 100644
--- a/units/sys-kernel-debug.mount
+++ b/units/sys-kernel-debug.mount
@@ -6,9 +6,9 @@
# (at your option) any later version.
[Unit]
-Description=Debug File System
+Description=Kernel Debug File System
Documentation=https://www.kernel.org/doc/Documentation/filesystems/debugfs.txt
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
DefaultDependencies=no
ConditionPathExists=/sys/kernel/debug
ConditionCapability=CAP_SYS_RAWIO
diff --git a/units/syslog.socket b/units/syslog.socket
index e6e9cf8525..d3987cb9a8 100644
--- a/units/syslog.socket
+++ b/units/syslog.socket
@@ -8,7 +8,7 @@
[Unit]
Description=Syslog Socket
Documentation=man:systemd.special(7)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/syslog
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/syslog
DefaultDependencies=no
Before=sockets.target shutdown.target
@@ -37,4 +37,4 @@ ReceiveBuffer=8M
# [Install]
# Alias=syslog.service
#
-# See http://www.freedesktop.org/wiki/Software/systemd/syslog for details.
+# See https://www.freedesktop.org/wiki/Software/systemd/syslog for details.
diff --git a/units/systemd-ask-password-console.service.in b/units/systemd-ask-password-console.service.in
index a24fa51903..adaa60da87 100644
--- a/units/systemd-ask-password-console.service.in
+++ b/units/systemd-ask-password-console.service.in
@@ -16,3 +16,4 @@ ConditionPathExists=!/run/plymouth/pid
[Service]
ExecStart=@rootbindir@/systemd-tty-ask-password-agent --watch --console
+SystemCallArchitectures=native
diff --git a/units/systemd-ask-password-wall.service.in b/units/systemd-ask-password-wall.service.in
index 0eaa274794..be380023a7 100644
--- a/units/systemd-ask-password-wall.service.in
+++ b/units/systemd-ask-password-wall.service.in
@@ -13,3 +13,4 @@ After=systemd-user-sessions.service
[Service]
ExecStartPre=-@SYSTEMCTL@ stop systemd-ask-password-console.path systemd-ask-password-console.service systemd-ask-password-plymouth.path systemd-ask-password-plymouth.service
ExecStart=@rootbindir@/systemd-tty-ask-password-agent --wall
+SystemCallArchitectures=native
diff --git a/units/systemd-coredump@.service.in b/units/systemd-coredump@.service.in
index 588c8d629c..18f2d2d605 100644
--- a/units/systemd-coredump@.service.in
+++ b/units/systemd-coredump@.service.in
@@ -19,6 +19,19 @@ Before=shutdown.target
ExecStart=-@rootlibexecdir@/systemd-coredump
Nice=9
OOMScoreAdjust=500
-PrivateNetwork=yes
-ProtectSystem=full
RuntimeMaxSec=5min
+PrivateTmp=yes
+PrivateDevices=yes
+PrivateNetwork=yes
+ProtectSystem=strict
+ProtectHome=yes
+ProtectControlGroups=yes
+ProtectKernelTunables=yes
+ProtectKernelModules=yes
+MemoryDenyWriteExecute=yes
+RestrictRealtime=yes
+RestrictNamespaces=yes
+RestrictAddressFamilies=AF_UNIX
+SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module @mount @obsolete @raw-io @reboot @swap
+SystemCallArchitectures=native
+ReadWritePaths=/var/lib/systemd/coredump
diff --git a/units/systemd-hostnamed.service.in b/units/systemd-hostnamed.service.in
index edc5a1722a..d29e9ff81b 100644
--- a/units/systemd-hostnamed.service.in
+++ b/units/systemd-hostnamed.service.in
@@ -8,7 +8,7 @@
[Unit]
Description=Hostname Service
Documentation=man:systemd-hostnamed.service(8) man:hostname(5) man:machine-info(5)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/hostnamed
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/hostnamed
[Service]
ExecStart=@rootlibexecdir@/systemd-hostnamed
@@ -18,11 +18,15 @@ CapabilityBoundingSet=CAP_SYS_ADMIN
PrivateTmp=yes
PrivateDevices=yes
PrivateNetwork=yes
-ProtectSystem=yes
+ProtectSystem=strict
ProtectHome=yes
ProtectControlGroups=yes
ProtectKernelTunables=yes
+ProtectKernelModules=yes
MemoryDenyWriteExecute=yes
RestrictRealtime=yes
+RestrictNamespaces=yes
RestrictAddressFamilies=AF_UNIX
-SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module @mount @obsolete @raw-io
+SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module @mount @obsolete @raw-io @reboot @swap
+SystemCallArchitectures=native
+ReadWritePaths=/etc
diff --git a/units/systemd-importd.service.in b/units/systemd-importd.service.in
index ac27c2bcba..58762055eb 100644
--- a/units/systemd-importd.service.in
+++ b/units/systemd-importd.service.in
@@ -8,7 +8,7 @@
[Unit]
Description=Virtual Machine and Container Download Service
Documentation=man:systemd-importd.service(8)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/importd
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/importd
[Service]
ExecStart=@rootlibexecdir@/systemd-importd
@@ -19,5 +19,7 @@ CapabilityBoundingSet=CAP_CHOWN CAP_FOWNER CAP_FSETID CAP_MKNOD CAP_SETFCAP CAP_
NoNewPrivileges=yes
MemoryDenyWriteExecute=yes
RestrictRealtime=yes
+RestrictNamespaces=net
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
-SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module @obsolete @raw-io
+SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module @obsolete @raw-io @reboot @swap
+SystemCallArchitectures=native
diff --git a/units/systemd-initctl.service.in b/units/systemd-initctl.service.in
index 27e663c8dc..5505309e92 100644
--- a/units/systemd-initctl.service.in
+++ b/units/systemd-initctl.service.in
@@ -11,5 +11,6 @@ Documentation=man:systemd-initctl.service(8)
DefaultDependencies=no
[Service]
-ExecStart=@rootlibexecdir@/systemd-initctl
NotifyAccess=all
+ExecStart=@rootlibexecdir@/systemd-initctl
+SystemCallArchitectures=native
diff --git a/units/systemd-journal-gatewayd.service.in b/units/systemd-journal-gatewayd.service.in
index efefaa4244..99099967e7 100644
--- a/units/systemd-journal-gatewayd.service.in
+++ b/units/systemd-journal-gatewayd.service.in
@@ -18,13 +18,16 @@ SupplementaryGroups=systemd-journal
PrivateTmp=yes
PrivateDevices=yes
PrivateNetwork=yes
-ProtectSystem=full
+ProtectSystem=strict
ProtectHome=yes
ProtectControlGroups=yes
ProtectKernelTunables=yes
+ProtectKernelModules=yes
MemoryDenyWriteExecute=yes
RestrictRealtime=yes
+RestrictNamespaces=yes
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
+SystemCallArchitectures=native
# If there are many split upjournal files we need a lot of fds to
# access them all and combine
diff --git a/units/systemd-journal-remote.service.in b/units/systemd-journal-remote.service.in
index 753dd6c158..5404bf1c03 100644
--- a/units/systemd-journal-remote.service.in
+++ b/units/systemd-journal-remote.service.in
@@ -18,13 +18,17 @@ WatchdogSec=3min
PrivateTmp=yes
PrivateDevices=yes
PrivateNetwork=yes
-ProtectSystem=full
+ProtectSystem=strict
ProtectHome=yes
ProtectControlGroups=yes
ProtectKernelTunables=yes
+ProtectKernelModules=yes
MemoryDenyWriteExecute=yes
RestrictRealtime=yes
+RestrictNamespaces=yes
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
+SystemCallArchitectures=native
+ReadWritePaths=/var/log/journal/remote
[Install]
Also=systemd-journal-remote.socket
diff --git a/units/systemd-journal-upload.service.in b/units/systemd-journal-upload.service.in
index d8fd243620..d00b929211 100644
--- a/units/systemd-journal-upload.service.in
+++ b/units/systemd-journal-upload.service.in
@@ -18,13 +18,17 @@ SupplementaryGroups=systemd-journal
WatchdogSec=3min
PrivateTmp=yes
PrivateDevices=yes
-ProtectSystem=full
+ProtectSystem=strict
ProtectHome=yes
ProtectControlGroups=yes
ProtectKernelTunables=yes
+ProtectKernelModules=yes
MemoryDenyWriteExecute=yes
RestrictRealtime=yes
+RestrictNamespaces=yes
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
+SystemCallArchitectures=native
+ReadWritePaths=/var/lib/systemd/journal-upload
# If there are many split up journal files we need a lot of fds to
# access them all and combine
diff --git a/units/systemd-journald.service.in b/units/systemd-journald.service.in
index 712ce55483..1e86d63648 100644
--- a/units/systemd-journald.service.in
+++ b/units/systemd-journald.service.in
@@ -19,15 +19,16 @@ Sockets=systemd-journald.socket systemd-journald-dev-log.socket systemd-journald
ExecStart=@rootlibexecdir@/systemd-journald
Restart=always
RestartSec=0
-NotifyAccess=all
StandardOutput=null
WatchdogSec=3min
-FileDescriptorStoreMax=1024
+FileDescriptorStoreMax=4224
CapabilityBoundingSet=CAP_SYS_ADMIN CAP_DAC_OVERRIDE CAP_SYS_PTRACE CAP_SYSLOG CAP_AUDIT_CONTROL CAP_AUDIT_READ CAP_CHOWN CAP_DAC_READ_SEARCH CAP_FOWNER CAP_SETUID CAP_SETGID CAP_MAC_OVERRIDE
MemoryDenyWriteExecute=yes
RestrictRealtime=yes
+RestrictNamespaces=yes
RestrictAddressFamilies=AF_UNIX AF_NETLINK
-SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module @mount @obsolete @raw-io
+SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module @mount @obsolete @raw-io @reboot @swap
+SystemCallArchitectures=native
# Increase the default a bit in order to allow many simultaneous
# services being run since we keep one fd open per service. Also, when
diff --git a/units/systemd-localed.service.in b/units/systemd-localed.service.in
index df829e1164..90a913881a 100644
--- a/units/systemd-localed.service.in
+++ b/units/systemd-localed.service.in
@@ -8,7 +8,7 @@
[Unit]
Description=Locale Service
Documentation=man:systemd-localed.service(8) man:locale.conf(5) man:vconsole.conf(5)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/localed
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/localed
[Service]
ExecStart=@rootlibexecdir@/systemd-localed
@@ -18,11 +18,15 @@ CapabilityBoundingSet=
PrivateTmp=yes
PrivateDevices=yes
PrivateNetwork=yes
-ProtectSystem=yes
+ProtectSystem=strict
ProtectHome=yes
ProtectControlGroups=yes
ProtectKernelTunables=yes
+ProtectKernelModules=yes
MemoryDenyWriteExecute=yes
RestrictRealtime=yes
+RestrictNamespaces=yes
RestrictAddressFamilies=AF_UNIX
-SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module @mount @obsolete @raw-io
+SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module @mount @obsolete @raw-io @reboot @swap
+SystemCallArchitectures=native
+ReadWritePaths=/etc
diff --git a/units/systemd-logind.service.in b/units/systemd-logind.service.in
index 0b6de35733..bb4a23ec83 100644
--- a/units/systemd-logind.service.in
+++ b/units/systemd-logind.service.in
@@ -8,8 +8,8 @@
[Unit]
Description=Login Service
Documentation=man:systemd-logind.service(8) man:logind.conf(5)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/logind
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/logind
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/multiseat
Wants=user.slice
After=nss-user-lookup.target user.slice
@@ -27,8 +27,11 @@ WatchdogSec=3min
CapabilityBoundingSet=CAP_SYS_ADMIN CAP_MAC_ADMIN CAP_AUDIT_CONTROL CAP_CHOWN CAP_KILL CAP_DAC_READ_SEARCH CAP_DAC_OVERRIDE CAP_FOWNER CAP_SYS_TTY_CONFIG
MemoryDenyWriteExecute=yes
RestrictRealtime=yes
+RestrictNamespaces=yes
RestrictAddressFamilies=AF_UNIX AF_NETLINK AF_INET AF_INET6
-SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module @obsolete @raw-io
+SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module @obsolete @raw-io @reboot @swap
+SystemCallArchitectures=native
+FileDescriptorStoreMax=512
# Increase the default a bit in order to allow many simultaneous
# logins since we keep one fd open per session.
diff --git a/units/systemd-machined.service.in b/units/systemd-machined.service.in
index 911ead79ee..a4f86aa7c8 100644
--- a/units/systemd-machined.service.in
+++ b/units/systemd-machined.service.in
@@ -8,9 +8,10 @@
[Unit]
Description=Virtual Machine and Container Registration Service
Documentation=man:systemd-machined.service(8)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/machined
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/machined
Wants=machine.slice
After=machine.slice
+RequiresMountsFor=/var/lib/machines
[Service]
ExecStart=@rootlibexecdir@/systemd-machined
@@ -20,7 +21,8 @@ CapabilityBoundingSet=CAP_KILL CAP_SYS_PTRACE CAP_SYS_ADMIN CAP_SETGID CAP_SYS_C
MemoryDenyWriteExecute=yes
RestrictRealtime=yes
RestrictAddressFamilies=AF_UNIX AF_NETLINK AF_INET AF_INET6
-SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module @obsolete @raw-io
+SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module @obsolete @raw-io @reboot @swap
+SystemCallArchitectures=native
# Note that machined cannot be placed in a mount namespace, since it
# needs access to the host's mount namespace in order to implement the
diff --git a/units/systemd-networkd-wait-online.service.in b/units/systemd-networkd-wait-online.service.in
index a9bad7aa8f..a84e91906d 100644
--- a/units/systemd-networkd-wait-online.service.in
+++ b/units/systemd-networkd-wait-online.service.in
@@ -10,7 +10,7 @@ Description=Wait for Network to be Configured
Documentation=man:systemd-networkd-wait-online.service(8)
DefaultDependencies=no
Conflicts=shutdown.target
-Requisite=systemd-networkd.service
+Requires=systemd-networkd.service
After=systemd-networkd.service
Before=network-online.target
diff --git a/units/systemd-networkd.service.m4.in b/units/systemd-networkd.service.m4.in
index 2623b21947..15e6ad99d8 100644
--- a/units/systemd-networkd.service.m4.in
+++ b/units/systemd-networkd.service.m4.in
@@ -28,17 +28,21 @@ RestartSec=0
ExecStart=@rootlibexecdir@/systemd-networkd
WatchdogSec=3min
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_BROADCAST CAP_NET_RAW CAP_SETUID CAP_SETGID CAP_SETPCAP CAP_CHOWN CAP_DAC_OVERRIDE CAP_FOWNER
-ProtectSystem=full
+ProtectSystem=strict
ProtectHome=yes
ProtectControlGroups=yes
+ProtectKernelModules=yes
MemoryDenyWriteExecute=yes
RestrictRealtime=yes
RestrictAddressFamilies=AF_UNIX AF_NETLINK AF_INET AF_INET6 AF_PACKET
-SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module @mount @obsolete @raw-io
+SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module @mount @obsolete @raw-io @reboot @swap
+SystemCallArchitectures=native
+ReadWritePaths=/run/systemd
[Install]
WantedBy=multi-user.target
Also=systemd-networkd.socket
+Alias=dbus-org.freedesktop.network1.service
# We want to enable systemd-networkd-wait-online.service whenever this service
# is enabled. systemd-networkd-wait-online.service has
diff --git a/units/systemd-quotacheck.service.in b/units/systemd-quotacheck.service.in
index 5cb9bc3bc9..6b1999aa51 100644
--- a/units/systemd-quotacheck.service.in
+++ b/units/systemd-quotacheck.service.in
@@ -10,7 +10,7 @@ Description=File System Quota Check
Documentation=man:systemd-quotacheck.service(8)
DefaultDependencies=no
After=systemd-remount-fs.service
-Before=local-fs.target shutdown.target
+Before=remote-fs.target shutdown.target
ConditionPathExists=@QUOTACHECK@
[Service]
diff --git a/units/systemd-remount-fs.service.in b/units/systemd-remount-fs.service.in
index 8d9daacaa5..29d0674ab3 100644
--- a/units/systemd-remount-fs.service.in
+++ b/units/systemd-remount-fs.service.in
@@ -8,7 +8,7 @@
[Unit]
Description=Remount Root and Kernel File Systems
Documentation=man:systemd-remount-fs.service(8)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
DefaultDependencies=no
Conflicts=shutdown.target
After=systemd-fsck-root.service
diff --git a/units/systemd-resolved.service.m4.in b/units/systemd-resolved.service.m4.in
index 41f696abe5..931156a861 100644
--- a/units/systemd-resolved.service.m4.in
+++ b/units/systemd-resolved.service.m4.in
@@ -8,9 +8,9 @@
[Unit]
Description=Network Name Resolution
Documentation=man:systemd-resolved.service(8)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/resolved
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/writing-network-configuration-managers
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/writing-resolver-clients
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/resolved
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/writing-network-configuration-managers
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/writing-resolver-clients
After=systemd-networkd.service network.target
Before=network-online.target nss-lookup.target
Wants=nss-lookup.target
@@ -29,14 +29,17 @@ WatchdogSec=3min
CapabilityBoundingSet=CAP_SETUID CAP_SETGID CAP_SETPCAP CAP_CHOWN CAP_DAC_OVERRIDE CAP_FOWNER CAP_NET_RAW CAP_NET_BIND_SERVICE
PrivateTmp=yes
PrivateDevices=yes
-ProtectSystem=full
+ProtectSystem=strict
ProtectHome=yes
ProtectControlGroups=yes
ProtectKernelTunables=yes
+ProtectKernelModules=yes
MemoryDenyWriteExecute=yes
RestrictRealtime=yes
RestrictAddressFamilies=AF_UNIX AF_NETLINK AF_INET AF_INET6
-SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module @mount @obsolete @raw-io
+SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module @mount @obsolete @raw-io @reboot @swap
+SystemCallArchitectures=native
+ReadWritePaths=/run/systemd
[Install]
WantedBy=multi-user.target
diff --git a/units/systemd-timedated.service.in b/units/systemd-timedated.service.in
index e8c4d5ed4b..2b5f0744c9 100644
--- a/units/systemd-timedated.service.in
+++ b/units/systemd-timedated.service.in
@@ -8,7 +8,7 @@
[Unit]
Description=Time & Date Service
Documentation=man:systemd-timedated.service(8) man:localtime(5)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/timedated
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/timedated
[Service]
ExecStart=@rootlibexecdir@/systemd-timedated
@@ -16,11 +16,15 @@ BusName=org.freedesktop.timedate1
WatchdogSec=3min
CapabilityBoundingSet=CAP_SYS_TIME
PrivateTmp=yes
-ProtectSystem=yes
+ProtectSystem=strict
ProtectHome=yes
ProtectControlGroups=yes
ProtectKernelTunables=yes
+ProtectKernelModules=yes
MemoryDenyWriteExecute=yes
RestrictRealtime=yes
+RestrictNamespaces=yes
RestrictAddressFamilies=AF_UNIX
-SystemCallFilter=~@cpu-emulation @debug @keyring @module @mount @obsolete @raw-io
+SystemCallFilter=~@cpu-emulation @debug @keyring @module @mount @obsolete @raw-io @reboot @swap
+SystemCallArchitectures=native
+ReadWritePaths=/etc
diff --git a/units/systemd-timesyncd.service.in b/units/systemd-timesyncd.service.in
index 9a6c6ea60d..8d328bb80a 100644
--- a/units/systemd-timesyncd.service.in
+++ b/units/systemd-timesyncd.service.in
@@ -26,14 +26,18 @@ WatchdogSec=3min
CapabilityBoundingSet=CAP_SYS_TIME CAP_SETUID CAP_SETGID CAP_SETPCAP CAP_CHOWN CAP_DAC_OVERRIDE CAP_FOWNER
PrivateTmp=yes
PrivateDevices=yes
-ProtectSystem=full
+ProtectSystem=strict
ProtectHome=yes
ProtectControlGroups=yes
ProtectKernelTunables=yes
+ProtectKernelModules=yes
MemoryDenyWriteExecute=yes
RestrictRealtime=yes
+RestrictNamespaces=yes
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
-SystemCallFilter=~@cpu-emulation @debug @keyring @module @mount @obsolete @raw-io
+SystemCallFilter=~@cpu-emulation @debug @keyring @module @mount @obsolete @raw-io @reboot @swap
+SystemCallArchitectures=native
+ReadWritePaths=/var/lib/systemd
[Install]
WantedBy=sysinit.target
diff --git a/units/systemd-udevd.service.in b/units/systemd-udevd.service.in
index 46d637883b..fc037b5a5c 100644
--- a/units/systemd-udevd.service.in
+++ b/units/systemd-udevd.service.in
@@ -28,3 +28,4 @@ MountFlags=slave
MemoryDenyWriteExecute=yes
RestrictRealtime=yes
RestrictAddressFamilies=AF_UNIX AF_NETLINK AF_INET AF_INET6
+SystemCallArchitectures=native
diff --git a/units/tmp.mount.m4 b/units/tmp.mount.m4
index 0baecfd22f..3a333d22ec 100644
--- a/units/tmp.mount.m4
+++ b/units/tmp.mount.m4
@@ -6,9 +6,9 @@
# (at your option) any later version.
[Unit]
-Description=Temporary Directory
+Description=Temporary Directory (/tmp)
Documentation=man:hier(7)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
ConditionPathIsSymbolicLink=!/tmp
DefaultDependencies=no
Conflicts=umount.target
diff --git a/units/user/meson.build b/units/user/meson.build
new file mode 100644
index 0000000000..b507144c05
--- /dev/null
+++ b/units/user/meson.build
@@ -0,0 +1,33 @@
+units = [
+ 'basic.target',
+ 'bluetooth.target',
+ 'default.target',
+ 'exit.target',
+ 'graphical-session-pre.target',
+ 'graphical-session.target',
+ 'paths.target',
+ 'printer.target',
+ 'shutdown.target',
+ 'smartcard.target',
+ 'sockets.target',
+ 'sound.target',
+ 'timers.target',
+]
+
+foreach file : units
+ install_data(file,
+ install_dir : userunitdir)
+endforeach
+
+in_units = [
+ 'systemd-exit.service',
+]
+
+foreach file : in_units
+ gen = configure_file(
+ input : file + '.in',
+ output : file,
+ configuration : substs)
+ install_data(gen,
+ install_dir : userunitdir)
+endforeach